diff options
author | Pierre Ossman <ossman@cendio.se> | 2014-08-22 14:43:33 +0200 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2014-08-22 14:56:45 +0200 |
commit | 2f11bd9a6afe160886e42081c2542b8b5b7caefc (patch) | |
tree | b61d262ce55324334d9db1a8568cba2ad879f302 /contrib/fltk/02-str2599-fltk-1.3.x-keyboard-win32.patch | |
parent | 1d36ed801f089114c3256f0fd8546825747b56ef (diff) | |
download | tigervnc-2f11bd9a6afe160886e42081c2542b8b5b7caefc.tar.gz tigervnc-2f11bd9a6afe160886e42081c2542b8b5b7caefc.zip |
Ship FLTK patches instead of referring a URI
It makes things more self contained (although you still need to
download FLTK itself), avoids the confusion of STR:s in varying
states, and allows us to refer to patches that aren't available
on an STR.
Diffstat (limited to 'contrib/fltk/02-str2599-fltk-1.3.x-keyboard-win32.patch')
-rw-r--r-- | contrib/fltk/02-str2599-fltk-1.3.x-keyboard-win32.patch | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/contrib/fltk/02-str2599-fltk-1.3.x-keyboard-win32.patch b/contrib/fltk/02-str2599-fltk-1.3.x-keyboard-win32.patch new file mode 100644 index 00000000..c29d3b97 --- /dev/null +++ b/contrib/fltk/02-str2599-fltk-1.3.x-keyboard-win32.patch @@ -0,0 +1,256 @@ +diff -ur fltk-1.3.0r9293.org/src/Fl_win32.cxx fltk-1.3.0r9293/src/Fl_win32.cxx +--- fltk-1.3.0r9293.org/src/Fl_win32.cxx 2012-06-18 09:07:56.522314557 +0200 ++++ fltk-1.3.0r9293/src/Fl_win32.cxx 2012-06-18 09:08:07.392836285 +0200 +@@ -87,6 +87,8 @@ + static Fl_Display_Device fl_gdi_display(&fl_gdi_driver); + Fl_Display_Device *Fl_Display_Device::_display = &fl_gdi_display; // the platform display + ++bool use_simple_keyboard = false; ++ + // dynamic wsock dll handling api: + #if defined(__CYGWIN__) && !defined(SOCKET) + # define SOCKET int +@@ -120,6 +122,8 @@ + * size and link dependencies. + */ + static HMODULE s_imm_module = 0; ++typedef BOOL (WINAPI* flTypeImmAssociateContextEx)(HWND, HIMC, DWORD); ++static flTypeImmAssociateContextEx flImmAssociateContextEx = 0; + typedef HIMC (WINAPI* flTypeImmGetContext)(HWND); + static flTypeImmGetContext flImmGetContext = 0; + typedef BOOL (WINAPI* flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM); +@@ -135,6 +139,7 @@ + if (!s_imm_module) + Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n" + "Please check your input method manager library accessibility."); ++ flImmAssociateContextEx = (flTypeImmAssociateContextEx)GetProcAddress(s_imm_module, "ImmAssociateContextEx"); + flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext"); + flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow"); + flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext"); +@@ -413,7 +418,12 @@ + } + } + +- TranslateMessage(&fl_msg); ++ // Don't bother with key to character translation as we do ++ // it manually for simpley keyboard widgets. In fact, calling ++ // TranslateMessage() just makes it more difficult as it sets ++ // a bunch of internal state. ++ if (!use_simple_keyboard) ++ TranslateMessage(&fl_msg); + DispatchMessageW(&fl_msg); + have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE); + } +@@ -638,6 +648,49 @@ + } + } + ++void fl_update_focus(void) ++{ ++ Fl_Widget *focus; ++ Fl_Window *win; ++ ++ get_imm_module(); ++ ++ focus = Fl::grab(); ++ if (!focus) ++ focus = Fl::focus(); ++ if (!focus) ++ return; ++ ++ // Grabs are special in that events are sent to the first ++ // available window ++ if (focus == Fl::grab()) ++ win = Fl::first_window(); ++ else { ++ win = focus->as_window(); ++ if (!win) ++ win = focus->window(); ++ } ++ ++ if (!win) { ++ Fl::warning("Cannot find window for widget receiving focus"); ++ return; ++ } ++ ++ // No Win32 window created yet ++ if (!Fl_X::i(win) || !fl_xid(win)) ++ return; ++ ++ if (focus->simple_keyboard()) { ++ use_simple_keyboard = true; ++ if (flImmGetContext(fl_xid(win)) != 0) ++ flImmAssociateContextEx(fl_xid(win), 0, 0); ++ } else { ++ use_simple_keyboard = false; ++ if (flImmGetContext(fl_xid(win)) == 0) ++ flImmAssociateContextEx(fl_xid(win), 0, IACE_DEFAULT); ++ } ++} ++ + HWND fl_capture; + + static int mouse_event(Fl_Window *window, int what, int button, +@@ -785,6 +838,27 @@ + return extended ? extendedlut[vk] : vklut[vk]; + } + ++static xchar msdead2fltk(xchar in) ++{ ++ switch (in) { ++ case 0x0060: // GRAVE ACCENT ++ return 0x0300; // COMBINING GRAVE ACCENT ++ case 0x00b4: // ACUTE ACCENT ++ return 0x0301; // COMBINING ACUTE ACCENT ++ case 0x005e: // CIRCUMFLEX ACCENT ++ return 0x0302; // COMBINING CIRCUMFLEX ACCENT ++ case 0x007e: // TILDE ++ return 0x0303; // COMBINING TILDE ++ case 0x00a8: // DIAERESIS ++ return 0x0308; // COMBINING DIAERESIS ++ // FIXME: Windows dead key behaviour isn't documented and I don't have ++ // any more keyboards to test with... ++ } ++ ++ // hope that Windows gave us something proper to begin with ++ return in; ++} ++ + #if USE_COLORMAP + extern HPALETTE fl_select_palette(void); // in fl_color_win32.cxx + #endif +@@ -846,6 +920,8 @@ + //fl_msg.pt = ??? + //fl_msg.lPrivate = ??? + ++ MSG fl_orig_msg = fl_msg; ++ + Fl_Window *window = fl_find(hWnd); + + if (window) switch (uMsg) { +@@ -1025,23 +1101,82 @@ + if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK; + Fl::e_state = state; + static char buffer[1024]; +- if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) { + ++ if (use_simple_keyboard) { ++ BYTE keystate[256]; ++ WCHAR wbuf[8]; ++ int ret; ++ ++ // I'm not sure if we ever get WM_CHAR (& friends) without an initial ++ // WM_KEYDOWN (& friends), but if we do then we should not send such ++ // side band events to simple keyboard widgets. ++ if ((fl_orig_msg.message != WM_KEYDOWN) && ++ (fl_orig_msg.message != WM_SYSKEYDOWN) && ++ (fl_orig_msg.message != WM_KEYUP) && ++ (fl_orig_msg.message != WM_SYSKEYUP)) ++ break; ++ ++ GetKeyboardState(keystate); ++ ++ // Pressing Ctrl wreaks havoc with the symbol lookup, so turn that off. ++ // But AltGr shows up as Ctrl+Alt in Windows, so keep Ctrl if Alt is ++ // active. ++ if (!(keystate[VK_MENU] & 0x80)) ++ keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0; ++ ++ // We cannot inspect or modify Windows' internal state of the keyboard ++ // so we have to try to infer information from ToUnicode() and wedge ++ // things into a known state. ++ for (int i = 0;i < 2;i++) { ++ ret = ToUnicode(fl_orig_msg.wParam, 0, keystate, wbuf, ++ sizeof(wbuf)/sizeof(wbuf[0]), 0); ++ ++ // No symbol for this key (or unexpected length) ++ if ((ret == 0) || (ret < -1)) { ++ buffer[0] = 0; ++ Fl::e_length = 0; ++ break; ++ } ++ ++ // A dead key. Convert this to a Unicode combining character so ++ // that the application can tell the difference between dead and ++ // normal keys. ++ if (ret == -1) { ++ xchar u = (xchar) msdead2fltk(wbuf[0]); ++ Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1); ++ buffer[Fl::e_length] = 0; ++ break; ++ } ++ ++ // If we have two characters (or more) from ToUnicode(), that's ++ // an invalid sequence. One character chould mean a proper symbol, ++ // or it could mean a composed one. In both cases we need to call ++ // ToUnicode() again to get something sane. ++ if (i == 0) ++ continue; ++ ++ // We should now have something sane. Give whatever we have to the ++ // application. ++ Fl::e_length = fl_utf8fromwc(buffer, 1024, wbuf, ret); ++ buffer[Fl::e_length] = 0; ++ } ++ } else if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) { + xchar u = (xchar) wParam; + // Fl::e_length = fl_unicode2utf(&u, 1, buffer); + Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1); + buffer[Fl::e_length] = 0; ++ } else { ++ buffer[0] = 0; ++ Fl::e_length = 0; ++ } + +- +- } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) { +- if (state & FL_NUM_LOCK) { +- // Convert to regular keypress... +- buffer[0] = Fl::e_keysym-FL_KP; +- Fl::e_length = 1; +- } else { +- // Convert to special keypress... +- buffer[0] = 0; +- Fl::e_length = 0; ++ // The keypad area is a bit odd in that we need to change the keysym ++ // to properly indicate what the user meant, unlike other keys where ++ // we normally change the text and keep keysym stable. ++ if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) { ++ // The initial mapping tables give us a keysym that corresponds to ++ // numlock being on, so we only do something when it is off. ++ if (!(state & FL_NUM_LOCK)) { + switch (Fl::e_keysym) { + case FL_KP + '0' : + Fl::e_keysym = FL_Insert; +@@ -1073,30 +1208,10 @@ + case FL_KP + '.' : + Fl::e_keysym = FL_Delete; + break; +- case FL_KP + '/' : +- case FL_KP + '*' : +- case FL_KP + '-' : +- case FL_KP + '+' : +- buffer[0] = Fl::e_keysym-FL_KP; +- Fl::e_length = 1; +- break; + } + } +- } else if ((lParam & (1<<31))==0) { +-#ifdef FLTK_PREVIEW_DEAD_KEYS +- if ((lParam & (1<<24))==0) { // clear if dead key (always?) +- xchar u = (xchar) wParam; +- Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1); +- buffer[Fl::e_length] = 0; +- } else { // set if "extended key" (never printable?) +- buffer[0] = 0; +- Fl::e_length = 0; +- } +-#else +- buffer[0] = 0; +- Fl::e_length = 0; +-#endif + } ++ + Fl::e_text = buffer; + if (lParam & (1<<31)) { // key up events. + if (Fl::handle(FL_KEYUP, window)) return 0; |