summaryrefslogtreecommitdiffstats
path: root/tigervnc/build/patches/fltk-1_v4.3.x-keyboard-x11.patch
blob: cabc0f1cae90f6a970161b2909135f7f9574af21 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
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;
 }