| diff -ur fltk-1.3.0r9619.org/FL/Fl_Widget.H fltk-1.3.0r9619/FL/Fl_Widget.H |
| --- fltk-1.3.0r9619.org/FL/Fl_Widget.H 2012-04-23 22:12:06.000000000 +0200 |
| +++ fltk-1.3.0r9619/FL/Fl_Widget.H 2012-06-18 13:46:07.302320825 +0200 |
| @@ -171,6 +171,7 @@ |
| GROUP_RELATIVE = 1<<16, ///< position this widget relative to the parent group, not to the window |
| COPIED_TOOLTIP = 1<<17, ///< the widget tooltip is internally copied, its destruction is handled by the widget |
| FULLSCREEN = 1<<18, ///< a fullscreen window (Fl_Window) |
| + SIMPLE_KEYBOARD = 1<<19, ///< the widget wants simple, consistent keypresses and not advanced input (like character composition and CJK input) |
| // (space for more flags) |
| USERFLAG3 = 1<<29, ///< reserved for 3rd party extensions |
| USERFLAG2 = 1<<30, ///< reserved for 3rd party extensions |
| @@ -776,6 +777,35 @@ |
| */ |
| void clear_changed() {flags_ &= ~CHANGED;} |
| |
| + /** |
| + Returns if the widget sees a simplified keyboard model or not. |
| + |
| + Normally widgets get a full-featured keyboard model that is geared |
| + towards text input. This includes support for compose sequences and |
| + advanced input methods, commonly used for asian writing system. This |
| + system however has downsides in that extra graphic can be presented |
| + to the user and that a physical key press doesn't correspond directly |
| + to a FLTK event. |
| + |
| + Widgets that need a direct correspondence between actual key events |
| + and those seen by the widget can swith to the simplified keyboard |
| + model. |
| + |
| + \retval 0 if the widget uses the normal keyboard model |
| + \see set_changed(), clear_changed() |
| + */ |
| + unsigned int simple_keyboard() const {return flags_&SIMPLE_KEYBOARD;} |
| + |
| + /** Marks a widget to use the simple keyboard model. |
| + \see changed(), clear_changed() |
| + */ |
| + void set_simple_keyboard() {flags_ |= SIMPLE_KEYBOARD;} |
| + |
| + /** Marks a widget to use the normal keyboard model. |
| + \see changed(), set_changed() |
| + */ |
| + void set_normal_keyboard() {flags_ &= ~SIMPLE_KEYBOARD;} |
| + |
| /** Gives the widget the keyboard focus. |
| Tries to make this widget be the Fl::focus() widget, by first sending |
| it an FL_FOCUS event, and if it returns non-zero, setting |
| diff -ur fltk-1.3.0r9619.org/src/Fl.cxx fltk-1.3.0r9619/src/Fl.cxx |
| --- fltk-1.3.0r9619.org/src/Fl.cxx 2012-03-23 17:47:53.000000000 +0100 |
| +++ fltk-1.3.0r9619/src/Fl.cxx 2012-06-18 13:46:07.303320877 +0200 |
| @@ -70,6 +70,8 @@ |
| extern double fl_mac_flush_and_wait(double time_to_wait, char in_idle); |
| #endif // WIN32 |
| |
| +extern void fl_update_focus(void); |
| + |
| // |
| // Globals... |
| // |
| @@ -876,6 +878,8 @@ |
| fl_oldfocus = p; |
| } |
| e_number = old_event; |
| + // let the platform code do what it needs |
| + fl_update_focus(); |
| } |
| } |
| |
| diff -ur fltk-1.3.0r9619.org/src/Fl_grab.cxx fltk-1.3.0r9619/src/Fl_grab.cxx |
| --- fltk-1.3.0r9619.org/src/Fl_grab.cxx 2012-03-23 17:47:53.000000000 +0100 |
| +++ fltk-1.3.0r9619/src/Fl_grab.cxx 2012-06-18 13:46:07.303320877 +0200 |
| @@ -29,6 +29,7 @@ |
| // override_redirect, it does similar things on WIN32. |
| |
| extern void fl_fix_focus(); // in Fl.cxx |
| +void fl_update_focus(void); |
| |
| #ifdef WIN32 |
| // We have to keep track of whether we have captured the mouse, since |
| @@ -80,6 +81,7 @@ |
| #endif |
| } |
| grab_ = win; |
| + fl_update_focus(); |
| } else { |
| if (grab_) { |
| #ifdef WIN32 |
| @@ -98,6 +100,7 @@ |
| XFlush(fl_display); |
| #endif |
| grab_ = 0; |
| + fl_update_focus(); |
| fl_fix_focus(); |
| } |
| } |
| diff -ur fltk-1.3.0r9619.org/src/Fl_x.cxx fltk-1.3.0r9619/src/Fl_x.cxx |
| --- fltk-1.3.0r9619.org/src/Fl_x.cxx 2012-06-18 13:46:07.205316173 +0200 |
| +++ fltk-1.3.0r9619/src/Fl_x.cxx 2012-06-18 13:46:18.216844629 +0200 |
| @@ -298,6 +298,7 @@ |
| 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; |
| |
| @@ -583,6 +584,65 @@ |
| 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; |
| +} |
| + |
| +extern Fl_Window *fl_xfocus; |
| + |
| +void fl_update_focus(void) |
| +{ |
| + Fl_Widget *focus; |
| + |
| + focus = Fl::grab(); |
| + if (!focus) |
| + focus = Fl::focus(); |
| + if (!focus) |
| + return; |
| + |
| + if (focus->simple_keyboard()) { |
| + fl_xim_deactivate(); |
| + } else { |
| + // fl_xfocus should always be set if something has focus, but let's |
| + // play it safe |
| + if (!fl_xfocus || !fl_xid(fl_xfocus)) |
| + return; |
| + |
| + fl_xim_activate(fl_xid(fl_xfocus)); |
| + } |
| +} |
| + |
| void fl_open_display() { |
| if (fl_display) return; |
| |
| @@ -917,10 +977,9 @@ |
| 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); |
| @@ -935,48 +994,10 @@ |
| return 0; |
| } |
| |
| - 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 |
| + if (fl_xim_ic) { |
| + if (XFilterEvent((XEvent *)&xevent, 0)) |
| + return 1; |
| } |
| - |
| - if ( XFilterEvent((XEvent *)&xevent, 0) ) |
| - return(1); |
| |
| #if USE_XRANDR |
| if( XRRUpdateConfiguration_f && xevent.type == randrEventBase + RRScreenChangeNotify) { |
| @@ -1326,15 +1347,15 @@ |
| //static XComposeStatus compose; |
| len = XLookupString((XKeyEvent*)&(xevent.xkey), |
| buffer, buffer_len, &keysym, 0/*&compose*/); |
| - if (keysym && keysym < 0x400) { // a character in latin-1,2,3,4 sets |
| - // force it to type a character (not sure if this ever is needed): |
| - // if (!len) {buffer[0] = char(keysym); len = 1;} |
| - len = fl_utf8encode(XKeysymToUcs(keysym), buffer); |
| - if (len < 1) len = 1; |
| - // ignore all effects of shift on the keysyms, which makes it a lot |
| - // easier to program shortcuts and is Windoze-compatible: |
| - keysym = XKeycodeToKeysym(fl_display, keycode, 0); |
| - } |
| + // XLookupString() is only defined to return Latin-1 (although it |
| + // often gives you more). To be safe, use our own lookups based on |
| + // keysym. |
| + len = fl_utf8encode(XKeysymToUcs(keysym), buffer); |
| + if (len < 1) |
| + len = 1; |
| + // ignore all effects of shift on the keysyms, which makes it a lot |
| + // easier to program shortcuts and is Windoze-compatable: |
| + keysym = XKeycodeToKeysym(fl_display, keycode, 0); |
| } |
| // MRS: Can't use Fl::event_state(FL_CTRL) since the state is not |
| // set until set_event_xy() is called later... |
| diff -ur fltk-1.3.0r9619.org/src/xutf8/imKStoUCS.c fltk-1.3.0r9619/src/xutf8/imKStoUCS.c |
| --- fltk-1.3.0r9619.org/src/xutf8/imKStoUCS.c 2009-03-13 23:43:43.000000000 +0100 |
| +++ fltk-1.3.0r9619/src/xutf8/imKStoUCS.c 2012-06-18 13:46:07.304320930 +0200 |
| @@ -266,6 +266,12 @@ |
| 0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */ |
| }; |
| |
| +static unsigned short const keysym_to_unicode_fe50_fe60[] = { |
| + 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0306, 0x0307, 0x0308, /* 0xfe50-0xfe57 */ |
| + 0x030a, 0x030b, 0x030c, 0x0327, 0x0328, 0x1da5, 0x3099, 0x309a, /* 0xfe58-0xfe5f */ |
| + 0x0323 /* 0xfe60-0xfe67 */ |
| +}; |
| + |
| unsigned int |
| KeySymToUcs4(KeySym keysym) |
| { |
| @@ -315,6 +321,8 @@ |
| return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f]; |
| else if (keysym > 0x209f && keysym < 0x20ad) |
| return keysym_to_unicode_20a0_20ac[keysym - 0x20a0]; |
| + else if (keysym > 0xfe4f && keysym < 0xfe61) |
| + return keysym_to_unicode_fe50_fe60[keysym - 0xfe50]; |
| else |
| return 0; |
| } |