aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/fltk/13-fltk-1.3.2-im.patch466
-rw-r--r--vncviewer/Viewport.cxx2
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: