You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

13-fltk-1.3.2-im.patch 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. diff -up fltk-1.3.2/FL/Fl.H.im fltk-1.3.2/FL/Fl.H
  2. --- fltk-1.3.2/FL/Fl.H.im 2014-09-10 14:40:05.193265424 +0200
  3. +++ fltk-1.3.2/FL/Fl.H 2014-09-10 14:40:05.196265471 +0200
  4. @@ -699,6 +699,17 @@ public:
  5. static int event_inside(const Fl_Widget*);
  6. static int test_shortcut(Fl_Shortcut);
  7. + /**
  8. + Enables the system input methods facilities. This is the default.
  9. + \see disable_im()
  10. + */
  11. + static void enable_im();
  12. + /**
  13. + Disables the system input methods facilities.
  14. + \see enable_im()
  15. + */
  16. + static void disable_im();
  17. +
  18. // event destinations:
  19. static int handle(int, Fl_Window*);
  20. static int handle_(int, Fl_Window*);
  21. diff -up fltk-1.3.2/FL/win32.H.im fltk-1.3.2/FL/win32.H
  22. --- fltk-1.3.2/FL/win32.H.im 2014-09-10 14:40:05.186265315 +0200
  23. +++ fltk-1.3.2/FL/win32.H 2014-09-10 14:40:05.196265471 +0200
  24. @@ -102,6 +102,8 @@ extern FL_EXPORT void fl_save_dc( HWND w
  25. inline Window fl_xid(const Fl_Window* w) { Fl_X *temp = Fl_X::i(w); return temp ? temp->xid : 0; }
  26. +extern FL_EXPORT void fl_open_display();
  27. +
  28. #else
  29. FL_EXPORT Window fl_xid_(const Fl_Window* w);
  30. #define fl_xid(w) fl_xid_(w)
  31. diff -up fltk-1.3.2/src/Fl_cocoa.mm.im fltk-1.3.2/src/Fl_cocoa.mm
  32. --- fltk-1.3.2/src/Fl_cocoa.mm.im 2014-09-10 14:40:05.193265424 +0200
  33. +++ fltk-1.3.2/src/Fl_cocoa.mm 2014-09-10 14:43:41.103642243 +0200
  34. @@ -88,6 +88,7 @@ static void createAppleMenu(void);
  35. static Fl_Region MacRegionMinusRect(Fl_Region r, int x,int y,int w,int h);
  36. static void cocoaMouseHandler(NSEvent *theEvent);
  37. static int calc_mac_os_version();
  38. +static void im_update(void);
  39. static Fl_Quartz_Graphics_Driver fl_quartz_driver;
  40. static Fl_Display_Device fl_quartz_display(&fl_quartz_driver);
  41. @@ -108,6 +109,30 @@ int fl_mac_os_version = calc_mac_os_vers
  42. static int got_events = 0;
  43. static Fl_Window* resize_from_system;
  44. static int main_screen_height; // height of menubar-containing screen used to convert between Cocoa and FLTK global screen coordinates
  45. +static int im_enabled = -1;
  46. +
  47. +// Carbon functions and definitions
  48. +
  49. +typedef void *TSMDocumentID;
  50. +
  51. +extern "C" enum {
  52. + kTSMDocumentEnabledInputSourcesPropertyTag = 'enis' // from Carbon/TextServices.h
  53. +};
  54. +
  55. +// Undocumented voodoo. Taken from Mozilla.
  56. +static const int smEnableRomanKybdsOnly = -23;
  57. +
  58. +typedef TSMDocumentID (*TSMGetActiveDocument_type)(void);
  59. +static TSMGetActiveDocument_type TSMGetActiveDocument;
  60. +typedef OSStatus (*TSMSetDocumentProperty_type)(TSMDocumentID, OSType, UInt32, void*);
  61. +static TSMSetDocumentProperty_type TSMSetDocumentProperty;
  62. +typedef OSStatus (*TSMRemoveDocumentProperty_type)(TSMDocumentID, OSType);
  63. +static TSMRemoveDocumentProperty_type TSMRemoveDocumentProperty;
  64. +typedef CFArrayRef (*TISCreateASCIICapableInputSourceList_type)(void);
  65. +static TISCreateASCIICapableInputSourceList_type TISCreateASCIICapableInputSourceList;
  66. +
  67. +typedef void (*KeyScript_type)(short);
  68. +static KeyScript_type KeyScript;
  69. #if CONSOLIDATE_MOTION
  70. static Fl_Window* send_motion;
  71. @@ -978,6 +1003,7 @@ void fl_open_callback(void (*cb)(const c
  72. #endif
  73. {
  74. BOOL seen_open_file;
  75. + TSMDocumentID currentDoc;
  76. }
  77. - (void)windowDidMove:(NSNotification *)notif;
  78. - (void)windowDidResize:(NSNotification *)notif;
  79. @@ -991,6 +1017,7 @@ void fl_open_callback(void (*cb)(const c
  80. - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender;
  81. - (void)applicationDidBecomeActive:(NSNotification *)notify;
  82. - (void)applicationDidChangeScreenParameters:(NSNotification *)aNotification;
  83. +- (void)applicationDidUpdate:(NSNotification *)aNotification;
  84. - (void)applicationWillResignActive:(NSNotification *)notify;
  85. - (void)applicationWillHide:(NSNotification *)notify;
  86. - (void)applicationWillUnhide:(NSNotification *)notify;
  87. @@ -1175,6 +1202,23 @@ void fl_open_callback(void (*cb)(const c
  88. }
  89. Fl::handle(FL_SCREEN_CONFIGURATION_CHANGED, NULL);
  90. }
  91. +- (void)applicationDidUpdate:(NSNotification *)aNotification
  92. +{
  93. + if ((fl_mac_os_version >= 100500) && (im_enabled != -1) &&
  94. + (TSMGetActiveDocument != NULL)) {
  95. + TSMDocumentID newDoc;
  96. + // It is extremely unclear when Cocoa decides to create/update
  97. + // the input context, but debugging reveals that it is done
  98. + // by NSApplication:updateWindows. So check if the input context
  99. + // has shifted after each such run so that we can update our
  100. + // input methods status.
  101. + newDoc = TSMGetActiveDocument();
  102. + if (newDoc != currentDoc) {
  103. + im_update();
  104. + currentDoc = newDoc;
  105. + }
  106. + }
  107. +}
  108. - (void)applicationWillResignActive:(NSNotification *)notify
  109. {
  110. fl_lock_function();
  111. @@ -1322,6 +1365,13 @@ void fl_open_display() {
  112. static char beenHereDoneThat = 0;
  113. if ( !beenHereDoneThat ) {
  114. beenHereDoneThat = 1;
  115. +
  116. + TSMGetActiveDocument = (TSMGetActiveDocument_type)Fl_X::get_carbon_function("TSMGetActiveDocument");
  117. + TSMSetDocumentProperty = (TSMSetDocumentProperty_type)Fl_X::get_carbon_function("TSMSetDocumentProperty");
  118. + TSMRemoveDocumentProperty = (TSMRemoveDocumentProperty_type)Fl_X::get_carbon_function("TSMRemoveDocumentProperty");
  119. + TISCreateASCIICapableInputSourceList = (TISCreateASCIICapableInputSourceList_type)Fl_X::get_carbon_function("TISCreateASCIICapableInputSourceList");
  120. +
  121. + KeyScript = (KeyScript_type)Fl_X::get_carbon_function("KeyScript");
  122. BOOL need_new_nsapp = (NSApp == nil);
  123. if (need_new_nsapp) [NSApplication sharedApplication];
  124. @@ -1390,6 +1440,66 @@ void fl_open_display() {
  125. void fl_close_display() {
  126. }
  127. +// Force a "Roman" or "ASCII" keyboard, which both the Mozilla and
  128. +// Safari people seem to think implies turning off advanced IME stuff
  129. +// (see nsTSMManager::SyncKeyScript in Mozilla and enableSecureTextInput
  130. +// in Safari/Webcore). Should be good enough for us then...
  131. +
  132. +static void im_update(void) {
  133. + if (fl_mac_os_version >= 100500) {
  134. + TSMDocumentID doc;
  135. +
  136. + if ((TSMGetActiveDocument == NULL) ||
  137. + (TSMSetDocumentProperty == NULL) ||
  138. + (TSMRemoveDocumentProperty == NULL) ||
  139. + (TISCreateASCIICapableInputSourceList == NULL))
  140. + return;
  141. +
  142. + doc = TSMGetActiveDocument();
  143. +
  144. + if (im_enabled)
  145. + TSMRemoveDocumentProperty(doc, kTSMDocumentEnabledInputSourcesPropertyTag);
  146. + else {
  147. + CFArrayRef inputSources;
  148. +
  149. + inputSources = TISCreateASCIICapableInputSourceList();
  150. + TSMSetDocumentProperty(doc, kTSMDocumentEnabledInputSourcesPropertyTag,
  151. + sizeof(CFArrayRef), &inputSources);
  152. + CFRelease(inputSources);
  153. + }
  154. + } else {
  155. + if (KeyScript == NULL)
  156. + return;
  157. +
  158. + if (im_enabled)
  159. + KeyScript(smKeyEnableKybds);
  160. + else
  161. + KeyScript(smEnableRomanKybdsOnly);
  162. + }
  163. +}
  164. +
  165. +void Fl::enable_im() {
  166. + fl_open_display();
  167. +
  168. + im_enabled = 1;
  169. +
  170. + if (fl_mac_os_version >= 100500)
  171. + [NSApp updateWindows];
  172. + else
  173. + im_update();
  174. +}
  175. +
  176. +void Fl::disable_im() {
  177. + fl_open_display();
  178. +
  179. + im_enabled = 0;
  180. +
  181. + if (fl_mac_os_version >= 100500)
  182. + [NSApp updateWindows];
  183. + else
  184. + im_update();
  185. +}
  186. +
  187. // Gets the border sizes and the titlebar size
  188. static void get_window_frame_sizes(int &bx, int &by, int &bt) {
  189. diff -up fltk-1.3.2/src/Fl.cxx.im fltk-1.3.2/src/Fl.cxx
  190. --- fltk-1.3.2/src/Fl.cxx.im 2014-09-10 14:40:05.194265440 +0200
  191. +++ fltk-1.3.2/src/Fl.cxx 2014-09-10 14:40:05.197265486 +0200
  192. @@ -593,45 +593,6 @@ int Fl::run() {
  193. return 0;
  194. }
  195. -#ifdef WIN32
  196. -
  197. -// Function to initialize COM/OLE for usage. This must be done only once.
  198. -// We define a flag to register whether we called it:
  199. -static char oleInitialized = 0;
  200. -
  201. -// This calls the Windows function OleInitialize() exactly once.
  202. -void fl_OleInitialize() {
  203. - if (!oleInitialized) {
  204. - OleInitialize(0L);
  205. - oleInitialized = 1;
  206. - }
  207. -}
  208. -
  209. -// This calls the Windows function OleUninitialize() only, if
  210. -// OleInitialize has been called before.
  211. -void fl_OleUninitialize() {
  212. - if (oleInitialized) {
  213. - OleUninitialize();
  214. - oleInitialized = 0;
  215. - }
  216. -}
  217. -
  218. -class Fl_Win32_At_Exit {
  219. -public:
  220. - Fl_Win32_At_Exit() { }
  221. - ~Fl_Win32_At_Exit() {
  222. - fl_free_fonts(); // do some WIN32 cleanup
  223. - fl_cleanup_pens();
  224. - fl_OleUninitialize();
  225. - fl_brush_action(1);
  226. - fl_cleanup_dc_list();
  227. - }
  228. -};
  229. -static Fl_Win32_At_Exit win32_at_exit;
  230. -#endif
  231. -
  232. -
  233. -
  234. /**
  235. Waits until "something happens" and then returns. Call this
  236. repeatedly to "run" your program. You can also check what happened
  237. 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
  238. --- fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx.im 2012-06-26 09:03:46.000000000 +0200
  239. +++ fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx 2014-09-10 14:40:05.197265486 +0200
  240. @@ -34,6 +34,7 @@ LPCWSTR utf8towchar(const char *in); //M
  241. char *wchartoutf8(LPCWSTR in); //MG
  242. #include <FL/Fl_Native_File_Chooser.H>
  243. +#include <FL/x.H>
  244. #define LCURLY_CHR '{'
  245. #define RCURLY_CHR '}'
  246. @@ -41,8 +42,6 @@ char *wchartoutf8(LPCWSTR in); //MG
  247. #define RBRACKET_CHR ']'
  248. #define MAXFILTERS 80
  249. -void fl_OleInitialize(); // in Fl.cxx (Windows only)
  250. -
  251. // STATIC: PRINT WINDOWS 'DOUBLE NULL' STRING (DEBUG)
  252. #ifdef DEBUG
  253. static void dnullprint(char *wp) {
  254. @@ -471,7 +470,7 @@ int CALLBACK Fl_Native_File_Chooser::Dir
  255. // SHOW DIRECTORY BROWSER
  256. int Fl_Native_File_Chooser::showdir() {
  257. // initialize OLE only once
  258. - fl_OleInitialize(); // init needed by BIF_USENEWUI
  259. + fl_open_display(); // init needed by BIF_USENEWUI
  260. ClearBINF();
  261. clear_pathnames();
  262. // PARENT WINDOW
  263. diff -up fltk-1.3.2/src/Fl_win32.cxx.im fltk-1.3.2/src/Fl_win32.cxx
  264. --- fltk-1.3.2/src/Fl_win32.cxx.im 2014-09-10 14:40:05.194265440 +0200
  265. +++ fltk-1.3.2/src/Fl_win32.cxx 2014-09-10 14:40:05.197265486 +0200
  266. @@ -60,8 +60,6 @@
  267. #include <ole2.h>
  268. #include <shellapi.h>
  269. -#include "aimm.h"
  270. -
  271. //
  272. // USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()...
  273. // USE_ASYNC_SELECT is OBSOLETED in 1.3 for the following reasons:
  274. @@ -121,27 +119,24 @@ static HMODULE get_wsock_mod() {
  275. * size and link dependencies.
  276. */
  277. static HMODULE s_imm_module = 0;
  278. +typedef BOOL (WINAPI* flTypeImmAssociateContextEx)(HWND, HIMC, DWORD);
  279. +static flTypeImmAssociateContextEx flImmAssociateContextEx = 0;
  280. typedef HIMC (WINAPI* flTypeImmGetContext)(HWND);
  281. static flTypeImmGetContext flImmGetContext = 0;
  282. typedef BOOL (WINAPI* flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM);
  283. static flTypeImmSetCompositionWindow flImmSetCompositionWindow = 0;
  284. typedef BOOL (WINAPI* flTypeImmReleaseContext)(HWND, HIMC);
  285. static flTypeImmReleaseContext flImmReleaseContext = 0;
  286. -typedef BOOL (WINAPI* flTypeImmIsIME)(HKL);
  287. -static flTypeImmIsIME flImmIsIME = 0;
  288. -static HMODULE get_imm_module() {
  289. - if (!s_imm_module) {
  290. - s_imm_module = LoadLibrary("IMM32.DLL");
  291. - if (!s_imm_module)
  292. - Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n"
  293. - "Please check your input method manager library accessibility.");
  294. - flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext");
  295. - flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow");
  296. - flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext");
  297. - flImmIsIME = (flTypeImmIsIME)GetProcAddress(s_imm_module, "ImmIsIME");
  298. - }
  299. - return s_imm_module;
  300. +static void get_imm_module() {
  301. + s_imm_module = LoadLibrary("IMM32.DLL");
  302. + if (!s_imm_module)
  303. + Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n"
  304. + "Please check your input method manager library accessibility.");
  305. + flImmAssociateContextEx = (flTypeImmAssociateContextEx)GetProcAddress(s_imm_module, "ImmAssociateContextEx");
  306. + flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext");
  307. + flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow");
  308. + flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext");
  309. }
  310. // USE_TRACK_MOUSE - define NO_TRACK_MOUSE if you don't have
  311. @@ -259,7 +254,9 @@ void fl_set_spot(int font, int size, int
  312. Fl_Window* tw = win;
  313. while (tw->parent()) tw = tw->window(); // find top level window
  314. - get_imm_module();
  315. + if (!tw->shown())
  316. + return;
  317. +
  318. HIMC himc = flImmGetContext(fl_xid(tw));
  319. if (himc) {
  320. @@ -338,7 +335,6 @@ void* Fl::thread_message() {
  321. extern int fl_send_system_handlers(void *e);
  322. -IActiveIMMApp *fl_aimm = NULL;
  323. MSG fl_msg;
  324. // This is never called with time_to_wait < 0.0.
  325. @@ -441,6 +437,58 @@ int fl_ready() {
  326. return get_wsock_mod() ? s_wsock_select(0,&fdt[0],&fdt[1],&fdt[2],&t) : 0;
  327. }
  328. +void fl_open_display() {
  329. + static char beenHereDoneThat = 0;
  330. +
  331. + if (beenHereDoneThat)
  332. + return;
  333. +
  334. + beenHereDoneThat = 1;
  335. +
  336. + OleInitialize(0L);
  337. +
  338. + get_imm_module();
  339. +}
  340. +
  341. +class Fl_Win32_At_Exit {
  342. +public:
  343. + Fl_Win32_At_Exit() { }
  344. + ~Fl_Win32_At_Exit() {
  345. + fl_free_fonts(); // do some WIN32 cleanup
  346. + fl_cleanup_pens();
  347. + OleUninitialize();
  348. + fl_brush_action(1);
  349. + fl_cleanup_dc_list();
  350. + }
  351. +};
  352. +static Fl_Win32_At_Exit win32_at_exit;
  353. +
  354. +static char im_enabled = 1;
  355. +
  356. +void Fl::enable_im() {
  357. + fl_open_display();
  358. +
  359. + Fl_X* i = Fl_X::first;
  360. + while (i) {
  361. + flImmAssociateContextEx(i->xid, 0, IACE_DEFAULT);
  362. + i = i->next;
  363. + }
  364. +
  365. + im_enabled = 1;
  366. +}
  367. +
  368. +void Fl::disable_im() {
  369. + fl_open_display();
  370. +
  371. + Fl_X* i = Fl_X::first;
  372. + while (i) {
  373. + flImmAssociateContextEx(i->xid, 0, 0);
  374. + i = i->next;
  375. + }
  376. +
  377. + im_enabled = 0;
  378. +}
  379. +
  380. ////////////////////////////////////////////////////////////////
  381. int Fl::x()
  382. @@ -683,7 +731,6 @@ void fl_clipboard_notify_untarget(HWND w
  383. }
  384. ////////////////////////////////////////////////////////////////
  385. -char fl_is_ime = 0;
  386. void fl_get_codepage()
  387. {
  388. HKL hkl = GetKeyboardLayout(0);
  389. @@ -691,14 +738,8 @@ void fl_get_codepage()
  390. GetLocaleInfo (LOWORD(hkl), LOCALE_IDEFAULTANSICODEPAGE, ld, 6);
  391. DWORD ccp = atol(ld);
  392. - fl_is_ime = 0;
  393. fl_codepage = ccp;
  394. - if (fl_aimm) {
  395. - fl_aimm->GetCodePageA(GetKeyboardLayout(0), &fl_codepage);
  396. - } else if (get_imm_module() && flImmIsIME(hkl)) {
  397. - fl_is_ime = 1;
  398. - }
  399. }
  400. HWND fl_capture;
  401. @@ -1564,6 +1605,8 @@ int fl_disable_transient_for; // secret
  402. Fl_X* Fl_X::make(Fl_Window* w) {
  403. Fl_Group::current(0); // get rid of very common user bug: forgot end()
  404. + fl_open_display();
  405. +
  406. // if the window is a subwindow and our parent is not mapped yet, we
  407. // mark this window visible, so that mapping the parent at a later
  408. // point in time will call this function again to finally map the subwindow.
  409. @@ -1767,16 +1810,10 @@ Fl_X* Fl_X::make(Fl_Window* w) {
  410. (Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
  411. // Register all windows for potential drag'n'drop operations
  412. - fl_OleInitialize();
  413. RegisterDragDrop(x->xid, flIDropTarget);
  414. - if (!fl_aimm) {
  415. - CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_INPROC_SERVER,
  416. - IID_IActiveIMMApp, (void**) &fl_aimm);
  417. - if (fl_aimm) {
  418. - fl_aimm->Activate(TRUE);
  419. - }
  420. - }
  421. + if (!im_enabled)
  422. + flImmAssociateContextEx(x->xid, 0, 0);
  423. return x;
  424. }
  425. diff -up fltk-1.3.2/src/Fl_x.cxx.im fltk-1.3.2/src/Fl_x.cxx
  426. --- fltk-1.3.2/src/Fl_x.cxx.im 2014-09-10 14:40:05.194265440 +0200
  427. +++ fltk-1.3.2/src/Fl_x.cxx 2014-09-10 14:40:05.198265502 +0200
  428. @@ -313,6 +313,7 @@ XVisualInfo *fl_visual;
  429. Colormap fl_colormap;
  430. XIM fl_xim_im = 0;
  431. XIC fl_xim_ic = 0;
  432. +Window fl_xim_win = 0;
  433. char fl_is_over_the_spot = 0;
  434. static XRectangle status_area;
  435. @@ -603,6 +604,55 @@ void fl_init_xim() {
  436. if(xim_styles) XFree(xim_styles);
  437. }
  438. +void fl_xim_deactivate(void);
  439. +
  440. +void fl_xim_activate(Window xid) {
  441. + if (!fl_xim_im)
  442. + return;
  443. +
  444. + // If the focused window has changed, then use the brute force method
  445. + // of completely recreating the input context.
  446. + if (fl_xim_win != xid) {
  447. + fl_xim_deactivate();
  448. +
  449. + fl_new_ic();
  450. + fl_xim_win = xid;
  451. +
  452. + XSetICValues(fl_xim_ic,
  453. + XNFocusWindow, fl_xim_win,
  454. + XNClientWindow, fl_xim_win,
  455. + NULL);
  456. + }
  457. +
  458. + fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
  459. +}
  460. +
  461. +void fl_xim_deactivate(void) {
  462. + if (!fl_xim_ic)
  463. + return;
  464. +
  465. + XDestroyIC(fl_xim_ic);
  466. + fl_xim_ic = NULL;
  467. +
  468. + fl_xim_win = 0;
  469. +}
  470. +
  471. +void Fl::enable_im() {
  472. + Fl_Window *win;
  473. +
  474. + win = Fl::first_window();
  475. + if (win && win->shown()) {
  476. + fl_xim_activate(fl_xid(win));
  477. + XSetICFocus(fl_xim_ic);
  478. + } else {
  479. + fl_new_ic();
  480. + }
  481. +}
  482. +
  483. +void Fl::disable_im() {
  484. + fl_xim_deactivate();
  485. +}
  486. +
  487. void fl_open_display() {
  488. if (fl_display) return;
  489. @@ -1053,10 +1103,9 @@ int fl_handle(const XEvent& thisevent)
  490. XEvent xevent = thisevent;
  491. fl_xevent = &thisevent;
  492. Window xid = xevent.xany.window;
  493. - static Window xim_win = 0;
  494. if (fl_xim_ic && xevent.type == DestroyNotify &&
  495. - xid != xim_win && !fl_find(xid))
  496. + xid != fl_xim_win && !fl_find(xid))
  497. {
  498. XIM xim_im;
  499. xim_im = XOpenIM(fl_display, NULL, NULL, NULL);
  500. @@ -1072,46 +1121,9 @@ int fl_handle(const XEvent& thisevent)
  501. }
  502. if (fl_xim_ic && (xevent.type == FocusIn))
  503. - {
  504. -#define POOR_XIM
  505. -#ifdef POOR_XIM
  506. - if (xim_win != xid)
  507. - {
  508. - xim_win = xid;
  509. - XDestroyIC(fl_xim_ic);
  510. - fl_xim_ic = NULL;
  511. - fl_new_ic();
  512. - XSetICValues(fl_xim_ic,
  513. - XNFocusWindow, xevent.xclient.window,
  514. - XNClientWindow, xid,
  515. - NULL);
  516. - }
  517. - fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
  518. -#else
  519. - if (Fl::first_window() && Fl::first_window()->modal()) {
  520. - Window x = fl_xid(Fl::first_window());
  521. - if (x != xim_win) {
  522. - xim_win = x;
  523. - XSetICValues(fl_xim_ic,
  524. - XNFocusWindow, xim_win,
  525. - XNClientWindow, xim_win,
  526. - NULL);
  527. - fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
  528. - }
  529. - } else if (xim_win != xid && xid) {
  530. - xim_win = xid;
  531. - XSetICValues(fl_xim_ic,
  532. - XNFocusWindow, xevent.xclient.window,
  533. - XNClientWindow, xid,
  534. - //XNFocusWindow, xim_win,
  535. - //XNClientWindow, xim_win,
  536. - NULL);
  537. - fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
  538. - }
  539. -#endif
  540. - }
  541. + fl_xim_activate(xid);
  542. - if ( XFilterEvent((XEvent *)&xevent, 0) )
  543. + if (fl_xim_ic && XFilterEvent((XEvent *)&xevent, 0))
  544. return(1);
  545. #if USE_XRANDR