summaryrefslogtreecommitdiffstats
path: root/contrib/fltk/02-str2599-fltk-1.3.x-keyboard-win32.patch
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2014-08-22 14:43:33 +0200
committerPierre Ossman <ossman@cendio.se>2014-08-22 14:56:45 +0200
commit2f11bd9a6afe160886e42081c2542b8b5b7caefc (patch)
treeb61d262ce55324334d9db1a8568cba2ad879f302 /contrib/fltk/02-str2599-fltk-1.3.x-keyboard-win32.patch
parent1d36ed801f089114c3256f0fd8546825747b56ef (diff)
downloadtigervnc-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.patch256
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;