//***************************************************************************** // // LoadAccelerator - compatibility support. // So much code for such a thing. // // 23-Jul-92 NanduriR Created. //***************************************************************************** #include "precomp.h" #pragma hdrstop MODNAME(waccel.c); extern ULONG SetCursorIconFlag(HAND16 hAccel16, BOOL bFlag); LPACCELALIAS lpAccelAlias = NULL; //***************************************************************************** // WU32LoadAccelerators - // This gets called from WU32NotifyWow. I use the familiar name WU32... // because this gets called indirectly in response to LoadAccelerator // // returs TRUE for success. //***************************************************************************** ULONG FASTCALL WU32LoadAccelerators(VPVOID vpData) { PLOADACCEL16 ploadaccel16; HACCEL hAccel; BOOL fReturn = (BOOL)FALSE; GETVDMPTR(vpData, sizeof(LOADACCEL16), ploadaccel16); if (FindAccelAlias((HANDLE)FETCHWORD(ploadaccel16->hAccel), HANDLE_16BIT)) { LOGDEBUG(0, ("AccelAlias already exists\n")); return (ULONG)TRUE; } if (hAccel = CreateAccel32(ploadaccel16->pAccel, ploadaccel16->cbAccel)) { fReturn = (BOOL)SetupAccelAlias(FETCHWORD(ploadaccel16->hInst), FETCHWORD(ploadaccel16->hAccel), hAccel, TRUE); } FREEVDMPTR(ploadaccel16); return (ULONG)fReturn; } //***************************************************************************** // SetupAccelAlias - // sets up the alias. the alias list is doubly linked. nothing fancy. // // returns pointer to the alias. //***************************************************************************** LPACCELALIAS SetupAccelAlias( HAND16 hInstance, HAND16 hAccel16, HAND32 hAccel32, BOOL f16 ) { LPACCELALIAS lpT; WORD hTask16; hTask16 = CURRENTPTD()->htask16; lpT = FindAccelAlias((HANDLE)hAccel16, HANDLE_16BIT); if (lpT == (LPACCELALIAS)NULL) { lpT = malloc_w_small(sizeof(ACCELALIAS)); if (lpT) { lpT->lpNext = lpAccelAlias; lpT->lpPrev = (LPACCELALIAS)NULL; if (lpAccelAlias) lpAccelAlias->lpPrev = lpT; lpAccelAlias = lpT; } } else { LOGDEBUG(0, ("SetupAccelAlias: Alias Already exists. how & why?\n")); WOW32ASSERT(FALSE); } if (lpT) { lpT->hInst = hInstance; lpT->hTask16 = CURRENTPTD()->htask16; lpT->h16 = hAccel16; lpT->h32 = hAccel32; lpT->f16 = (WORD)f16; // mark this so we can remove it from the alias list when // FreeResource() (in user.exe) calls GlobalFree() (in krnl386) SetCursorIconFlag(hAccel16, TRUE); } else { WOW32ASSERT(FALSE); } return (LPACCELALIAS)lpT; } //***************************************************************************** // DestroyAccelAlias - // Deletes the 32bit table and Frees the memory // // returns TRUE for success //***************************************************************************** BOOL DestroyAccelAlias(WORD hTask16) { WORD hCurTask16; LPACCELALIAS lpT; LPACCELALIAS lpTFree; hCurTask16 = CURRENTPTD()->htask16; lpT = lpAccelAlias; while (lpT) { if (lpT->hTask16 == hCurTask16) { if (lpT->lpPrev) lpT->lpPrev->lpNext = lpT->lpNext; if (lpT->lpNext) lpT->lpNext->lpPrev = lpT->lpPrev; if ( lpT->f16 ) { DestroyAcceleratorTable(lpT->h32); } else { // this function - DestroyAccelAlias- gets called during // taskexit time and the 16bit task cleanup code has already // freed this memory handle. so this callback is not needed. // - nanduri // WOWGlobalFree16( lpT->h16 ); } lpTFree = lpT; lpT = lpT->lpNext; if (lpTFree == lpAccelAlias) lpAccelAlias = lpT; free_w_small(lpTFree); } else lpT = lpT->lpNext; } return TRUE; } //***************************************************************************** // FindAccelAlias - // maps 16 bit handle to 32bit handle and vice versa // // returns TRUE for success //***************************************************************************** LPACCELALIAS FindAccelAlias(HANDLE hAccel, UINT fSize) { WORD hCurTask16; LPACCELALIAS lpT; hCurTask16 = CURRENTPTD()->htask16; lpT = lpAccelAlias; while (lpT) { if (lpT->hTask16 == hCurTask16) { if (fSize & HANDLE_16BIT) { if (lpT->h16 == (HAND16)hAccel) return lpT; } else { if (lpT->h32 == (HAND32)hAccel) return lpT; } } lpT = lpT->lpNext; } return NULL; } //***************************************************************************** // GetAccelHandle32 - // Returns h32, given h16. // //***************************************************************************** HAND32 GetAccelHandle32(HAND16 h16) { LPACCELALIAS lpT; if (!(lpT = FindAccelAlias((HANDLE)(h16), HANDLE_16BIT))) { DWORD cbAccel16; VPVOID vpAccel16; HACCEL hAccel; if (vpAccel16 = RealLockResource16(h16, &cbAccel16)) { if (hAccel = CreateAccel32(vpAccel16, cbAccel16)) { lpT = SetupAccelAlias(CURRENTPTD()->hInst16, h16, hAccel, TRUE); } GlobalUnlock16(h16); } } return (lpT) ? lpT->h32 : (HAND32)NULL; } //***************************************************************************** // GetAccelHandle16 - // Returns h16, given h32. // //***************************************************************************** HAND16 GetAccelHandle16(HAND32 h32) { LPACCELALIAS lpT; HAND16 hAccel16; if (!(lpT = FindAccelAlias((HANDLE)(h32), HANDLE_32BIT))) { // // There isn't a corresponding 16-bit accelerator table handle already // so create one. // if ( (hAccel16 = CreateAccel16(h32)) != 0 ) { lpT = SetupAccelAlias(CURRENTPTD()->hInst16, hAccel16, h32, FALSE ); } } return (lpT) ? lpT->h16 : (HAND16)NULL; } //***************************************************************************** // CreateAccel32 - // This gets called from WU32NotifyWow. // // returs TRUE for success. //***************************************************************************** HACCEL CreateAccel32(VPVOID vpAccel16, DWORD cbAccel16) { PSZ pAccel16; DWORD nElem16; LPACCEL lpAccel; HACCEL hAccel = (HACCEL)NULL; UINT i; #if DBG UINT LastKeyIndex = 0xffffffff; #endif // // pAccel16 is pointer to an array of records of length: // (BYTE+WORD+WORD) // GETVDMPTR(vpAccel16 , cbAccel16, pAccel16); if (pAccel16) { // // convert the 16bit accel table to 32bit format and create it. // nElem16 = cbAccel16 / (sizeof(BYTE) + 2 * sizeof(WORD)); lpAccel = (LPACCEL)malloc_w(nElem16 * sizeof(ACCEL)); if (lpAccel) { for (i=0; ilpNext; if (lpT->lpPrev) lpT->lpPrev->lpNext = lpT->lpNext; if (lpT->lpNext) lpT->lpNext->lpPrev = lpT->lpPrev; if ( lpT->f16 ) { DestroyAcceleratorTable(lpT->h32); } else { // this function - FreeAccelAliasEntry -- is being called // indirectly from GlobalFree() in krnl386. GlobalFree() // takes care of freeing h16 so this callback is not needed. // - a-craigj // WOWGlobalFree16( lpT->h16 ); } free_w_small(lpT); }