mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-12-03 21:49:02 +01:00
257 lines
8.4 KiB
Diff
257 lines
8.4 KiB
Diff
|
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;
|