DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.
[STR New]
Link: http://www.fltk.org/str.php?L2599
Version: 1.4-feature
Attached file "fltk-1_v2.3.x-keyboard-x11.patch"...
Link: http://www.fltk.org/str.php?L2599
Version: 1.4-feature
diff -up fltk-1.3.x-r8659/FL/Fl_Widget.H.kbd-x11 fltk-1.3.x-r8659/FL/Fl_Widget.H
--- fltk-1.3.x-r8659/FL/Fl_Widget.H.kbd-x11 2011-04-24 19:09:41.000000000
+0200
+++ fltk-1.3.x-r8659/FL/Fl_Widget.H 2011-05-13 13:51:26.307888360 +0200
@@ -179,6 +179,7 @@ protected:
NO_OVERLAY = 1<<15, ///< window not using a hardware overlay
plane (Fl_Menu_Window)
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
+ SIMPLE_KEYBOARD = 1<<18, ///< 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
@@ -784,6 +785,35 @@ public:
*/
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 -up fltk-1.3.x-r8659/src/Fl.cxx.kbd-x11 fltk-1.3.x-r8659/src/Fl.cxx
--- fltk-1.3.x-r8659/src/Fl.cxx.kbd-x11 2011-04-11 22:10:02.000000000 +0200
+++ fltk-1.3.x-r8659/src/Fl.cxx 2011-05-13 13:51:26.308888510 +0200
@@ -63,6 +63,8 @@ void fl_cleanup_dc_list(void);
extern double fl_mac_flush_and_wait(double time_to_wait, char in_idle);
#endif // WIN32
+extern void fl_update_focus(void);
+
//
// Globals...
//
@@ -864,6 +866,8 @@ void Fl::focus(Fl_Widget *o) {
fl_oldfocus = p;
}
e_number = old_event;
+ // let the platform code do what it needs
+ fl_update_focus();
}
}
diff -up fltk-1.3.x-r8659/src/Fl_grab.cxx.kbd-x11
fltk-1.3.x-r8659/src/Fl_grab.cxx
--- fltk-1.3.x-r8659/src/Fl_grab.cxx.kbd-x11 2010-12-18 23:31:01.000000000
+0100
+++ fltk-1.3.x-r8659/src/Fl_grab.cxx 2011-05-13 13:51:26.309888660 +0200
@@ -38,6 +38,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
@@ -79,6 +80,7 @@ void Fl::grab(Fl_Window* win) {
#endif
}
grab_ = win;
+ fl_update_focus();
} else {
if (grab_) {
#ifdef WIN32
@@ -94,6 +96,7 @@ void Fl::grab(Fl_Window* win) {
XFlush(fl_display);
#endif
grab_ = 0;
+ fl_update_focus();
fl_fix_focus();
}
}
diff -up fltk-1.3.x-r8659/src/Fl_x.cxx.kbd-x11 fltk-1.3.x-r8659/src/Fl_x.cxx
--- fltk-1.3.x-r8659/src/Fl_x.cxx.kbd-x11 2011-04-27 10:47:00.000000000
+0200
+++ fltk-1.3.x-r8659/src/Fl_x.cxx 2011-05-13 13:54:28.813284014 +0200
@@ -300,6 +300,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;
@@ -581,6 +582,79 @@ 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_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_Window *win;
+
+ // 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 X11 window created yet
+ if (!Fl_X::i(win) || !fl_xid(win))
+ return;
+
+ fl_xim_activate(fl_xid(win));
+ }
+}
+
void fl_open_display() {
if (fl_display) return;
@@ -864,10 +938,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);
@@ -882,48 +955,15 @@ int fl_handle(const XEvent& thisevent)
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
- }
+ // Activate XIM for this window early, so that XFilterEvent() can start
+ // doing its magic.
+ if (xevent.type == FocusIn)
+ fl_xim_activate(xid);
- if ( XFilterEvent((XEvent *)&xevent, 0) )
- return(1);
+ if (fl_xim_ic) {
+ if (XFilterEvent((XEvent *)&xevent, 0))
+ return 1;
+ }
switch (xevent.type) {
@@ -1248,15 +1288,15 @@ int fl_handle(const XEvent& thisevent)
//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 -up fltk-1.3.x-r8659/src/xutf8/imKStoUCS.c.kbd-x11
fltk-1.3.x-r8659/src/xutf8/imKStoUCS.c
--- fltk-1.3.x-r8659/src/xutf8/imKStoUCS.c.kbd-x11 2009-03-13
23:43:43.000000000 +0100
+++ fltk-1.3.x-r8659/src/xutf8/imKStoUCS.c 2011-05-13 13:51:26.311888960
+0200
@@ -266,6 +266,12 @@ static unsigned short const keysym_to_un
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 @@ KeySymToUcs4(KeySym keysym)
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;
}
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev