Blame SOURCES/fltk-1_v4.3.x-keyboard-x11.patch

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