diff options
-rw-r--r-- | contrib/fltk/13-fltk-1.3.2-im.patch | 466 | ||||
-rw-r--r-- | vncviewer/Viewport.cxx | 2 |
2 files changed, 468 insertions, 0 deletions
diff --git a/contrib/fltk/13-fltk-1.3.2-im.patch b/contrib/fltk/13-fltk-1.3.2-im.patch new file mode 100644 index 00000000..fbdcd785 --- /dev/null +++ b/contrib/fltk/13-fltk-1.3.2-im.patch @@ -0,0 +1,466 @@ +diff -up fltk-1.3.2/FL/Fl.H.im fltk-1.3.2/FL/Fl.H +--- fltk-1.3.2/FL/Fl.H.im 2014-07-25 14:28:52.771417210 +0200 ++++ fltk-1.3.2/FL/Fl.H 2014-07-25 14:28:52.774417261 +0200 +@@ -699,6 +699,17 @@ public: + static int event_inside(const Fl_Widget*); + static int test_shortcut(Fl_Shortcut); + ++ /** ++ Enables the system input methods facilities. This is the default. ++ \see disable_im() ++ */ ++ static void enable_im(); ++ /** ++ Disables the system input methods facilities. ++ \see enable_im() ++ */ ++ static void disable_im(); ++ + // event destinations: + static int handle(int, Fl_Window*); + static int handle_(int, Fl_Window*); +diff -up fltk-1.3.2/FL/win32.H.im fltk-1.3.2/FL/win32.H +--- fltk-1.3.2/FL/win32.H.im 2014-07-25 14:28:52.765417109 +0200 ++++ fltk-1.3.2/FL/win32.H 2014-07-25 14:28:52.774417261 +0200 +@@ -102,6 +102,8 @@ extern FL_EXPORT void fl_save_dc( HWND w + + inline Window fl_xid(const Fl_Window* w) { Fl_X *temp = Fl_X::i(w); return temp ? temp->xid : 0; } + ++extern FL_EXPORT void fl_open_display(); ++ + #else + FL_EXPORT Window fl_xid_(const Fl_Window* w); + #define fl_xid(w) fl_xid_(w) +diff -up fltk-1.3.2/src/Fl_cocoa.mm.im fltk-1.3.2/src/Fl_cocoa.mm +--- fltk-1.3.2/src/Fl_cocoa.mm.im 2014-07-25 14:37:30.656153283 +0200 ++++ fltk-1.3.2/src/Fl_cocoa.mm 2014-07-25 14:38:03.540708006 +0200 +@@ -53,6 +53,7 @@ extern "C" { + #include <math.h> + + #import <Cocoa/Cocoa.h> ++#import <Carbon/Carbon.h> + + #ifndef NSINTEGER_DEFINED // appears with 10.5 in NSObjCRuntime.h + #if defined(__LP64__) && __LP64__ +@@ -1391,6 +1392,35 @@ void fl_close_display() { + } + + ++// Undocumented voodoo. Taken from Mozilla. ++#define ENABLE_ROMAN_KYBDS_ONLY -23 ++ ++void Fl::enable_im() { ++#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) ++ TSMRemoveDocumentProperty(TSMGetActiveDocument(), ++ kTSMDocumentEnabledInputSourcesPropertyTag); ++#else ++ KeyScript(smKeyEnableKybds); ++#endif ++} ++ ++void Fl::disable_im() { ++ // Force a "Roman" or "ASCII" keyboard, which both the Mozilla and ++ // Safari people seem to think implies turning off advanced IME stuff ++ // (see nsTSMManager::SyncKeyScript in Mozilla and enableSecureTextInput ++ // in Safari/Webcore). Should be good enough for us then... ++#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) ++ CFArrayRef inputSources = TISCreateASCIICapableInputSourceList(); ++ TSMSetDocumentProperty(TSMGetActiveDocument(), ++ kTSMDocumentEnabledInputSourcesPropertyTag, ++ sizeof(CFArrayRef), &inputSources); ++ CFRelease(inputSources); ++#else ++ KeyScript(ENABLE_ROMAN_KYBDS_ONLY); ++#endif ++} ++ ++ + // Gets the border sizes and the titlebar size + static void get_window_frame_sizes(int &bx, int &by, int &bt) { + static bool first = true; +diff -up fltk-1.3.2/src/Fl.cxx.im fltk-1.3.2/src/Fl.cxx +--- fltk-1.3.2/src/Fl.cxx.im 2014-07-25 14:28:52.772417227 +0200 ++++ fltk-1.3.2/src/Fl.cxx 2014-07-25 14:28:52.774417261 +0200 +@@ -593,45 +593,6 @@ int Fl::run() { + return 0; + } + +-#ifdef WIN32 +- +-// Function to initialize COM/OLE for usage. This must be done only once. +-// We define a flag to register whether we called it: +-static char oleInitialized = 0; +- +-// This calls the Windows function OleInitialize() exactly once. +-void fl_OleInitialize() { +- if (!oleInitialized) { +- OleInitialize(0L); +- oleInitialized = 1; +- } +-} +- +-// This calls the Windows function OleUninitialize() only, if +-// OleInitialize has been called before. +-void fl_OleUninitialize() { +- if (oleInitialized) { +- OleUninitialize(); +- oleInitialized = 0; +- } +-} +- +-class Fl_Win32_At_Exit { +-public: +- Fl_Win32_At_Exit() { } +- ~Fl_Win32_At_Exit() { +- fl_free_fonts(); // do some WIN32 cleanup +- fl_cleanup_pens(); +- fl_OleUninitialize(); +- fl_brush_action(1); +- fl_cleanup_dc_list(); +- } +-}; +-static Fl_Win32_At_Exit win32_at_exit; +-#endif +- +- +- + /** + Waits until "something happens" and then returns. Call this + repeatedly to "run" your program. You can also check what happened +diff -up fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx.im fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx +--- fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx.im 2012-06-26 09:03:46.000000000 +0200 ++++ fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx 2014-07-25 14:28:52.774417261 +0200 +@@ -34,6 +34,7 @@ LPCWSTR utf8towchar(const char *in); //M + char *wchartoutf8(LPCWSTR in); //MG + + #include <FL/Fl_Native_File_Chooser.H> ++#include <FL/x.H> + + #define LCURLY_CHR '{' + #define RCURLY_CHR '}' +@@ -41,8 +42,6 @@ char *wchartoutf8(LPCWSTR in); //MG + #define RBRACKET_CHR ']' + #define MAXFILTERS 80 + +-void fl_OleInitialize(); // in Fl.cxx (Windows only) +- + // STATIC: PRINT WINDOWS 'DOUBLE NULL' STRING (DEBUG) + #ifdef DEBUG + static void dnullprint(char *wp) { +@@ -471,7 +470,7 @@ int CALLBACK Fl_Native_File_Chooser::Dir + // SHOW DIRECTORY BROWSER + int Fl_Native_File_Chooser::showdir() { + // initialize OLE only once +- fl_OleInitialize(); // init needed by BIF_USENEWUI ++ fl_open_display(); // init needed by BIF_USENEWUI + ClearBINF(); + clear_pathnames(); + // PARENT WINDOW +diff -up fltk-1.3.2/src/Fl_win32.cxx.im fltk-1.3.2/src/Fl_win32.cxx +--- fltk-1.3.2/src/Fl_win32.cxx.im 2014-07-25 14:28:52.772417227 +0200 ++++ fltk-1.3.2/src/Fl_win32.cxx 2014-07-25 14:28:52.775417277 +0200 +@@ -60,8 +60,6 @@ + #include <ole2.h> + #include <shellapi.h> + +-#include "aimm.h" +- + // + // USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()... + // USE_ASYNC_SELECT is OBSOLETED in 1.3 for the following reasons: +@@ -121,27 +119,24 @@ static HMODULE get_wsock_mod() { + * 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); + static flTypeImmSetCompositionWindow flImmSetCompositionWindow = 0; + typedef BOOL (WINAPI* flTypeImmReleaseContext)(HWND, HIMC); + static flTypeImmReleaseContext flImmReleaseContext = 0; +-typedef BOOL (WINAPI* flTypeImmIsIME)(HKL); +-static flTypeImmIsIME flImmIsIME = 0; + +-static HMODULE get_imm_module() { +- if (!s_imm_module) { +- s_imm_module = LoadLibrary("IMM32.DLL"); +- if (!s_imm_module) +- Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n" +- "Please check your input method manager library accessibility."); +- flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext"); +- flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow"); +- flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext"); +- flImmIsIME = (flTypeImmIsIME)GetProcAddress(s_imm_module, "ImmIsIME"); +- } +- return s_imm_module; ++static void get_imm_module() { ++ s_imm_module = LoadLibrary("IMM32.DLL"); ++ 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"); + } + + // USE_TRACK_MOUSE - define NO_TRACK_MOUSE if you don't have +@@ -259,7 +254,9 @@ void fl_set_spot(int font, int size, int + Fl_Window* tw = win; + while (tw->parent()) tw = tw->window(); // find top level window + +- get_imm_module(); ++ if (!tw->shown()) ++ return; ++ + HIMC himc = flImmGetContext(fl_xid(tw)); + + if (himc) { +@@ -338,7 +335,6 @@ void* Fl::thread_message() { + + extern bool fl_send_xhandlers(void *e); + +-IActiveIMMApp *fl_aimm = NULL; + MSG fl_msg; + + // This is never called with time_to_wait < 0.0. +@@ -441,6 +437,58 @@ int fl_ready() { + return get_wsock_mod() ? s_wsock_select(0,&fdt[0],&fdt[1],&fdt[2],&t) : 0; + } + ++void fl_open_display() { ++ static char beenHereDoneThat = 0; ++ ++ if (beenHereDoneThat) ++ return; ++ ++ beenHereDoneThat = 1; ++ ++ OleInitialize(0L); ++ ++ get_imm_module(); ++} ++ ++class Fl_Win32_At_Exit { ++public: ++ Fl_Win32_At_Exit() { } ++ ~Fl_Win32_At_Exit() { ++ fl_free_fonts(); // do some WIN32 cleanup ++ fl_cleanup_pens(); ++ OleUninitialize(); ++ fl_brush_action(1); ++ fl_cleanup_dc_list(); ++ } ++}; ++static Fl_Win32_At_Exit win32_at_exit; ++ ++static char im_enabled = 1; ++ ++void Fl::enable_im() { ++ fl_open_display(); ++ ++ Fl_X* i = Fl_X::first; ++ while (i) { ++ flImmAssociateContextEx(i->xid, 0, IACE_DEFAULT); ++ i = i->next; ++ } ++ ++ im_enabled = 1; ++} ++ ++void Fl::disable_im() { ++ fl_open_display(); ++ ++ Fl_X* i = Fl_X::first; ++ while (i) { ++ flImmAssociateContextEx(i->xid, 0, 0); ++ i = i->next; ++ } ++ ++ im_enabled = 0; ++} ++ + //////////////////////////////////////////////////////////////// + + int Fl::x() +@@ -683,7 +731,6 @@ void fl_clipboard_notify_untarget(HWND w + } + + //////////////////////////////////////////////////////////////// +-char fl_is_ime = 0; + void fl_get_codepage() + { + HKL hkl = GetKeyboardLayout(0); +@@ -691,14 +738,8 @@ void fl_get_codepage() + + GetLocaleInfo (LOWORD(hkl), LOCALE_IDEFAULTANSICODEPAGE, ld, 6); + DWORD ccp = atol(ld); +- fl_is_ime = 0; + + fl_codepage = ccp; +- if (fl_aimm) { +- fl_aimm->GetCodePageA(GetKeyboardLayout(0), &fl_codepage); +- } else if (get_imm_module() && flImmIsIME(hkl)) { +- fl_is_ime = 1; +- } + } + + HWND fl_capture; +@@ -1564,6 +1605,8 @@ int fl_disable_transient_for; // secret + Fl_X* Fl_X::make(Fl_Window* w) { + Fl_Group::current(0); // get rid of very common user bug: forgot end() + ++ fl_open_display(); ++ + // if the window is a subwindow and our parent is not mapped yet, we + // mark this window visible, so that mapping the parent at a later + // point in time will call this function again to finally map the subwindow. +@@ -1767,16 +1810,10 @@ Fl_X* Fl_X::make(Fl_Window* w) { + (Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL); + + // Register all windows for potential drag'n'drop operations +- fl_OleInitialize(); + RegisterDragDrop(x->xid, flIDropTarget); + +- if (!fl_aimm) { +- CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_INPROC_SERVER, +- IID_IActiveIMMApp, (void**) &fl_aimm); +- if (fl_aimm) { +- fl_aimm->Activate(TRUE); +- } +- } ++ if (!im_enabled) ++ flImmAssociateContextEx(x->xid, 0, 0); + + return x; + } +diff -up fltk-1.3.2/src/Fl_x.cxx.im fltk-1.3.2/src/Fl_x.cxx +--- fltk-1.3.2/src/Fl_x.cxx.im 2014-07-25 14:28:52.773417244 +0200 ++++ fltk-1.3.2/src/Fl_x.cxx 2014-07-25 14:28:52.775417277 +0200 +@@ -313,6 +313,7 @@ XVisualInfo *fl_visual; + Colormap fl_colormap; + XIM fl_xim_im = 0; + XIC fl_xim_ic = 0; ++Window fl_xim_win = 0; + char fl_is_over_the_spot = 0; + static XRectangle status_area; + +@@ -603,6 +604,55 @@ void fl_init_xim() { + if(xim_styles) XFree(xim_styles); + } + ++void fl_xim_deactivate(void); ++ ++void fl_xim_activate(Window xid) { ++ if (!fl_xim_im) ++ return; ++ ++ // If the focused window has changed, then use the brute force method ++ // of completely recreating the input context. ++ if (fl_xim_win != xid) { ++ fl_xim_deactivate(); ++ ++ fl_new_ic(); ++ fl_xim_win = xid; ++ ++ XSetICValues(fl_xim_ic, ++ XNFocusWindow, fl_xim_win, ++ XNClientWindow, fl_xim_win, ++ NULL); ++ } ++ ++ fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height); ++} ++ ++void fl_xim_deactivate(void) { ++ if (!fl_xim_ic) ++ return; ++ ++ XDestroyIC(fl_xim_ic); ++ fl_xim_ic = NULL; ++ ++ fl_xim_win = 0; ++} ++ ++void Fl::enable_im() { ++ Fl_Window *win; ++ ++ win = Fl::first_window(); ++ if (win && win->shown()) { ++ fl_xim_activate(fl_xid(win)); ++ XSetICFocus(fl_xim_ic); ++ } else { ++ fl_new_ic(); ++ } ++} ++ ++void Fl::disable_im() { ++ fl_xim_deactivate(); ++} ++ + void fl_open_display() { + if (fl_display) return; + +@@ -1053,10 +1103,9 @@ int fl_handle(const XEvent& thisevent) + XEvent xevent = thisevent; + fl_xevent = &thisevent; + Window xid = xevent.xany.window; +- static Window xim_win = 0; + + if (fl_xim_ic && xevent.type == DestroyNotify && +- xid != xim_win && !fl_find(xid)) ++ xid != fl_xim_win && !fl_find(xid)) + { + XIM xim_im; + xim_im = XOpenIM(fl_display, NULL, NULL, NULL); +@@ -1072,46 +1121,9 @@ int fl_handle(const XEvent& thisevent) + } + + if (fl_xim_ic && (xevent.type == FocusIn)) +- { +-#define POOR_XIM +-#ifdef POOR_XIM +- if (xim_win != xid) +- { +- xim_win = xid; +- XDestroyIC(fl_xim_ic); +- fl_xim_ic = NULL; +- fl_new_ic(); +- XSetICValues(fl_xim_ic, +- XNFocusWindow, xevent.xclient.window, +- XNClientWindow, xid, +- NULL); +- } +- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height); +-#else +- if (Fl::first_window() && Fl::first_window()->modal()) { +- Window x = fl_xid(Fl::first_window()); +- if (x != xim_win) { +- xim_win = x; +- XSetICValues(fl_xim_ic, +- XNFocusWindow, xim_win, +- XNClientWindow, xim_win, +- NULL); +- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height); +- } +- } else if (xim_win != xid && xid) { +- xim_win = xid; +- XSetICValues(fl_xim_ic, +- XNFocusWindow, xevent.xclient.window, +- XNClientWindow, xid, +- //XNFocusWindow, xim_win, +- //XNClientWindow, xim_win, +- NULL); +- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height); +- } +-#endif +- } ++ fl_xim_activate(xid); + +- if ( XFilterEvent((XEvent *)&xevent, 0) ) ++ if (fl_xim_ic && XFilterEvent((XEvent *)&xevent, 0)) + return(1); + + #if USE_XRANDR diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx index 917a9817..81dc7ac0 100644 --- a/vncviewer/Viewport.cxx +++ b/vncviewer/Viewport.cxx @@ -410,6 +410,7 @@ int Viewport::handle(int event) return 1; case FL_FOCUS: + Fl::disable_im(); // Yes, we would like some focus please! return 1; @@ -418,6 +419,7 @@ int Viewport::handle(int event) // sense (e.g. Alt+Tab where we only see the Alt press) while (!downKeySym.empty()) handleKeyRelease(downKeySym.begin()->first); + Fl::enable_im(); return 1; case FL_KEYDOWN: |