this repo has no description
at main 6299 lines 133 kB view raw
1/* 2 OSGLUWIN.c 3 4 Copyright (C) 2009 Philip Cummins, Weston Pawlowski, 5 Bradford L. Barrett, Paul C. Pratt, Fabio Concas 6 7 You can redistribute this file and/or modify it under the terms 8 of version 2 of the GNU General Public License as published by 9 the Free Software Foundation. You should have received a copy 10 of the license along with this file; see the file COPYING. 11 12 This file is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 license for more details. 16*/ 17 18/* 19 Operating System GLUe for microsoft WINdows 20 21 All operating system dependent code for the 22 Microsoft Windows platform should go here. 23 24 This code is descended from Weston Pawlowski's Windows 25 port of vMac, by Philip Cummins. 26 Adapted by Fabio Concas to run on Pocket PC 2003 devices. 27 28 The main entry point '_tWinMain' is at the end of this file. 29*/ 30 31#include "OSGCOMUI.h" 32#include "OSGCOMUD.h" 33 34#ifdef WantOSGLUWIN 35 36 37/* --- adapting to API/ABI version differences --- */ 38 39#ifdef UNICODE 40#define MyUseUni 1 41#else 42#define MyUseUni 0 43#endif 44 45#ifdef _WIN32_WCE 46#define UseWinCE 1 47#else 48#define UseWinCE 0 49#endif 50 51 52#define My_CSIDL_APPDATA 0x001a 53 54typedef BOOL (WINAPI *SHGetSpecialFolderPathProcPtr) ( 55 HWND hwndOwner, 56 LPTSTR lpszPath, 57 int nFolder, 58 BOOL fCreate 59); 60LOCALVAR SHGetSpecialFolderPathProcPtr MySHGetSpecialFolderPath = NULL; 61LOCALVAR blnr DidSHGetSpecialFolderPath = falseblnr; 62 63LOCALFUNC blnr HaveMySHGetSpecialFolderPath(void) 64{ 65 if (! DidSHGetSpecialFolderPath) { 66 HMODULE hLibModule = LoadLibrary(TEXT("shell32.dll")); 67 if (NULL != hLibModule) { 68 MySHGetSpecialFolderPath = 69 (SHGetSpecialFolderPathProcPtr) 70 GetProcAddress(hLibModule, 71#if MyUseUni 72 TEXT("SHGetSpecialFolderPathW") 73#else 74 TEXT("SHGetSpecialFolderPathA") 75#endif 76 ); 77 /* FreeLibrary(hLibModule); */ 78 } 79 DidSHGetSpecialFolderPath = trueblnr; 80 } 81 return (MySHGetSpecialFolderPath != NULL); 82} 83 84 85/* --- end of adapting to API/ABI version differences --- */ 86 87#if MyUseUni 88#define NeedCell2UnicodeMap 1 89#else 90#define NeedCell2WinAsciiMap 1 91#endif 92#define NeedRequestInsertDisk 1 93#define NeedDoMoreCommandsMsg 1 94#define NeedDoAboutMsg 1 95 96#include "INTLCHAR.h" 97 98 99LOCALPROC NativeStrFromCStr(LPTSTR r, char *s, blnr AddEllipsis) 100{ 101 ui3b ps[ClStrMaxLength]; 102 int i; 103 int L; 104 105 ClStrFromSubstCStr(&L, ps, s); 106 107 for (i = 0; i < L; ++i) { 108 r[i] = (TCHAR) 109#if MyUseUni 110 Cell2UnicodeMap[ps[i]]; 111#else 112 Cell2WinAsciiMap[ps[i]]; 113#endif 114 } 115 116 if (AddEllipsis) { 117#if MyUseUni 118 r[L] = 0x2026; 119 ++L; 120#else 121 r[L] = '.'; 122 ++L; 123 r[L] = '.'; 124 ++L; 125 r[L] = '.'; 126 ++L; 127#endif 128 } 129 130 r[L] = 0; 131} 132 133LOCALFUNC LPTSTR FindLastTerm(LPTSTR s, TCHAR delim) 134{ 135 TCHAR c; 136 LPTSTR p0 = s; 137 LPTSTR p = (LPTSTR)nullpr; 138 139 while ((c = *p0++) != (TCHAR)('\0')) { 140 if (c == delim) { 141 p = p0; 142 } 143 } 144 145 return p; 146} 147 148LOCALVAR HINSTANCE AppInstance; 149 150LOCALFUNC blnr GetAppDir(LPTSTR pathName) 151/* be sure at least _MAX_PATH long! */ 152{ 153 if (GetModuleFileName(AppInstance, pathName, _MAX_PATH) == 0) { 154 /* MacMsg("error", "GetModuleFileName failed", falseblnr); */ 155 } else { 156 LPTSTR p = FindLastTerm(pathName, 157 (TCHAR)('\\')); 158 if (p == nullpr) { 159 /* MacMsg("error", "strrchr failed", falseblnr); */ 160 } else { 161 *--p = (TCHAR)('\0'); 162 return trueblnr; 163 } 164 } 165 return falseblnr; 166} 167 168/* --- sending debugging info to file --- */ 169 170#if dbglog_HAVE 171 172LOCALVAR HANDLE dbglog_File = INVALID_HANDLE_VALUE; 173 174LOCALFUNC blnr dbglog_open0(void) 175{ 176 TCHAR pathName[_MAX_PATH]; 177 TCHAR Child0[] = TEXT("\\dbglog.txt"); 178 size_t newlen; 179 180 if (GetAppDir(pathName)) { 181 newlen = _tcslen(pathName) + _tcslen(Child0); 182 if (newlen + 1 < _MAX_PATH) { 183 _tcscat(pathName, Child0); 184 185 dbglog_File = CreateFile( 186 pathName, /* pointer to name of the file */ 187 GENERIC_READ + GENERIC_WRITE, 188 /* access (read-write) mode */ 189 0, /* share mode */ 190 NULL, /* pointer to security descriptor */ 191 OPEN_ALWAYS, /* how to create */ 192 FILE_ATTRIBUTE_NORMAL, /* file attributes */ 193 NULL /* handle to file with attributes to copy */ 194 ); 195 if (INVALID_HANDLE_VALUE == dbglog_File) { 196 /* report error (how?) */ 197 } else if (SetFilePointer( 198 dbglog_File, /* handle of file */ 199 0, /* number of bytes to move file pointer */ 200 nullpr, 201 /* address of high-order word of distance to move */ 202 FILE_BEGIN /* how to move */ 203 ) != 0) 204 { 205 /* report error (how?) */ 206 } 207 } 208 } 209 210 return (INVALID_HANDLE_VALUE != dbglog_File); 211} 212 213LOCALPROC dbglog_write0(char *s, uimr L) 214{ 215 DWORD BytesWritten; 216 217 if (INVALID_HANDLE_VALUE != dbglog_File) { 218 if (! WriteFile(dbglog_File, /* handle of file to read */ 219 (LPVOID)s, /* address of buffer that receives data */ 220 (DWORD)L, /* number of bytes to read */ 221 &BytesWritten, /* address of number of bytes read */ 222 nullpr) /* address of structure for data */ 223 || ((ui5b)BytesWritten != L)) 224 { 225 /* report error (how?) */ 226 } 227 } 228} 229 230LOCALPROC dbglog_close0(void) 231{ 232 if (INVALID_HANDLE_VALUE != dbglog_File) { 233 if (! SetEndOfFile(dbglog_File)) { 234 /* report error (how?) */ 235 } 236 (void) CloseHandle(dbglog_File); 237 dbglog_File = INVALID_HANDLE_VALUE; 238 } 239} 240 241#endif 242 243#include "COMOSGLU.h" 244 245#ifndef InstallFileIcons 246#define InstallFileIcons 0 247#endif 248 249/* Resource Ids */ 250 251#define IDI_VMAC 256 252#if InstallFileIcons 253#define IDI_ROM 257 254#define IDI_DISK 258 255#endif 256 257/* --- some simple utilities --- */ 258 259#define TestBit(i, p) (((unsigned long)(i) & PowOf2(p)) != 0) 260 261GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount) 262{ 263/* 264 must work even if blocks overlap in memory 265*/ 266 (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount); 267} 268 269/* --- Parameter buffers --- */ 270 271#if IncludePbufs 272LOCALVAR HGLOBAL PbufDat[NumPbufs]; 273#endif 274 275#if IncludePbufs 276LOCALFUNC tMacErr PbufNewFromHandle(HGLOBAL h, ui5b count, tPbuf *r) 277{ 278 tPbuf i; 279 tMacErr err; 280 281 if (! FirstFreePbuf(&i)) { 282 (void) GlobalFree(h); 283 err = mnvm_miscErr; 284 } else { 285 *r = i; 286 PbufDat[i] = h; 287 PbufNewNotify(i, count); 288 err = mnvm_noErr; 289 } 290 291 return err; 292} 293#endif 294 295#if IncludePbufs 296GLOBALOSGLUFUNC tMacErr PbufNew(ui5b count, tPbuf *r) 297{ 298 HGLOBAL h; 299 tMacErr err = mnvm_miscErr; 300 301 h = GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT, count); 302 if (h != NULL) { 303 /* need to clear h */ 304 err = PbufNewFromHandle(h, count, r); 305 } 306 307 return err; 308} 309#endif 310 311#if IncludePbufs 312GLOBALOSGLUPROC PbufDispose(tPbuf i) 313{ 314 (void) GlobalFree(PbufDat[i]); 315 PbufDisposeNotify(i); 316} 317#endif 318 319#if IncludePbufs 320LOCALPROC UnInitPbufs(void) 321{ 322 tPbuf i; 323 324 for (i = 0; i < NumPbufs; ++i) { 325 if (PbufIsAllocated(i)) { 326 PbufDispose(i); 327 } 328 } 329} 330#endif 331 332#if IncludePbufs 333#define PbufHaveLock 1 334#endif 335 336#if IncludePbufs 337LOCALFUNC ui3p PbufLock(tPbuf i) 338{ 339 HGLOBAL h = PbufDat[i]; 340 return (ui3p)GlobalLock(h); 341} 342#endif 343 344#if IncludePbufs 345LOCALPROC PbufUnlock(tPbuf i) 346{ 347 (void) GlobalUnlock(PbufDat[i]); 348} 349#endif 350 351#if IncludePbufs 352GLOBALOSGLUPROC PbufTransfer(ui3p Buffer, 353 tPbuf i, ui5r offset, ui5r count, blnr IsWrite) 354{ 355 HGLOBAL h = PbufDat[i]; 356 ui3p p0 = GlobalLock(h); 357 if (p0 != NULL) { 358 void *p = p0 + offset; 359 if (IsWrite) { 360 (void) memcpy(p, Buffer, count); 361 } else { 362 (void) memcpy(Buffer, p, count); 363 } 364 } 365 (void) GlobalUnlock(h); 366} 367#endif 368 369/* --- control mode and internationalization --- */ 370 371#include "CONTROLM.h" 372 373/* --- main window info --- */ 374 375LOCALVAR HWND MainWnd = NULL; 376 377LOCALVAR int WndX; 378LOCALVAR int WndY; 379 380#if UseWinCE 381LOCALVAR short oldOrientation; 382LOCALVAR unsigned long oldDisplayOrientation; 383#endif 384 385#if VarFullScreen 386LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0); 387#endif 388 389#if EnableMagnify 390LOCALVAR blnr UseMagnify = (WantInitMagnify != 0); 391#endif 392 393#if MayFullScreen 394LOCALVAR short hOffset; 395LOCALVAR short vOffset; 396#endif 397 398/* cursor hiding */ 399 400LOCALVAR blnr HaveCursorHidden = falseblnr; 401LOCALVAR blnr WantCursorHidden = falseblnr; 402 403LOCALPROC ForceShowCursor(void) 404{ 405 if (HaveCursorHidden) { 406 HaveCursorHidden = falseblnr; 407 (void) ShowCursor(TRUE); 408 SetCursor(LoadCursor(NULL, IDC_ARROW)); 409 } 410} 411 412/* cursor moving */ 413 414LOCALFUNC blnr MyMoveMouse(si4b h, si4b v) 415{ 416 POINT NewMousePos; 417 ui5b difftime; 418 blnr IsOk; 419 DWORD StartTime = GetTickCount(); 420 LONG x = h; 421 LONG y = v; 422 423#if VarFullScreen 424 if (UseFullScreen) 425#endif 426#if MayFullScreen 427 { 428 x -= ViewHStart; 429 y -= ViewVStart; 430 } 431#endif 432 433#if EnableMagnify 434 if (UseMagnify) { 435 x *= MyWindowScale; 436 y *= MyWindowScale; 437 } 438#endif 439 440#if VarFullScreen 441 if (UseFullScreen) 442#endif 443#if MayFullScreen 444 { 445 x += hOffset; 446 y += vOffset; 447 } 448#endif 449 450 x += WndX; 451 y += WndY; 452 453 do { 454 (void) SetCursorPos(x, y); 455 if (! GetCursorPos(&NewMousePos)) { 456 IsOk = falseblnr; 457 } else { 458 IsOk = (x == NewMousePos.x) && (y == NewMousePos.y); 459 } 460 difftime = (ui5b)(GetTickCount() - StartTime); 461 } while ((! IsOk) && (difftime < 100)); 462 return IsOk; 463} 464 465#if EnableFSMouseMotion 466LOCALPROC StartSaveMouseMotion(void) 467{ 468 if (! HaveMouseMotion) { 469 if (MyMoveMouse(ViewHStart + (ViewHSize / 2), 470 ViewVStart + (ViewVSize / 2))) 471 { 472 SavedMouseH = ViewHStart + (ViewHSize / 2); 473 SavedMouseV = ViewVStart + (ViewVSize / 2); 474 HaveMouseMotion = trueblnr; 475 } 476 } 477} 478#endif 479 480#if EnableFSMouseMotion 481LOCALPROC StopSaveMouseMotion(void) 482{ 483 if (HaveMouseMotion) { 484 (void) MyMoveMouse(CurMouseH, CurMouseV); 485 HaveMouseMotion = falseblnr; 486 } 487} 488#endif 489 490LOCALVAR blnr MyMouseCaptured = falseblnr; 491 492LOCALPROC MyMouseCaptureSet(blnr v) 493{ 494 if (v != MyMouseCaptured) { 495 if (v) { 496 (void) SetCapture(MainWnd); 497 } else { 498 (void) ReleaseCapture(); 499 } 500 MyMouseCaptured = v; 501 } 502} 503 504LOCALPROC SetCurMouseButton(blnr v) 505{ 506 MyMouseButtonSet(v); 507 MyMouseCaptureSet(v); 508} 509 510/* keyboard */ 511 512/* these constants weren't in the header files I have */ 513#define myVK_Subtract 0xBD 514#define myVK_Equal 0xBB 515#define myVK_BackSlash 0xDC 516#define myVK_Comma 0xBC 517#define myVK_Period 0xBE 518#define myVK_Slash 0xBF 519#define myVK_SemiColon 0xBA 520#define myVK_SingleQuote 0xDE 521#define myVK_LeftBracket 0xDB 522#define myVK_RightBracket 0xDD 523#define myVK_Grave 0xC0 524 525/* some new ones, need to check if in all header versions */ 526#define myVK_PRIOR 0x21 527#define myVK_NEXT 0x22 528#define myVK_END 0x23 529#define myVK_HOME 0x24 530#define myVK_INSERT 0x2D 531#define myVK_DELETE 0x2E 532#define myVK_HELP 0x2F 533#define myVK_SCROLL 0x91 534#define myVK_SNAPSHOT 0x2C 535#define myVK_PAUSE 0x13 536#define myVK_CLEAR 0x0C 537 538#define myVK_OEM_8 0xDF 539#define myVK_OEM_102 0xE2 540 541#ifndef ItnlKyBdFix 542#define ItnlKyBdFix 0 543#endif 544 545#if ItnlKyBdFix 546LOCALVAR ui3b MyVkMapA[256]; 547#endif 548 549#if ItnlKyBdFix 550LOCALPROC MyVkSwapZY(void) 551{ 552 MyVkMapA['Z'] = 'Y'; 553 MyVkMapA['Y'] = 'Z'; 554} 555#endif 556 557#if ItnlKyBdFix 558LOCALPROC MyVkSwapGraveQuote(void) 559{ 560 MyVkMapA[myVK_Grave] = myVK_SingleQuote; 561 MyVkMapA[myVK_SingleQuote] = myVK_Grave; 562} 563#endif 564 565#if ItnlKyBdFix 566LOCALPROC MyVkSwapSlashSubtract(void) 567{ 568 MyVkMapA[myVK_Slash] = myVK_Subtract; 569 MyVkMapA[myVK_Subtract] = myVK_Slash; 570} 571#endif 572 573#if ItnlKyBdFix 574LOCALPROC MyVkSwapAQZWGraveQuote(void) 575{ 576 MyVkSwapGraveQuote(); 577 MyVkMapA['A'] = 'Q'; 578 MyVkMapA['Q'] = 'A'; 579 MyVkMapA['Z'] = 'W'; 580 MyVkMapA['W'] = 'Z'; 581} 582#endif 583 584#if ItnlKyBdFix 585LOCALPROC MyVkMapBelgian(void) 586{ 587 MyVkSwapAQZWGraveQuote(); 588 MyVkMapA['M'] = myVK_SemiColon; 589 MyVkMapA[myVK_SemiColon] = myVK_RightBracket; 590 MyVkMapA[myVK_RightBracket] = myVK_LeftBracket; 591 MyVkMapA[myVK_LeftBracket] = myVK_Subtract; 592 MyVkMapA[myVK_Subtract] = myVK_Equal; 593 MyVkMapA[myVK_Equal] = myVK_Slash; 594 MyVkMapA[myVK_Slash] = myVK_Period; 595 MyVkMapA[myVK_Period] = myVK_Comma; 596 MyVkMapA[myVK_Comma] = 'M'; 597} 598#endif 599 600#if ItnlKyBdFix 601LOCALPROC MyVkMapSwiss(void) 602{ 603 MyVkSwapZY(); 604 MyVkMapA[myVK_OEM_8] = myVK_BackSlash; 605 MyVkMapA[myVK_BackSlash] = myVK_SingleQuote; 606 MyVkMapA[myVK_SingleQuote] = myVK_SemiColon; 607 MyVkMapA[myVK_SemiColon] = myVK_LeftBracket; 608 MyVkMapA[myVK_LeftBracket] = myVK_Subtract; 609 MyVkMapA[myVK_Subtract] = myVK_Slash; 610 MyVkMapA[myVK_Slash] = myVK_Grave; 611 MyVkMapA[myVK_Grave] = myVK_RightBracket; 612 MyVkMapA[myVK_RightBracket] = myVK_Equal; 613} 614#endif 615 616#if ItnlKyBdFix 617LOCALPROC MyVkMapDanish(void) 618{ 619 MyVkMapA[myVK_Equal] = myVK_Subtract; 620 MyVkMapA[myVK_Subtract] = myVK_Slash; 621 MyVkMapA[myVK_Slash] = myVK_BackSlash; 622 MyVkMapA[myVK_BackSlash] = myVK_Grave; 623 MyVkMapA[myVK_Grave] = myVK_SemiColon; 624 MyVkMapA[myVK_SemiColon] = myVK_RightBracket; 625 MyVkMapA[myVK_RightBracket] = myVK_LeftBracket; 626 MyVkMapA[myVK_LeftBracket] = myVK_Equal; 627} 628#endif 629 630#if ItnlKyBdFix 631LOCALPROC MyVkMapBritish(void) 632{ 633 MyVkMapA[myVK_OEM_8] = myVK_Grave; 634 MyVkMapA[myVK_Grave] = myVK_SingleQuote; 635 MyVkMapA[myVK_SingleQuote] = myVK_BackSlash; 636 MyVkMapA[myVK_BackSlash] = myVK_OEM_102; 637} 638#endif 639 640#if ItnlKyBdFix 641LOCALPROC MyVkMapSpanish(void) 642{ 643 MyVkMapA[myVK_SemiColon] = myVK_LeftBracket; 644 MyVkMapA[myVK_LeftBracket] = myVK_Subtract; 645 MyVkMapA[myVK_Subtract] = myVK_Slash; 646 MyVkMapA[myVK_Slash] = myVK_BackSlash; 647 MyVkMapA[myVK_BackSlash] = myVK_Grave; 648 MyVkMapA[myVK_Grave] = myVK_SemiColon; 649 650 MyVkMapA[myVK_RightBracket] = myVK_Equal; 651 MyVkMapA[myVK_Equal] = myVK_RightBracket; 652} 653#endif 654 655#if ItnlKyBdFix 656LOCALPROC MyVkMapDutch(void) 657{ 658 MyVkSwapGraveQuote(); 659 MyVkMapA[myVK_SemiColon] = myVK_RightBracket; 660 MyVkMapA[myVK_RightBracket] = myVK_LeftBracket; 661 MyVkMapA[myVK_LeftBracket] = myVK_Subtract; 662 MyVkMapA[myVK_Subtract] = myVK_Slash; 663 MyVkMapA[myVK_Slash] = myVK_Equal; 664 MyVkMapA[myVK_Equal] = myVK_SemiColon; 665} 666#endif 667 668#if ItnlKyBdFix 669LOCALPROC MyVkMapGreekIBM(void) 670{ 671 MyVkSwapSlashSubtract(); 672 MyVkMapA[myVK_LeftBracket] = myVK_Equal; 673 MyVkMapA[myVK_Equal] = myVK_LeftBracket; 674} 675#endif 676 677#if ItnlKyBdFix 678LOCALPROC MyVkMapFrench(void) 679{ 680 MyVkSwapAQZWGraveQuote(); 681 MyVkMapA['M'] = myVK_SemiColon; 682 MyVkMapA[myVK_SemiColon] = myVK_RightBracket; 683 MyVkMapA[myVK_RightBracket] = myVK_LeftBracket; 684 MyVkMapA[myVK_LeftBracket] = myVK_Subtract; 685 MyVkMapA[myVK_Comma] = 'M'; 686 MyVkMapA[myVK_Period] = myVK_Comma; 687 MyVkMapA[myVK_Slash] = myVK_Period; 688 MyVkMapA[myVK_OEM_8] = myVK_Slash; 689} 690#endif 691 692#if ItnlKyBdFix 693LOCALPROC MyVkMapGerman(void) 694{ 695 MyVkSwapZY(); 696 MyVkMapSpanish(); 697} 698#endif 699 700#if ItnlKyBdFix 701LOCALPROC MyVkMapBosnian(void) 702{ 703 MyVkSwapZY(); 704 /* not in Windows 95 */ 705 MyVkSwapSlashSubtract(); 706} 707#endif 708 709#if ItnlKyBdFix 710LOCALPROC MyVkMapBulgarian(void) 711{ 712 MyVkMapA[myVK_OEM_8] = myVK_Comma; 713 MyVkMapA[myVK_Comma] = 'Q'; 714 MyVkMapA['Q'] = myVK_Period; 715 MyVkMapA[myVK_Period] = myVK_Equal; 716} 717#endif 718 719#if ItnlKyBdFix 720LOCALPROC MyVkMapFromLayout(uimr sv) 721{ 722 int i; 723 724 for (i = 0; i < 256; ++i) { 725 MyVkMapA[i] = i; 726 } 727 728 switch (sv) { 729 case 0x00000409: 730 /* United States 101 */ 731 break; 732 case 0x0000041c: 733 /* Albanian; */ 734 MyVkSwapZY(); 735 break; 736 case 0x0000042B: 737 /* Armenian Eastern; */ 738 MyVkMapDutch(); 739 break; 740 case 0x0001042B: 741 /* Armenian Western; */ 742 MyVkMapDutch(); 743 break; 744 case 0x0000042C: 745 /* not in Windows 95 */ 746 /* Azeri Latin */ 747 MyVkMapBritish(); 748 break; 749 case 0x0001080C: 750 /* Belgian (comma) */ 751 MyVkMapBelgian(); 752 break; 753 case 0x0000080c: 754 /* Belgian French */ 755 MyVkMapBelgian(); 756 break; 757 case 0x00000813: 758 /* not in Windows 95 */ 759 /* Belgian (period); */ 760 MyVkMapBelgian(); 761 break; 762 case 0x0000141A: 763 /* not in Windows 95 */ 764 /* Bosnian */ 765 MyVkMapBosnian(); 766 break; 767 case 0x00000809: 768 /* British / United Kingdom */ 769 MyVkMapBritish(); 770 break; 771 case 0x00000452: 772 /* not in Windows 95 */ 773 /* United Kingdom Extended */ 774 MyVkMapBritish(); 775 break; 776 case 0x00000402: 777 /* Bulgarian */ 778 /* not same in Windows 95 */ 779 MyVkMapBulgarian(); 780 break; 781 case 0x00030402: 782 /* Bulgarian */ 783 MyVkMapBulgarian(); 784 break; 785 case 0x00020402: 786 /* Bulgarian (Phonetic) */ 787 MyVkMapBosnian(); 788 break; 789 case 0x00001009: 790 /* Canadian Multilingual */ 791 /* not in Windows 95 */ 792 MyVkSwapGraveQuote(); 793 break; 794 case 0x00011009: 795 /* Canadian Standard */ 796 MyVkSwapGraveQuote(); 797 break; 798 case 0x0000041a: 799 /* Croatian */ 800 MyVkMapBosnian(); 801 break; 802 case 0x00000405: 803 /* Czech */ 804 MyVkMapBosnian(); 805#if 0 806 /* but Windows 7 gives */ 807 MyVkSwapZY(); 808 MyVkMapA[myVK_Equal] = myVK_Subtract; 809 MyVkMapA[myVK_Subtract] = myVK_Slash; 810 MyVkMapA[myVK_Slash] = myVK_Equal; 811#endif 812 break; 813 case 0x00020405: 814 /* Czech (Programmers) */ 815 /* only in Windows 95 */ 816 /* MyVkSwapZY(); */ 817 break; 818 case 0x00010405: 819 /* Czech (Qwerty) */ 820 /* only in Windows 95 */ 821 /* MyVkSwapZY(); */ 822 break; 823 case 0x00000406: 824 /* Danish */ 825 MyVkMapDanish(); 826 break; 827 case 0x00000413: 828 /* Dutch */ 829 MyVkMapDutch(); 830 break; 831 case 0x00000425: 832 /* Estonian */ 833 MyVkMapA[myVK_Grave] = myVK_LeftBracket; 834 MyVkMapA[myVK_LeftBracket] = myVK_RightBracket; 835 MyVkMapA[myVK_RightBracket] = myVK_Slash; 836 MyVkMapA[myVK_Slash] = myVK_SingleQuote; 837 MyVkMapA[myVK_SingleQuote] = myVK_Grave; 838 /* only in Windows 95 ? */ 839 /* MyVkMapA[VK_DECIMAL] = VK_DELETE; */ 840 break; 841 case 0x00000438: 842 /* Faeroe Islands */ 843 MyVkMapDanish(); 844 break; 845 case 0x0000040b: 846 /* Finnish */ 847 MyVkMapDanish(); 848 break; 849 case 0x0001083B: 850 /* not in Windows 95 */ 851 /* Finnish with Sami */ 852 MyVkMapDanish(); 853 break; 854 case 0x0000040c: 855 /* v = kMyKbdFrench; */ 856 /* French */ 857 MyVkMapFrench(); 858 break; 859 case 0x00000c0c: 860 /* French Canadian */ 861 MyVkSwapGraveQuote(); 862 break; 863 case 0x00011809: 864 /* not in Windows 95 */ 865 /* Gaelic */ 866 MyVkMapBritish(); 867 break; 868 case 0x00010407: 869 /* German (IBM) */ 870 MyVkMapGerman(); 871 break; 872 case 0x00000407: 873 /* German (Standard) */ 874 MyVkMapGerman(); 875 break; 876 case 0x00010408: 877 /* Greek IBM 220 */ 878 /* not in Windows 95 */ 879 MyVkMapGreekIBM(); 880 break; 881 case 0x00030408: 882 /* Greek IBM 319 */ 883 /* not in Windows 95 */ 884 MyVkMapGreekIBM(); 885 break; 886 case 0x00020408: 887 /* Greek Latin IBM 220 */ 888 /* not in Windows 95 */ 889 MyVkSwapSlashSubtract(); 890 break; 891 case 0x00040408: 892 /* Greek Latin IBM 319 */ 893 /* not in Windows 95 */ 894 MyVkSwapSlashSubtract(); 895 break; 896 case 0x0000040e: 897 /* Hungarian */ 898 MyVkMapBosnian(); 899 MyVkMapA[myVK_Grave] = '0'; 900 MyVkMapA['0'] = myVK_Grave; 901 break; 902 case 0x0001040E: 903 /* Hungarian (101 Keys) */ 904 MyVkMapA[myVK_Grave] = '0'; 905 MyVkMapA['0'] = myVK_Grave; 906 break; 907 case 0x0000040f: 908 /* Icelandic */ 909 MyVkMapDanish(); 910 break; 911 case 0x00001809: 912 /* Irish */ 913 MyVkMapBritish(); 914 break; 915 case 0x00000410: 916 /* Italian */ 917 MyVkMapSpanish(); 918 break; 919 case 0x00010410: 920 /* Italian 142 */ 921 MyVkMapSpanish(); 922 break; 923 case 0x0000080a: 924 /* Latin American */ 925 MyVkMapSpanish(); 926 break; 927 case 0x0000046E: 928 /* Luxembourgish */ 929 MyVkMapSwiss(); 930 break; 931 case 0x00000414: 932 /* Norwegian */ 933 MyVkMapDanish(); 934 break; 935 case 0x0000043B: 936 /* Norwegian with Sami */ 937 MyVkMapDanish(); 938 break; 939 case 0x00010415: 940 /* Polish (214) */ 941 MyVkSwapZY(); 942 /* not in windows 95 */ 943 MyVkMapA[myVK_Equal] = myVK_Subtract; 944 MyVkMapA[myVK_Subtract] = myVK_Slash; 945 MyVkMapA[myVK_Slash] = myVK_Equal; 946 break; 947 case 0x00010416: 948 /* Porguguese (Brazilian ABNT2) */ 949 /* MyVkMapA[myVK_OEM_8] = ??; */ 950 /* MyVkMapA[VK_SEPARATOR] = ??; */ 951 break; 952 case 0x00000816: 953 /* Porguguese (Standard) */ 954 MyVkMapA[myVK_SemiColon] = myVK_RightBracket; 955 MyVkMapA[myVK_RightBracket] = myVK_Equal; 956 MyVkMapA[myVK_Equal] = myVK_LeftBracket; 957 MyVkMapA[myVK_LeftBracket] = myVK_Subtract; 958 MyVkMapA[myVK_Subtract] = myVK_Slash; 959 MyVkMapA[myVK_Slash] = myVK_BackSlash; 960 MyVkMapA[myVK_BackSlash] = myVK_Grave; 961 MyVkMapA[myVK_Grave] = myVK_SemiColon; 962 break; 963 case 0x00000418: 964 /* Romanian (Legacy) */ 965 MyVkSwapZY(); 966 /* only in Windows 95 */ 967 /* MyVkSwapSlashSubtract(); */ 968 break; 969 case 0x0002083B: 970 /* Sami Extended Finland-Sweden */ 971 MyVkMapDanish(); 972 break; 973 case 0x0001043B: 974 /* Sami Extended Norway */ 975 MyVkMapDanish(); 976 break; 977 case 0x00010C1A: 978 /* in Windows 95 */ 979 /* Serbian (Latin) */ 980 MyVkSwapZY(); 981 break; 982 case 0x0000081A: 983 /* not in Windows 95 */ 984 /* Serbian (Latin) */ 985 MyVkMapBosnian(); 986 break; 987 case 0x0000041b: 988 /* Slovak */ 989 MyVkMapBosnian(); 990 /* not in Windows 95 */ 991 MyVkMapA[myVK_OEM_8] = myVK_Equal; 992 break; 993 case 0x00000424: 994 /* Slovenian */ 995 MyVkMapBosnian(); 996 break; 997 case 0x0000040A: 998 /* Spanish, not windows 95 */ 999 MyVkMapSpanish(); 1000 break; 1001 case 0x0001040A: 1002 /* Spanish Variation, not windows 95 */ 1003 MyVkMapA[myVK_OEM_8] = myVK_Slash; 1004 MyVkMapA[myVK_Slash] = myVK_BackSlash; 1005 MyVkMapA[myVK_BackSlash] = myVK_Grave; 1006 MyVkMapA[myVK_Grave] = myVK_SemiColon; 1007 MyVkMapA[myVK_SemiColon] = myVK_RightBracket; 1008 MyVkMapA[myVK_RightBracket] = myVK_LeftBracket; 1009 MyVkMapA[myVK_LeftBracket] = myVK_Equal; 1010 break; 1011 case 0x00000c0a: 1012 /* kMyKbdSpanish; */ 1013 /* Spanish Modern, windows 95 */ 1014 MyVkMapSpanish(); 1015 break; 1016 case 0x00000403: 1017 /* Spanish Traditional */ 1018 MyVkMapSpanish(); 1019 break; 1020 case 0x0000041d: 1021 /* Swedish */ 1022 MyVkMapDanish(); 1023 break; 1024 case 0x0000083B: 1025 /* not in windows 95 */ 1026 /* Swedish with Sami */ 1027 MyVkMapDanish(); 1028 break; 1029 case 0x0000100c: 1030 /* Swiss French */ 1031 MyVkMapSwiss(); 1032 break; 1033 case 0x00000807: 1034 /* Swiss German */ 1035 MyVkMapSwiss(); 1036 break; 1037 case 0x0000085D: 1038 /* Inuktitut Latin */ 1039 /* in windows 7, not XP */ 1040 MyVkMapBritish(); 1041 break; 1042 case 0x0001045D: 1043 /* Inuktitut - Naqittaut */ 1044 MyVkMapBritish(); 1045 break; 1046 case 0x0000046F: 1047 /* Greenlandic */ 1048 MyVkMapDanish(); 1049 break; 1050 case 0x00020427: 1051 /* Lithuanian Standard */ 1052 MyVkMapDanish(); 1053 break; 1054 case 0x0000042f: 1055 /* Macedonian (FYROM) - Standard */ 1056 MyVkMapBosnian(); 1057 break; 1058 case 0x0000042E: 1059 /* Sorbian Standard (Legacy) */ 1060 MyVkMapGerman(); 1061 break; 1062 case 0x0001042E: 1063 /* Sorbian Extended */ 1064 MyVkMapGerman(); 1065 break; 1066 case 0x0002042E: 1067 /* Sorbian Standard */ 1068 MyVkMapGerman(); 1069 break; 1070 case 0x00000488: 1071 /* Wolof */ 1072 MyVkMapFrench(); 1073 break; 1074 case 0x0000041f: 1075 /* Turkish (Q type) */ 1076 /* windows 95 */ 1077 /* MyVkMapA[myVK_Equal] = myVK_Subtract; */ 1078 /* MyVkMapA[myVK_Subtract] = myVK_Equal; */ 1079 /* not windows 95 */ 1080 MyVkMapA[myVK_OEM_8] = myVK_Subtract; 1081 MyVkMapA[myVK_Subtract] = myVK_Equal; 1082 1083 MyVkMapA[myVK_Comma] = myVK_BackSlash; 1084 MyVkMapA[myVK_BackSlash] = myVK_Period; 1085 MyVkMapA[myVK_Period] = myVK_Slash; 1086 MyVkMapA[myVK_Slash] = myVK_Comma; 1087 break; 1088 case 0x00010409: 1089 /* United States Dvorak */ 1090 MyVkMapA[myVK_LeftBracket] = myVK_Subtract; 1091 MyVkMapA[myVK_RightBracket] = myVK_Equal; 1092 MyVkMapA[myVK_SingleQuote] = 'Q'; 1093 MyVkMapA[myVK_Comma] = 'W'; 1094 MyVkMapA[myVK_Period] = 'E'; 1095 MyVkMapA['P'] = 'R'; 1096 MyVkMapA['Y'] = 'T'; 1097 MyVkMapA['F'] = 'Y'; 1098 MyVkMapA['G'] = 'U'; 1099 MyVkMapA['C'] = 'I'; 1100 MyVkMapA['R'] = 'O'; 1101 MyVkMapA['L'] = 'P'; 1102 MyVkMapA[myVK_Slash] = myVK_LeftBracket; 1103 MyVkMapA[myVK_Equal] = myVK_RightBracket; 1104 MyVkMapA['O'] = 'S'; 1105 MyVkMapA['E'] = 'D'; 1106 MyVkMapA['U'] = 'F'; 1107 MyVkMapA['I'] = 'G'; 1108 MyVkMapA['D'] = 'H'; 1109 MyVkMapA['H'] = 'J'; 1110 MyVkMapA['T'] = 'K'; 1111 MyVkMapA['N'] = 'L'; 1112 MyVkMapA['S'] = myVK_SemiColon; 1113 MyVkMapA[myVK_Subtract] = myVK_SingleQuote; 1114 MyVkMapA[myVK_SemiColon] = 'Z'; 1115 MyVkMapA['Q'] = 'X'; 1116 MyVkMapA['J'] = 'C'; 1117 MyVkMapA['K'] = 'V'; 1118 MyVkMapA['X'] = 'B'; 1119 MyVkMapA['B'] = 'N'; 1120 MyVkMapA['W'] = myVK_Comma; 1121 MyVkMapA['V'] = myVK_Period; 1122 MyVkMapA['Z'] = myVK_Slash; 1123 break; 1124#if 0 1125 /* too complicated, don't bother with */ 1126 case 0x0x00000426: 1127 /* Latvian */ 1128 MyVkMapA['F'] = myVK_Equal; 1129 MyVkMapA['G'] = 'W'; 1130 MyVkMapA['J'] = 'E'; 1131 MyVkMapA['M'] = 'T'; 1132 MyVkMapA['V'] = 'Y'; 1133 MyVkMapA['N'] = 'U'; 1134 MyVkMapA['Z'] = 'I'; 1135 MyVkMapA['W'] = 'O'; 1136 MyVkMapA['X'] = 'P'; 1137 MyVkMapA['Y'] = myVK_LeftBracket; 1138 MyVkMapA['H'] = myVK_RightBracket; 1139 MyVkMapA[myVK_SemiColon] = 'A'; 1140 MyVkMapA['U'] = 'S'; 1141 MyVkMapA['S'] = 'D'; 1142 MyVkMapA['I'] = 'F'; 1143 MyVkMapA['L'] = 'G'; 1144 MyVkMapA['D'] = 'H'; 1145 MyVkMapA['A'] = 'J'; 1146 MyVkMapA['T'] = 'K'; 1147 MyVkMapA['E'] = 'L'; 1148 MyVkMapA['C'] = myVK_SemiColon; 1149 MyVkMapA[myVK_LeftBracket] = 'Z'; 1150 MyVkMapA['B'] = 'X'; 1151 MyVkMapA[myVK_RightBracket] = 'C'; 1152 MyVkMapA['K'] = 'V'; 1153 MyVkMapA['P'] = 'B'; 1154 MyVkMapA['O'] = 'N'; 1155 MyVkMapA[myVK_OEM_8] = 'M'; 1156 break; 1157 case 0x0001041F: 1158 /* Turkish (F type) */ 1159 1160 MyVkMapA[myVK_Equal] = myVK_Subtract; 1161 MyVkMapA[myVK_Subtract] = myVK_Equal; 1162 MyVkMapA['F'] = 'Q'; 1163 MyVkMapA['G'] = 'W'; 1164 MyVkMapA[myVK_SemiColon] = 'E'; 1165 MyVkMapA['I'] = 'R'; 1166 MyVkMapA['O'] = 'T'; 1167 MyVkMapA['D'] = 'Y'; 1168 MyVkMapA['R'] = 'U'; 1169 MyVkMapA['N'] = 'I'; 1170 MyVkMapA['H'] = 'O'; 1171 MyVkMapA['Q'] = myVK_LeftBracket; 1172 MyVkMapA['W'] = myVK_RightBracket; 1173 MyVkMapA['U'] = 'A'; 1174 MyVkMapA[myVK_LeftBracket] = 'S'; 1175 MyVkMapA['E'] = 'D'; 1176 MyVkMapA['A'] = 'F'; 1177 MyVkMapA[myVK_RightBracket] = 'G'; 1178 MyVkMapA['T'] = 'H'; 1179 MyVkMapA['K'] = 'J'; 1180 MyVkMapA['M'] = 'K'; 1181 MyVkMapA['Y'] = myVK_SemiColon; 1182 MyVkMapA['X'] = myVK_BackSlash; 1183 MyVkMapA['J'] = 'Z'; 1184 MyVkMapA[myVK_BackSlash] = 'X'; 1185 MyVkMapA['V'] = 'C'; 1186 MyVkMapA['C'] = 'V'; 1187 MyVkMapA[myVK_Slash] = 'B'; 1188 MyVkMapA['Z'] = 'N'; 1189 MyVkMapA['S'] = 'M'; 1190 MyVkMapA['B'] = myVK_Comma; 1191 MyVkMapA[myVK_Comma] = myVK_Slash; 1192 break; 1193 case 0x00030409: 1194 /* United States LH Dvorak */ 1195 MyVkMapA[myVK_LeftBracket] = '1'; 1196 MyVkMapA[myVK_RightBracket] = '2'; 1197 MyVkMapA[myVK_Slash] = '3'; 1198 MyVkMapA['P'] = '4'; 1199 MyVkMapA['F'] = '5'; 1200 MyVkMapA['M'] = '6'; 1201 MyVkMapA['L'] = '7'; 1202 MyVkMapA['J'] = '8'; 1203 MyVkMapA['4'] = '9'; 1204 MyVkMapA['3'] = '0'; 1205 MyVkMapA['2'] = myVK_Subtract; 1206 MyVkMapA['1'] = myVK_Equal; 1207 MyVkMapA[myVK_SemiColon] = 'Q'; 1208 MyVkMapA['Q'] = 'W'; 1209 MyVkMapA['B'] = 'E'; 1210 MyVkMapA['Y'] = 'R'; 1211 MyVkMapA['U'] = 'T'; 1212 MyVkMapA['R'] = 'Y'; 1213 MyVkMapA['S'] = 'U'; 1214 MyVkMapA['O'] = 'I'; 1215 MyVkMapA[myVK_Period] = 'O'; 1216 MyVkMapA['6'] = 'P'; 1217 MyVkMapA['5'] = myVK_LeftBracket; 1218 MyVkMapA[myVK_Equal] = myVK_RightBracket; 1219 MyVkMapA[myVK_Subtract] = 'A'; 1220 MyVkMapA['K'] = 'S'; 1221 MyVkMapA['C'] = 'D'; 1222 MyVkMapA['D'] = 'F'; 1223 MyVkMapA['T'] = 'G'; 1224 MyVkMapA['E'] = 'J'; 1225 MyVkMapA['A'] = 'K'; 1226 MyVkMapA['Z'] = 'L'; 1227 MyVkMapA['8'] = myVK_SemiColon; 1228 MyVkMapA['7'] = myVK_SingleQuote; 1229 MyVkMapA[myVK_SingleQuote] = 'Z'; 1230 MyVkMapA['G'] = 'C'; 1231 MyVkMapA['W'] = 'B'; 1232 MyVkMapA['I'] = 'M'; 1233 MyVkMapA['0'] = myVK_Period; 1234 MyVkMapA['9'] = myVK_Slash; 1235 break; 1236 case 0x00040409: 1237 /* United States RH Dvorak */ 1238 MyVkMapA['J'] = '5'; 1239 MyVkMapA['L'] = '6'; 1240 MyVkMapA['M'] = '7'; 1241 MyVkMapA['F'] = '8'; 1242 MyVkMapA['P'] = '9'; 1243 MyVkMapA[myVK_Slash] = '0'; 1244 MyVkMapA[myVK_LeftBracket] = myVK_Subtract; 1245 MyVkMapA[myVK_RightBracket] = myVK_Equal; 1246 MyVkMapA['5'] = 'Q'; 1247 MyVkMapA['6'] = 'W'; 1248 MyVkMapA['Q'] = 'E'; 1249 MyVkMapA[myVK_Period] = 'R'; 1250 MyVkMapA['O'] = 'T'; 1251 MyVkMapA['R'] = 'Y'; 1252 MyVkMapA['S'] = 'U'; 1253 MyVkMapA['U'] = 'I'; 1254 MyVkMapA['Y'] = 'O'; 1255 MyVkMapA['B'] = 'P'; 1256 MyVkMapA[myVK_SemiColon] = myVK_LeftBracket; 1257 MyVkMapA[myVK_Equal] = myVK_RightBracket; 1258 MyVkMapA['7'] = 'A'; 1259 MyVkMapA['8'] = 'S'; 1260 MyVkMapA['Z'] = 'D'; 1261 MyVkMapA['A'] = 'F'; 1262 MyVkMapA['E'] = 'G'; 1263 MyVkMapA['T'] = 'J'; 1264 MyVkMapA['D'] = 'K'; 1265 MyVkMapA['C'] = 'L'; 1266 MyVkMapA['K'] = myVK_SemiColon; 1267 MyVkMapA[myVK_Subtract] = myVK_SingleQuote; 1268 MyVkMapA['9'] = 'Z'; 1269 MyVkMapA['0'] = 'X'; 1270 MyVkMapA['X'] = 'C'; 1271 MyVkMapA[myVK_Comma] = 'V'; 1272 MyVkMapA['I'] = 'B'; 1273 MyVkMapA['W'] = 'M'; 1274 MyVkMapA['V'] = myVK_Comma; 1275 MyVkMapA['G'] = myVK_Period; 1276 MyVkMapA[myVK_SingleQuote] = myVK_Slash; 1277 break; 1278#endif 1279#if 0 1280 case 0x0000082C: 1281 /* not in Windows 95 */ 1282 /* Azeri Cyrillic */ 1283 break; 1284 case 0x00000423: 1285 /* Belarusian */ 1286 break; 1287 case 0x00000445: 1288 /* not in Windows 95 */ 1289 /* Bengali */ 1290 break; 1291 case 0x00010445: 1292 /* not in Windows 95 */ 1293 /* Bengali (Inscript) */ 1294 break; 1295 case 0x0000201A: 1296 /* not in Windows 95 */ 1297 /* Bosnian Cyrillic*/ 1298 break; 1299 case 0x00010402: 1300 /* Bulgarian Latin */ 1301#if 0 /* Only in Windows 95 */ 1302 MyVkMapA['J'] = 'Q'; 1303 MyVkMapA['C'] = 'W'; 1304 MyVkMapA['U'] = 'E'; 1305 MyVkMapA['K'] = 'R'; 1306 MyVkMapA['E'] = 'T'; 1307 MyVkMapA['N'] = 'Y'; 1308 MyVkMapA['G'] = 'U'; 1309 MyVkMapA[myVK_SemiColon] = 'I'; 1310 MyVkMapA[myVK_OEM_102] = 'O'; 1311 MyVkMapA['Z'] = 'P'; 1312 MyVkMapA['H'] = myVK_LeftBracket; 1313 MyVkMapA['F'] = 'A'; 1314 MyVkMapA['Y'] = 'S'; 1315 MyVkMapA['W'] = 'D'; 1316 MyVkMapA['A'] = 'F'; 1317 MyVkMapA['P'] = 'G'; 1318 MyVkMapA['R'] = 'H'; 1319 MyVkMapA['O'] = 'J'; 1320 MyVkMapA['L'] = 'K'; 1321 MyVkMapA['D'] = 'L'; 1322 MyVkMapA['V'] = myVK_SemiColon; 1323 MyVkMapA[myVK_LeftBracket] = 'Z'; 1324 MyVkMapA['S'] = 'X'; 1325 MyVkMapA['M'] = 'C'; 1326 MyVkMapA['I'] = 'V'; 1327 MyVkMapA['T'] = 'B'; 1328 MyVkMapA['X'] = 'N'; 1329 MyVkMapA['B'] = 'M'; 1330 MyVkMapA['Q'] = myVK_OEM_102; 1331#endif 1332 break; 1333 case 0x00000408: 1334 /* Greek */ 1335 break; 1336 case 0x00050408: 1337 /* Greek Latin */ 1338 break; 1339 case 0x00060408: 1340 /* Greek Polytonic */ 1341 break; 1342 case 0x0000043F: 1343 /* Kazakh */ 1344 break; 1345 case 0x00000440: 1346 /* Kyrgyz Cyrillic */ 1347 break; 1348 case 0x00010426: 1349 /* Latvian Latin */ 1350 break; 1351 case 0x00010427: 1352 /* Lithuanian */ 1353 break; 1354 case 0x00000427: 1355 /* Lithuanian (IBM) */ 1356 break; 1357 case 0x0000044C: 1358 /* Malayalam */ 1359 break; 1360 case 0x0000042f: 1361 /* Macedonian (FYROM) */ 1362 break; 1363 case 0x0000043A: 1364 /* Maltese 47-key */ 1365 break; 1366 case 0x0001043A: 1367 /* Maltese 48-key */ 1368 break; 1369 case 0x00000481: 1370 /* Maori */ 1371 break; 1372 case 0x00000450: 1373 /* Mongolian Cyrillic */ 1374 break; 1375 case 0x00000461: 1376 /* Nepali */ 1377 break; 1378 case 0x00000463: 1379 /* Pashto */ 1380 break; 1381 case 0x00000415: 1382 /* Polish (Programmers) */ 1383 break; 1384 case 0x00000416: 1385 /* Porguguese (Brazilian standard) */ 1386 break; 1387 case 0x00000419: 1388 /* Russian */ 1389 break; 1390 case 0x00010419: 1391 /* Russian (Typewriter) */ 1392 break; 1393 case 0x00000c1a: 1394 /* Serbian */ 1395 break; 1396 case 0x0001041B: 1397 /* Slovak (Qwerty) */ 1398 break; 1399 case 0x00000444: 1400 /* Tatar */ 1401 break; 1402 case 0x00000422: 1403 /* Ukrainian */ 1404 break; 1405 case 0x00020409: 1406 /* United States International */ 1407 break; 1408 case 0x00000843: 1409 /* Uzbek Cyrillic */ 1410 break; 1411 case 0x00010418: 1412 /* Romanian (Standard) */ 1413 break; 1414 case 0x00020418: 1415 /* Romanian (Programmers) */ 1416 break; 1417 case 0x00000401: 1418 /* Arabic (101) */ 1419 break; 1420 case 0x00010401: 1421 /* Arabic (102) */ 1422 break; 1423 case 0x0000044D: 1424 /* Assamese - INSCRIPT */ 1425 break; 1426 case 0x0000046D: 1427 /* Bashkir */ 1428 break; 1429 case 0x00040402: 1430 /* Bulgarian (Phonetic Traditional) */ 1431 break; 1432 case 0x00000404: 1433 /* Chinese (Traditional) */ 1434 break; 1435 case 0x00000804: 1436 /* Chinese (Simplified) */ 1437 break; 1438 case 0x00000C04: 1439 /* Chinese (Traditional, Hong Kong S.A.R.) */ 1440 break; 1441 case 0x00001004: 1442 /* Chinese (Simplified, Singapore) */ 1443 break; 1444 case 0x00001404: 1445 /* Chinese (Traditional, Macao S.A.R.) */ 1446 break; 1447 case 0x0000040D: 1448 /* Hebrew */ 1449 break; 1450 case 0x00000447: 1451 /* Gujarati */ 1452 break; 1453 case 0x00000468: 1454 /* Hausa */ 1455 break; 1456 case 0x00010439: 1457 /* Hindi Traditional */ 1458 break; 1459 case 0x00000439: 1460 /* Devanagari - INSCRIPT */ 1461 break; 1462 case 0x00000465: 1463 /* Divehi Phonetic */ 1464 break; 1465 case 0x00010465: 1466 /* Divehi Typewriter */ 1467 break; 1468 case 0x00000437: 1469 /* Georgian */ 1470 break; 1471 case 0x00010437: 1472 /* Georgian (QWERTY) */ 1473 break; 1474 case 0x00020437: 1475 /* Georgian (Ergonomic) */ 1476 break; 1477 case 0x00000470: 1478 /* Igbo */ 1479 break; 1480 case 0x00000411: 1481 /* Japanese */ 1482 /* MyVkMapA[??] = ??; */ 1483 break; 1484 case 0x00000412: 1485 /* Korean */ 1486 /* MyVkMapA[VK_ZOOM] = ??; */ 1487 /* MyVkMapA[VK_HELP] = VK_ZOOM; */ 1488 /* MyVkMapA[??] = VK_HELP; */ 1489 /* MyVkMapA[??] = ??; */ 1490 break; 1491 case 0x0000044B: 1492 /* Kannada */ 1493 break; 1494 case 0x00000453: 1495 /* Khmer */ 1496 break; 1497 case 0x00000454: 1498 /* Lao */ 1499 break; 1500 case 0x00000448: 1501 /* Oriya */ 1502 break; 1503 case 0x0000044E: 1504 /* Marathi */ 1505 break; 1506 case 0x00000850: 1507 /* Mongolian (Mongolian Script) */ 1508 break; 1509 case 0x00000429: 1510 /* Persion */ 1511 break; 1512 case 0x00000446: 1513 /* Punjabi */ 1514 break; 1515 case 0x0000046C: 1516 /* Sesotho sa Leboa */ 1517 break; 1518 case 0x00000432: 1519 /* Setswana */ 1520 break; 1521 case 0x0000045B: 1522 /* Sinhala */ 1523 break; 1524 case 0x0001045B: 1525 /* Sinhala - Wij 9 */ 1526 break; 1527 case 0x0000045A: 1528 /* Syriac */ 1529 break; 1530 case 0x0001045A: 1531 /* Syriac Phonetic */ 1532 break; 1533 case 0x00000428: 1534 /* Tajik */ 1535 break; 1536 case 0x00000449: 1537 /* Tamil */ 1538 break; 1539 case 0x0000044A: 1540 /* Telugu */ 1541 break; 1542 case 0x0000041E: 1543 /* Thai Kedmanee */ 1544 break; 1545 case 0x0001041E: 1546 /* Thai Pattachote */ 1547 break; 1548 case 0x0002041E: 1549 /* Thai Kedmanee (non-ShiftLock) */ 1550 break; 1551 case 0x0003041E: 1552 /* Thai Pattachote (non-ShiftLock) */ 1553 break; 1554 case 0x00000451: 1555 /* Tibetan (PRC) */ 1556 break; 1557 case 0x00000442: 1558 /* Turkmen */ 1559 break; 1560 case 0x00020422: 1561 /* Ukrainian (Enhanced) */ 1562 break; 1563 case 0x00000420: 1564 /* Urdu */ 1565 break; 1566 case 0x00050409: 1567 /* US English Table for IBM Arabic 238_L */ 1568 break; 1569 case 0x00000480: 1570 /* Uyghur (Legacy) */ 1571 break; 1572 case 0x00010480: 1573 /* Uyghur */ 1574 break; 1575 case 0x0000042A: 1576 /* Vietnamese */ 1577 break; 1578 case 0x00000485: 1579 /* Yakut */ 1580 break; 1581 case 0x0000046A: 1582 /* Yoruba */ 1583 break; 1584#endif 1585 } 1586} 1587#endif 1588 1589#if ItnlKyBdFix 1590LOCALVAR uimr CurKyBdLytNm = 0; 1591#endif 1592 1593#if ItnlKyBdFix 1594LOCALFUNC blnr tStrIsHex(TCHAR *s, int n, uimr *r) 1595{ 1596 short i; 1597 TCHAR c1; 1598 TCHAR *p = s; 1599 uimr v = 0; 1600 1601 for (i = n; --i >= 0; ) { 1602 v <<= 4; 1603 c1 = *p++; 1604 if ((c1 >= '0') && (c1 <= '9')) { 1605 v += c1 - '0'; 1606 } else if ((c1 >= 'A') && (c1 <= 'F')) { 1607 v += c1 - ('A' - 10); 1608 } else if ((c1 >= 'a') && (c1 <= 'f')) { 1609 v += c1 - ('a' - 10); 1610 } else { 1611 return falseblnr; 1612 } 1613 } 1614 1615 *r = v; 1616 return trueblnr; 1617} 1618#endif 1619 1620#if ItnlKyBdFix 1621LOCALFUNC blnr MyGetKeyboardLayoutHex(uimr *r) 1622{ 1623 TCHAR s[KL_NAMELENGTH]; 1624 blnr IsOk = falseblnr; 1625 1626 if (! GetKeyboardLayoutName(s)) { 1627 /* ReportWinLastError(); */ 1628 } else { 1629 size_t n = _tcslen(s); 1630 1631 if (8 != n) { 1632 /* fail */ 1633 } else { 1634 IsOk = tStrIsHex(s, n, r); 1635 } 1636 } 1637 1638 return IsOk; 1639} 1640#endif 1641 1642#if ItnlKyBdFix && ! UseWinCE 1643LOCALPROC MyCheckKeyboardLayout(void) 1644{ 1645 uimr sv; 1646 1647 if (! MyGetKeyboardLayoutHex(&sv)) { 1648 } else if (sv == CurKyBdLytNm) { 1649 /* no change */ 1650 } else { 1651 CurKyBdLytNm = sv; 1652 1653 MyVkMapFromLayout(sv); 1654 } 1655} 1656#endif 1657 1658#if ItnlKyBdFix 1659LOCALPROC MyInitCheckKeyboardLayout(void) 1660{ 1661 uimr sv; 1662 1663 if (! MyGetKeyboardLayoutHex(&sv)) { 1664 sv = 0x00000409; 1665 } 1666 1667 CurKyBdLytNm = sv; 1668 1669 MyVkMapFromLayout(sv); 1670} 1671#endif 1672 1673LOCALVAR ui3b WinKey2Mac[256]; 1674 1675LOCALPROC AssignOneMacKey(ui3b WinKey, ui3r MacKey) 1676{ 1677 WinKey2Mac[WinKey] = MacKey; 1678} 1679 1680LOCALFUNC blnr InitWinKey2Mac(void) 1681{ 1682 int i; 1683 1684 for (i = 0; i < 256; ++i) { 1685 WinKey2Mac[i] = MKC_None; 1686 } 1687 1688 AssignOneMacKey('A', MKC_A); 1689 AssignOneMacKey('S', MKC_S); 1690 AssignOneMacKey('D', MKC_D); 1691 AssignOneMacKey('F', MKC_F); 1692 AssignOneMacKey('H', MKC_H); 1693 AssignOneMacKey('G', MKC_G); 1694 AssignOneMacKey('Z', MKC_Z); 1695 AssignOneMacKey('X', MKC_X); 1696 AssignOneMacKey('C', MKC_C); 1697 AssignOneMacKey('V', MKC_V); 1698 AssignOneMacKey('B', MKC_B); 1699 AssignOneMacKey('Q', MKC_Q); 1700 AssignOneMacKey('W', MKC_W); 1701 AssignOneMacKey('E', MKC_E); 1702 AssignOneMacKey('R', MKC_R); 1703 AssignOneMacKey('Y', MKC_Y); 1704 AssignOneMacKey('T', MKC_T); 1705 AssignOneMacKey('1', MKC_1); 1706 AssignOneMacKey('2', MKC_2); 1707 AssignOneMacKey('3', MKC_3); 1708 AssignOneMacKey('4', MKC_4); 1709 AssignOneMacKey('6', MKC_6); 1710 AssignOneMacKey('5', MKC_5); 1711 AssignOneMacKey(myVK_Equal, MKC_Equal); 1712 AssignOneMacKey('9', MKC_9); 1713 AssignOneMacKey('7', MKC_7); 1714 AssignOneMacKey(myVK_Subtract, MKC_Minus); 1715 AssignOneMacKey('8', MKC_8); 1716 AssignOneMacKey('0', MKC_0); 1717 AssignOneMacKey(myVK_RightBracket, MKC_RightBracket); 1718 AssignOneMacKey('O', MKC_O); 1719 AssignOneMacKey('U', MKC_U); 1720 AssignOneMacKey(myVK_LeftBracket, MKC_LeftBracket); 1721 AssignOneMacKey('I', MKC_I); 1722 AssignOneMacKey('P', MKC_P); 1723 AssignOneMacKey(VK_RETURN, MKC_Return); 1724 AssignOneMacKey('L', MKC_L); 1725 AssignOneMacKey('J', MKC_J); 1726 AssignOneMacKey(myVK_SingleQuote, MKC_SingleQuote); 1727 AssignOneMacKey('K', MKC_K); 1728 AssignOneMacKey(myVK_SemiColon, MKC_SemiColon); 1729 AssignOneMacKey(myVK_BackSlash, MKC_formac_BackSlash); 1730 AssignOneMacKey(myVK_Comma, MKC_Comma); 1731 AssignOneMacKey(myVK_Slash, MKC_formac_Slash); 1732 AssignOneMacKey('N', MKC_N); 1733 AssignOneMacKey('M', MKC_M); 1734 AssignOneMacKey(myVK_Period, MKC_Period); 1735 1736 AssignOneMacKey(VK_TAB, MKC_Tab); 1737 AssignOneMacKey(VK_SPACE, MKC_Space); 1738 AssignOneMacKey(myVK_Grave, MKC_formac_Grave); 1739 AssignOneMacKey(VK_BACK, MKC_BackSpace); 1740 AssignOneMacKey(VK_ESCAPE, MKC_formac_Escape); 1741 1742 AssignOneMacKey(VK_MENU, MKC_formac_Command); 1743 1744 AssignOneMacKey(VK_LMENU, MKC_formac_Command); 1745 1746 AssignOneMacKey(VK_RMENU, MKC_formac_RCommand); 1747 1748 AssignOneMacKey(VK_SHIFT, MKC_formac_Shift); 1749 AssignOneMacKey(VK_LSHIFT, MKC_formac_Shift); 1750 AssignOneMacKey(VK_RSHIFT, MKC_formac_RShift); 1751 1752 AssignOneMacKey(VK_CAPITAL, MKC_formac_CapsLock); 1753 1754 AssignOneMacKey(VK_APPS, MKC_formac_ROption); 1755 1756 AssignOneMacKey(VK_LWIN, MKC_formac_Option); 1757 1758 AssignOneMacKey(VK_RWIN, MKC_formac_ROption); 1759 1760 AssignOneMacKey(VK_CONTROL, MKC_formac_Control); 1761 1762 AssignOneMacKey(VK_LCONTROL, MKC_formac_Control); 1763 1764 AssignOneMacKey(VK_RCONTROL, MKC_formac_RControl); 1765 1766 AssignOneMacKey(VK_F1, MKC_formac_F1); 1767 AssignOneMacKey(VK_F2, MKC_formac_F2); 1768 AssignOneMacKey(VK_F3, MKC_formac_F3); 1769 AssignOneMacKey(VK_F4, MKC_formac_F4); 1770 AssignOneMacKey(VK_F5, MKC_formac_F5); 1771 AssignOneMacKey(VK_F6, MKC_F6); 1772 AssignOneMacKey(VK_F7, MKC_F7); 1773 AssignOneMacKey(VK_F8, MKC_F8); 1774 AssignOneMacKey(VK_F9, MKC_F9); 1775 AssignOneMacKey(VK_F10, MKC_F10); 1776 AssignOneMacKey(VK_F11, MKC_F11); 1777 AssignOneMacKey(VK_F12, MKC_F12); 1778 1779 AssignOneMacKey(VK_DECIMAL, MKC_Decimal); 1780 AssignOneMacKey(VK_DELETE, MKC_Decimal); 1781 /* AssignOneMacKey(VK_RIGHT, 0x42); */ 1782 AssignOneMacKey(VK_MULTIPLY, MKC_KPMultiply); 1783 AssignOneMacKey(VK_ADD, MKC_KPAdd); 1784 /* AssignOneMacKey(VK_LEFT, 0x46); */ 1785 AssignOneMacKey(VK_NUMLOCK, MKC_Clear); 1786 1787 /* AssignOneMacKey(VK_DOWN, 0x48); */ 1788 AssignOneMacKey(VK_DIVIDE, MKC_KPDevide); 1789 /* AssignOneMacKey(VK_RETURN, MKC_formac_Enter); */ 1790 /* AssignOneMacKey(VK_UP, 0x4D); */ 1791 AssignOneMacKey(VK_DIVIDE, MKC_KPDevide); 1792 AssignOneMacKey(VK_SUBTRACT, MKC_KPSubtract); 1793 1794 AssignOneMacKey(VK_SEPARATOR, MKC_KPEqual); 1795 AssignOneMacKey(VK_NUMPAD0, MKC_KP0); 1796 AssignOneMacKey(VK_NUMPAD1, MKC_KP1); 1797 AssignOneMacKey(VK_NUMPAD2, MKC_KP2); 1798 AssignOneMacKey(VK_NUMPAD3, MKC_KP3); 1799 AssignOneMacKey(VK_NUMPAD4, MKC_KP4); 1800 AssignOneMacKey(VK_NUMPAD5, MKC_KP5); 1801 1802 AssignOneMacKey(VK_NUMPAD6, MKC_KP6); 1803 AssignOneMacKey(VK_NUMPAD7, MKC_KP7); 1804 AssignOneMacKey(VK_NUMPAD8, MKC_KP8); 1805 AssignOneMacKey(VK_NUMPAD9, MKC_KP9); 1806 1807 AssignOneMacKey(VK_LEFT, MKC_Left); 1808 AssignOneMacKey(VK_RIGHT, MKC_Right); 1809 AssignOneMacKey(VK_DOWN, MKC_Down); 1810 AssignOneMacKey(VK_UP, MKC_Up); 1811 1812 AssignOneMacKey(myVK_PRIOR, MKC_formac_PageUp); 1813 AssignOneMacKey(myVK_NEXT, MKC_formac_PageDown); 1814 AssignOneMacKey(myVK_END, MKC_formac_End); 1815 AssignOneMacKey(myVK_HOME, MKC_formac_Home); 1816 AssignOneMacKey(myVK_INSERT, MKC_formac_Help); 1817 AssignOneMacKey(myVK_DELETE, MKC_formac_ForwardDel); 1818 AssignOneMacKey(myVK_HELP, MKC_formac_Help); 1819 AssignOneMacKey(myVK_SNAPSHOT, MKC_Print); 1820 AssignOneMacKey(myVK_SCROLL, MKC_ScrollLock); 1821 AssignOneMacKey(myVK_PAUSE, MKC_Pause); 1822 1823 AssignOneMacKey(myVK_OEM_102, MKC_AngleBracket); 1824 1825 InitKeyCodes(); 1826 1827#if ItnlKyBdFix 1828 MyInitCheckKeyboardLayout(); 1829#endif 1830 1831 return trueblnr; 1832} 1833 1834LOCALPROC DoKeyCode(int i, blnr down) 1835{ 1836 ui3r key = WinKey2Mac[ 1837#if ItnlKyBdFix 1838 MyVkMapA[i] 1839#else 1840 i 1841#endif 1842 ]; 1843 if (MKC_None != key) { 1844 Keyboard_UpdateKeyMap2(key, down); 1845 } 1846} 1847 1848#ifndef EnableGrabSpecialKeys 1849#if UseWinCE 1850#define EnableGrabSpecialKeys 0 1851#else 1852#define EnableGrabSpecialKeys (MayFullScreen && GrabKeysFullScreen) 1853#endif 1854#endif /* EnableGrabSpecialKeys */ 1855 1856#if EnableGrabSpecialKeys 1857LOCALVAR blnr HaveSetSysParam = falseblnr; 1858#endif 1859 1860LOCALPROC CheckTheCapsLock(void) 1861{ 1862 DoKeyCode(VK_CAPITAL, (GetKeyState(VK_CAPITAL) & 1) != 0); 1863} 1864 1865#if EnableGrabSpecialKeys 1866LOCALVAR blnr VK_LWIN_pressed = falseblnr; 1867LOCALVAR blnr VK_RWIN_pressed = falseblnr; 1868#endif 1869 1870#if EnableGrabSpecialKeys 1871LOCALPROC CheckForLostKeyUps(void) 1872{ 1873 if (HaveSetSysParam) { 1874 /* check for lost key ups */ 1875 if (VK_LWIN_pressed) { 1876 if ((GetAsyncKeyState(VK_LWIN) & 0x8000) == 0) { 1877 DoKeyCode(VK_LWIN, falseblnr); 1878 VK_LWIN_pressed = falseblnr; 1879 } 1880 } 1881 if (VK_RWIN_pressed) { 1882 if ((GetAsyncKeyState(VK_RWIN) & 0x8000) == 0) { 1883 DoKeyCode(VK_RWIN, falseblnr); 1884 VK_RWIN_pressed = falseblnr; 1885 } 1886 } 1887 } 1888} 1889#endif 1890 1891LOCALPROC DoVKcode0(int i, blnr down) 1892{ 1893#if EnableGrabSpecialKeys 1894 if (HaveSetSysParam) { 1895 /* will need to check for lost key ups */ 1896 if (VK_LWIN == i) { 1897 VK_LWIN_pressed = down; 1898 } else if (VK_RWIN == i) { 1899 VK_RWIN_pressed = down; 1900 } 1901 } 1902#endif 1903 DoKeyCode(i, down); 1904} 1905 1906LOCALPROC DoVKcode(int i, ui3r flags, blnr down) 1907{ 1908 switch (i) { 1909#if MKC_formac_Control != MKC_formac_RControl 1910 case VK_CONTROL: 1911 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1912 ? MKC_formac_RControl : MKC_formac_Control, 1913 down); 1914 break; 1915#endif 1916#if MKC_formac_RCommand != MKC_formac_Command 1917 case VK_MENU: 1918 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1919 ? MKC_formac_RCommand : MKC_formac_Command, 1920 down); 1921 break; 1922#endif 1923 case VK_RETURN: 1924 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1925 ? MKC_formac_Enter : MKC_Return, 1926 down); 1927 break; 1928 case myVK_HOME: 1929 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1930 ? MKC_formac_Home : MKC_KP7, 1931 down); 1932 break; 1933 case VK_UP: 1934 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1935 ? MKC_Up : MKC_KP8, 1936 down); 1937 break; 1938 case myVK_PRIOR: 1939 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1940 ? MKC_formac_PageUp : MKC_KP9, 1941 down); 1942 break; 1943 case VK_LEFT: 1944 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1945 ? MKC_Left : MKC_KP4, 1946 down); 1947 break; 1948 case myVK_CLEAR: 1949 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1950 ? MKC_Clear : MKC_KP5, 1951 down); 1952 break; 1953 case VK_RIGHT: 1954 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1955 ? MKC_Right : MKC_KP6, 1956 down); 1957 break; 1958 case myVK_END: 1959 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1960 ? MKC_formac_End : MKC_KP1, 1961 down); 1962 break; 1963 case VK_DOWN: 1964 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1965 ? MKC_Down : MKC_KP2, 1966 down); 1967 break; 1968 case myVK_NEXT: 1969 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1970 ? MKC_formac_PageDown : MKC_KP3, 1971 down); 1972 break; 1973 case myVK_INSERT: 1974 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1975 ? MKC_formac_Help : MKC_KP0, 1976 down); 1977 break; 1978 case myVK_DELETE: 1979 Keyboard_UpdateKeyMap2(TestBit(flags, 0) 1980 ? MKC_formac_ForwardDel : MKC_Decimal, 1981 down); 1982 break; 1983 case VK_CAPITAL: 1984 CheckTheCapsLock(); 1985 break; 1986 default: 1987 if ((i >= 0) && (i < 256)) { 1988 DoVKcode0(i, down); 1989 } 1990 break; 1991 } 1992} 1993 1994LOCALVAR blnr WantCmdOptOnReconnect = falseblnr; 1995 1996LOCALPROC ReconnectKeyCodes3(void) 1997{ 1998 int i; 1999 2000 CheckTheCapsLock(); 2001 2002 if (WantCmdOptOnReconnect) { 2003 WantCmdOptOnReconnect = falseblnr; 2004 2005 for (i = 0; i < 256; ++i) { 2006 if ((GetKeyState(i) & 0x8000) != 0) { 2007 if ((VK_CAPITAL != i) 2008 && (VK_RETURN != i)) 2009 { 2010 DoVKcode0(i, trueblnr); 2011 } 2012 } 2013 } 2014 } 2015} 2016 2017LOCALPROC DisconnectKeyCodes3(void) 2018{ 2019 DisconnectKeyCodes2(); 2020 SetCurMouseButton(falseblnr); 2021} 2022 2023#if EnableGrabSpecialKeys 2024static HHOOK hKeyHook = NULL; 2025#endif 2026 2027#if EnableGrabSpecialKeys 2028typedef struct { 2029 DWORD vkCode; 2030 DWORD scanCode; 2031 DWORD flags; 2032 DWORD time; 2033 DWORD dwExtraInfo; 2034} My_KBDLLHOOKSTRUCT; 2035#endif 2036 2037#if EnableGrabSpecialKeys 2038LRESULT CALLBACK LowLevelKeyboardProc( 2039 int nCode, /* hook code */ 2040 WPARAM wParam, /* message identifier */ 2041 LPARAM lParam /* pointer to structure with message data */ 2042); 2043#endif 2044 2045#if EnableGrabSpecialKeys 2046LRESULT CALLBACK LowLevelKeyboardProc( 2047 int nCode, /* hook code */ 2048 WPARAM wParam, /* message identifier */ 2049 LPARAM lParam /* pointer to structure with message data */ 2050) 2051{ 2052 if (nCode == HC_ACTION) { 2053 My_KBDLLHOOKSTRUCT *p = (My_KBDLLHOOKSTRUCT *)lParam; 2054 if (p->vkCode != VK_CAPITAL) { 2055 switch (wParam) { 2056 case WM_KEYDOWN: 2057 case WM_SYSKEYDOWN: 2058 DoVKcode(p->vkCode, p->flags, trueblnr); 2059 return 1; 2060 break; 2061 case WM_KEYUP: 2062 case WM_SYSKEYUP: 2063 DoVKcode(p->vkCode, p->flags, falseblnr); 2064 return 1; 2065 break; 2066 } 2067 } 2068 } 2069 return CallNextHookEx(hKeyHook, /* handle to current hook */ 2070 nCode, /* hook code passed to hook procedure */ 2071 wParam, /* value passed to hook procedure */ 2072 lParam /* value passed to hook procedure */ 2073 ); 2074 2075} 2076#endif 2077 2078#if EnableGrabSpecialKeys 2079#define My_WH_KEYBOARD_LL 13 2080#define My_SPI_SETSCREENSAVERRUNNING 0x0061 2081#endif 2082 2083#if EnableGrabSpecialKeys 2084LOCALVAR UINT nPreviousState; 2085#endif 2086 2087#if EnableGrabSpecialKeys 2088LOCALPROC GrabSpecialKeys(void) 2089{ 2090 if ((hKeyHook == NULL) && ! HaveSetSysParam) { 2091 /* this works on Windows XP */ 2092 hKeyHook = SetWindowsHookEx( 2093 My_WH_KEYBOARD_LL, /* type of hook to install */ 2094 (HOOKPROC)LowLevelKeyboardProc, 2095 /* address of hook procedure */ 2096 AppInstance, /* handle to application instance */ 2097 0 /* identity of thread to install hook for */ 2098 ); 2099 if (hKeyHook == NULL) { 2100 /* this works on Windows 95/98 */ 2101 SystemParametersInfo(My_SPI_SETSCREENSAVERRUNNING, TRUE, 2102 &nPreviousState, 0); 2103 HaveSetSysParam = trueblnr; 2104 } 2105 } 2106} 2107#endif 2108 2109#if EnableGrabSpecialKeys 2110LOCALPROC UnGrabSpecialKeys(void) 2111{ 2112 if (hKeyHook != NULL) { 2113 (void) UnhookWindowsHookEx(hKeyHook); 2114 hKeyHook = NULL; 2115 } 2116 if (HaveSetSysParam) { 2117 SystemParametersInfo(My_SPI_SETSCREENSAVERRUNNING, FALSE, 2118 &nPreviousState, 0); 2119 HaveSetSysParam = falseblnr; 2120 } 2121} 2122#endif 2123 2124/* --- priority --- */ 2125 2126#ifndef EnableChangePriority 2127#if UseWinCE 2128#define EnableChangePriority 0 2129#else 2130#define EnableChangePriority MayFullScreen 2131#endif 2132#endif /* EnableChangePriority */ 2133 2134#if EnableChangePriority 2135LOCALVAR blnr MyPriorityRaised = falseblnr; 2136#endif 2137 2138#if EnableChangePriority 2139LOCALPROC RaiseMyPriority(void) 2140{ 2141 if (! MyPriorityRaised) { 2142 if (! SetPriorityClass( 2143 GetCurrentProcess(), /* handle to the process */ 2144 HIGH_PRIORITY_CLASS 2145 /* REALTIME_PRIORITY_CLASS (not, killer) */ 2146 /* priority class value */ 2147 )) 2148 { 2149 /* 2150 not recursive: 2151 MacMsg("SetPriorityClass failed", 2152 "Sorry, Mini vMac encountered errors" 2153 " and cannot continue.", trueblnr); 2154 */ 2155 } 2156 MyPriorityRaised = trueblnr; 2157 } 2158} 2159#endif 2160 2161#if EnableChangePriority 2162LOCALPROC LowerMyPriority(void) 2163{ 2164 if (MyPriorityRaised) { 2165 if (! SetPriorityClass( 2166 GetCurrentProcess(), /* handle to the process */ 2167 NORMAL_PRIORITY_CLASS /* priority class value */ 2168 )) 2169 { 2170 /* 2171 not recursive: 2172 MacMsg("SetPriorityClass failed", 2173 "Sorry, Mini vMac encountered errors" 2174 " and cannot continue.", trueblnr); 2175 */ 2176 } 2177 MyPriorityRaised = falseblnr; 2178 } 2179} 2180#endif 2181 2182 2183/* --- time, date, location --- */ 2184 2185#define dbglog_TimeStuff (0 && dbglog_HAVE) 2186 2187LOCALVAR ui5b TrueEmulatedTime = 0; 2188 2189#define MyInvTimeDivPow 16 2190#define MyInvTimeDiv (1 << MyInvTimeDivPow) 2191#define MyInvTimeDivMask (MyInvTimeDiv - 1) 2192#define MyInvTimeStep 1089590 /* 1000 / 60.14742 * MyInvTimeDiv */ 2193 2194LOCALVAR DWORD LastTime; 2195 2196LOCALVAR DWORD NextIntTime; 2197LOCALVAR ui5b NextFracTime; 2198 2199LOCALPROC IncrNextTime(void) 2200{ 2201 NextFracTime += MyInvTimeStep; 2202 NextIntTime += (NextFracTime >> MyInvTimeDivPow); 2203 NextFracTime &= MyInvTimeDivMask; 2204} 2205 2206LOCALPROC InitNextTime(void) 2207{ 2208 NextIntTime = LastTime; 2209 NextFracTime = 0; 2210 IncrNextTime(); 2211} 2212 2213LOCALFUNC blnr UpdateTrueEmulatedTime(void) 2214{ 2215 DWORD LatestTime; 2216 si5b TimeDiff; 2217 2218 LatestTime = timeGetTime(); 2219 if (LatestTime != LastTime) { 2220 LastTime = LatestTime; 2221 TimeDiff = (LatestTime - NextIntTime); 2222 /* this should work even when time wraps */ 2223 if (TimeDiff >= 0) { 2224 if (TimeDiff > 256) { 2225 /* emulation interrupted, forget it */ 2226 ++TrueEmulatedTime; 2227 InitNextTime(); 2228 2229#if dbglog_TimeStuff 2230 dbglog_writelnNum("emulation interrupted", 2231 TrueEmulatedTime); 2232#endif 2233 } else { 2234 do { 2235 ++TrueEmulatedTime; 2236 IncrNextTime(); 2237 TimeDiff = (LatestTime - NextIntTime); 2238 } while (TimeDiff >= 0); 2239 } 2240 return trueblnr; 2241 } else if (TimeDiff < -256) { 2242 /* clock goofed if ever get here, reset */ 2243#if dbglog_TimeStuff 2244 dbglog_writeln("clock set back"); 2245#endif 2246 2247 InitNextTime(); 2248 } 2249 } 2250 return falseblnr; 2251} 2252 2253LOCALVAR ui5b TimeSecBase; 2254LOCALVAR DWORD TimeMilliBase; 2255 2256#include "DATE2SEC.h" 2257 2258LOCALFUNC blnr CheckDateTime(void) 2259{ 2260 ui5b NewMacDateInSecond; 2261 2262 NewMacDateInSecond = 2263 ((ui5b)(LastTime - TimeMilliBase)) / 1000 + TimeSecBase; 2264 if (CurMacDateInSeconds != NewMacDateInSecond) { 2265 CurMacDateInSeconds = NewMacDateInSecond; 2266 2267 return trueblnr; 2268 } else { 2269 return falseblnr; 2270 } 2271} 2272 2273LOCALFUNC blnr Init60thCheck(void) 2274{ 2275 SYSTEMTIME s; 2276#if AutoTimeZone 2277 TIME_ZONE_INFORMATION r; 2278 DWORD v; 2279#endif 2280 DWORD t; 2281 2282 GetLocalTime(&s); 2283 t = timeGetTime(); 2284 TimeSecBase = Date2MacSeconds(s.wSecond, s.wMinute, s.wHour, 2285 s.wDay, s.wMonth, s.wYear); 2286 TimeMilliBase = t - s.wMilliseconds; 2287 2288#if AutoTimeZone 2289 v = GetTimeZoneInformation(&r); 2290 if ((v != 0xFFFFFFFF) && (v != TIME_ZONE_ID_UNKNOWN)) { 2291 si5b dlsBias = (v != TIME_ZONE_ID_DAYLIGHT) 2292 ? r.StandardBias : r.DaylightBias; 2293 CurMacDelta = (((ui5b)(- (r.Bias + dlsBias) * 60)) 2294 & 0x00FFFFFF) 2295 | (((v != TIME_ZONE_ID_DAYLIGHT) ? 0 : 0x80) 2296 << 24); 2297 } 2298#endif 2299 2300 LastTime = timeGetTime(); 2301 InitNextTime(); 2302 2303 OnTrueTime = TrueEmulatedTime; 2304 2305 (void) CheckDateTime(); 2306 2307 return trueblnr; 2308} 2309 2310#ifndef MyTimeResolution 2311#define MyTimeResolution 3 2312#endif 2313 /* 2314 Setting MyTimeResolution to 1 seems to drastically slow down 2315 the clock in Virtual PC 7.0.2 for Mac. Using 3 is more polite 2316 anyway, and should not cause much observable difference. 2317 */ 2318 2319#if (MyTimeResolution != 0) 2320LOCALVAR blnr HaveSetTimeResolution = falseblnr; 2321#endif 2322 2323#if (MyTimeResolution != 0) 2324LOCALPROC MyTimer_Suspend(void) 2325{ 2326 if (HaveSetTimeResolution) { 2327 (void) timeEndPeriod(MyTimeResolution); 2328 HaveSetTimeResolution = falseblnr; 2329 } 2330} 2331#endif 2332 2333#if (MyTimeResolution != 0) 2334LOCALPROC MyTimer_Resume(void) 2335{ 2336 TIMECAPS tc; 2337 2338 if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) 2339 == TIMERR_NOERROR) 2340 { 2341 if ((MyTimeResolution >= tc.wPeriodMin) 2342 && (MyTimeResolution <= tc.wPeriodMax)) 2343 { 2344 if (timeBeginPeriod(MyTimeResolution) 2345 == TIMERR_NOERROR) 2346 { 2347 HaveSetTimeResolution = trueblnr; 2348 } 2349 } 2350 } 2351} 2352#endif 2353 2354/* --- sound --- */ 2355 2356#if MySoundEnabled 2357 2358 2359#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */ 2360#define kSoundBuffers (1 << kLn2SoundBuffers) 2361#define kSoundBuffMask (kSoundBuffers - 1) 2362 2363#define DesiredMinFilledSoundBuffs 3 2364 /* 2365 if too big then sound lags behind emulation. 2366 if too small then sound will have pauses. 2367 */ 2368 2369#define kLnOneBuffLen 9 2370#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen) 2371#define kOneBuffLen (1UL << kLnOneBuffLen) 2372#define kAllBuffLen (1UL << kLnAllBuffLen) 2373#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3) 2374#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3) 2375#define kOneBuffSz (1UL << kLnOneBuffSz) 2376#define kAllBuffSz (1UL << kLnAllBuffSz) 2377#define kOneBuffMask (kOneBuffLen - 1) 2378#define kAllBuffMask (kAllBuffLen - 1) 2379#define dbhBufferSize (kAllBuffSz + kOneBuffSz) 2380 2381#define dbglog_SoundStuff (0 && dbglog_HAVE) 2382#define dbglog_SoundBuffStats (0 && dbglog_HAVE) 2383 2384LOCALVAR tpSoundSamp TheSoundBuffer = nullpr; 2385LOCALVAR ui4b ThePlayOffset; 2386LOCALVAR ui4b TheFillOffset; 2387LOCALVAR blnr wantplaying; 2388LOCALVAR ui4b MinFilledSoundBuffs; 2389LOCALVAR ui4b TheWriteOffset; 2390 2391#define SOUND_SAMPLERATE /* 22050 */ 22255 2392 /* = round(7833600 * 2 / 704) */ 2393 2394 2395LOCALPROC FillWithSilence(tpSoundSamp p, int n, trSoundSamp v) 2396{ 2397 int i; 2398 2399 for (i = n; --i >= 0; ) { 2400 *p++ = v; 2401 } 2402} 2403 2404 2405LOCALVAR HWAVEOUT hWaveOut = NULL; 2406LOCALVAR WAVEHDR whdr[kSoundBuffers]; 2407 2408 2409LOCALPROC MySound_BeginPlaying(void) 2410{ 2411#if dbglog_SoundStuff 2412 fprintf(stderr, "MySound_BeginPlaying\n"); 2413#endif 2414} 2415 2416LOCALPROC MySound_Start(void) 2417{ 2418 if (hWaveOut == NULL) { 2419 WAVEFORMATEX wfex; 2420 MMRESULT mmr; 2421 int i; 2422 tpSoundSamp p; 2423 WAVEHDR *pwh; 2424 2425 wfex.wFormatTag = WAVE_FORMAT_PCM; 2426 wfex.nChannels = 1; 2427 wfex.nSamplesPerSec = SOUND_SAMPLERATE; 2428 wfex.nAvgBytesPerSec = SOUND_SAMPLERATE; 2429#if 3 == kLn2SoundSampSz 2430 wfex.nBlockAlign = 1; 2431 wfex.wBitsPerSample = 8; 2432#elif 4 == kLn2SoundSampSz 2433 wfex.nBlockAlign = 2; 2434 wfex.wBitsPerSample = 16; 2435#else 2436#error "unsupported audio format" 2437#endif 2438 wfex.cbSize = 0; 2439 mmr = waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfex, 0, 2440 0 /* (DWORD) AppInstance */, CALLBACK_NULL); 2441 if (mmr != MMSYSERR_NOERROR) { 2442 /* 2443 not recursive: 2444 MacMsg("waveOutOpen failed", 2445 "Sorry, Mini vMac encountered errors" 2446 " and cannot continue.", trueblnr); 2447 */ 2448 } else { 2449 p = TheSoundBuffer; 2450 pwh = whdr; 2451 for (i = 0; i < kSoundBuffers; ++i) { 2452 pwh->lpData = (LPSTR)p; 2453 pwh->dwBufferLength = kOneBuffSz; 2454 pwh->dwBytesRecorded = 0; 2455 pwh->dwUser = 0; 2456 pwh->dwFlags = 0; 2457 pwh->dwLoops = 0; 2458 mmr = waveOutPrepareHeader(hWaveOut, pwh, 2459 sizeof(WAVEHDR)); 2460 if (mmr != MMSYSERR_NOERROR) { 2461 /* 2462 not recursive: 2463 MacMsg("waveOutPrepareHeader failed", 2464 "Sorry, Mini vMac encountered errors" 2465 " and cannot continue.", trueblnr); 2466 */ 2467 } else { 2468 pwh->dwFlags |= WHDR_DONE; 2469 } 2470 p += kOneBuffLen; 2471 ++pwh; 2472 } 2473 2474 TheFillOffset = 0; 2475 ThePlayOffset = 0; 2476 TheWriteOffset = 0; 2477 MinFilledSoundBuffs = kSoundBuffers; 2478 wantplaying = falseblnr; 2479 } 2480 } 2481} 2482 2483LOCALPROC MySound_Stop(void) 2484{ 2485 MMRESULT mmr; 2486 int i; 2487 2488 wantplaying = falseblnr; 2489 if (hWaveOut != NULL) { 2490 DWORD StartTime = GetTickCount(); 2491 for (i = 0; i < kSoundBuffers; ++i) { 2492 while (((whdr[i].dwFlags & WHDR_DONE) == 0) 2493 && ((ui5b)(GetTickCount() - StartTime) < 1000)) 2494 { 2495 Sleep(1); 2496 } 2497 2498 mmr = waveOutUnprepareHeader(hWaveOut, &whdr[i], 2499 sizeof(WAVEHDR)); 2500 if (mmr != MMSYSERR_NOERROR) { 2501 /* 2502 not recursive: 2503 MacMsg("waveOutUnprepareHeader failed", 2504 "Sorry, Mini vMac encountered errors" 2505 " and cannot continue.", trueblnr); 2506 */ 2507 } 2508 } 2509 2510 mmr = waveOutClose(hWaveOut); 2511 if (mmr != MMSYSERR_NOERROR) { 2512 /* 2513 MacMsg("waveOutClose failed", 2514 "Sorry, Mini vMac encountered errors" 2515 " and cannot continue.", trueblnr); 2516 */ 2517 } 2518 hWaveOut = NULL; 2519 } 2520} 2521 2522LOCALPROC SoundCheckVeryOften(void) 2523{ 2524 if ((hWaveOut != NULL) && (wantplaying)) { 2525label_retry: 2526 { 2527 ui4b FilledSoundBuffs; 2528 ui4b ToPlaySize = TheFillOffset - ThePlayOffset; 2529 ui4b CurPlayBuffer = 2530 (ThePlayOffset >> kLnOneBuffLen) & kSoundBuffMask; 2531 2532 if ((ToPlaySize > kOneBuffLen) 2533 && ((whdr[CurPlayBuffer].dwFlags & WHDR_DONE) != 0)) 2534 { 2535 ThePlayOffset += kOneBuffLen; 2536 goto label_retry; 2537 } 2538 FilledSoundBuffs = ToPlaySize >> kLnOneBuffLen; 2539 2540 if (FilledSoundBuffs < MinFilledSoundBuffs) { 2541 MinFilledSoundBuffs = FilledSoundBuffs; 2542 } 2543 2544 if (FilledSoundBuffs < 2) { 2545 MMRESULT mmr; 2546 ui4b PrevPlayOffset = ThePlayOffset - kOneBuffLen; 2547 ui4b PrevPlayBuffer = 2548 (PrevPlayOffset >> kLnOneBuffLen) & kSoundBuffMask; 2549 ui4b LastPlayedOffset = 2550 ((TheFillOffset >> kLnOneBuffLen) << kLnOneBuffLen) 2551 - 1; 2552 2553 FillWithSilence( 2554 TheSoundBuffer + (PrevPlayOffset & kAllBuffMask), 2555 kOneBuffLen, 2556 *(TheSoundBuffer 2557 + (LastPlayedOffset & kAllBuffMask))); 2558 mmr = waveOutWrite( 2559 hWaveOut, &whdr[PrevPlayBuffer], sizeof(WAVEHDR)); 2560 if (mmr != MMSYSERR_NOERROR) { 2561 whdr[PrevPlayBuffer].dwFlags |= WHDR_DONE; 2562 /* 2563 not recursive: 2564 MacMsg("waveOutWrite failed", 2565 "Sorry, Mini vMac encountered errors" 2566 " and cannot continue.", trueblnr); 2567 */ 2568 } 2569 ThePlayOffset = PrevPlayOffset; 2570 goto label_retry; 2571 } 2572 } 2573 } 2574} 2575 2576#if 4 == kLn2SoundSampSz 2577LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p) 2578{ 2579 int i; 2580 2581 for (i = kOneBuffLen; --i >= 0; ) { 2582 *p++ -= 0x8000; 2583 } 2584} 2585#else 2586#define ConvertSoundBlockToNative(p) 2587#endif 2588 2589LOCALPROC MySound_FilledBlocks(void) 2590{ 2591 while (0 != ((TheWriteOffset - TheFillOffset) >> kLnOneBuffLen)) { 2592 ui4b CurFillBuffer = 2593 (TheFillOffset >> kLnOneBuffLen) & kSoundBuffMask; 2594 blnr IsOk = falseblnr; 2595 2596 ConvertSoundBlockToNative((tpSoundSamp) 2597 whdr[CurFillBuffer].lpData); 2598 2599 if (hWaveOut != NULL) { 2600 MMRESULT mmr = waveOutWrite(hWaveOut, 2601 &whdr[CurFillBuffer], sizeof(WAVEHDR)); 2602 if (mmr == MMSYSERR_NOERROR) { 2603 IsOk = trueblnr; 2604 } 2605 } 2606 2607 if (! IsOk) { 2608 /* 2609 not recursive: 2610 MacMsg("waveOutWrite failed", 2611 "Sorry, Mini vMac encountered errors" 2612 " and cannot continue.", trueblnr); 2613 */ 2614 whdr[CurFillBuffer].dwFlags |= WHDR_DONE; 2615 } 2616 2617 TheFillOffset += kOneBuffLen; 2618 } 2619} 2620 2621LOCALPROC MySound_WroteABlock(void) 2622{ 2623 if (wantplaying) { 2624 MySound_FilledBlocks(); 2625 } else if (((TheWriteOffset - ThePlayOffset) >> kLnOneBuffLen) < 12) 2626 { 2627 /* just wait */ 2628 } else { 2629 MySound_FilledBlocks(); 2630 wantplaying = trueblnr; 2631 MySound_BeginPlaying(); 2632 } 2633} 2634 2635GLOBALOSGLUPROC MySound_EndWrite(ui4r actL) 2636{ 2637 TheWriteOffset += actL; 2638 2639 if (0 == (TheWriteOffset & kOneBuffMask)) { 2640 /* just finished a block */ 2641 2642 MySound_WroteABlock(); 2643 } 2644} 2645 2646GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL) 2647{ 2648 ui4b ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset); 2649 ui4b WriteBuffContig = 2650 kOneBuffLen - (TheWriteOffset & kOneBuffMask); 2651 2652 if (WriteBuffContig < n) { 2653 n = WriteBuffContig; 2654 } 2655 if (ToFillLen < n) { 2656 /* overwrite previous buffer */ 2657 TheWriteOffset -= kOneBuffLen; 2658 } 2659 2660 *actL = n; 2661 return TheSoundBuffer + (TheWriteOffset & kAllBuffMask); 2662} 2663 2664LOCALPROC MySound_SecondNotify(void) 2665{ 2666 if (hWaveOut != NULL) { 2667 if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) { 2668#if dbglog_SoundStuff 2669 dbglog_writeln("MinFilledSoundBuffs too high"); 2670#endif 2671 IncrNextTime(); 2672 } else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) { 2673#if dbglog_SoundStuff 2674 dbglog_writeln("MinFilledSoundBuffs too low"); 2675#endif 2676 ++TrueEmulatedTime; 2677 } 2678 MinFilledSoundBuffs = kSoundBuffers; 2679 } 2680} 2681 2682#endif 2683 2684/* --- overall grab --- */ 2685 2686#if MayFullScreen 2687LOCALPROC GrabTheMachine(void) 2688{ 2689#if EnableFSMouseMotion 2690 StartSaveMouseMotion(); 2691#endif 2692#if EnableChangePriority 2693 if ((ui3b) -1 == SpeedValue) { 2694 RaiseMyPriority(); 2695 } 2696#endif 2697#if EnableGrabSpecialKeys 2698 GrabSpecialKeys(); 2699#endif 2700} 2701#endif 2702 2703#if MayFullScreen 2704LOCALPROC UnGrabTheMachine(void) 2705{ 2706#if EnableGrabSpecialKeys 2707 UnGrabSpecialKeys(); 2708#endif 2709#if EnableFSMouseMotion 2710 StopSaveMouseMotion(); 2711#endif 2712#if EnableChangePriority 2713 LowerMyPriority(); 2714#endif 2715} 2716#endif 2717 2718#if MayFullScreen 2719LOCALVAR blnr GrabMachine = falseblnr; 2720#endif 2721 2722#if MayFullScreen 2723LOCALPROC AdjustMachineGrab(void) 2724{ 2725 if (GrabMachine) { 2726 if (MainWnd != NULL) { 2727 GrabTheMachine(); 2728 } 2729 } else { 2730 UnGrabTheMachine(); 2731 } 2732} 2733#endif 2734 2735/* --- basic dialogs --- */ 2736 2737LOCALPROC MyBeginDialog(void) 2738{ 2739 DisconnectKeyCodes3(); 2740#if MayFullScreen 2741 GrabMachine = falseblnr; 2742 UnGrabTheMachine(); 2743#endif 2744 ForceShowCursor(); 2745} 2746 2747LOCALPROC MyEndDialog(void) 2748{ 2749 ReconnectKeyCodes3(); 2750} 2751 2752LOCALPROC CheckSavedMacMsg(void) 2753{ 2754 if (nullpr != SavedBriefMsg) { 2755 TCHAR briefMsg0[ClStrMaxLength + 1]; 2756 TCHAR longMsg0[ClStrMaxLength + 1]; 2757 2758 NativeStrFromCStr(briefMsg0, SavedBriefMsg, falseblnr); 2759 NativeStrFromCStr(longMsg0, SavedLongMsg, falseblnr); 2760 2761 MessageBox(MainWnd, longMsg0, briefMsg0, 2762 MB_APPLMODAL | MB_OK | (SavedFatalMsg ? MB_ICONSTOP : 0)); 2763 2764 SavedBriefMsg = nullpr; 2765 } 2766} 2767 2768/* --- main window --- */ 2769 2770enum { 2771 ID_MENU_NULL = 256, 2772 ID_FILE_INSERTDISK1, 2773 ID_FILE_QUIT, 2774 ID_SPECIAL_MORECOMMANDS, 2775 ID_HELP_ABOUT, 2776 2777 kNum_ID_MENU 2778}; 2779 2780 2781#if (1 == vMacScreenDepth) || (vMacScreenDepth >= 4) 2782#define EnableScalingBuff 1 2783#else 2784#define EnableScalingBuff (1 && EnableMagnify && (MyWindowScale == 2)) 2785#endif 2786 2787#if EnableScalingBuff 2788LOCALVAR ui3p ScalingBuff = NULL; 2789#endif 2790 2791LOCALVAR HDC MainWndDC = NULL; 2792 2793LOCALVAR si5b CmdShow; 2794 2795LOCALVAR TCHAR WndTitle[_MAX_PATH]; 2796LOCALVAR const TCHAR WndClassName[] = TEXT("minivmac"); 2797 2798LOCALVAR blnr gBackgroundFlag = falseblnr; 2799LOCALVAR blnr gTrueBackgroundFlag = falseblnr; 2800LOCALVAR blnr CurSpeedStopped = trueblnr; 2801 2802LOCALPROC GetWndTitle(void) 2803{ 2804 TCHAR pathName[_MAX_PATH]; 2805 WIN32_FIND_DATA fd; 2806 blnr IsOk = falseblnr; 2807 2808 if (GetModuleFileName(AppInstance, pathName, _MAX_PATH) != 0) { 2809 HANDLE hf = FindFirstFile(pathName, &fd); 2810 2811 if (hf != INVALID_HANDLE_VALUE) { 2812 /* get rid of extension, presumably '.exe' */ 2813 LPTSTR p = FindLastTerm(fd.cFileName, 2814 (TCHAR)('.')); 2815 if (p != nullpr) { 2816 *--p = (TCHAR)('\0'); 2817 } 2818 2819 _tcscpy(WndTitle, fd.cFileName); 2820 IsOk = trueblnr; 2821 FindClose(hf); 2822 } 2823 } 2824 if (! IsOk) { 2825 _tcscpy(WndTitle, TEXT(kStrAppName)); 2826 } 2827} 2828 2829LOCALPROC DisposeMainWindow(void) 2830{ 2831#if UseWinCE 2832 /* Show the taskbar */ 2833 SHFullScreen(MainWnd, SHFS_SHOWTASKBAR); 2834#endif 2835 2836 if (MainWndDC != NULL) { 2837 ReleaseDC(MainWnd, MainWndDC); 2838 } 2839 if (MainWnd != NULL) { 2840 DestroyWindow(MainWnd); 2841 MainWnd = NULL; /* so MacMsg will still work */ 2842 } 2843} 2844 2845enum { 2846 kMagStateNormal, 2847#if EnableMagnify 2848 kMagStateMagnifgy, 2849#endif 2850 kNumMagStates 2851}; 2852 2853#define kMagStateAuto kNumMagStates 2854 2855#if MayNotFullScreen 2856LOCALVAR int CurWinIndx; 2857LOCALVAR blnr HavePositionWins[kNumMagStates]; 2858LOCALVAR POINT WinPositionWins[kNumMagStates]; 2859#endif 2860 2861#if MayNotFullScreen 2862LOCALPROC MyAppendConvertMenuItem(HMENU hMenu, 2863 UINT uIDNewItem, char *s, blnr AddEllipsis) 2864{ 2865 TCHAR ts[ClStrMaxLength + 1]; 2866 2867 NativeStrFromCStr(ts, s, AddEllipsis); 2868 2869 (void) AppendMenu(hMenu, MF_ENABLED + MF_STRING, 2870 uIDNewItem, ts); 2871} 2872#endif 2873 2874#if MayNotFullScreen 2875LOCALPROC MyAppendSubmenuConvertName(HMENU hMenu, 2876 HMENU hSubMenu, char *s) 2877{ 2878 TCHAR ts[ClStrMaxLength + 1]; 2879 MENUITEMINFO mii; 2880 2881 NativeStrFromCStr(ts, s, falseblnr); 2882 2883#if 0 2884 (void) InsertMenu(hMenu, 0xFFFFFFFF, 2885 MF_BYPOSITION + MF_POPUP + MF_STRING + MF_ENABLED, 2886 (UINT)hSubMenu, ts); 2887#endif 2888 2889 memset(&mii, 0, sizeof(MENUITEMINFO)); 2890 mii.cbSize = sizeof(MENUITEMINFO); 2891 mii.fMask = MIIM_TYPE | MIIM_SUBMENU; 2892 mii.fType = MFT_STRING; 2893 mii.hSubMenu = hSubMenu; 2894 mii.dwTypeData = ts; 2895 mii.cch = (UINT)_tcslen(ts); 2896 (void) InsertMenuItem(hMenu, (UINT) -1, TRUE, 2897 &mii); 2898} 2899#endif 2900 2901#ifndef kStrMenuFile_win 2902#define kStrMenuFile_win kStrMenuFile 2903#endif 2904 2905LOCALFUNC blnr ReCreateMainWindow(void) 2906{ 2907#if MayNotFullScreen 2908 HMENU m; 2909 int DfltWndX; 2910 int DfltWndY; 2911 int WinIndx; 2912#endif 2913 HMENU mb; 2914 HWND NewMainWindow; 2915 HDC NewMainWndDC = NULL; 2916 int ScreenX = GetSystemMetrics(SM_CXSCREEN); 2917 int ScreenY = GetSystemMetrics(SM_CYSCREEN); 2918 short NewWindowHeight = vMacScreenHeight; 2919 short NewWindowWidth = vMacScreenWidth; 2920 HWND OldMainWindow = MainWnd; 2921 HDC OldMainWndDC = MainWndDC; 2922 RECT NewWinR; 2923 DWORD MyWStyle; 2924 DWORD MyWExStyle; 2925 2926#if VarFullScreen 2927 if (! UseFullScreen) 2928#endif 2929#if MayNotFullScreen 2930 { 2931 /* save old position */ 2932 if (OldMainWindow != NULL) { 2933 WinPositionWins[CurWinIndx].x = WndX; 2934 WinPositionWins[CurWinIndx].y = WndY; 2935 } 2936 } 2937#endif 2938 2939#if MayNotFullScreen 2940#if EnableMagnify 2941 if (WantMagnify) { 2942 WinIndx = kMagStateMagnifgy; 2943 } else 2944#endif 2945 { 2946 WinIndx = kMagStateNormal; 2947 } 2948#endif 2949 2950#if EnableMagnify 2951 if (WantMagnify) { 2952 NewWindowHeight *= MyWindowScale; 2953 NewWindowWidth *= MyWindowScale; 2954 } 2955#endif 2956 2957#if VarFullScreen 2958 if (WantFullScreen) 2959#endif 2960#if MayFullScreen 2961 { 2962 MyWStyle = WS_VISIBLE | WS_POPUP; 2963 MyWExStyle = WS_EX_TOPMOST; 2964 2965 hOffset = (ScreenX - NewWindowWidth) / 2; 2966 vOffset = (ScreenY - NewWindowHeight) / 2; 2967 if (hOffset < 0) { 2968 hOffset = 0; 2969 } 2970 if (vOffset < 0) { 2971 vOffset = 0; 2972 } 2973 2974 NewWinR.left = 0; 2975 NewWinR.top = 0; 2976 NewWinR.right = ScreenX; 2977 NewWinR.bottom = ScreenY; 2978 } 2979#endif 2980#if VarFullScreen 2981 else 2982#endif 2983#if MayNotFullScreen 2984 { 2985 MyWStyle = WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU 2986 | WS_MINIMIZEBOX; 2987 MyWExStyle = WS_EX_ACCEPTFILES; 2988 2989 DfltWndX = (ScreenX - NewWindowWidth) / 2; 2990 DfltWndY = (ScreenY - NewWindowHeight) / 2; 2991 2992 if (DfltWndX < 0) { 2993 DfltWndX = 0; 2994 } 2995 if (DfltWndY < 0) { 2996 DfltWndY = 0; 2997 } 2998 2999 if (! HavePositionWins[WinIndx]) { 3000 WinPositionWins[WinIndx].x = DfltWndX; 3001 WinPositionWins[WinIndx].y = DfltWndY; 3002 HavePositionWins[WinIndx] = trueblnr; 3003 } 3004 3005 NewWinR.left = WinPositionWins[WinIndx].x; 3006 NewWinR.top = WinPositionWins[WinIndx].y; 3007 NewWinR.right = NewWinR.left + NewWindowWidth; 3008 NewWinR.bottom = NewWinR.top + NewWindowHeight; 3009 3010 (void) AdjustWindowRectEx(&NewWinR, MyWStyle, TRUE, MyWExStyle); 3011 3012 if ((NewWinR.right <= 0) 3013 || (NewWinR.left >= ScreenX) 3014 || (NewWinR.bottom <= 0) 3015 || (NewWinR.top >= ScreenY)) 3016 { 3017 NewWinR.left = DfltWndX; 3018 NewWinR.top = DfltWndY; 3019 NewWinR.right = DfltWndX + NewWindowWidth; 3020 NewWinR.bottom = DfltWndY + NewWindowHeight; 3021 3022 (void) AdjustWindowRectEx(&NewWinR, 3023 MyWStyle, TRUE, MyWExStyle); 3024 } 3025 } 3026#endif 3027 3028 if ((OldMainWindow == NULL) 3029#if VarFullScreen 3030 || (WantFullScreen != UseFullScreen) 3031#endif 3032 ) 3033 { 3034 3035#if VarFullScreen 3036 if (WantFullScreen) 3037#endif 3038#if MayFullScreen 3039 { 3040 mb = NULL; 3041 } 3042#endif 3043#if VarFullScreen 3044 else 3045#endif 3046#if MayNotFullScreen 3047 { 3048 mb = CreateMenu(); 3049 if (mb != NULL) { 3050 m = CreateMenu(); 3051 if (m != NULL) { 3052 MyAppendConvertMenuItem(m, ID_FILE_INSERTDISK1, 3053 kStrMenuItemOpen, trueblnr); 3054 (void) AppendMenu(m, MF_SEPARATOR, 0, NULL); 3055 MyAppendConvertMenuItem(m, ID_FILE_QUIT, 3056 kStrMenuItemQuit, falseblnr); 3057 MyAppendSubmenuConvertName(mb, m, kStrMenuFile_win); 3058 } 3059 m = CreateMenu(); 3060 if (m != NULL) { 3061 MyAppendConvertMenuItem(m, ID_SPECIAL_MORECOMMANDS, 3062 kStrMenuItemMore, trueblnr); 3063 MyAppendSubmenuConvertName(mb, m, kStrMenuSpecial); 3064 } 3065 m = CreateMenu(); 3066 if (m != NULL) { 3067 MyAppendConvertMenuItem(m, ID_HELP_ABOUT, 3068 kStrMenuItemAbout, trueblnr); 3069 MyAppendSubmenuConvertName(mb, m, kStrMenuHelp); 3070 } 3071 } 3072 } 3073#endif 3074 3075 NewMainWindow = CreateWindowEx( 3076 MyWExStyle, 3077 WndClassName, 3078 WndTitle, 3079 MyWStyle, 3080 NewWinR.left, NewWinR.top, 3081 NewWinR.right - NewWinR.left, NewWinR.bottom - NewWinR.top, 3082 NULL, 3083 mb, 3084 AppInstance, NULL); 3085 if (NewMainWindow == NULL) { 3086 MacMsg("CreateWindow failed", 3087 "Sorry, Mini vMac encountered errors" 3088 " and cannot continue.", trueblnr); 3089 return falseblnr; 3090 } 3091 3092 NewMainWndDC = GetDC(NewMainWindow); 3093 if (NewMainWndDC == NULL) { 3094 MacMsg("GetDC failed", 3095 "Sorry, Mini vMac encountered errors" 3096 " and cannot continue.", trueblnr); 3097 DestroyWindow(NewMainWindow); 3098 return falseblnr; 3099 } 3100 } else { 3101 NewMainWndDC = OldMainWndDC; 3102 NewMainWindow = OldMainWindow; 3103 (void) MoveWindow(NewMainWindow, NewWinR.left, NewWinR.top, 3104 NewWinR.right - NewWinR.left, NewWinR.bottom - NewWinR.top, 3105 TRUE); 3106 } 3107 3108#if 0 != vMacScreenDepth 3109 ColorModeWorks = trueblnr; 3110#endif 3111 3112 { 3113 POINT p; 3114 3115 /* 3116 Find out where the window really went, on 3117 the off chance that the WM_MOVE message wasn't 3118 called on CreateWindowEx/MoveWindow, or that 3119 the window wasn't put where asked for. 3120 */ 3121 p.x = 0; 3122 p.y = 0; 3123 (void) MapWindowPoints(NewMainWindow, NULL, &p, 1); 3124 WndX = (si4b)p.x; 3125 WndY = (si4b)p.y; 3126 } 3127 3128#if MayFullScreen 3129 GrabMachine = falseblnr; 3130 UnGrabTheMachine(); 3131#endif 3132 3133#if UseWinCE && 0 3134 /* Show the taskbar */ 3135 SHFullScreen(MainWnd, SHFS_SHOWTASKBAR); 3136#endif 3137 3138#if MayNotFullScreen 3139 CurWinIndx = WinIndx; 3140#endif 3141 3142 MainWnd = NewMainWindow; 3143 MainWndDC = NewMainWndDC; 3144 gTrueBackgroundFlag = falseblnr; 3145#if VarFullScreen 3146 UseFullScreen = WantFullScreen; 3147#endif 3148#if EnableMagnify 3149 UseMagnify = WantMagnify; 3150#endif 3151 3152#if VarFullScreen 3153 if (UseFullScreen) 3154#endif 3155#if MayFullScreen 3156 { 3157 ViewHSize = ScreenX; 3158 ViewVSize = ScreenY; 3159#if EnableMagnify 3160 if (UseMagnify) { 3161 ViewHSize /= MyWindowScale; 3162 ViewVSize /= MyWindowScale; 3163 } 3164#endif 3165 if (ViewHSize >= vMacScreenWidth) { 3166 ViewHStart = 0; 3167 ViewHSize = vMacScreenWidth; 3168 } else { 3169 ViewHSize &= ~ 1; 3170 } 3171 if (ViewVSize >= vMacScreenHeight) { 3172 ViewVStart = 0; 3173 ViewVSize = vMacScreenHeight; 3174 } else { 3175 ViewVSize &= ~ 1; 3176 } 3177 } 3178#endif 3179 3180 if (NewMainWindow != OldMainWindow) { 3181 ShowWindow(NewMainWindow, SW_SHOW /* CmdShow */); 3182 if (OldMainWndDC != NULL) { 3183 ReleaseDC(MainWnd, OldMainWndDC); 3184 } 3185 if (OldMainWindow != NULL) { 3186 /* ShowWindow(OldMainWindow, SW_HIDE); */ 3187 DestroyWindow(OldMainWindow); 3188 } 3189 3190 DisconnectKeyCodes3(); 3191 /* since key events per window */ 3192 } else { 3193 (void) InvalidateRgn(MainWnd, NULL, FALSE); 3194 } 3195 3196#if UseWinCE 3197 /* Create and set logical palette for this window */ 3198 { 3199 HPALETTE hpal; 3200 LOGPALETTE *lppal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + 3201 sizeof(PALETTEENTRY) * 2); 3202 3203 if (! lppal) 3204 { 3205 MacMsg("CreateWindow failed", 3206 "Sorry, Mini vMac encountered errors" 3207 " and cannot continue.", trueblnr); 3208 return falseblnr; 3209 } 3210 3211 lppal->palNumEntries = 2; 3212 lppal->palVersion = 0x0300; 3213 lppal->palPalEntry[0].peRed = 255; 3214 lppal->palPalEntry[0].peGreen = 255; 3215 lppal->palPalEntry[0].peBlue = 255; 3216 lppal->palPalEntry[0].peFlags = 0; 3217 lppal->palPalEntry[1].peRed = 0; 3218 lppal->palPalEntry[1].peGreen = 0; 3219 lppal->palPalEntry[1].peBlue = 0; 3220 lppal->palPalEntry[1].peFlags = 0; 3221 3222 hpal = CreatePalette(lppal); 3223 3224 if (hpal == NULL) { 3225 free(lppal); 3226 MacMsg("CreateWindow failed", 3227 "Sorry, Mini vMac encountered errors" 3228 " and cannot continue.", trueblnr); 3229 return falseblnr; 3230 } 3231 3232 if (SelectPalette(MainWndDC, hpal, FALSE) == NULL) { 3233 free(lppal); 3234 MacMsg("CreateWindow failed", 3235 "Sorry, Mini vMac encountered errors" 3236 " and cannot continue.", trueblnr); 3237 return falseblnr; 3238 } 3239 3240 if (RealizePalette(MainWndDC) == GDI_ERROR) { 3241 free(lppal); 3242 MacMsg("CreateWindow failed", 3243 "Sorry, Mini vMac encountered errors" 3244 " and cannot continue.", trueblnr); 3245 return falseblnr; 3246 } 3247 3248 free(lppal); 3249 } 3250#endif 3251 3252#if UseWinCE 3253 /* Hide the taskbar */ 3254 SHFullScreen(MainWnd, SHFS_HIDETASKBAR); 3255 (void) MoveWindow(MainWnd, 0, 0, 3256 ScreenX, ScreenY, TRUE); 3257#endif 3258 3259 if (HaveCursorHidden) { 3260 (void) MyMoveMouse(CurMouseH, CurMouseV); 3261 WantCursorHidden = trueblnr; 3262 } 3263 3264 return trueblnr; 3265} 3266 3267#if UseWinCE 3268LOCALFUNC blnr AlreadyRunningCheck(void) 3269{ 3270 /* 3271 Adapted from example program from Microsoft eMbedded Visual C++ 3272 */ 3273 3274 /* If it is already running, then focus on the window */ 3275 HWND hWnd = FindWindow(WndClassName, WndTitle); 3276 if (hWnd == NULL) { 3277 return falseblnr; 3278 } else { 3279 /* 3280 Set focus to foremost child window. 3281 The "| 0x01" is used to bring any owned 3282 windows to the foreground and activate them. 3283 */ 3284 SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001)); 3285 return trueblnr; 3286 } 3287} 3288#endif 3289 3290typedef struct BITMAPINFOHEADER256 { 3291 BITMAPINFOHEADER bmi; 3292#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4) 3293 RGBQUAD colors[CLUT_size]; 3294#else 3295 RGBQUAD colors[2]; 3296#endif 3297} BITMAPINFOHEADER256; 3298 3299#if EnableMagnify 3300#define MyScaledHeight (MyWindowScale * vMacScreenHeight) 3301#define MyScaledWidth (MyWindowScale * vMacScreenWidth) 3302#endif 3303 3304LOCALPROC HaveChangedScreenBuff(si4b top, si4b left, 3305 si4b bottom, si4b right) 3306{ 3307 BITMAPINFOHEADER256 bmh; 3308 ui3b *cdb = GetCurDrawBuff(); 3309 int XDest; 3310 int YDest; 3311 3312#if VarFullScreen 3313 if (UseFullScreen) 3314#endif 3315#if MayFullScreen 3316 { 3317 if (top < ViewVStart) { 3318 top = ViewVStart; 3319 } 3320 if (left < ViewHStart) { 3321 left = ViewHStart; 3322 } 3323 if (bottom > ViewVStart + ViewVSize) { 3324 bottom = ViewVStart + ViewVSize; 3325 } 3326 if (right > ViewHStart + ViewHSize) { 3327 right = ViewHStart + ViewHSize; 3328 } 3329 3330 if ((top >= bottom) || (left >= right)) { 3331 goto label_exit; 3332 } 3333 } 3334#endif 3335 3336 XDest = left; 3337 YDest = top; 3338 3339#if VarFullScreen 3340 if (UseFullScreen) 3341#endif 3342#if MayFullScreen 3343 { 3344 XDest -= ViewHStart; 3345 YDest -= ViewVStart; 3346 } 3347#endif 3348 3349#if EnableMagnify 3350 if (UseMagnify) { 3351 XDest *= MyWindowScale; 3352 YDest *= MyWindowScale; 3353 } 3354#endif 3355#if VarFullScreen 3356 if (UseFullScreen) 3357#endif 3358#if MayFullScreen 3359 { 3360 XDest += hOffset; 3361 YDest += vOffset; 3362 } 3363#endif 3364 3365#if 0 3366 { /* testing code */ 3367 if (PatBlt(MainWndDC, 3368 (int)left - 1, 3369 (int)top - 1, 3370 (int)right - left + 2, 3371 (int)bottom - top + 2, PATCOPY)) { 3372 } 3373 } 3374#endif 3375#if 0 != vMacScreenDepth 3376 if (UseColorMode) { 3377 int i; 3378 int nDestWidth = (right - left); 3379 int nDestHeight = (bottom - top); 3380#if 1 == vMacScreenDepth 3381 ui3b *p 3382 = ScalingBuff + ((ui5r)vMacScreenWidth / 4) * top; 3383#elif vMacScreenDepth >= 4 3384 ui3b *p = ScalingBuff + (ui5r)vMacScreenByteWidth * top; 3385#else 3386 ui3b *p = cdb + (ui5r)vMacScreenByteWidth * top; 3387#endif 3388 3389 memset(&bmh, 0, sizeof (bmh)); 3390 bmh.bmi.biSize = sizeof(BITMAPINFOHEADER); 3391 bmh.bmi.biWidth = vMacScreenWidth; 3392 bmh.bmi.biHeight = - (bottom - top); 3393 bmh.bmi.biPlanes = 1; 3394#if 1 == vMacScreenDepth 3395 bmh.bmi.biBitCount = 4; 3396#else 3397 bmh.bmi.biBitCount = (1 << vMacScreenDepth); 3398#endif 3399 bmh.bmi.biCompression= BI_RGB; 3400 bmh.bmi.biSizeImage = 0; 3401 bmh.bmi.biXPelsPerMeter = 0; 3402 bmh.bmi.biYPelsPerMeter = 0; 3403#if 1 == vMacScreenDepth 3404 bmh.bmi.biClrUsed = 4; 3405#else 3406 bmh.bmi.biClrUsed = 0; 3407#endif 3408 bmh.bmi.biClrImportant = 0; 3409 3410#if vMacScreenDepth < 4 3411 for (i = 0; i < CLUT_size; ++i) { 3412 bmh.colors[i].rgbRed = CLUT_reds[i] >> 8; 3413 bmh.colors[i].rgbGreen = CLUT_greens[i] >> 8; 3414 bmh.colors[i].rgbBlue = CLUT_blues[i] >> 8; 3415 bmh.colors[i].rgbReserved = 0; 3416 } 3417#endif 3418 3419#if 1 == vMacScreenDepth 3420 { 3421 int j; 3422 ui3b *p1 = (ui3b *)(cdb + (ui5r)vMacScreenByteWidth * top); 3423 ui4b *p2 = (ui4b *)p; 3424 for (i = bottom - top; --i >= 0; ) { 3425 for (j = vMacScreenWidth / 4; --j >= 0; ) { 3426 ui4r t0 = *p1++; 3427 *p2 ++ 3428 = ((t0 & 0xC0) >> 2) 3429 | ((t0 & 0x30) >> 4) 3430 | ((t0 & 0x0C) << 10) 3431 | ((t0 & 0x03) << 8); 3432 } 3433 } 3434 } 3435#elif 4 == vMacScreenDepth 3436 { 3437 int j; 3438 ui4b *p1 = (ui4b *)(cdb + (ui5r)vMacScreenByteWidth * top); 3439 ui4b *p2 = (ui4b *)p; 3440 for (i = bottom - top; --i >= 0; ) { 3441 for (j = vMacScreenWidth; --j >= 0; ) { 3442 ui4r t0 = *p1++; 3443 *p2 ++ = 3444 ((t0 & 0xFF00) >> 8) | ((t0 & 0x00FF) << 8); 3445 } 3446 } 3447 } 3448#elif 5 == vMacScreenDepth 3449 { 3450 int j; 3451 ui5b *p1 = (ui5b *)(cdb + (ui5r)vMacScreenByteWidth * top); 3452 ui5b *p2 = (ui5b *)p; 3453 for (i = bottom - top; --i >= 0; ) { 3454 for (j = vMacScreenWidth; --j >= 0; ) { 3455 ui5r t0 = *p1++; 3456 *p2++ 3457 = ((t0 & 0xFF000000) >> 24) 3458 | ((t0 & 0x00FF0000) >> 8) 3459 | ((t0 & 0x0000FF00) << 8) 3460 | ((t0 & 0x000000FF) << 24); 3461 } 3462 } 3463 } 3464#endif 3465 3466#if EnableMagnify 3467 if (UseMagnify) { 3468 nDestWidth *= MyWindowScale; 3469 nDestHeight *= MyWindowScale; 3470 } 3471#endif 3472 3473 if (StretchDIBits( 3474 MainWndDC, /* handle of device context */ 3475 XDest, 3476 /* x-coordinate of upper-left corner of dest. rect. */ 3477 YDest, 3478 /* y-coordinate of upper-left corner of dest. rect. */ 3479 nDestWidth, /* dest. rectangle width */ 3480 nDestHeight, /* dest. rectangle height */ 3481 left, 3482 /* x-coordinate of lower-left corner of source rect. */ 3483 0, /* y-coordinate of lower-left corner of source rect. */ 3484 (right - left), /* source rectangle width */ 3485 (bottom - top), /* source rectangle height */ 3486 (CONST VOID *)p, /* address of array with DIB bits */ 3487 (const struct tagBITMAPINFO *)&bmh, 3488 /* address of structure with bitmap info. */ 3489 DIB_RGB_COLORS, /* RGB or palette indices */ 3490 SRCCOPY 3491 ) == 0) { 3492 /* ReportWinLastError(); */ 3493 } 3494 } else 3495#endif 3496 { 3497 ui3b *p = cdb + (ui5r)vMacScreenMonoByteWidth * top; 3498 3499 memset(&bmh, 0, sizeof (bmh)); 3500 bmh.bmi.biSize = sizeof(BITMAPINFOHEADER); 3501 bmh.bmi.biWidth = vMacScreenWidth; 3502 bmh.bmi.biHeight = - (bottom - top); 3503 bmh.bmi.biPlanes = 1; 3504 bmh.bmi.biBitCount = 1; 3505 bmh.bmi.biCompression= BI_RGB; 3506 bmh.bmi.biSizeImage = 0; 3507 bmh.bmi.biXPelsPerMeter = 0; 3508 bmh.bmi.biYPelsPerMeter = 0; 3509 bmh.bmi.biClrUsed = 0; 3510 bmh.bmi.biClrImportant = 0; 3511#if ! UseWinCE 3512 bmh.colors[0].rgbRed = 255; 3513 bmh.colors[0].rgbGreen = 255; 3514 bmh.colors[0].rgbBlue = 255; 3515 bmh.colors[0].rgbReserved = 0; 3516 bmh.colors[1].rgbRed = 0; 3517 bmh.colors[1].rgbGreen = 0; 3518 bmh.colors[1].rgbBlue = 0; 3519 bmh.colors[1].rgbReserved = 0; 3520#endif 3521 3522#if EnableMagnify 3523 if (UseMagnify) { 3524#if EnableScalingBuff 3525 if (ScalingBuff != NULL) { 3526 int i; 3527 int j; 3528 int k; 3529 ui4r left1 = left & (~ 7); 3530 ui4r right1 = (right + 7) & (~ 7); 3531 ui4r jn = (right1 - left1) / 8; 3532 ui3b *p1 = 3533 cdb + ((left1 + vMacScreenWidth * (ui5r)top) / 8); 3534 ui3b *p2 = ScalingBuff 3535 /* 3536 + ((left1 + vMacScreenWidth * MyWindowScale 3537 * (ui5r)top) 3538 * MyWindowScale / 8) 3539 */ 3540 ; 3541 ui3b *p3; 3542 ui3b t0; 3543 ui3b t1; 3544 ui3b t2; 3545 ui3b m; 3546 3547 for (i = bottom - top; --i >= 0; ) { 3548 p3 = p2; 3549 for (j = jn; --j >= 0; ) { 3550 t0 = *p1++; 3551 t1 = t0; 3552 m = 0x80; 3553 t2 = 0; 3554 for (k = 4; --k >= 0; ) { 3555 t2 |= t1 & m; 3556 t1 >>= 1; 3557 m >>= 2; 3558 } 3559 *p2++ = t2 | (t2 >> 1); 3560 3561 t1 = t0 << 4; 3562 m = 0x80; 3563 t2 = 0; 3564 for (k = 4; --k >= 0; ) { 3565 t2 |= t1 & m; 3566 t1 >>= 1; 3567 m >>= 2; 3568 } 3569 *p2++ = t2 | (t2 >> 1); 3570 } 3571 p1 += vMacScreenWidth / 8 - jn; 3572 p2 += MyScaledWidth / 8 - (MyWindowScale * jn); 3573 for (j = MyWindowScale * jn; --j >= 0; ) { 3574 *p2++ = *p3++; 3575 } 3576 p2 += MyScaledWidth / 8 - (MyWindowScale * jn); 3577 } 3578 3579 bmh.bmi.biWidth = vMacScreenWidth * MyWindowScale; 3580 bmh.bmi.biHeight = - ((bottom - top) * MyWindowScale); 3581 if (SetDIBitsToDevice( 3582 MainWndDC, /* handle of device context */ 3583 XDest, 3584 /* 3585 x-coordinate of upper-left corner 3586 of dest. rect. 3587 */ 3588 YDest, 3589 /* 3590 y-coordinate of upper-left corner 3591 of dest. rect. 3592 */ 3593 (right - left) * MyWindowScale, 3594 /* source rectangle width */ 3595 (bottom - top) * MyWindowScale, 3596 /* source rectangle height */ 3597 (left & 7) * MyWindowScale, 3598 /* 3599 x-coordinate of lower-left corner 3600 of source rect. 3601 */ 3602 0, 3603 /* 3604 y-coordinate of lower-left corner 3605 of source rect. 3606 */ 3607 0, /* first scan line in array */ 3608 (bottom - top) * MyWindowScale, 3609 /* number of scan lines */ 3610 (CONST VOID *)ScalingBuff, 3611 /* address of array with DIB bits */ 3612 (const struct tagBITMAPINFO *)&bmh, 3613 /* address of structure with bitmap info. */ 3614#if ! UseWinCE 3615 DIB_RGB_COLORS /* RGB or palette indices */ 3616#else 3617 DIB_PAL_COLORS /* palette indices */ 3618#endif 3619 ) == 0) { 3620 /* ReportWinLastError(); */ 3621 } 3622 } 3623#else 3624 if (StretchDIBits( 3625 MainWndDC, /* handle of device context */ 3626 XDest, 3627 /* 3628 x-coordinate of upper-left corner of dest. rect. 3629 */ 3630 YDest, 3631 /* 3632 y-coordinate of upper-left corner of dest. rect. 3633 */ 3634 (right - left) * MyWindowScale, 3635 /* dest. rectangle width */ 3636 (bottom - top) * MyWindowScale, 3637 /* dest. rectangle height */ 3638 left, 3639 /* 3640 x-coordinate of lower-left corner 3641 of source rect. 3642 */ 3643 0, 3644 /* 3645 y-coordinate of lower-left corner 3646 of source rect. 3647 */ 3648 (right - left), /* source rectangle width */ 3649 (bottom - top), /* source rectangle height */ 3650 (CONST VOID *)p, /* address of array with DIB bits */ 3651 (const struct tagBITMAPINFO *)&bmh, 3652 /* address of structure with bitmap info. */ 3653#if ! UseWinCE 3654 DIB_RGB_COLORS, /* RGB or palette indices */ 3655#else 3656 DIB_PAL_COLORS, /* palette indices */ 3657#endif 3658 SRCCOPY 3659 ) == 0) { 3660 /* ReportWinLastError(); */ 3661 } 3662#endif 3663 } else 3664#endif 3665 3666 { 3667 if (SetDIBitsToDevice( 3668 MainWndDC, /* handle of device context */ 3669 XDest, 3670 /* 3671 x-coordinate of upper-left corner of dest. rect. 3672 */ 3673 YDest, 3674 /* 3675 y-coordinate of upper-left corner of dest. rect. 3676 */ 3677 (right - left), /* source rectangle width */ 3678 (bottom - top), /* source rectangle height */ 3679 left, 3680 /* 3681 x-coordinate of lower-left corner 3682 of source rect. 3683 */ 3684 0, 3685 /* 3686 y-coordinate of lower-left corner 3687 of source rect. 3688 */ 3689 0, /* first scan line in array */ 3690 (bottom - top), /* number of scan lines */ 3691 (CONST VOID *)p, /* address of array with DIB bits */ 3692 (const struct tagBITMAPINFO *)&bmh, 3693 /* address of structure with bitmap info. */ 3694#if ! UseWinCE 3695 DIB_RGB_COLORS /* RGB or palette indices */ 3696#else 3697 DIB_PAL_COLORS /* palette indices */ 3698#endif 3699 ) == 0) { 3700 /* ReportWinLastError(); */ 3701 } 3702 } 3703 } 3704 3705#if MayFullScreen 3706label_exit: 3707 ; 3708#endif 3709} 3710 3711LOCALPROC Screen_DrawAll(void) 3712{ 3713 HaveChangedScreenBuff(0, 0, vMacScreenHeight, vMacScreenWidth); 3714} 3715 3716LOCALPROC MyDrawChangesAndClear(void) 3717{ 3718 if (ScreenChangedBottom > ScreenChangedTop) { 3719 HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft, 3720 ScreenChangedBottom, ScreenChangedRight); 3721 ScreenClearChanges(); 3722 } 3723} 3724 3725GLOBALOSGLUPROC DoneWithDrawingForTick(void) 3726{ 3727#if EnableFSMouseMotion 3728 if (HaveMouseMotion) { 3729 AutoScrollScreen(); 3730 } 3731#endif 3732 MyDrawChangesAndClear(); 3733} 3734 3735LOCALFUNC blnr InitTheCursor(void) 3736{ 3737 SetCursor(LoadCursor(NULL, IDC_ARROW)); 3738 return trueblnr; 3739} 3740 3741#if EnableFSMouseMotion 3742LOCALPROC MyMouseConstrain(void) 3743{ 3744 si4b shiftdh; 3745 si4b shiftdv; 3746 3747 if (SavedMouseH < ViewHStart + (ViewHSize / 4)) { 3748 shiftdh = ViewHSize / 2; 3749 } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4)) 3750 { 3751 shiftdh = - ViewHSize / 2; 3752 } else { 3753 shiftdh = 0; 3754 } 3755 if (SavedMouseV < ViewVStart + (ViewVSize / 4)) { 3756 shiftdv = ViewVSize / 2; 3757 } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4)) 3758 { 3759 shiftdv = - ViewVSize / 2; 3760 } else { 3761 shiftdv = 0; 3762 } 3763 if ((shiftdh != 0) || (shiftdv != 0)) { 3764 SavedMouseH += shiftdh; 3765 SavedMouseV += shiftdv; 3766 if (! MyMoveMouse(SavedMouseH, SavedMouseV)) { 3767 HaveMouseMotion = falseblnr; 3768 } 3769 } 3770} 3771#endif 3772 3773LOCALPROC MousePositionNotify(LONG NewMousePosx, LONG NewMousePosy) 3774{ 3775 blnr ShouldHaveCursorHidden = trueblnr; 3776 3777#if VarFullScreen 3778 if (UseFullScreen) 3779#endif 3780#if MayFullScreen 3781 { 3782 NewMousePosx -= hOffset; 3783 NewMousePosy -= vOffset; 3784 } 3785#endif 3786 3787#if EnableMagnify 3788 if (UseMagnify) { 3789 NewMousePosx /= MyWindowScale; 3790 NewMousePosy /= MyWindowScale; 3791 } 3792#endif 3793 3794#if VarFullScreen 3795 if (UseFullScreen) 3796#endif 3797#if MayFullScreen 3798 { 3799 NewMousePosx += ViewHStart; 3800 NewMousePosy += ViewVStart; 3801 } 3802#endif 3803 3804#if EnableFSMouseMotion 3805 if (HaveMouseMotion) { 3806 MyMousePositionSetDelta(NewMousePosx - SavedMouseH, 3807 NewMousePosy - SavedMouseV); 3808 SavedMouseH = NewMousePosx; 3809 SavedMouseV = NewMousePosy; 3810 } else 3811#endif 3812 { 3813 if (NewMousePosx < 0) { 3814 NewMousePosx = 0; 3815 ShouldHaveCursorHidden = falseblnr; 3816 } else if (NewMousePosx > vMacScreenWidth) { 3817 NewMousePosx = vMacScreenWidth - 1; 3818 ShouldHaveCursorHidden = falseblnr; 3819 } 3820 if (NewMousePosy < 0) { 3821 NewMousePosy = 0; 3822 ShouldHaveCursorHidden = falseblnr; 3823 } else if (NewMousePosy > vMacScreenHeight) { 3824 NewMousePosy = vMacScreenHeight - 1; 3825 ShouldHaveCursorHidden = falseblnr; 3826 } 3827 3828#if VarFullScreen 3829 if (UseFullScreen) 3830#endif 3831#if MayFullScreen 3832 { 3833 ShouldHaveCursorHidden = trueblnr; 3834 } 3835#endif 3836 3837#if ! UseWinCE 3838 /* if (ShouldHaveCursorHidden || CurMouseButton) */ 3839 /* 3840 for a game like arkanoid, would like mouse to still 3841 move even when outside window in one direction 3842 */ 3843#endif 3844 MyMousePositionSet(NewMousePosx, NewMousePosy); 3845 } 3846 3847 WantCursorHidden = ShouldHaveCursorHidden; 3848} 3849 3850#if ! UseWinCE 3851LOCALPROC CheckMouseState(void) 3852{ 3853 POINT NewMousePos; 3854 3855 GetCursorPos(&NewMousePos); 3856 NewMousePos.x -= WndX; 3857 NewMousePos.y -= WndY; 3858 MousePositionNotify(NewMousePos.x, NewMousePos.y); 3859} 3860#endif 3861 3862LOCALVAR const ui3b Native2MacRomanTab[] = { 3863 0xAD, 0xB0, 0xE2, 0xC4, 0xE3, 0xC9, 0xA0, 0xE0, 3864 0xF6, 0xE4, 0xB6, 0xDC, 0xCE, 0xB2, 0xB3, 0xB7, 3865 0xB8, 0xD4, 0xD5, 0xD2, 0xD3, 0xA5, 0xD0, 0xD1, 3866 0xF7, 0xAA, 0xC5, 0xDD, 0xCF, 0xB9, 0xC3, 0xD9, 3867 0xCA, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4, 0xBA, 0xA4, 3868 0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0xBD, 0xA8, 0xF8, 3869 0xA1, 0xB1, 0xC6, 0xD7, 0xAB, 0xB5, 0xA6, 0xE1, 3870 0xFC, 0xDA, 0xBC, 0xC8, 0xDE, 0xDF, 0xF0, 0xC0, 3871 0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82, 3872 0xE9, 0x83, 0xE6, 0xE8, 0xED, 0xEA, 0xEB, 0xEC, 3873 0xF5, 0x84, 0xF1, 0xEE, 0xEF, 0xCD, 0x85, 0xF9, 3874 0xAF, 0xF4, 0xF2, 0xF3, 0x86, 0xFA, 0xFB, 0xA7, 3875 0x88, 0x87, 0x89, 0x8B, 0x8A, 0x8C, 0xBE, 0x8D, 3876 0x8F, 0x8E, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, 3877 0xFD, 0x96, 0x98, 0x97, 0x99, 0x9B, 0x9A, 0xD6, 3878 0xBF, 0x9D, 0x9C, 0x9E, 0x9F, 0xFE, 0xFF, 0xD8 3879}; 3880 3881#if IncludePbufs 3882LOCALFUNC tMacErr NativeTextToMacRomanPbuf(HGLOBAL x, tPbuf *r) 3883{ 3884#if MyUseUni 3885#define MyUnsignedChar ui4b 3886#else 3887#define MyUnsignedChar ui3b 3888#endif 3889 HGLOBAL h; 3890 LPTSTR p1; 3891 ui5b n; 3892 MyUnsignedChar v; 3893 tMacErr err = mnvm_miscErr; 3894 3895 p1 = GlobalLock(x); 3896 if (p1 != NULL) { 3897 n = 0; 3898 while ((v = *p1++) != 0) { 3899 if (v != 10) { 3900 ++n; 3901 } 3902 } 3903 (void) GlobalUnlock(x); 3904 3905 h = GlobalAlloc(GMEM_DDESHARE, n); 3906 if (h != NULL) { 3907 p1 = GlobalLock(x); 3908 if (p1 != NULL) { 3909 ui3b *p2 = GlobalLock(h); 3910 if (p2 != NULL) { 3911 while ((v = (MyUnsignedChar)*p1++) != 0) { 3912 if (v >= 128) { 3913 *p2++ = Native2MacRomanTab[v & 0x7F]; 3914 /* 3915 if MyUseUni, then for gives 3916 garbage for v > 256. 3917 */ 3918 } else if (v != 10) { 3919 *p2++ = v; 3920 } 3921 } 3922 3923 err = mnvm_noErr; 3924 3925 (void) GlobalUnlock(h); 3926 } 3927 (void) GlobalUnlock(x); 3928 } 3929 3930 if (mnvm_noErr != err) { 3931 (void) GlobalFree(h); 3932 } else { 3933 err = PbufNewFromHandle(h, n, r); 3934 } 3935 } 3936 } 3937 3938 return err; 3939} 3940#endif 3941 3942LOCALVAR const ui3b MacRoman2NativeTab[] = { 3943 0xC4, 0xC5, 0xC7, 0xC9, 0xD1, 0xD6, 0xDC, 0xE1, 3944 0xE0, 0xE2, 0xE4, 0xE3, 0xE5, 0xE7, 0xE9, 0xE8, 3945 0xEA, 0xEB, 0xED, 0xEC, 0xEE, 0xEF, 0xF1, 0xF3, 3946 0xF2, 0xF4, 0xF6, 0xF5, 0xFA, 0xF9, 0xFB, 0xFC, 3947 0x86, 0xB0, 0xA2, 0xA3, 0xA7, 0x95, 0xB6, 0xDF, 3948 0xAE, 0xA9, 0x99, 0xB4, 0xA8, 0x80, 0xC6, 0xD8, 3949 0x81, 0xB1, 0x8D, 0x8E, 0xA5, 0xB5, 0x8A, 0x8F, 3950 0x90, 0x9D, 0xA6, 0xAA, 0xBA, 0xAD, 0xE6, 0xF8, 3951 0xBF, 0xA1, 0xAC, 0x9E, 0x83, 0x9A, 0xB2, 0xAB, 3952 0xBB, 0x85, 0xA0, 0xC0, 0xC3, 0xD5, 0x8C, 0x9C, 3953 0x96, 0x97, 0x93, 0x94, 0x91, 0x92, 0xF7, 0xB3, 3954 0xFF, 0x9F, 0xB9, 0xA4, 0x8B, 0x9B, 0xBC, 0xBD, 3955 0x87, 0xB7, 0x82, 0x84, 0x89, 0xC2, 0xCA, 0xC1, 3956 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0xD3, 0xD4, 3957 0xBE, 0xD2, 0xDA, 0xDB, 0xD9, 0xD0, 0x88, 0x98, 3958 0xAF, 0xD7, 0xDD, 0xDE, 0xB8, 0xF0, 0xFD, 0xFE 3959}; 3960 3961#if IncludePbufs 3962LOCALFUNC blnr MacRomanTextToNativeHand(tPbuf Pbuf_no, 3963 blnr IsFileName, HGLOBAL *r) 3964{ 3965 HGLOBAL h; 3966 ui5b i; 3967 ui5b rn = 0; 3968 HGLOBAL bh = PbufDat[Pbuf_no]; 3969 ui5b L = PbufSize[Pbuf_no]; 3970 blnr IsOk = falseblnr; 3971 3972 if (IsFileName) { 3973 if (L > 255) { 3974 L = 255; 3975 } 3976 } else { 3977 ui3b *Buffer = (ui3b *)GlobalLock(bh); 3978 if (Buffer != NULL) { 3979 for (i = 0; i < L; ++i) { 3980 if (Buffer[i] == 13) { 3981 ++rn; 3982 } 3983 } 3984 (void) GlobalUnlock(bh); 3985 } 3986 } 3987 3988 h = GlobalAlloc(GMEM_DDESHARE, (L + rn + 1) * sizeof(TCHAR)); 3989 if (h != NULL) { 3990 ui3b *Buffer = (ui3b *)GlobalLock(bh); 3991 if (Buffer != NULL) { 3992 LPTSTR p1 = GlobalLock(h); 3993 if (p1 != NULL) { 3994 for (i = 0; i < L; ++i) { 3995 TCHAR y; 3996 ui3b x = ((ui3b *)Buffer)[i]; 3997 if (x >= 128) { 3998 y = (TCHAR)MacRoman2NativeTab[x - 128]; 3999 } else { 4000 if (IsFileName) { 4001 if ((x < 32) 4002 || ('\\' == x) || ('/' == x) 4003 || (':' == x) || ('*' == x) 4004 || ('?' == x) || ('"' == x) 4005 || ('<' == x) || ('>' == x) 4006 || ('|' == x)) 4007 { 4008 y = (TCHAR)('-'); 4009 } else { 4010 y = (TCHAR)x; 4011 } 4012 } else { 4013 if (13 == x) { 4014 *p1++ = (TCHAR)(13); 4015 y = (TCHAR)(10); 4016 } else { 4017 y = (TCHAR)x; 4018 } 4019 } 4020 } 4021 *p1++ = y; 4022 } 4023 *p1++ = (TCHAR) 0; /* null character */ 4024 4025 *r = h; 4026 IsOk = trueblnr; 4027 4028 (void) GlobalUnlock(h); 4029 } 4030 (void) GlobalUnlock(bh); 4031 } 4032 if (! IsOk) { 4033 (void) GlobalFree(h); 4034 } 4035 } 4036 4037 return IsOk; 4038} 4039#endif 4040 4041#if IncludeHostTextClipExchange 4042GLOBALOSGLUFUNC tMacErr HTCEexport(tPbuf i) 4043{ 4044 HGLOBAL h; 4045 tMacErr err = mnvm_miscErr; 4046 4047 if (MacRomanTextToNativeHand(i, falseblnr, &h)) { 4048 if (! OpenClipboard(MainWnd)) { 4049 /* ReportGetLastError(); */ 4050 } else { 4051 if (! EmptyClipboard()) { 4052 /* ReportGetLastError(); */ 4053 } 4054 if (SetClipboardData(CF_TEXT, h) == NULL) { 4055 /* ReportGetLastError(); */ 4056 } else { 4057 err = mnvm_noErr; 4058 } 4059 h = NULL; 4060 if (! CloseClipboard()) { 4061 /* ReportGetLastError(); */ 4062 } 4063 } 4064 if (h != NULL) { 4065 (void) GlobalFree(h); 4066 } 4067 } 4068 4069 PbufDispose(i); 4070 4071 return err; 4072} 4073#endif 4074 4075#if IncludeHostTextClipExchange 4076GLOBALOSGLUFUNC tMacErr HTCEimport(tPbuf *r) 4077{ 4078 tMacErr err = mnvm_miscErr; 4079 4080 if (IsClipboardFormatAvailable(CF_TEXT)) { 4081 if (! OpenClipboard(MainWnd)) { 4082 /* ReportGetLastError(); */ 4083 } else { 4084 HGLOBAL h = GetClipboardData(CF_TEXT); 4085 if (h == NULL) { 4086 /* ReportGetLastError(); */ 4087 } else { 4088 err = NativeTextToMacRomanPbuf(h, r); 4089 } 4090 if (! CloseClipboard()) { 4091 /* ReportGetLastError(); */ 4092 } 4093 } 4094 } 4095 4096 return err; 4097} 4098#endif 4099 4100 4101#if EmLocalTalk 4102 4103LOCALFUNC blnr EntropyGather(void) 4104{ 4105 /* 4106 gather some entropy from several places, just in case 4107 /dev/urandom is not available. 4108 */ 4109 4110 { 4111 DWORD t = timeGetTime(); 4112 4113 EntropyPoolAddPtr((ui3p)&t, sizeof(t) / sizeof(ui3b)); 4114 } 4115 4116 { 4117 SYSTEMTIME t; 4118 4119 GetLocalTime(&t); 4120 4121 EntropyPoolAddPtr((ui3p)&t, sizeof(t) / sizeof(ui3b)); 4122 } 4123 4124 { 4125 POINT t; 4126 4127 GetCursorPos(&t); 4128 4129 EntropyPoolAddPtr((ui3p)&t, sizeof(t) / sizeof(ui3b)); 4130 } 4131 4132#if 0 4133 /* 4134 Another possible source of entropy. But if available, 4135 almost certainly /dev/urandom is also available. 4136 */ 4137 /* #include <sys/sysinfo.h> */ 4138 { 4139 struct sysinfo t; 4140 4141 if (0 != sysinfo(&t)) { 4142#if dbglog_HAVE 4143 dbglog_writeln("sysinfo fails"); 4144#endif 4145 } 4146 4147 /* 4148 continue even if error, it doesn't hurt anything 4149 if t is garbage. 4150 */ 4151 EntropyPoolAddPtr((ui3p)&t, sizeof(t) / sizeof(ui3b)); 4152 } 4153#endif 4154 4155 4156 { 4157 DWORD t = GetCurrentProcessId(); 4158 4159 EntropyPoolAddPtr((ui3p)&t, sizeof(t) / sizeof(ui3b)); 4160 } 4161 4162 return trueblnr; 4163} 4164#endif 4165 4166#if EmLocalTalk 4167 4168#include "LOCALTLK.h" 4169 4170#endif 4171 4172 4173/* --- drives --- */ 4174 4175#define NotAfileRef INVALID_HANDLE_VALUE 4176 4177LOCALVAR HANDLE Drives[NumDrives]; /* open disk image files */ 4178 4179#define NeedDriveNames (IncludeSonyGetName || IncludeSonyNew) 4180 4181#if NeedDriveNames 4182LOCALVAR HGLOBAL DriveNames[NumDrives]; 4183 /* 4184 It is supposed to be possible to use 4185 GetMappedFileName to get name of open file, 4186 but that seems ugly kludge, so instead 4187 save the name on open. 4188 */ 4189#endif 4190 4191LOCALPROC InitDrives(void) 4192{ 4193 /* 4194 This isn't really needed, Drives[i] and DriveNames[i] 4195 need not have valid values when not vSonyIsInserted[i]. 4196 */ 4197 tDrive i; 4198 4199 for (i = 0; i < NumDrives; ++i) { 4200 Drives[i] = NotAfileRef; 4201#if NeedDriveNames 4202 DriveNames[i] = NULL; 4203#endif 4204 } 4205} 4206 4207GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer, 4208 tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count, 4209 ui5r *Sony_ActCount) 4210{ 4211 HANDLE refnum; 4212 DWORD newL; 4213 tMacErr result; 4214 DWORD BytesTransferred = 0; 4215 4216 refnum = Drives[Drive_No]; 4217 newL = SetFilePointer( 4218 refnum, /* handle of file */ 4219 Sony_Start, /* number of bytes to move file pointer */ 4220 nullpr, /* address of high-order word of distance to move */ 4221 FILE_BEGIN /* how to move */ 4222 ); 4223 if (newL == 0xFFFFFFFF) { 4224 result = mnvm_miscErr; /*& figure out what really to return &*/ 4225 } else if (Sony_Start != (ui5b)newL) { 4226 /* not supposed to get here */ 4227 result = mnvm_miscErr; /*& figure out what really to return &*/ 4228 } else { 4229 if (IsWrite) { 4230 if (! WriteFile(refnum, /* handle of file to read */ 4231 (LPVOID)Buffer 4232 , /* address of buffer that receives data */ 4233 (DWORD)Sony_Count, /* number of bytes to read */ 4234 &BytesTransferred, /* address of number of bytes read */ 4235 nullpr)) /* address of structure for data */ 4236 { 4237 result = mnvm_miscErr; 4238 /*& figure out what really to return &*/ 4239 } else if ((ui5b)BytesTransferred != Sony_Count) { 4240 result = mnvm_miscErr; 4241 /*& figure out what really to return &*/ 4242 } else { 4243 result = mnvm_noErr; 4244 } 4245 } else { 4246 if (! ReadFile(refnum, /* handle of file to read */ 4247 (LPVOID)Buffer, 4248 /* address of buffer that receives data */ 4249 (DWORD)Sony_Count, /* number of bytes to read */ 4250 &BytesTransferred, 4251 /* address of number of bytes read */ 4252 nullpr)) /* address of structure for data */ 4253 { 4254 result = mnvm_miscErr; 4255 /*& figure out what really to return &*/ 4256 } else if ((ui5b)BytesTransferred != Sony_Count) { 4257 result = mnvm_miscErr; 4258 /*& figure out what really to return &*/ 4259 } else { 4260 result = mnvm_noErr; 4261 } 4262 } 4263 } 4264 4265 if (nullpr != Sony_ActCount) { 4266 *Sony_ActCount = BytesTransferred; 4267 } 4268 4269 return result; 4270} 4271 4272GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count) 4273{ 4274 tMacErr result; 4275 DWORD L; 4276 4277 L = GetFileSize(Drives[Drive_No], nullpr); 4278 if (L == 0xFFFFFFFF) { 4279 result = mnvm_miscErr; /*& figure out what really to return &*/ 4280 } else { 4281 *Sony_Count = L; 4282 result = mnvm_noErr; 4283 } 4284 4285 return result; 4286} 4287 4288LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit) 4289{ 4290 HANDLE refnum = Drives[Drive_No]; 4291 4292#if ! NeedDriveNames 4293 UnusedParam(deleteit); 4294#endif 4295 4296 Drives[Drive_No] = NotAfileRef; /* not really needed */ 4297 4298 DiskEjectedNotify(Drive_No); 4299 4300 (void) FlushFileBuffers(refnum); 4301 (void) CloseHandle(refnum); 4302 4303#if NeedDriveNames 4304 { 4305 HGLOBAL h = DriveNames[Drive_No]; 4306 if (NULL != h) { 4307 if (deleteit) { 4308 LPTSTR drivepath = GlobalLock(h); 4309 if (drivepath != NULL) { 4310 (void) DeleteFile(drivepath); 4311 (void) GlobalUnlock(h); 4312 } 4313 } 4314 (void) GlobalFree(h); 4315 DriveNames[Drive_No] = NULL; /* not really needed */ 4316 } 4317 } 4318#endif 4319 4320 return mnvm_noErr; 4321} 4322 4323GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No) 4324{ 4325 return vSonyEject0(Drive_No, falseblnr); 4326} 4327 4328#if IncludeSonyNew 4329GLOBALOSGLUFUNC tMacErr vSonyEjectDelete(tDrive Drive_No) 4330{ 4331 return vSonyEject0(Drive_No, trueblnr); 4332} 4333#endif 4334 4335LOCALPROC UnInitDrives(void) 4336{ 4337 tDrive i; 4338 4339 for (i = 0; i < NumDrives; ++i) { 4340 if (vSonyIsInserted(i)) { 4341 (void) vSonyEject(i); 4342 } 4343 } 4344} 4345 4346#if NeedDriveNames 4347LOCALFUNC blnr LPTSTRtoHand(LPTSTR s, HGLOBAL *r) 4348{ 4349 blnr IsOk = falseblnr; 4350 4351 size_t L = _tcslen(s); 4352 HGLOBAL h = GlobalAlloc(GMEM_DDESHARE, 4353 (L + 1) * sizeof(TCHAR)); 4354 if (h != NULL) { 4355 LPTSTR p = GlobalLock(h); 4356 if (p != NULL) { 4357 _tcscpy(p, s); 4358 IsOk = trueblnr; 4359 (void) GlobalUnlock(h); 4360 } 4361 if (! IsOk) { 4362 (void) GlobalFree(h); 4363 } else { 4364 *r = h; 4365 } 4366 } 4367 4368 return IsOk; 4369} 4370#endif 4371 4372#if IncludeSonyGetName 4373GLOBALOSGLUFUNC tMacErr vSonyGetName(tDrive Drive_No, tPbuf *r) 4374{ 4375 WIN32_FIND_DATA fd; 4376 tMacErr err = mnvm_miscErr; 4377 HGLOBAL ph = DriveNames[Drive_No]; 4378 if (NULL != ph) { 4379 LPTSTR drivepath = GlobalLock(ph); 4380 if (drivepath != NULL) { 4381 HANDLE hf = FindFirstFile(drivepath, &fd); 4382 (void) GlobalUnlock(ph); 4383 4384 if (hf != INVALID_HANDLE_VALUE) { 4385 HGLOBAL h; 4386 if (LPTSTRtoHand(fd.cFileName, &h)) { 4387 err = NativeTextToMacRomanPbuf(h, r); 4388 } 4389 FindClose(hf); 4390 } 4391 } 4392 } 4393 4394 return err; 4395} 4396#endif 4397 4398LOCALFUNC blnr Sony_Insert0(HANDLE refnum, blnr locked, 4399 LPTSTR drivepath) 4400{ 4401 tDrive Drive_No; 4402 4403#if ! NeedDriveNames 4404 UnusedParam(drivepath); 4405#endif 4406 4407 if (! FirstFreeDisk(&Drive_No)) { 4408 (void) CloseHandle(refnum); 4409 MacMsg(kStrTooManyImagesTitle, 4410 kStrTooManyImagesMessage, falseblnr); 4411 return falseblnr; 4412 } else { 4413 Drives[Drive_No] = refnum; 4414 DiskInsertNotify(Drive_No, locked); 4415#if NeedDriveNames 4416 { 4417 HGLOBAL h; 4418 4419 if (! LPTSTRtoHand(drivepath, &h)) { 4420 h = NULL; 4421 } 4422 4423 DriveNames[Drive_No] = h; 4424 } 4425#endif 4426 return trueblnr; 4427 } 4428} 4429 4430LOCALFUNC blnr Sony_Insert1(LPTSTR drivepath, blnr SilentOnMissing) 4431{ 4432 blnr locked = falseblnr; 4433 HANDLE refnum = CreateFile( 4434 drivepath, /* pointer to name of the file */ 4435 GENERIC_READ + GENERIC_WRITE, /* access (read-write) mode */ 4436 0, /* share mode */ 4437 nullpr, /* pointer to security descriptor */ 4438 OPEN_EXISTING, /* how to create */ 4439 FILE_ATTRIBUTE_NORMAL, /* file attributes */ 4440 nullpr /* handle to file with attributes to copy */ 4441 ); 4442 if (refnum == INVALID_HANDLE_VALUE) { 4443 if (ERROR_ACCESS_DENIED == GetLastError()) { 4444 locked = trueblnr; 4445 refnum = CreateFile( 4446 drivepath, /* pointer to name of the file */ 4447 GENERIC_READ, /* access (read-write) mode */ 4448 FILE_SHARE_READ, /* share mode */ 4449 nullpr, /* pointer to security descriptor */ 4450 OPEN_EXISTING, /* how to create */ 4451 FILE_ATTRIBUTE_NORMAL, /* file attributes */ 4452 nullpr /* handle to file with attributes to copy */ 4453 ); 4454 } 4455 } 4456 if (refnum == INVALID_HANDLE_VALUE) { 4457 DWORD err = GetLastError(); 4458 if (ERROR_SHARING_VIOLATION == err) { 4459 MacMsg(kStrImageInUseTitle, 4460 kStrImageInUseMessage, falseblnr); 4461 } else if ((ERROR_FILE_NOT_FOUND == err) && SilentOnMissing) { 4462 /* ignore it */ 4463 } else { 4464 MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr); 4465 } 4466 } else { 4467 return Sony_Insert0(refnum, locked, drivepath); 4468 } 4469 return falseblnr; 4470} 4471 4472LOCALFUNC blnr LoadMacRomFromPath(LPTSTR drivepath) 4473{ 4474 HANDLE refnum = INVALID_HANDLE_VALUE; 4475 blnr IsOk = falseblnr; 4476 4477 refnum = CreateFile( 4478 drivepath, /* pointer to name of the file */ 4479 GENERIC_READ, /* access (read-write) mode */ 4480 FILE_SHARE_READ, /* share mode */ 4481 nullpr, /* pointer to security descriptor */ 4482 OPEN_EXISTING, /* how to create */ 4483 FILE_ATTRIBUTE_NORMAL, /* file attributes */ 4484 nullpr /* handle to file with attributes to copy */ 4485 ); 4486 4487 if (refnum == INVALID_HANDLE_VALUE) { 4488 /* MacMsg(kStrNoROMTitle, kStrNoROMMessage, trueblnr); */ 4489 } else { 4490 DWORD BytesRead; 4491 4492 if (! ReadFile(refnum, /* handle of file to read */ 4493 (LPVOID)ROM, /* address of buffer that receives data */ 4494 (DWORD)kROM_Size, /* number of bytes to read */ 4495 &BytesRead, /* address of number of bytes read */ 4496 nullpr)) /* address of structure for data */ 4497 { 4498 MacMsgOverride(kStrNoReadROMTitle, kStrNoReadROMMessage); 4499 } else 4500 if ((ui5b)BytesRead != kROM_Size) { 4501 MacMsgOverride(kStrShortROMTitle, kStrShortROMMessage); 4502 } else 4503 { 4504 IsOk = (mnvm_noErr == ROM_IsValid()); 4505 } 4506 (void) CloseHandle(refnum); 4507 } 4508 4509 return IsOk; 4510} 4511 4512#ifndef EnableShellLinks 4513#define EnableShellLinks 1 4514#endif 4515 4516#if EnableShellLinks 4517LOCALVAR blnr COMinited = falseblnr; 4518LOCALVAR blnr COMinitedOK; 4519#endif 4520 4521#if EnableShellLinks 4522LOCALPROC MyUninitCOM(void) 4523{ 4524 if (COMinited) { 4525 CoUninitialize(); 4526 } 4527} 4528#endif 4529 4530#if EnableShellLinks 4531LOCALFUNC blnr MyNeedCOM(void) 4532{ 4533 HRESULT hres; 4534 4535 if (! COMinited) { 4536 COMinitedOK = falseblnr; 4537 hres = CoInitialize(NULL); 4538 if (SUCCEEDED(hres)) { 4539 COMinitedOK = trueblnr; 4540 } 4541 4542 COMinited = trueblnr; 4543 } 4544 return COMinitedOK; 4545} 4546#endif 4547 4548#if EnableShellLinks 4549LOCALFUNC blnr MyResolveShortcut(LPTSTR FilePath, blnr *directory) 4550/* adapted from Microsoft example code */ 4551{ 4552 HRESULT hres; 4553 IShellLink *psl; 4554 IPersistFile* ppf; 4555 TCHAR szGotPath[MAX_PATH]; 4556 WIN32_FIND_DATA wfd; 4557 blnr IsOk = falseblnr; 4558 4559 if (MyNeedCOM()) { 4560 hres = CoCreateInstance(&CLSID_ShellLink, NULL, 4561 CLSCTX_INPROC_SERVER, &IID_IShellLink, 4562 (LPVOID *)(void *)&psl); 4563 /* 4564 the (void *) prevents a compiler warning 4565 from gcc 4566 */ 4567 if (SUCCEEDED(hres)) { 4568 /* Get a pointer to the IPersistFile interface. */ 4569 hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, 4570 (void **)(void *)&ppf); 4571 if (SUCCEEDED(hres)) { 4572 /* Ensure that the string is Unicode. */ 4573#if MyUseUni 4574#define wsz FilePath 4575#else 4576 WORD wsz[MAX_PATH]; 4577 MultiByteToWideChar(CP_ACP, 0, FilePath, -1, wsz, 4578 MAX_PATH); 4579#endif 4580 4581 /* Load the shortcut. */ 4582 hres = ppf->lpVtbl->Load(ppf, wsz, STGM_READ); 4583 if (SUCCEEDED(hres)) { 4584 /* Resolve the link. */ 4585 hres = psl->lpVtbl->Resolve(psl, MainWnd, 4586 SLR_ANY_MATCH); 4587 if (SUCCEEDED(hres)) { 4588 /* Get the path to the link target. */ 4589 hres = psl->lpVtbl->GetPath(psl, szGotPath, 4590 MAX_PATH, &wfd, 4591 SLGP_SHORTPATH); 4592 if (SUCCEEDED(hres)) { 4593 /* 4594 This is in the sample code, but doesn't 4595 seem to be needed: 4596 Get the description of the target. 4597 char szDescription[MAX_PATH]; 4598 hres = psl->lpVtbl->GetDescription(psl, 4599 szDescription, MAX_PATH); 4600 if (SUCCEEDED(hres)) { 4601 } 4602 */ 4603 lstrcpy(FilePath, szGotPath); 4604 if (NULL != directory) { 4605 *directory = (0 != (wfd.dwFileAttributes 4606 & FILE_ATTRIBUTE_DIRECTORY)); 4607 } 4608 IsOk = trueblnr; 4609 } 4610 } 4611 } 4612 4613 ppf->lpVtbl->Release(ppf); 4614 } 4615 psl->lpVtbl->Release(psl); 4616 } 4617 } 4618 return IsOk; 4619} 4620#endif 4621 4622#if EnableShellLinks 4623LOCALFUNC blnr FileIsLink(LPTSTR drivepath) 4624{ 4625 LPTSTR p = FindLastTerm(drivepath, (TCHAR)('.')); 4626 4627 if (p != nullpr) { 4628 if (_tcscmp(p, TEXT("lnk")) == 0) { 4629 return trueblnr; 4630 } 4631 } 4632 return falseblnr; 4633} 4634#endif 4635 4636LOCALFUNC blnr InsertDiskOrAlias(LPTSTR drivepath, 4637 blnr MaybeROM, blnr MaybeAlias) 4638{ 4639#if EnableShellLinks 4640 if (MaybeAlias && FileIsLink(drivepath)) { 4641 if (! MyResolveShortcut(drivepath, NULL)) { 4642 return falseblnr; 4643 } 4644 } 4645#endif 4646 4647 if (MaybeROM && ! ROM_loaded) { 4648 return LoadMacRomFromPath(drivepath); 4649 } else { 4650 return Sony_Insert1(drivepath, falseblnr); 4651 } 4652} 4653 4654LOCALFUNC blnr MyFileExists(LPTSTR pathName, blnr *directory) 4655{ 4656 WIN32_FIND_DATA fd; 4657 HANDLE hf = FindFirstFile(pathName, &fd); 4658 blnr IsOk = falseblnr; 4659 4660 if (hf != INVALID_HANDLE_VALUE) { 4661 if (NULL != directory) { 4662 *directory = 4663 (0 != (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)); 4664 } 4665 IsOk = trueblnr; 4666 FindClose(hf); 4667 } 4668 4669 return IsOk; 4670} 4671 4672LOCALFUNC tMacErr ResolveNamedChild0(LPTSTR pathName, 4673 LPTSTR Child, blnr *directory) 4674{ 4675 size_t newlen; 4676 size_t oldlen = _tcslen(pathName); 4677 tMacErr err = mnvm_miscErr; 4678 4679 newlen = oldlen + 1 + _tcslen(Child); 4680 if (newlen + 1 < _MAX_PATH) { 4681 _tcscat(pathName, TEXT("\\")); 4682 _tcscat(pathName, Child); 4683 4684 if (MyFileExists(pathName, directory)) { 4685 err = mnvm_noErr; 4686 } else { 4687 err = mnvm_fnfErr; 4688#if EnableShellLinks 4689 if (newlen + 5 < _MAX_PATH) { 4690 _tcscat(pathName, TEXT(".lnk")); 4691 if (MyFileExists(pathName, NULL)) 4692 if (MyResolveShortcut(pathName, directory)) 4693 { 4694 err = mnvm_noErr; 4695 } 4696 if (mnvm_noErr != err) { 4697 pathName[newlen] = (TCHAR)('\0'); 4698 } 4699 } 4700#endif 4701 } 4702 } 4703 4704 return err; 4705} 4706 4707LOCALFUNC tMacErr ResolveNamedChild(LPTSTR pathName, 4708 char *Child, blnr *directory) 4709{ 4710 TCHAR Child0[ClStrMaxLength + 1]; 4711 4712 NativeStrFromCStr(Child0, Child, falseblnr); 4713 4714 return ResolveNamedChild0(pathName, Child0, directory); 4715} 4716 4717LOCALFUNC blnr ResolveNamedChildDir(LPTSTR pathName, char *Child) 4718{ 4719 blnr directory; 4720 4721 return (mnvm_noErr == ResolveNamedChild( 4722 pathName, Child, &directory)) 4723 && directory; 4724} 4725 4726LOCALFUNC blnr ResolveNamedChildFile(LPTSTR pathName, char *Child) 4727{ 4728 blnr directory; 4729 4730 return (mnvm_noErr == ResolveNamedChild( 4731 pathName, Child, &directory)) 4732 && ! directory; 4733} 4734 4735#if UseActvFile || (IncludeSonyNew && ! SaveDialogEnable) 4736LOCALFUNC blnr MakeNamedChildDir(LPTSTR pathName, char *Child) 4737{ 4738 blnr directory; 4739 blnr IsOk = falseblnr; 4740 tMacErr err = ResolveNamedChild(pathName, Child, &directory); 4741 4742 if (mnvm_noErr == err) { 4743 IsOk = directory; 4744 } else if (mnvm_fnfErr == err) { 4745 if (CreateDirectory(pathName, NULL)) { 4746 IsOk = trueblnr; 4747 } 4748 } 4749 4750 return IsOk; 4751} 4752#endif 4753 4754LOCALFUNC blnr MyGetAppDataPath(LPTSTR lpszPath, 4755 BOOL fCreate) 4756{ 4757 blnr IsOk = falseblnr; 4758 4759 if (HaveMySHGetSpecialFolderPath()) 4760 if (MySHGetSpecialFolderPath( 4761 NULL /* HWND hwndOwner */, 4762 lpszPath, My_CSIDL_APPDATA, fCreate)) 4763 { 4764 IsOk = trueblnr; 4765 } 4766 /* 4767 if not available, could perhaps 4768 use GetWindowsDirectory. 4769 */ 4770 /* 4771 SHGetFolderPath is more recent, 4772 could perhaps check for it first. 4773 might also be in "SHFolder.dll". 4774 4775 SHGetKnownFolderPath is even 4776 more recent. 4777 */ 4778 4779 return IsOk; 4780} 4781 4782#if UseWinCE 4783/* Are we in control mode? */ 4784/* Needed because you can't hold down a key with the virtual keyboard */ 4785LOCALVAR blnr CtrlMode = falseblnr; 4786#endif 4787 4788LOCALPROC InsertADisk0(void) 4789{ 4790 OPENFILENAME ofn; 4791 TCHAR szDirName[256]; 4792 TCHAR szFile[256]; 4793#if ! UseWinCE 4794 TCHAR szFileTitle[256]; 4795#endif 4796 UINT i; 4797 size_t cbString; 4798 TCHAR chReplace; 4799 TCHAR szFilter[256]; 4800 blnr IsOk; 4801 4802 szDirName[0] = (TCHAR)('\0'); 4803 szFile[0] = (TCHAR)('\0'); 4804 _tcscpy(szFilter, 4805 TEXT("Disk images|*.dsk;*.HF?;*.IMG;*.IMA;*.IMAGE") 4806 TEXT("|All files (*.*)|*.*|\0")); 4807 4808 cbString = _tcslen(szFilter); 4809 4810 chReplace = szFilter[cbString - 1]; 4811 4812 for (i = 0; szFilter[i] != (TCHAR)('\0'); ++i) 4813 { 4814 if (szFilter[i] == chReplace) { 4815 szFilter[i] = (TCHAR)('\0'); 4816 } 4817 } 4818 4819 memset(&ofn, 0, sizeof(OPENFILENAME)); 4820 4821 ofn.lStructSize = sizeof(OPENFILENAME); 4822 ofn.hwndOwner = MainWnd; 4823 ofn.lpstrFilter = szFilter; 4824 ofn.nFilterIndex = 2; 4825 ofn.lpstrFile= szFile; 4826 ofn.nMaxFile = sizeof(szFile); 4827#if ! UseWinCE 4828 ofn.lpstrFileTitle = szFileTitle; 4829 ofn.nMaxFileTitle = sizeof(szFileTitle); 4830#endif 4831 ofn.lpstrInitialDir = szDirName; 4832 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST 4833 | OFN_HIDEREADONLY; 4834 4835 MyBeginDialog(); 4836 IsOk = GetOpenFileName(&ofn); 4837 MyEndDialog(); 4838 4839 if(! IsOk) { 4840 /* report error */ 4841#if UseWinCE 4842 if (szFile[0]) { 4843 char wMsg[1024]; 4844 sprintf(wMsg, "Couldn't open %ls", szFile); 4845 MacMsg("error", wMsg, falseblnr); 4846 } 4847#endif 4848 } else { 4849 (void) InsertDiskOrAlias(ofn.lpstrFile, 4850 trueblnr, falseblnr); 4851 } 4852 4853#if UseWinCE 4854 CtrlMode = falseblnr; 4855#endif 4856} 4857 4858LOCALFUNC blnr LoadInitialImageFromName(char *ImageName) 4859{ 4860 TCHAR ImageFile[_MAX_PATH]; 4861 4862 if (GetAppDir(ImageFile)) 4863 if (ResolveNamedChildFile(ImageFile, ImageName)) 4864 if (Sony_Insert1(ImageFile, trueblnr)) 4865 { 4866 return trueblnr; 4867 } 4868 return falseblnr; 4869} 4870 4871LOCALFUNC blnr Sony_InsertIth(int i) 4872{ 4873 blnr v; 4874 4875 if ((i > 9) || ! FirstFreeDisk(nullpr)) { 4876 v = falseblnr; 4877 } else { 4878 char s[] = "disk?.dsk"; 4879 4880 s[4] = '0' + i; 4881 4882 /* stop on first error (including file not found) */ 4883 v = LoadInitialImageFromName(s); 4884 } 4885 4886 return v; 4887} 4888 4889LOCALFUNC blnr LoadInitialImages(void) 4890{ 4891 if (! AnyDiskInserted()) { 4892 int i; 4893 4894 for (i = 1; Sony_InsertIth(i); ++i) { 4895 /* stop on first error (including file not found) */ 4896 } 4897 } 4898 4899 return trueblnr; 4900} 4901 4902#if UseActvFile 4903 4904#define ActvCodeFileName "act_1" 4905 4906LOCALFUNC tMacErr ActvCodeFileLoad(ui3p p) 4907{ 4908 TCHAR pathName[_MAX_PATH]; 4909 DWORD BytesRead; 4910 HANDLE refnum = INVALID_HANDLE_VALUE; 4911 blnr IsOk = falseblnr; 4912 4913 if (MyGetAppDataPath(pathName, FALSE)) 4914 if (ResolveNamedChildDir(pathName, "Gryphel")) 4915 if (ResolveNamedChildDir(pathName, "mnvm_act")) 4916 if (ResolveNamedChildFile(pathName, ActvCodeFileName)) 4917 { 4918 refnum = CreateFile( 4919 pathName, /* pointer to name of the file */ 4920 GENERIC_READ, /* access (read-write) mode */ 4921 FILE_SHARE_READ, /* share mode */ 4922 NULL, /* pointer to security descriptor */ 4923 OPEN_EXISTING, /* how to create */ 4924 FILE_ATTRIBUTE_NORMAL, /* file attributes */ 4925 NULL /* handle to file with attributes to copy */ 4926 ); 4927 if (INVALID_HANDLE_VALUE == refnum) { 4928 /* report error */ 4929 } else { 4930 if (SetFilePointer( 4931 refnum, /* handle of file */ 4932 0, /* number of bytes to move file pointer */ 4933 nullpr, 4934 /* address of high-order word of distance to move */ 4935 FILE_BEGIN /* how to move */ 4936 ) != 0) 4937 { 4938 /* report error */ 4939 } else if (! ReadFile(refnum, /* handle of file to read */ 4940 (LPVOID)p, /* address of buffer that receives data */ 4941 (DWORD)ActvCodeFileLen, /* number of bytes to read */ 4942 &BytesRead, /* address of number of bytes read */ 4943 nullpr) /* address of structure for data */ 4944 || ((ui5b)BytesRead != ActvCodeFileLen)) 4945 { 4946 /* report error */ 4947 } else { 4948 IsOk = trueblnr; 4949 } 4950 (void) CloseHandle(refnum); 4951 } 4952 } 4953 4954 return IsOk ? mnvm_noErr : mnvm_miscErr; 4955} 4956 4957LOCALFUNC blnr NewNamedChildFile(LPTSTR pathName, char *Child) 4958{ 4959 blnr directory; 4960 blnr IsOk = falseblnr; 4961 tMacErr err = ResolveNamedChild(pathName, Child, &directory); 4962 4963 if (mnvm_noErr == err) { 4964 IsOk = ! directory; 4965 } else if (mnvm_fnfErr == err) { 4966 IsOk = trueblnr; 4967 } 4968 4969 return IsOk; 4970} 4971 4972LOCALFUNC tMacErr ActvCodeFileSave(ui3p p) 4973{ 4974 TCHAR pathName[_MAX_PATH]; 4975 DWORD BytesWritten; 4976 HANDLE refnum = INVALID_HANDLE_VALUE; 4977 blnr IsOk = falseblnr; 4978 4979 if (MyGetAppDataPath(pathName, TRUE)) 4980 if (MakeNamedChildDir(pathName, "Gryphel")) 4981 if (MakeNamedChildDir(pathName, "mnvm_act")) 4982 if (NewNamedChildFile(pathName, ActvCodeFileName)) 4983 { 4984 refnum = CreateFile( 4985 pathName, /* pointer to name of the file */ 4986 GENERIC_READ + GENERIC_WRITE, /* access (read-write) mode */ 4987 0, /* share mode */ 4988 NULL, /* pointer to security descriptor */ 4989 CREATE_ALWAYS, /* how to create */ 4990 FILE_ATTRIBUTE_NORMAL, /* file attributes */ 4991 NULL /* handle to file with attributes to copy */ 4992 ); 4993 if (INVALID_HANDLE_VALUE == refnum) { 4994 /* report error */ 4995 } else { 4996 if (SetFilePointer( 4997 refnum, /* handle of file */ 4998 0, /* number of bytes to move file pointer */ 4999 nullpr, 5000 /* address of high-order word of distance to move */ 5001 FILE_BEGIN /* how to move */ 5002 ) != 0) 5003 { 5004 /* report error */ 5005 } else if (! WriteFile(refnum, /* handle of file to read */ 5006 (LPVOID)p, /* address of buffer that receives data */ 5007 (DWORD)ActvCodeFileLen, /* number of bytes to read */ 5008 &BytesWritten, /* address of number of bytes read */ 5009 nullpr) /* address of structure for data */ 5010 || ((ui5b)BytesWritten != ActvCodeFileLen)) 5011 { 5012 /* report error */ 5013 } else { 5014 IsOk = trueblnr; 5015 } 5016 (void) CloseHandle(refnum); 5017 if (! IsOk) { 5018 (void) DeleteFile(pathName); 5019 } 5020 } 5021 } 5022 5023 return IsOk ? mnvm_noErr : mnvm_miscErr; 5024} 5025 5026#endif /* UseActvFile */ 5027 5028#if IncludeSonyNew 5029LOCALFUNC blnr WriteZero(HANDLE refnum, ui5b L) 5030{ 5031 if (SetFilePointer( 5032 refnum, /* handle of file */ 5033 0, /* number of bytes to move file pointer */ 5034 nullpr, /* address of high-order word of distance to move */ 5035 FILE_BEGIN /* how to move */ 5036 ) != 0) 5037 { 5038 return falseblnr; 5039 } else { 5040#define ZeroBufferSize 2048 5041 ui5b i; 5042 ui3b buffer[ZeroBufferSize]; 5043 DWORD BytesWritten; 5044 5045 memset(&buffer, 0, ZeroBufferSize); 5046 5047 while (L > 0) { 5048 i = (L > ZeroBufferSize) ? ZeroBufferSize : L; 5049 if (! WriteFile(refnum, /* handle of file to read */ 5050 (LPVOID)buffer, 5051 /* address of buffer that receives data */ 5052 (DWORD)i, /* number of bytes to read */ 5053 &BytesWritten, /* address of number of bytes read */ 5054 nullpr) /* address of structure for data */ 5055 || ((ui5b)BytesWritten != i)) 5056 { 5057 return falseblnr; 5058 } 5059 L -= i; 5060 } 5061 return trueblnr; 5062 } 5063} 5064#endif 5065 5066#define MaxSavePathSize MAX_PATH 5067 5068#if IncludeSonyNew 5069LOCALPROC MakeNewDisk0(ui5b L, LPTSTR pathName) 5070{ 5071 blnr IsOk = falseblnr; 5072 HANDLE newrefNum; 5073 5074 IsOk = falseblnr; 5075 newrefNum = CreateFile( 5076 pathName, /* pointer to name of the file */ 5077 GENERIC_READ + GENERIC_WRITE, /* access (read-write) mode */ 5078 0, /* share mode */ 5079 NULL, /* pointer to security descriptor */ 5080 CREATE_ALWAYS, /* how to create */ 5081 FILE_ATTRIBUTE_NORMAL, /* file attributes */ 5082 NULL /* handle to file with attributes to copy */ 5083 ); 5084 if (newrefNum == INVALID_HANDLE_VALUE) { 5085 /* report error */ 5086 } else { 5087 if (SetFilePointer( 5088 newrefNum, /* handle of file */ 5089 L, /* number of bytes to move file pointer */ 5090 nullpr, 5091 /* address of high-order word of distance to move */ 5092 FILE_BEGIN /* how to move */ 5093 ) != L) 5094 { 5095 /* report error */ 5096 } else if (! SetEndOfFile(newrefNum)) { 5097 /* report error */ 5098 } else if (! WriteZero(newrefNum, L)) { 5099 /* report error */ 5100 } else { 5101 IsOk = 5102 Sony_Insert0(newrefNum, falseblnr, pathName); 5103 newrefNum = INVALID_HANDLE_VALUE; 5104 } 5105 if (INVALID_HANDLE_VALUE != newrefNum) { 5106 (void) CloseHandle(newrefNum); 5107 } 5108 if (! IsOk) { 5109 (void) DeleteFile(pathName); 5110 } 5111 } 5112} 5113#endif 5114 5115#if IncludeSonyNew 5116LOCALPROC MakeNewDisk(ui5b L, HGLOBAL NewDiskNameDat) 5117{ 5118#if SaveDialogEnable 5119 OPENFILENAME ofn; 5120 blnr IsOk = falseblnr; 5121 TCHAR szFile[MaxSavePathSize]; 5122 TCHAR szFileTitle[MaxSavePathSize]; 5123 5124 memset(&ofn, 0, sizeof(OPENFILENAME)); 5125 szFile[0] = 0; 5126 szFileTitle[0] = 0; 5127 5128#if IncludeSonyGetName 5129 if (NewDiskNameDat != NULL) { 5130 LPTSTR p = GlobalLock(NewDiskNameDat); 5131 if (p != NULL) { 5132 _tcscpy(szFile, p); 5133 (void) GlobalUnlock(NewDiskNameDat); 5134 } 5135 } else 5136#endif 5137 { 5138 NativeStrFromCStr(szFile, "untitled", falseblnr); 5139 } 5140 5141 ofn.lStructSize = sizeof(OPENFILENAME); 5142 ofn.lpstrFile = szFile; 5143 ofn.hwndOwner = MainWnd; 5144 /* ofn.lpstrFilter = "All\0*.*\0Text\0*.txt\0Datafile\0*.dsk\0"; */ 5145 /* ofn.lpstrFilter = NULL; */ /* szFilter */ 5146 ofn.nMaxFile = MaxSavePathSize; 5147 ofn.lpstrFileTitle = szFileTitle; 5148 ofn.nMaxFileTitle = MaxSavePathSize; 5149 ofn.lpstrInitialDir = NULL; 5150 ofn.Flags = OFN_OVERWRITEPROMPT + OFN_HIDEREADONLY; 5151 /* + OFN_SHOWHELP */ 5152 5153 MyBeginDialog(); 5154 IsOk = GetSaveFileName(&ofn); 5155 MyEndDialog(); 5156 5157 if (! IsOk) { 5158 /* report error */ 5159 } else { 5160 MakeNewDisk0(L, ofn.lpstrFile); 5161 } 5162#else /* SaveDialogEnable */ 5163 TCHAR pathName[MaxSavePathSize]; 5164 5165 if (GetAppDir(pathName)) 5166 if (MakeNamedChildDir(pathName, "out")) 5167 { 5168 blnr directory; 5169 LPTSTR p = GlobalLock(NewDiskNameDat); 5170 5171 if (p != NULL) { 5172 tMacErr err = ResolveNamedChild0(pathName, p, 5173 &directory); 5174 5175 if (mnvm_fnfErr == err) { 5176 err = mnvm_noErr; 5177 } else if (mnvm_noErr == err) { 5178 if (directory) { 5179 err = mnvm_miscErr; 5180 } 5181 } 5182 5183 if (mnvm_noErr == err) { 5184 MakeNewDisk0(L, pathName); 5185 } 5186 5187 (void) GlobalUnlock(NewDiskNameDat); 5188 } 5189 } 5190#endif /* SaveDialogEnable */ 5191} 5192#endif 5193 5194LOCALFUNC blnr LoadMacRom(void) 5195{ 5196 TCHAR ROMFile[_MAX_PATH]; 5197 blnr IsOk = falseblnr; 5198 5199 if (GetAppDir(ROMFile)) 5200 if (ResolveNamedChildFile(ROMFile, RomFileName)) 5201 { 5202 IsOk = trueblnr; 5203 } 5204 5205 if (! IsOk) { 5206 if (MyGetAppDataPath(ROMFile, FALSE)) 5207 if (ResolveNamedChildDir(ROMFile, "Gryphel")) 5208 if (ResolveNamedChildDir(ROMFile, "mnvm_rom")) 5209 if (ResolveNamedChildFile(ROMFile, RomFileName)) 5210 { 5211 IsOk = trueblnr; 5212 } 5213 5214 } 5215 5216 if (IsOk) { 5217 IsOk = LoadMacRomFromPath(ROMFile); 5218 } 5219 5220 return trueblnr; 5221} 5222 5223#if InstallFileIcons 5224LOCALPROC MySetRegKey(HKEY hKeyRoot, 5225 LPTSTR strRegKey, LPTSTR strRegValue) 5226{ 5227 HKEY RegKey; 5228 DWORD dwDisposition; 5229 5230 if (ERROR_SUCCESS == RegCreateKeyEx(hKeyRoot, strRegKey, 0, NULL, 5231 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 5232 NULL, &RegKey, &dwDisposition)) 5233 { 5234 RegSetValueEx(RegKey, NULL, 0, REG_SZ, 5235 (CONST BYTE *)strRegValue, 5236 (DWORD)((_tcslen(strRegValue) + 1) * sizeof(TCHAR))); 5237 RegCloseKey(RegKey); 5238 } 5239} 5240 5241LOCALPROC RegisterShellFileType(LPTSTR AppPath, LPTSTR strFilterExt, 5242 LPTSTR strFileTypeId, LPTSTR strFileTypeName, 5243 LPTSTR strIconId, blnr CanOpen) 5244{ 5245 TCHAR strRegKey[_MAX_PATH]; 5246 TCHAR strRegValue[_MAX_PATH + 2]; 5247 /* extra room for ","{strIconId} */ 5248 5249 MySetRegKey(HKEY_CLASSES_ROOT, strFileTypeId, strFileTypeName); 5250 MySetRegKey(HKEY_CLASSES_ROOT, strFilterExt, strFileTypeId); 5251 5252 _tcscpy(strRegKey, strFileTypeId); 5253 _tcscat(strRegKey, TEXT("\\DefaultIcon")); 5254 _tcscpy(strRegValue, TEXT("\"")); 5255 _tcscat(strRegValue, AppPath); 5256 _tcscat(strRegValue, TEXT("\",")); 5257 _tcscat(strRegValue, strIconId); 5258 MySetRegKey(HKEY_CLASSES_ROOT, strRegKey, strRegValue); 5259 5260 if (CanOpen) { 5261 _tcscpy(strRegKey, strFileTypeId); 5262 _tcscat(strRegKey, TEXT("\\shell\\open\\command")); 5263 _tcscpy(strRegValue, TEXT("\"")); 5264 _tcscat(strRegValue, AppPath); 5265 _tcscat(strRegValue, TEXT("\" \"%1\"")); 5266 MySetRegKey(HKEY_CLASSES_ROOT, strRegKey, strRegValue); 5267 } 5268} 5269 5270LOCALFUNC blnr RegisterInRegistry(void) 5271{ 5272 TCHAR AppPath[_MAX_PATH]; 5273 5274 GetModuleFileName(NULL, AppPath, _MAX_PATH); 5275#if 0 5276 GetShortPathName(AppPath, AppPath, _MAX_PATH); 5277#endif 5278 5279 RegisterShellFileType(AppPath, TEXT(".rom"), TEXT("minivmac.rom"), 5280 TEXT("Mini vMac ROM Image"), TEXT("1"), falseblnr); 5281 RegisterShellFileType(AppPath, TEXT(".dsk"), TEXT("minivmac.dsk"), 5282 TEXT("Mini vMac Disk Image"), TEXT("2"), trueblnr); 5283 5284 return trueblnr; 5285} 5286#endif 5287 5288LOCALVAR LPTSTR CommandLine; 5289 5290LOCALFUNC blnr ScanCommandLine(void) 5291{ 5292 TCHAR *p = CommandLine; 5293 TCHAR *p1; 5294 TCHAR *p2; 5295 TCHAR v; 5296 size_t L; 5297 5298 v = *p; 5299 while (0 != v) { 5300 if (' ' == v) { 5301 v = *++p; 5302 } else { 5303 if ('\"' == v) { 5304 v = *++p; 5305 p1 = p; 5306 while (('\"' != v) && (0 != v)) { 5307 v = *++p; 5308 } 5309 p2 = p; 5310 if ('\"' == v) { 5311 v = *++p; 5312 } 5313 } else { 5314 p1 = p; 5315 while ((' ' != v) && (0 != v)) { 5316 v = *++p; 5317 } 5318 p2 = p; 5319 } 5320 L = p2 - p1; 5321 if (L + 1 <= _MAX_PATH) { 5322 TCHAR fileName[_MAX_PATH]; 5323 TCHAR *filePtr = fileName; 5324 size_t i = L; 5325 5326 while (i > 0) { 5327 *filePtr++ = *p1++; 5328 --i; 5329 } 5330 *filePtr = (char)0; 5331 5332 if ((L > 0) 5333 && (('/' == fileName[0]) || ('-' == fileName[0]))) 5334 { 5335#if 0 5336 TCHAR *p3 = &fileName[1]; 5337 if (0 == _tcscmp(p3, TEXT("l"))) { 5338 SpeedValue = 0; 5339 } else 5340#endif 5341 { 5342 MacMsg(kStrBadArgTitle, kStrBadArgMessage, 5343 falseblnr); 5344 } 5345 } else { 5346 (void) InsertDiskOrAlias(fileName, 5347 falseblnr, trueblnr); 5348 } 5349 } 5350 } 5351 } 5352 5353 return trueblnr; 5354} 5355 5356#if EnableRecreateW 5357LOCALPROC CheckMagnifyAndFullScreen(void) 5358{ 5359 if ( 5360#if EnableMagnify 5361 (UseMagnify != WantMagnify) 5362#endif 5363#if EnableMagnify && VarFullScreen 5364 || 5365#endif 5366#if VarFullScreen 5367 (UseFullScreen != WantFullScreen) 5368#endif 5369 ) 5370 { 5371 (void) ReCreateMainWindow(); 5372 } 5373} 5374#endif 5375 5376#if VarFullScreen && EnableMagnify 5377enum { 5378 kWinStateWindowed, 5379#if EnableMagnify 5380 kWinStateFullScreen, 5381#endif 5382 kNumWinStates 5383}; 5384#endif 5385 5386#if VarFullScreen && EnableMagnify 5387LOCALVAR int WinMagStates[kNumWinStates]; 5388#endif 5389 5390LOCALPROC ZapWinStateVars(void) 5391{ 5392#if MayNotFullScreen 5393 { 5394 int i; 5395 5396 for (i = 0; i < kNumMagStates; ++i) { 5397 HavePositionWins[i] = falseblnr; 5398 } 5399 } 5400#endif 5401#if VarFullScreen && EnableMagnify 5402 { 5403 int i; 5404 5405 for (i = 0; i < kNumWinStates; ++i) { 5406 WinMagStates[i] = kMagStateAuto; 5407 } 5408 } 5409#endif 5410} 5411 5412#if VarFullScreen 5413LOCALPROC ToggleWantFullScreen(void) 5414{ 5415 WantFullScreen = ! WantFullScreen; 5416 5417#if EnableMagnify 5418 { 5419 int OldWinState = 5420 UseFullScreen ? kWinStateFullScreen : kWinStateWindowed; 5421 int OldMagState = 5422 UseMagnify ? kMagStateMagnifgy : kMagStateNormal; 5423 int NewWinState = 5424 WantFullScreen ? kWinStateFullScreen : kWinStateWindowed; 5425 int NewMagState = WinMagStates[NewWinState]; 5426 5427 WinMagStates[OldWinState] = OldMagState; 5428 if (kMagStateAuto != NewMagState) { 5429 WantMagnify = (kMagStateMagnifgy == NewMagState); 5430 } else { 5431 WantMagnify = falseblnr; 5432 if (WantFullScreen) { 5433 if ((GetSystemMetrics(SM_CXSCREEN) 5434 >= vMacScreenWidth * MyWindowScale) 5435 && (GetSystemMetrics(SM_CYSCREEN) 5436 >= vMacScreenHeight * MyWindowScale) 5437 ) 5438 { 5439 WantMagnify = trueblnr; 5440 } 5441 } 5442 } 5443 } 5444#endif 5445} 5446#endif 5447 5448#if EnableDragDrop 5449LOCALPROC DragFunc(HDROP hDrop) 5450{ 5451 WORD n; 5452 WORD i; 5453 TCHAR a[_MAX_PATH]; 5454 5455 n = DragQueryFile(hDrop, (UINT) -1, NULL, 0); 5456 for (i = 0; i < n; ++i) { 5457 if (DragQueryFile(hDrop, i, NULL, 0) < _MAX_PATH - 1) { 5458 (void) DragQueryFile(hDrop, i, a, _MAX_PATH); 5459 (void) InsertDiskOrAlias(a, trueblnr, trueblnr); 5460 } 5461 } 5462 5463 DragFinish(hDrop); 5464 5465 if (gTrueBackgroundFlag) { 5466 if (! SetForegroundWindow(MainWnd)) { 5467 /* error message here ? */ 5468 } 5469 5470 WantCmdOptOnReconnect = trueblnr; 5471 } 5472} 5473#endif 5474 5475GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void) 5476{ 5477#if MySoundEnabled 5478 SoundCheckVeryOften(); 5479#endif 5480 (void) UpdateTrueEmulatedTime(); 5481 return (TrueEmulatedTime == OnTrueTime); 5482} 5483 5484/* --- platform independent code can be thought of as going here --- */ 5485 5486LOCALPROC LeaveBackground(void) 5487{ 5488 ReconnectKeyCodes3(); 5489} 5490 5491LOCALPROC EnterBackground(void) 5492{ 5493 DisconnectKeyCodes3(); 5494 5495#if VarFullScreen 5496 if (WantFullScreen) { 5497 ToggleWantFullScreen(); 5498 } 5499#endif 5500} 5501 5502LOCALPROC LeaveSpeedStopped(void) 5503{ 5504#if MySoundEnabled 5505 MySound_Start(); 5506#endif 5507#if (MyTimeResolution != 0) 5508 MyTimer_Resume(); 5509#endif 5510} 5511 5512LOCALPROC EnterSpeedStopped(void) 5513{ 5514#if (MyTimeResolution != 0) 5515 MyTimer_Suspend(); 5516#endif 5517#if MySoundEnabled 5518 MySound_Stop(); 5519#endif 5520} 5521 5522LOCALPROC CheckForSavedTasks(void) 5523{ 5524 /* 5525 Check for things to do that rather wouldn't 5526 have done at an awkward time. 5527 */ 5528 5529 if (MyEvtQNeedRecover) { 5530 MyEvtQNeedRecover = falseblnr; 5531 5532 /* attempt cleanup, MyEvtQNeedRecover may get set again */ 5533 MyEvtQTryRecoverFromFull(); 5534 } 5535 5536#if EnableFSMouseMotion 5537 if (HaveMouseMotion) { 5538 MyMouseConstrain(); 5539 } 5540#endif 5541 5542 if (RequestMacOff) { 5543 RequestMacOff = falseblnr; 5544 if (AnyDiskInserted()) { 5545 MacMsgOverride(kStrQuitWarningTitle, 5546 kStrQuitWarningMessage); 5547 } else { 5548 ForceMacOff = trueblnr; 5549 } 5550 } 5551 5552 if (ForceMacOff) { 5553 return; 5554 } 5555 5556 if (gTrueBackgroundFlag != gBackgroundFlag) { 5557 gBackgroundFlag = gTrueBackgroundFlag; 5558 if (gTrueBackgroundFlag) { 5559 EnterBackground(); 5560 } else { 5561 LeaveBackground(); 5562 } 5563 } 5564 5565 if (CurSpeedStopped != (SpeedStopped || 5566 (gBackgroundFlag && ! RunInBackground 5567#if EnableAutoSlow && 0 5568 && (QuietSubTicks >= 4092) 5569#endif 5570 ))) 5571 { 5572 CurSpeedStopped = ! CurSpeedStopped; 5573 if (CurSpeedStopped) { 5574 EnterSpeedStopped(); 5575 } else { 5576 LeaveSpeedStopped(); 5577 } 5578 } 5579 5580#if EnableRecreateW 5581 if (! (gTrueBackgroundFlag)) { 5582 CheckMagnifyAndFullScreen(); 5583 } 5584#endif 5585 5586#if MayFullScreen 5587 if (GrabMachine != ( 5588#if VarFullScreen 5589 UseFullScreen && 5590#endif 5591 ! (gTrueBackgroundFlag || CurSpeedStopped))) 5592 { 5593 GrabMachine = ! GrabMachine; 5594 AdjustMachineGrab(); 5595 } 5596#endif 5597 5598 if (gTrueBackgroundFlag) { 5599 /* 5600 wait til later 5601 */ 5602 } else { 5603#if IncludeSonyNew 5604 if (vSonyNewDiskWanted) { 5605#if IncludeSonyNameNew 5606 if (vSonyNewDiskName != NotAPbuf) { 5607 HGLOBAL NewDiskNameDat; 5608 if (MacRomanTextToNativeHand(vSonyNewDiskName, trueblnr, 5609 &NewDiskNameDat)) 5610 { 5611 MakeNewDisk(vSonyNewDiskSize, NewDiskNameDat); 5612 GlobalFree(NewDiskNameDat); 5613 } 5614 PbufDispose(vSonyNewDiskName); 5615 vSonyNewDiskName = NotAPbuf; 5616 } else 5617#endif 5618 { 5619 MakeNewDisk(vSonyNewDiskSize, NULL); 5620 } 5621 vSonyNewDiskWanted = falseblnr; 5622 /* must be done after may have gotten disk */ 5623 } 5624#endif 5625 if (RequestInsertDisk) { 5626 RequestInsertDisk = falseblnr; 5627 InsertADisk0(); 5628 } 5629 } 5630 5631#if NeedRequestIthDisk 5632 if (0 != RequestIthDisk) { 5633 Sony_InsertIth(RequestIthDisk); 5634 RequestIthDisk = 0; 5635 } 5636#endif 5637 5638 if (HaveCursorHidden != (WantCursorHidden 5639 && ! (gTrueBackgroundFlag || CurSpeedStopped))) 5640 { 5641 HaveCursorHidden = ! HaveCursorHidden; 5642 if (HaveCursorHidden) { 5643 (void) ShowCursor(FALSE); 5644 } else { 5645 (void) ShowCursor(TRUE); 5646 SetCursor(LoadCursor(NULL, IDC_ARROW)); 5647 } 5648 } 5649 5650 if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) { 5651 MacMsgDisplayOn(); 5652 } 5653 5654 if (NeedWholeScreenDraw) { 5655 NeedWholeScreenDraw = falseblnr; 5656 ScreenChangedAll(); 5657 } 5658} 5659 5660#if UseWinCE 5661/* Sip Status ON/OFF */ 5662LOCALVAR blnr SipOn = falseblnr; 5663#endif 5664 5665LRESULT CALLBACK Win32WMProc(HWND hwnd, 5666 UINT uMessage, WPARAM wparam, LPARAM lparam); 5667 5668LRESULT CALLBACK Win32WMProc(HWND hwnd, 5669 UINT uMessage, WPARAM wparam, LPARAM lparam) 5670{ 5671 switch (uMessage) 5672 { 5673 case WM_PAINT: 5674 { 5675 PAINTSTRUCT ps; 5676 5677 BeginPaint(hwnd, (LPPAINTSTRUCT)&ps); 5678#if VarFullScreen 5679 if (UseFullScreen) 5680#endif 5681#if MayFullScreen 5682 { 5683 if (! FillRect(ps.hdc, 5684 &ps.rcPaint, 5685 GetStockObject(BLACK_BRUSH))) 5686 { 5687 /* ReportGetLastError(); */ 5688 } 5689 } 5690#endif 5691 if (MainWnd == hwnd) { 5692 Screen_DrawAll(); 5693 } 5694 EndPaint(hwnd, (LPPAINTSTRUCT)&ps); 5695 } 5696 break; 5697 5698 case WM_KEYDOWN: 5699 case WM_SYSKEYDOWN: 5700#if UseWinCE 5701 SipOn = falseblnr; 5702 5703 { 5704 SIPINFO r; 5705 5706 memset(&r, 0 , sizeof(SIPINFO)); 5707 r.cbSize = sizeof(SIPINFO); 5708 if (SipGetInfo(&r)) { 5709 SipOn = 0 != (r.fdwFlags & SIPF_ON); 5710 } 5711 } 5712 5713 if (wparam == 0xAE) { 5714 break; 5715 } else if ((! SipOn) && (wparam == VK_RETURN)) { 5716 break; 5717 } else if ((! SipOn) 5718 && (wparam >= VK_LEFT) && (wparam <= VK_DOWN)) 5719 { 5720 break; 5721 } else if (wparam == VK_CONTROL && CtrlMode) { 5722 DoVKcode0(wparam, falseblnr); 5723 CtrlMode = falseblnr; 5724 break; 5725 } else if (wparam == VK_CONTROL) { 5726 DoVKcode0(wparam, trueblnr); 5727 CtrlMode = trueblnr; 5728 break; 5729 } 5730#endif 5731 if (! TestBit(lparam, 30)) { /* ignore repeats */ 5732 DoVKcode(wparam, lparam >> 24, trueblnr); 5733 } 5734 5735#if UseWinCE 5736 return TRUE; 5737 /* 5738 So that hardware keys won't be 5739 processed by the default handler 5740 */ 5741#endif 5742 5743 break; 5744 case WM_KEYUP: 5745 case WM_SYSKEYUP: 5746#if UseWinCE 5747 SipOn = falseblnr; 5748 5749 { 5750 SIPINFO r; 5751 5752 memset(&r, 0 , sizeof(SIPINFO)); 5753 r.cbSize = sizeof(SIPINFO); 5754 if (SipGetInfo(&r)) { 5755 SipOn = 0 != (r.fdwFlags & SIPF_ON); 5756 } 5757 } 5758 5759 if (wparam == 0xAE) { /* to hide SoftInput panel */ 5760 SipShowIM(SIPF_OFF); 5761 break; 5762 } else if ((! SipOn) && (wparam == VK_RETURN)) { 5763 /* DPad Action to show SIP */ 5764 /* Show SoftInput Panel */ 5765 SipShowIM(SIPF_ON); 5766 break; 5767 } else if ((! SipOn) 5768 && (wparam >= VK_LEFT) && (wparam <= VK_DOWN)) 5769 { 5770 switch (wparam) { 5771 case VK_LEFT: 5772 if (ViewHStart < (ViewHSize / 2)) { 5773 ViewHStart = 0; 5774 } else { 5775 ViewHStart -= (ViewHSize / 2); 5776 } 5777 break; 5778 case VK_UP: 5779 if (ViewVStart < (ViewVSize / 2)) { 5780 ViewVStart = 0; 5781 } else { 5782 ViewVStart -= (ViewVSize / 2); 5783 } 5784 break; 5785 case VK_RIGHT: 5786 ViewHStart += (ViewHSize / 2); 5787 if (ViewHStart >= (vMacScreenWidth - ViewHSize)) 5788 { 5789 ViewHStart = vMacScreenWidth - ViewHSize; 5790 } 5791 break; 5792 case VK_DOWN: 5793 ViewVStart += (ViewVSize / 2); 5794 if (ViewVStart 5795 >= (vMacScreenHeight - ViewVSize)) 5796 { 5797 ViewVStart = vMacScreenHeight - ViewVSize; 5798 } 5799 break; 5800 } 5801 Screen_DrawAll(); 5802 } else 5803 if (wparam == VK_CONTROL && CtrlMode) { 5804 break; 5805 } 5806#endif 5807 DoVKcode(wparam, lparam >> 24, falseblnr); 5808 5809#if UseWinCE 5810 return TRUE; 5811 /* 5812 So that hardware keys won't be 5813 processed by the default handler 5814 */ 5815#endif 5816 5817 break; 5818#if ItnlKyBdFix && ! UseWinCE 5819 case WM_INPUTLANGCHANGE: 5820 MyCheckKeyboardLayout(); 5821 return TRUE; 5822 break; 5823#endif 5824 5825 case WM_CLOSE: 5826 RequestMacOff = trueblnr; 5827 break; 5828#if ! UseWinCE 5829 case WM_QUERYENDSESSION: 5830 if (AnyDiskInserted()) { 5831 RequestMacOff = trueblnr; 5832 return FALSE; 5833 } else { 5834 return TRUE; 5835 } 5836 break; 5837#endif 5838 case WM_ACTIVATE: 5839 if (MainWnd == hwnd) { 5840 gTrueBackgroundFlag = (LOWORD(wparam) == WA_INACTIVE); 5841 } 5842 break; 5843 case WM_COMMAND: 5844 switch(LOWORD(wparam)) 5845 { 5846 case ID_FILE_INSERTDISK1: 5847 RequestInsertDisk = trueblnr; 5848 break; 5849 case ID_FILE_QUIT: 5850 RequestMacOff = trueblnr; 5851 break; 5852 case ID_SPECIAL_MORECOMMANDS: 5853 DoMoreCommandsMsg(); 5854 break; 5855 case ID_HELP_ABOUT: 5856 DoAboutMsg(); 5857 break; 5858 } 5859 break; 5860 case WM_MOVE: 5861 WndX = (si4b) LOWORD(lparam); 5862 WndY = (si4b) HIWORD(lparam); 5863 break; 5864 case WM_SYSCHAR: 5865 case WM_CHAR: 5866 /* prevent any further processing */ 5867 break; 5868 case WM_LBUTTONDOWN: 5869 case WM_RBUTTONDOWN: 5870 MousePositionNotify(LOWORD (lparam), HIWORD (lparam)); 5871 SetCurMouseButton(trueblnr); 5872 break; 5873 case WM_LBUTTONUP: 5874 case WM_RBUTTONUP: 5875 MousePositionNotify(LOWORD (lparam), HIWORD (lparam)); 5876 SetCurMouseButton(falseblnr); 5877 break; 5878 case WM_MOUSEMOVE: 5879#if UseWinCE 5880 MousePositionNotify(LOWORD (lparam), HIWORD (lparam)); 5881#endif 5882 /* windows may have messed up cursor */ 5883 /* 5884 there is no notification when the mouse moves 5885 outside the window, and the cursor is automatically 5886 changed 5887 */ 5888 if (! HaveCursorHidden) { 5889 /* SetCursor(LoadCursor(NULL, IDC_ARROW)); */ 5890 } 5891 break; 5892#if EnableDragDrop 5893 case WM_CREATE: 5894 DragAcceptFiles(hwnd, TRUE); 5895 break; 5896 case WM_DROPFILES: 5897 DragFunc((HDROP) wparam); 5898 break; 5899 case WM_DESTROY: 5900 DragAcceptFiles(hwnd, FALSE); 5901 break; 5902#endif 5903 default: 5904 return DefWindowProc(hwnd, uMessage, wparam, lparam); 5905 } 5906 return 0; 5907} 5908 5909LOCALFUNC blnr RegisterOurClass(void) 5910{ 5911 WNDCLASS wc; 5912 5913 wc.style = CS_HREDRAW | CS_VREDRAW 5914#if ! UseWinCE 5915 | CS_OWNDC 5916#endif 5917 ; 5918 wc.lpfnWndProc = (WNDPROC)Win32WMProc; 5919 wc.cbClsExtra = 0; 5920 wc.cbWndExtra = 0; 5921 wc.hInstance = AppInstance; 5922 wc.hIcon = LoadIcon(AppInstance, MAKEINTRESOURCE(IDI_VMAC)); 5923 wc.hCursor = LoadCursor(NULL, IDC_ARROW); 5924 wc.hbrBackground = GetStockObject(BLACK_BRUSH); 5925 wc.lpszMenuName = NULL; 5926 wc.lpszClassName = WndClassName; 5927 5928 if (! RegisterClass(&wc)) { 5929 MacMsg("RegisterClass failed", 5930 "Sorry, Mini vMac encountered errors" 5931 " and cannot continue.", trueblnr); 5932 return falseblnr; 5933 } else { 5934 return trueblnr; 5935 } 5936} 5937 5938LOCALPROC WaitForTheNextEvent(void) 5939{ 5940 MSG msg; 5941 5942 if (-1 != GetMessage(&msg, NULL, 0, 0)) { 5943 DispatchMessage(&msg); 5944 } 5945} 5946 5947LOCALPROC CheckForSystemEvents(void) 5948{ 5949 MSG msg; 5950 ui3r i = 0; 5951 5952 while ((i < 32) && (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))) { 5953 DispatchMessage(&msg); 5954 ++i; 5955 } 5956} 5957 5958GLOBALOSGLUPROC WaitForNextTick(void) 5959{ 5960label_retry: 5961 CheckForSystemEvents(); 5962 CheckForSavedTasks(); 5963 5964 if (ForceMacOff) { 5965 return; 5966 } 5967 5968 if (CurSpeedStopped) { 5969 DoneWithDrawingForTick(); 5970 WaitForTheNextEvent(); 5971 goto label_retry; 5972 } 5973 5974 if (ExtraTimeNotOver()) { 5975 Sleep(NextIntTime - LastTime); 5976 goto label_retry; 5977 } 5978 5979 if (CheckDateTime()) { 5980#if MySoundEnabled 5981 MySound_SecondNotify(); 5982#endif 5983#if EnableDemoMsg 5984 DemoModeSecondNotify(); 5985#endif 5986 } 5987 5988 if (! (gBackgroundFlag)) { 5989#if ! UseWinCE 5990 CheckMouseState(); 5991#endif 5992 5993#if EnableGrabSpecialKeys 5994 CheckForLostKeyUps(); 5995#endif 5996 } 5997 5998 OnTrueTime = TrueEmulatedTime; 5999 6000#if dbglog_TimeStuff 6001 dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime); 6002#endif 6003} 6004 6005#if UseWinCE 6006LOCALFUNC blnr Init_ChangeOrientation(void) 6007{ 6008 DEVMODE dm; 6009 6010 /* initialize the DEVMODE structure */ 6011 ZeroMemory(&dm, sizeof (dm)); 6012 dm.dmSize = sizeof (dm); 6013 6014 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm); 6015 6016 /* Backup old values */ 6017 oldOrientation = dm.dmOrientation; 6018 oldDisplayOrientation = dm.dmDisplayOrientation; 6019 6020 6021 /* Hide SIP (you can never tell...) */ 6022 SipShowIM(SIPF_OFF); 6023 6024 /* Switch to Landscape mode if possible */ 6025 dm.dmOrientation = DMORIENT_LANDSCAPE; 6026 dm.dmDisplayOrientation = DMDO_90; 6027 dm.dmFields = DM_ORIENTATION | DM_DISPLAYORIENTATION; 6028 (void) ChangeDisplaySettingsEx(NULL, &dm, NULL, 0, 0); 6029 /* 6030 if (ChangeDisplaySettingsEx(NULL, &dm, NULL, 0, 0) != 6031 DISP_CHANGE_SUCCESSFUL) 6032 { 6033 MacMsg ("warning", 6034 "Couldn't switch to Landscape mode.", falseblnr); 6035 } 6036 */ 6037 6038 return trueblnr; 6039} 6040#endif 6041 6042#if UseWinCE 6043LOCALPROC Uninit_ChangeOrientation(void) 6044{ 6045 DEVMODE dm; 6046 6047 /* Restore old display orientation */ 6048 ZeroMemory(&dm, sizeof (dm)); 6049 dm.dmSize = sizeof(dm); 6050 6051 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm); 6052 6053 dm.dmOrientation = oldOrientation; 6054 dm.dmDisplayOrientation = oldDisplayOrientation; 6055 dm.dmFields = DM_ORIENTATION | DM_DISPLAYORIENTATION; 6056 6057 ChangeDisplaySettingsEx(NULL, &dm, 0, 0, 0); 6058} 6059#endif 6060 6061 6062/* ** code for handling hardware keys in Pocket PC devices ** */ 6063 6064#if UseWinCE 6065typedef BOOL (__stdcall *UnregisterFunc1Proc)(UINT, UINT); 6066LOCALVAR HINSTANCE hCoreDLL = NULL; 6067#endif 6068 6069#if UseWinCE 6070LOCALFUNC blnr InitHotKeys(void) 6071{ 6072 UnregisterFunc1Proc procUndergisterFunc; 6073 int i; 6074 6075 hCoreDLL = LoadLibrary(TEXT("coredll.dll")); 6076 if (! hCoreDLL) { 6077 MacMsg ("Fatal", "Could not load coredll.dll", trueblnr); 6078 } else { 6079 procUndergisterFunc = 6080 (UnregisterFunc1Proc) GetProcAddress(hCoreDLL, 6081 TEXT("UnregisterFunc1")); 6082 if (! procUndergisterFunc) { 6083 MacMsg ("Fatal", 6084 "Could not get UnregisterFunc1 procedure", trueblnr); 6085 } else { 6086 for (i = 0xc1; i <= 0xcf; ++i) { 6087 procUndergisterFunc(MOD_WIN, i); 6088 RegisterHotKey(MainWnd, i, MOD_WIN, i); 6089 } 6090 } 6091 } 6092 return trueblnr; 6093} 6094#endif 6095 6096#if UseWinCE 6097LOCALPROC UninitHotKeys(void) 6098{ 6099 if (! hCoreDLL) { 6100 FreeLibrary(hCoreDLL); 6101 } 6102} 6103#endif 6104 6105#include "PROGMAIN.h" 6106 6107/* ************************ */ 6108 6109LOCALPROC ZapOSGLUVars(void) 6110{ 6111 InitDrives(); 6112 ZapWinStateVars(); 6113} 6114 6115LOCALPROC ReserveAllocAll(void) 6116{ 6117#if dbglog_HAVE 6118 dbglog_ReserveAlloc(); 6119#endif 6120 ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr); 6121 ReserveAllocOneBlock(&screencomparebuff, 6122 vMacScreenNumBytes, 5, trueblnr); 6123#if UseControlKeys 6124 ReserveAllocOneBlock(&CntrlDisplayBuff, 6125 vMacScreenNumBytes, 5, falseblnr); 6126#endif 6127#if EnableScalingBuff 6128 { 6129 ui5r n = vMacScreenMonoNumBytes 6130#if EnableMagnify 6131 * MyWindowScale * MyWindowScale 6132#endif 6133 ; 6134#if 1 == vMacScreenDepth 6135 if (vMacScreenNumBytes * 2 > n) { 6136 n = vMacScreenNumBytes * 2; 6137 } 6138#elif vMacScreenDepth >= 4 6139 if (vMacScreenNumBytes > n) { 6140 n = vMacScreenNumBytes; 6141 } 6142#endif 6143 ReserveAllocOneBlock(&ScalingBuff, n, 5, falseblnr); 6144 } 6145#endif 6146#if MySoundEnabled 6147 ReserveAllocOneBlock((ui3p *)&TheSoundBuffer, 6148 dbhBufferSize, 5, falseblnr); 6149#endif 6150 6151 EmulationReserveAlloc(); 6152} 6153 6154LOCALFUNC blnr AllocMyMemory(void) 6155{ 6156 uimr n; 6157 blnr IsOk = falseblnr; 6158 6159 ReserveAllocOffset = 0; 6160 ReserveAllocBigBlock = nullpr; 6161 ReserveAllocAll(); 6162 n = ReserveAllocOffset; 6163 ReserveAllocBigBlock = 6164 (ui3p)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, n); 6165 if (NULL == ReserveAllocBigBlock) { 6166 MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr); 6167 } else { 6168 ReserveAllocOffset = 0; 6169 ReserveAllocAll(); 6170 if (n != ReserveAllocOffset) { 6171 /* oops, program error */ 6172 } else { 6173 IsOk = trueblnr; 6174 } 6175 } 6176 6177 return IsOk; 6178} 6179 6180LOCALPROC UnallocMyMemory(void) 6181{ 6182 if (nullpr != ReserveAllocBigBlock) { 6183 if (GlobalFree(ReserveAllocBigBlock) != NULL) { 6184 MacMsg("error", "GlobalFree failed", falseblnr); 6185 } 6186 } 6187} 6188 6189LOCALFUNC blnr InitOSGLU(void) 6190{ 6191 if (AllocMyMemory()) 6192#if dbglog_HAVE 6193 if (dbglog_open()) 6194#endif 6195 if (RegisterOurClass()) 6196 if (ScanCommandLine()) 6197 if (LoadInitialImages()) 6198#if InstallFileIcons 6199 if (RegisterInRegistry()) 6200#endif 6201 if (LoadMacRom()) 6202#if UseActvCode 6203 if (ActvCodeInit()) 6204#endif 6205#if UseWinCE 6206 if (Init_ChangeOrientation()) 6207#endif 6208 if (ReCreateMainWindow()) 6209 if (InitWinKey2Mac()) 6210 if (InitTheCursor()) 6211#if UseWinCE 6212 if (InitHotKeys()) 6213#endif 6214 if (Init60thCheck()) 6215#if EmLocalTalk 6216 if (EntropyGather()) 6217 if (InitLocalTalk()) 6218#endif 6219 if (WaitForRom()) 6220 { 6221 return trueblnr; 6222 } 6223 return falseblnr; 6224} 6225 6226LOCALPROC UnInitOSGLU(void) 6227{ 6228#if (MyTimeResolution != 0) 6229 MyTimer_Suspend(); 6230#endif 6231 MyMouseCaptureSet(falseblnr); 6232 6233 if (MacMsgDisplayed) { 6234 MacMsgDisplayOff(); 6235 } 6236 6237#if EmLocalTalk 6238 UnInitLocalTalk(); 6239#endif 6240 6241#if MayFullScreen 6242 UnGrabTheMachine(); 6243#endif 6244#if MySoundEnabled 6245 MySound_Stop(); 6246#endif 6247#if IncludePbufs 6248 UnInitPbufs(); 6249#endif 6250 UnInitDrives(); 6251 6252 ForceShowCursor(); 6253#if UseWinCE 6254 Uninit_ChangeOrientation(); 6255 UninitHotKeys(); 6256#endif 6257 6258#if EnableShellLinks 6259 MyUninitCOM(); 6260#endif 6261 6262 if (! gTrueBackgroundFlag) { 6263 CheckSavedMacMsg(); 6264 } 6265 6266 DisposeMainWindow(); 6267 6268#if dbglog_HAVE 6269 dbglog_close(); 6270#endif 6271 6272 UnallocMyMemory(); 6273} 6274 6275int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 6276 LPTSTR lpCmdLine, int nCmdShow) 6277{ 6278 UnusedParam(hPrevInstance); 6279 AppInstance = hInstance; 6280 CmdShow = nCmdShow; 6281 CommandLine = lpCmdLine; 6282 6283 GetWndTitle(); 6284#if UseWinCE 6285 if (AlreadyRunningCheck()) { 6286 return 0; 6287 } 6288#endif 6289 6290 ZapOSGLUVars(); 6291 if (InitOSGLU()) { 6292 ProgramMain(); 6293 } 6294 UnInitOSGLU(); 6295 6296 return(0); 6297} 6298 6299#endif /* WantOSGLUWIN */