From 1c8c3458bcba19bc709f4e9b2ebdbcd375736f74 Mon Sep 17 00:00:00 2001 From: Justin Marshall Date: Fri, 7 Aug 2026 08:15:19 -0700 Subject: [PATCH] Fixed ctrl a/c etc. --- src/CMakeLists.txt | 4 +++ src/Opus/init2.c | 37 +++++++++++++++++++++----- src/Opus/initwin.c | 9 +++++-- src/Opus/wordwin.h | 7 +++-- src/Opus/wproc.c | 18 ++++++++++++- src/port/icons/ICON2_1.ico | Bin 0 -> 5350 bytes src/port/icons/ICON8_1.ico | Bin 0 -> 318 bytes src/port/original/opus_asm_movecmds.c | 4 +-- src/port/word1.rc | 2 ++ 9 files changed, 68 insertions(+), 13 deletions(-) create mode 100644 src/port/icons/ICON2_1.ico create mode 100644 src/port/icons/ICON8_1.ico diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 678053c..f83d51f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -977,6 +977,10 @@ add_test(NAME opus_word1_ui_test COMMAND $ $ ) set_tests_properties(opus_word1_ui_test PROPERTIES TIMEOUT 20) +add_test(NAME opus_word1_clipboard_shortcut_test + COMMAND $ $ --clipboard +) +set_tests_properties(opus_word1_clipboard_shortcut_test PROPERTIES TIMEOUT 20) add_test(NAME opus_word1_typing_test COMMAND $ $ --typing ) diff --git a/src/Opus/init2.c b/src/Opus/init2.c index edef863..9080d9f 100644 --- a/src/Opus/init2.c +++ b/src/Opus/init2.c @@ -502,6 +502,15 @@ BOOL fTutorial; AddKeyToKmp(hkmpBase, kcSubscript, bcmSubscript); AddKeyToKmp(hkmpBase, kcSuperscript, bcmSuperscript); AddKeyToKmp(hkmpBase, kcShowAll, bcmShowAll); +#ifdef OPUS_X64 + /* Word 95 editing accelerators. Register them in the original base + keymap so commands retain Word's normal selection/undo legality. */ + AddKeyToKmp(hkmpBase, KcCtrl('A'), bcmSelectAll); + AddKeyToKmp(hkmpBase, KcCtrl('C'), bcmCopy); + AddKeyToKmp(hkmpBase, KcCtrl('V'), bcmPaste); + AddKeyToKmp(hkmpBase, KcCtrl('X'), bcmCut); + AddKeyToKmp(hkmpBase, KcCtrl('Z'), bcmUndo); +#endif } Debug( vdbs.fReportHeap ? @@ -1281,8 +1290,10 @@ FCreateSysMenu() HDC hdcBitmap; HBITMAP hbmpOld; HPEN hpenOld; + HICON hiconDocument; int dxMenu; int dyMenu; + int dyIcon; dxMenu = GetSystemMetrics(SM_CXSMICON); dyMenu = GetSystemMetrics(SM_CYMENU); @@ -1310,12 +1321,26 @@ FCreateSysMenu() hbmpOld = SelectObject(hdcBitmap, hbmpSystem); PatBlt(hdcBitmap, 0, 0, dxMenu, dyMenu, WHITENESS); - hpenOld = SelectObject(hdcBitmap, GetStockObject(BLACK_PEN)); - MoveToEx(hdcBitmap, 3, 3, NULL); - LineTo(hdcBitmap, dxMenu - 3, dyMenu - 3); - MoveToEx(hdcBitmap, dxMenu - 4, 3, NULL); - LineTo(hdcBitmap, 2, dyMenu - 3); - SelectObject(hdcBitmap, hpenOld); + dyIcon = min(dxMenu, dyMenu); + hiconDocument = (HICON)LoadImage(vhInstance, MAKEINTRESOURCE(302), + IMAGE_ICON, dyIcon, dyIcon, LR_DEFAULTCOLOR); + if (hiconDocument != NULL) + { + DrawIconEx(hdcBitmap, (dxMenu - dyIcon) / 2, + (dyMenu - dyIcon) / 2, hiconDocument, dyIcon, dyIcon, + 0, NULL, DI_NORMAL); + DestroyIcon(hiconDocument); + } + else + { + /* Keep a recognizable fallback if the product resource is missing. */ + hpenOld = SelectObject(hdcBitmap, GetStockObject(BLACK_PEN)); + MoveToEx(hdcBitmap, 3, 3, NULL); + LineTo(hdcBitmap, dxMenu - 3, dyMenu - 3); + MoveToEx(hdcBitmap, dxMenu - 4, 3, NULL); + LineTo(hdcBitmap, 2, dyMenu - 3); + SelectObject(hdcBitmap, hpenOld); + } SelectObject(hdcBitmap, hbmpOld); DeleteDC(hdcBitmap); vsci.dxpBmpSystem = dxMenu; diff --git a/src/Opus/initwin.c b/src/Opus/initwin.c index 72967c7..7701c18 100644 --- a/src/Opus/initwin.c +++ b/src/Opus/initwin.c @@ -2159,9 +2159,14 @@ FInitHandles() vwWinVersion > 0x0299); #endif /* OPUS_X64 */ for (ilrd = 0; ilrd < ilrdRcdsIcoMax; ilrd++) - if ((*rglrdRcdsIco[ilrd].ph = fRes ? - LoadIcon(vhInstance, rglrdRcdsIco[ilrd].id+1) : + if ((*rglrdRcdsIco[ilrd].ph = +#ifdef OPUS_X64 + /* Native executable resource requested for the restored shell. */ + LoadIcon(vhInstance, MAKEINTRESOURCE(301))) +#else + fRes ? LoadIcon(vhInstance, rglrdRcdsIco[ilrd].id+1) : HLoadRes0(rglrdRcdsIco[ilrd].id)) +#endif == NULL) return fFalse; diff --git a/src/Opus/wordwin.h b/src/Opus/wordwin.h index c2c6478..c2c8de1 100644 --- a/src/Opus/wordwin.h +++ b/src/Opus/wordwin.h @@ -451,8 +451,11 @@ struct DRC { /* Key Map Entry */ typedef struct _kme { - int kc : 12; - int kt : 3; + /* These are encoded fields, not signed arithmetic values. Modern MSVC + sign-extends the historical plain-int bitfields (ktMacro 6 became -2), + which made every command key fail to dispatch in the 64-bit port. */ + unsigned kc : 12; + unsigned kt : 3; union { int w; /* generic */ BCM bcm; /* ktMacro */ diff --git a/src/Opus/wproc.c b/src/Opus/wproc.c index 343a24a..32dc161 100644 --- a/src/Opus/wproc.c +++ b/src/Opus/wproc.c @@ -1755,6 +1755,18 @@ LONG lParam; return (LRESULT)OpusGetWin95ZoomPercent(hwnd); case 79: return (LRESULT)selCur.chp.ico; + case 80: + { + extern BOOL FExecKc(); + return (LRESULT)FExecKc((int)lParam); + } + case 81: + { + extern KME * PkmeOfKcInChain(); + KME *pkme = PkmeOfKcInChain((int)lParam); + return (LRESULT)(pkme != 0 && pkme->kt == ktMacro + ? pkme->bcm : -1); + } } return (LRESULT) -1; #endif @@ -2545,7 +2557,11 @@ LInsert: /* Get current Ctrl key state; OurGetKeyState cannot be trusted (sez bradch(rp)) */ - vgrpfKeyBoardState |= (GetKeyState(VK_CONTROL)<0) ? wKbsControlMask : 0; + vgrpfKeyBoardState |= (GetKeyState(VK_CONTROL)<0 +#ifdef OPUS_X64 + || GetAsyncKeyState(VK_CONTROL)<0 +#endif + ) ? wKbsControlMask : 0; /* FUTURE: cursor keys will be in keymap someday... */ /* but because they're not, need to special case preview */ diff --git a/src/port/icons/ICON2_1.ico b/src/port/icons/ICON2_1.ico new file mode 100644 index 0000000000000000000000000000000000000000..5f57f9a0b7069044e533bf3642f868c7a5b17129 GIT binary patch literal 5350 zcmeH~v2PSd6vm%}lRHJ|&NLPU5)KtKk)^3TNFy&`L} zE?Zk0*8ldN$Y&yQ{(P;kiF|xUWMd=gm(e%h7untx@O}AyAo9rvB9~dSg?x&rKW!Pl zx?9F1Gg+28t_)=|nb7M*w4cPNBZNOS>E+#9f7G@+Ebrr|Y44!VN28tCjc3Z*YV$qY zNn&tE24#<5yWaF+%WqH?{Fdg6Vo(%I^Tl9L43YzlkHW8Up!%#VX2mGtBF&o~<7lVW znLXFEb4rYM!WF~wY2)&5Q}{8+H^A? z<2{>h_4~Sdu|6*R->+N7WV7)@#;eFr;3g|d22KUPYseX-hYXR6$Teg~>-;>jjV$V% zd!oB#$ssk(2;q;xU#s&)Ia7;^)HY)dS!?vDJr&QNu`lvX9Y|e-S`$*%1;)6bdbPN) z7c?s@9hZd`U7YKfiWI5~%%B`FLvfLh)L6R-xn>V9;EsrHmgZ%uslE=@V%U3`A zNCby?Bu7G09X5x}VRLHZouUwr-81mmJ$8>>m*v=V>^Vw~J;zQb0eiq6um=nQdqj`u zF<4~B)#2RX$g#-r9<%UV92^`R92^`Rj1n9i92^`R92^{sCLA0b92^`R92|@~92^`R z92^`R99+Z(4+jsYJa}iq%2;@=9xfg(9xk?JxOjql0(qQzxL6vP^b9;)JX|a-@bK{P z@bK{P@UT?D!^6SD!NWmQ=i%Yu;NcML4IWYoiIe`&Exno@SP?r1XQ?K34yT-;IRSDw z<;2dJ%!!>7J14dshsDND{G9kX@%4yu;^*WhheHmBoIL2UkrmrL7J9CFjN~8?FTgFp zBM{GyR(X(v0FR(N*q9wRivnB%TmmEl0j&h!5?B}j1q=Z${1E(bCIK!%^I=@H8uS#f z!6CvS!Xd&T!Xd)J$_Wku4iOF!4gn6hLBPWy!Xd&T!U5L^b~r>hL^wnUMB)dWMHWUt z9v>dv!y}q+#d!HhzLndzZwn6^xqJ7nJb3Ux9zA*_dwYBGd54n#sva9!icK9<*{i>?kqE)N31$wnX)xutuZ*Q`UZ~mn?y)Xa! z_*Z59r&;*t_uE82+5gXn^GI!RM$1_`mY+&q);C*K>QrZ|&-d`~a8DG!XQNf{hf>ve zMsMSTR{}KnJvlW%%jXcciI0v>Td=@G9Jk6pjXD@<0$My!?qvg8sLu2(<3&?scpaTW zXvx0@sPP&qom7nNBkvfWO5K`&8#Mu{<{4HU!>jXz*EEr=)T(kk-XD*vs&^cZ+jI`E zQUGNHpR$@xS#c6?>@}@Cv~33#psL2x{po&(f6|%!J}Ld?eqAAn>hOaF(z6bkd zeEo_ce~Uj3e+&Ku{LT22 z@HgT+;BUkq+p6umGoST-k7g#NsmXCyeG{Sqo$pNR`Hr>zV%=Y>`<=Sy#?<*W?X9)_A7+RkaR2}S literal 0 HcmV?d00001 diff --git a/src/port/icons/ICON8_1.ico b/src/port/icons/ICON8_1.ico new file mode 100644 index 0000000000000000000000000000000000000000..630dff20cbd9333cd22683f5ad41917ef4dd624d GIT binary patch literal 318 zcmaKmK@P$&3TkHBVl%q;1xG&na)tXPha>?=?QB%0~_DE5kcPDj2xT8A_p;XnK hgh%{D;eU99$HM5>oilDuI|uIXaFa&98Yj>F;Rz-0MJ@mU literal 0 HcmV?d00001 diff --git a/src/port/original/opus_asm_movecmds.c b/src/port/original/opus_asm_movecmds.c index 0ad003a..76709d1 100644 --- a/src/port/original/opus_asm_movecmds.c +++ b/src/port/original/opus_asm_movecmds.c @@ -49,8 +49,8 @@ typedef struct _OPUS_NATIVE_SYT typedef struct _OPUS_NATIVE_KME { - int kc : 12; - int kt : 3; + unsigned kc : 12; + unsigned kt : 3; union { int w; void *pfn; diff --git a/src/port/word1.rc b/src/port/word1.rc index 5b79fab..9910e19 100644 --- a/src/port/word1.rc +++ b/src/port/word1.rc @@ -2,6 +2,8 @@ 1 RT_MANIFEST "winword.manifest" 201 BITMAP "assets\\word95-toolbar.bmp" +301 ICON "icons\\ICON8_1.ico" +302 ICON "icons\\ICON2_1.ico" VS_VERSION_INFO VERSIONINFO FILEVERSION 0,2,0,0