From 6d068a01b6d3775e96a8d1897fc9433f41f9ad94 Mon Sep 17 00:00:00 2001 From: "dougt%meer.net" Date: Fri, 10 Feb 2006 21:55:02 +0000 Subject: [PATCH] WINCE only. move hotkey handling to use dispatch window. r/a=dveditz. b=325298 --- widget/src/windows/nsToolkit.cpp | 206 ++++++++++++++++++++++++++++++- widget/src/windows/nsWindow.cpp | 165 ++----------------------- widget/src/windows/nsWindow.h | 4 - 3 files changed, 215 insertions(+), 160 deletions(-) diff --git a/widget/src/windows/nsToolkit.cpp b/widget/src/windows/nsToolkit.cpp index 1c2cd853e815..5bfb8e5a128f 100644 --- a/widget/src/windows/nsToolkit.cpp +++ b/widget/src/windows/nsToolkit.cpp @@ -138,6 +138,199 @@ BOOL APIENTRY DllMain( HINSTANCE hModule, #endif + +#ifdef WINCE + +#define NS_VK_APP1 0x0201 +#define NS_VK_APP2 0x0202 +#define NS_VK_APP3 0x0203 +#define NS_VK_APP4 0x0204 +#define NS_VK_APP5 0x0205 +#define NS_VK_APP6 0x0206 +#define NS_VK_APP7 0x0207 +#define NS_VK_APP8 0x0208 +#define NS_VK_APP9 0x0209 +#define NS_VK_APP10 0x020A +#define NS_VK_APP11 0x020B + +extern PRBool gOverrideHWKeys; + +typedef BOOL (__stdcall *UnregisterFunc1Proc)( UINT, UINT ); +static UnregisterFunc1Proc gProcUnregisterFunc = NULL; +static HINSTANCE gCoreDll = NULL; + +UINT gHardwareKeys[][2] = + { + { 0xc1, MOD_WIN }, + { 0xc2, MOD_WIN }, + { 0xc3, MOD_WIN }, + { 0xc4, MOD_WIN }, + { 0xc5, MOD_WIN }, + { 0xc6, MOD_WIN }, + + { 0x72, 0 },// Answer - 0x72 Modifier - 0 + { 0x73, 0 },// Hangup - 0x73 Modifier - 0 + { 0x74, 0 },// + { 0x75, 0 },// Volume Up - 0x75 Modifier - 0 + { 0x76, 0 },// Volume Down - 0x76 Modifier - 0 + { 0, 0 }, + }; + +static void MapHardwareButtons(HWND window) +{ + if (!window) + return; + + // handle hardware buttons so that they broadcast into our + // application. the following code is based on an article + // on the Pocket PC Developer Network: + // + // http://www.pocketpcdn.com/articles/handle_hardware_keys.html + + if (gOverrideHWKeys) + { + if (!gProcUnregisterFunc) + { + gCoreDll = LoadLibrary(_T("coredll.dll")); // leak + + if (gCoreDll) + gProcUnregisterFunc = (UnregisterFunc1Proc)GetProcAddress( gCoreDll, _T("UnregisterFunc1")); + } + + if (gProcUnregisterFunc) + { + for (int i=0; gHardwareKeys[i][0]; i++) + { + UINT mod = gHardwareKeys[i][1]; + UINT kc = gHardwareKeys[i][0]; + + gProcUnregisterFunc(mod, kc); + RegisterHotKey(window, kc, mod, kc); + } + } + } +} + +static void UnmapHardwareButtons() +{ + if (!gProcUnregisterFunc) + return; + + for (int i=0; gHardwareKeys[i][0]; i++) + { + UINT mod = gHardwareKeys[i][1]; + UINT kc = gHardwareKeys[i][0]; + + gProcUnregisterFunc(mod, kc); + } +} + +void CreateSoftKeyMenuBar(HWND wnd) +{ + if (!wnd) + return; + + SHMENUBARINFO mbi; + ZeroMemory(&mbi, sizeof(SHMENUBARINFO)); + mbi.cbSize = sizeof(SHMENUBARINFO); + mbi.hwndParent = wnd; + + // On windows ce smartphone, events never occur if the + // menubar is empty. This doesn't work: + // mbi.dwFlags = SHCMBF_EMPTYBAR; + + mbi.nToolBarId = IDC_DUMMY_CE_MENUBAR; + mbi.hInstRes = GetModuleHandle(NULL); + + if (!SHCreateMenuBar(&mbi)) + return; + + SetWindowPos(mbi.hwndMB, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE); + + SendMessage(mbi.hwndMB, SHCMBM_OVERRIDEKEY, VK_TBACK, + MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, + SHMBOF_NODEFAULT | SHMBOF_NOTIFY)); + + SendMessage(mbi.hwndMB, SHCMBM_OVERRIDEKEY, VK_TSOFT1, + MAKELPARAM (SHMBOF_NODEFAULT | SHMBOF_NOTIFY, + SHMBOF_NODEFAULT | SHMBOF_NOTIFY)); + + + SendMessage(mbi.hwndMB, SHCMBM_OVERRIDEKEY, VK_TSOFT2, + MAKELPARAM (SHMBOF_NODEFAULT | SHMBOF_NOTIFY, + SHMBOF_NODEFAULT | SHMBOF_NOTIFY)); +} + +void HandleHotKey(WPARAM wParam, LPARAM lParam) +{ + // SmartPhones has a one or two menu buttons at the + // bottom of the screen. They are dispatched via a + // menu resource, rather then a hotkey. To make + // this look consistent, we have mapped this menu to + // fire hotkey events. See + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/win_ce/html/pwc_TheBackButtonandOtherInterestingButtons.asp + + // Also, an important thing to not here is that the + // handling of the hot key is not tied to a specific + // nsWindow or native window. + + if (VK_TSOFT1 == HIWORD(lParam) && (0 != (MOD_KEYUP & LOWORD(lParam)))) + { + keybd_event(VK_F23, 0, 0, 0); + keybd_event(VK_F23, 0, KEYEVENTF_KEYUP, 0); + return; + } + + if (VK_TSOFT2 == HIWORD(lParam) && (0 != (MOD_KEYUP & LOWORD(lParam)))) + { + keybd_event(VK_F24, 0, 0, 0); + keybd_event(VK_F24, 0, KEYEVENTF_KEYUP, 0); + return; + } + + if (VK_TBACK == HIWORD(lParam) && (0 != (MOD_KEYUP & LOWORD(lParam)))) + { + keybd_event(VK_BACK, 0, 0, 0); + keybd_event(VK_BACK, 0, KEYEVENTF_KEYUP, 0); + return; + } + + switch (wParam) + { + case VK_APP1: + keybd_event(VK_F1, 0, 0, 0); + keybd_event(VK_F1, 0, KEYEVENTF_KEYUP, 0); + return; + + case VK_APP2: + keybd_event(VK_F2, 0, 0, 0); + keybd_event(VK_F2, 0, KEYEVENTF_KEYUP, 0); + return; + + case VK_APP3: + keybd_event(VK_F3, 0, 0, 0); + keybd_event(VK_F3, 0, KEYEVENTF_KEYUP, 0); + return; + + case VK_APP4: + keybd_event(VK_F4, 0, 0, 0); + keybd_event(VK_F4, 0, KEYEVENTF_KEYUP, 0); + return; + + case VK_APP5: + keybd_event(VK_F5, 0, 0, 0); + keybd_event(VK_F5, 0, KEYEVENTF_KEYUP, 0); + return; + + case VK_APP6: + keybd_event(VK_F6, 0, 0, 0); + keybd_event(VK_F6, 0, KEYEVENTF_KEYUP, 0); + return; + } +} +#endif + + // // main for the message pump thread // @@ -715,8 +908,12 @@ void nsToolkit::CreateInternalWindow(PRThread *aThread) NULL, nsToolkit::mDllInstance, NULL); - VERIFY(mDispatchWnd); + +#ifdef WINCE + CreateSoftKeyMenuBar(mDispatchWnd); + MapHardwareButtons(mDispatchWnd); +#endif } @@ -819,6 +1016,13 @@ LRESULT CALLBACK nsToolkit::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, nsWindow::GlobalMsgWindowProc(hWnd, msg, wParam, lParam); } +#ifdef WINCE + case WM_HOTKEY: + { + HandleHotKey(wParam, lParam); + return 0; + } +#endif } if(nsToolkit::gAIMMApp) { diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index da0b5e8e71ae..aabb7621e0fc 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -77,28 +77,6 @@ #include #include -static PRBool dummy = nsToolkit::InitVersionInfo(); - -#ifdef WINCE - -#define NS_VK_APP1 0x0201 -#define NS_VK_APP2 0x0202 -#define NS_VK_APP3 0x0203 -#define NS_VK_APP4 0x0204 -#define NS_VK_APP5 0x0205 -#define NS_VK_APP6 0x0206 -#define NS_VK_APP7 0x0207 -#define NS_VK_APP8 0x0208 -#define NS_VK_APP9 0x0209 -#define NS_VK_APP10 0x020A -#define NS_VK_APP11 0x020B - - -#include "aygshell.h" -#include "imm.h" -#include "tpcshell.h" -#endif - // unknwn.h is needed to build with WIN32_LEAN_AND_MEAN #include @@ -154,6 +132,14 @@ static PRBool dummy = nsToolkit::InitVersionInfo(); #include "prprf.h" #include "prmem.h" +#ifdef WINCE +#include "aygshell.h" +#include "tpcshell.h" + +PRBool gOverrideHWKeys = PR_FALSE; +PRBool gUseOkayButton = PR_FALSE; +#endif + static const char kMozHeapDumpMessageString[] = "MOZ_HeapDump"; #define kWindowPositionSlop 20 @@ -198,121 +184,6 @@ static inline PRBool IsAlphaTranslucencySupported() { return pUpdateLayeredWindo #endif - -#ifdef WINCE -static PRBool gUseOkayButton = PR_FALSE; -static PRBool gOverrideHWKeys = PR_TRUE; - -typedef BOOL (__stdcall *UnregisterFunc1Proc)( UINT, UINT ); -static UnregisterFunc1Proc gProcUnregisterFunc = NULL; -static HINSTANCE gCoreDll = NULL; - -UINT gHardwareKeys[][2] = - { - { 0xc1, MOD_WIN }, - { 0xc2, MOD_WIN }, - { 0xc3, MOD_WIN }, - { 0xc4, MOD_WIN }, - { 0xc5, MOD_WIN }, - { 0xc6, MOD_WIN }, - - { 0x72, 0 },// Answer - 0x72 Modifier - 0 - { 0x73, 0 },// Hangup - 0x73 Modifier - 0 - { 0x74, 0 },// - { 0x75, 0 },// Volume Up - 0x75 Modifier - 0 - { 0x76, 0 },// Volume Down - 0x76 Modifier - 0 - { 0, 0 }, - }; - -static void MapHardwareButtons(HWND window) -{ - if (!window) - return; - - // handle hardware buttons so that they broadcast into our - // application. the following code is based on an article - // on the Pocket PC Developer Network: - // - // http://www.pocketpcdn.com/articles/handle_hardware_keys.html - - if (gOverrideHWKeys) - { - if (!gProcUnregisterFunc) - { - gCoreDll = LoadLibrary(_T("coredll.dll")); // leak - - if (gCoreDll) - gProcUnregisterFunc = (UnregisterFunc1Proc)GetProcAddress( gCoreDll, _T("UnregisterFunc1")); - } - - if (gProcUnregisterFunc) - { - for (int i=0; gHardwareKeys[i][0]; i++) - { - UINT mod = gHardwareKeys[i][1]; - UINT kc = gHardwareKeys[i][0]; - - gProcUnregisterFunc(mod, kc); - RegisterHotKey(window, kc, mod, kc); - } - } - } -} - -static void UnmapHardwareButtons() -{ - if (!gProcUnregisterFunc) - return; - - for (int i=0; gHardwareKeys[i][0]; i++) - { - UINT mod = gHardwareKeys[i][1]; - UINT kc = gHardwareKeys[i][0]; - - gProcUnregisterFunc(mod, kc); - } -} - -HWND CreateSoftKeyMenuBar(HWND wnd) -{ - if (!wnd) - return nsnull; - - SHMENUBARINFO mbi; - ZeroMemory(&mbi, sizeof(SHMENUBARINFO)); - mbi.cbSize = sizeof(SHMENUBARINFO); - mbi.hwndParent = wnd; - - // On windows ce smartphone, events never occur if the - // menubar is empty. This doesn't work: - // mbi.dwFlags = SHCMBF_EMPTYBAR; - - mbi.nToolBarId = IDC_DUMMY_CE_MENUBAR; - mbi.hInstRes = GetModuleHandle(NULL); - - if (!SHCreateMenuBar(&mbi)) - return nsnull; - - SetWindowPos(mbi.hwndMB, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE); - - SendMessage(mbi.hwndMB, SHCMBM_OVERRIDEKEY, VK_TBACK, - MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, - SHMBOF_NODEFAULT | SHMBOF_NOTIFY)); - - SendMessage(mbi.hwndMB, SHCMBM_OVERRIDEKEY, VK_TSOFT1, - MAKELPARAM (SHMBOF_NODEFAULT | SHMBOF_NOTIFY, - SHMBOF_NODEFAULT | SHMBOF_NOTIFY)); - - - SendMessage(mbi.hwndMB, SHCMBM_OVERRIDEKEY, VK_TSOFT2, - MAKELPARAM (SHMBOF_NODEFAULT | SHMBOF_NOTIFY, - SHMBOF_NODEFAULT | SHMBOF_NOTIFY)); - - return mbi.hwndMB; -} - -#endif - static PRBool IsCursorTranslucencySupported() { static PRBool didCheck = PR_FALSE; static PRBool isSupported = PR_FALSE; @@ -506,6 +377,8 @@ static PRBool is_vk_down(int vk) #define IME_X_OFFSET 0 #define IME_Y_OFFSET 0 + + #define IS_IME_CODEPAGE(cp) ((932==(cp))||(936==(cp))||(949==(cp))||(950==(cp))) // @@ -894,9 +767,6 @@ nsWindow::nsWindow() : nsBaseWidget() prefBranch->GetBoolPref("config.wince.overrideHWKeys", &gOverrideHWKeys); } } - - mSoftKeyMenuBar = nsnull; - #endif } @@ -957,9 +827,6 @@ nsWindow::~nsWindow() NS_IF_RELEASE(mNativeDragTarget); -#ifdef WINCE - // XXX do we free mSoftKeyMenuBar. MSDN isn't sure. -#endif } @@ -1570,13 +1437,6 @@ nsWindow::StandardWindowCreate(nsIWidget *aParent, } } } -#ifdef WINCE - if (mWindowType == eWindowType_dialog || mWindowType == eWindowType_toplevel ) - mSoftKeyMenuBar = CreateSoftKeyMenuBar(mWnd); - - MapHardwareButtons(mWnd); -#endif - return NS_OK; } @@ -2228,11 +2088,6 @@ NS_METHOD nsWindow::SetFocus(PRBool aRaise) if (::IsIconic(toplevelWnd)) ::OpenIcon(toplevelWnd); ::SetFocus(mWnd); - -#ifdef WINCE - MapHardwareButtons(mWnd); -#endif - } return NS_OK; } diff --git a/widget/src/windows/nsWindow.h b/widget/src/windows/nsWindow.h index 3f04e5754ab1..4514060b48e4 100644 --- a/widget/src/windows/nsWindow.h +++ b/widget/src/windows/nsWindow.h @@ -453,10 +453,6 @@ protected: // Drag & Drop nsNativeDragTarget * mNativeDragTarget; -#ifdef WINCE - HWND mSoftKeyMenuBar; -#endif - // Enumeration of the methods which are accessible on the "main GUI thread" // via the CallMethod(...) mechanism... // see nsSwitchToUIThread