blob: cabc0f1cae90f6a970161b2909135f7f9574af21 [file] [log] [blame]
Pierre Ossman2f11bd92014-08-22 14:43:33 +02001diff -ur fltk-1.3.0r9619.org/FL/Fl_Widget.H fltk-1.3.0r9619/FL/Fl_Widget.H
2--- fltk-1.3.0r9619.org/FL/Fl_Widget.H 2012-04-23 22:12:06.000000000 +0200
3+++ fltk-1.3.0r9619/FL/Fl_Widget.H 2012-06-18 13:46:07.302320825 +0200
4@@ -171,6 +171,7 @@
5 GROUP_RELATIVE = 1<<16, ///< position this widget relative to the parent group, not to the window
6 COPIED_TOOLTIP = 1<<17, ///< the widget tooltip is internally copied, its destruction is handled by the widget
7 FULLSCREEN = 1<<18, ///< a fullscreen window (Fl_Window)
8+ SIMPLE_KEYBOARD = 1<<19, ///< the widget wants simple, consistent keypresses and not advanced input (like character composition and CJK input)
9 // (space for more flags)
10 USERFLAG3 = 1<<29, ///< reserved for 3rd party extensions
11 USERFLAG2 = 1<<30, ///< reserved for 3rd party extensions
12@@ -776,6 +777,35 @@
13 */
14 void clear_changed() {flags_ &= ~CHANGED;}
15
16+ /**
17+ Returns if the widget sees a simplified keyboard model or not.
18+
19+ Normally widgets get a full-featured keyboard model that is geared
20+ towards text input. This includes support for compose sequences and
21+ advanced input methods, commonly used for asian writing system. This
22+ system however has downsides in that extra graphic can be presented
23+ to the user and that a physical key press doesn't correspond directly
24+ to a FLTK event.
25+
26+ Widgets that need a direct correspondence between actual key events
27+ and those seen by the widget can swith to the simplified keyboard
28+ model.
29+
30+ \retval 0 if the widget uses the normal keyboard model
31+ \see set_changed(), clear_changed()
32+ */
33+ unsigned int simple_keyboard() const {return flags_&SIMPLE_KEYBOARD;}
34+
35+ /** Marks a widget to use the simple keyboard model.
36+ \see changed(), clear_changed()
37+ */
38+ void set_simple_keyboard() {flags_ |= SIMPLE_KEYBOARD;}
39+
40+ /** Marks a widget to use the normal keyboard model.
41+ \see changed(), set_changed()
42+ */
43+ void set_normal_keyboard() {flags_ &= ~SIMPLE_KEYBOARD;}
44+
45 /** Gives the widget the keyboard focus.
46 Tries to make this widget be the Fl::focus() widget, by first sending
47 it an FL_FOCUS event, and if it returns non-zero, setting
48diff -ur fltk-1.3.0r9619.org/src/Fl.cxx fltk-1.3.0r9619/src/Fl.cxx
49--- fltk-1.3.0r9619.org/src/Fl.cxx 2012-03-23 17:47:53.000000000 +0100
50+++ fltk-1.3.0r9619/src/Fl.cxx 2012-06-18 13:46:07.303320877 +0200
51@@ -70,6 +70,8 @@
52 extern double fl_mac_flush_and_wait(double time_to_wait, char in_idle);
53 #endif // WIN32
54
55+extern void fl_update_focus(void);
56+
57 //
58 // Globals...
59 //
60@@ -876,6 +878,8 @@
61 fl_oldfocus = p;
62 }
63 e_number = old_event;
64+ // let the platform code do what it needs
65+ fl_update_focus();
66 }
67 }
68
69diff -ur fltk-1.3.0r9619.org/src/Fl_grab.cxx fltk-1.3.0r9619/src/Fl_grab.cxx
70--- fltk-1.3.0r9619.org/src/Fl_grab.cxx 2012-03-23 17:47:53.000000000 +0100
71+++ fltk-1.3.0r9619/src/Fl_grab.cxx 2012-06-18 13:46:07.303320877 +0200
72@@ -29,6 +29,7 @@
73 // override_redirect, it does similar things on WIN32.
74
75 extern void fl_fix_focus(); // in Fl.cxx
76+void fl_update_focus(void);
77
78 #ifdef WIN32
79 // We have to keep track of whether we have captured the mouse, since
80@@ -80,6 +81,7 @@
81 #endif
82 }
83 grab_ = win;
84+ fl_update_focus();
85 } else {
86 if (grab_) {
87 #ifdef WIN32
88@@ -98,6 +100,7 @@
89 XFlush(fl_display);
90 #endif
91 grab_ = 0;
92+ fl_update_focus();
93 fl_fix_focus();
94 }
95 }
96diff -ur fltk-1.3.0r9619.org/src/Fl_x.cxx fltk-1.3.0r9619/src/Fl_x.cxx
97--- fltk-1.3.0r9619.org/src/Fl_x.cxx 2012-06-18 13:46:07.205316173 +0200
98+++ fltk-1.3.0r9619/src/Fl_x.cxx 2012-06-18 13:46:18.216844629 +0200
99@@ -298,6 +298,7 @@
100 Colormap fl_colormap;
101 XIM fl_xim_im = 0;
102 XIC fl_xim_ic = 0;
103+Window fl_xim_win = 0;
104 char fl_is_over_the_spot = 0;
105 static XRectangle status_area;
106
107@@ -583,6 +584,65 @@
108 if(xim_styles) XFree(xim_styles);
109 }
110
111+void fl_xim_deactivate(void);
112+
113+void fl_xim_activate(Window xid)
114+{
115+ if (!fl_xim_im)
116+ return;
117+
118+ // If the focused window has changed, then use the brute force method
119+ // of completely recreating the input context.
120+ if (fl_xim_win != xid) {
121+ fl_xim_deactivate();
122+
123+ fl_new_ic();
124+ fl_xim_win = xid;
125+
126+ XSetICValues(fl_xim_ic,
127+ XNFocusWindow, fl_xim_win,
128+ XNClientWindow, fl_xim_win,
129+ NULL);
130+ }
131+
132+ fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
133+}
134+
135+void fl_xim_deactivate(void)
136+{
137+ if (!fl_xim_ic)
138+ return;
139+
140+ XDestroyIC(fl_xim_ic);
141+ fl_xim_ic = NULL;
142+
143+ fl_xim_win = 0;
144+}
145+
146+extern Fl_Window *fl_xfocus;
147+
148+void fl_update_focus(void)
149+{
150+ Fl_Widget *focus;
151+
152+ focus = Fl::grab();
153+ if (!focus)
154+ focus = Fl::focus();
155+ if (!focus)
156+ return;
157+
158+ if (focus->simple_keyboard()) {
159+ fl_xim_deactivate();
160+ } else {
161+ // fl_xfocus should always be set if something has focus, but let's
162+ // play it safe
163+ if (!fl_xfocus || !fl_xid(fl_xfocus))
164+ return;
165+
166+ fl_xim_activate(fl_xid(fl_xfocus));
167+ }
168+}
169+
170 void fl_open_display() {
171 if (fl_display) return;
172
173@@ -917,10 +977,9 @@
174 XEvent xevent = thisevent;
175 fl_xevent = &thisevent;
176 Window xid = xevent.xany.window;
177- static Window xim_win = 0;
178
179 if (fl_xim_ic && xevent.type == DestroyNotify &&
180- xid != xim_win && !fl_find(xid))
181+ xid != fl_xim_win && !fl_find(xid))
182 {
183 XIM xim_im;
184 xim_im = XOpenIM(fl_display, NULL, NULL, NULL);
185@@ -935,48 +994,10 @@
186 return 0;
187 }
188
189- if (fl_xim_ic && (xevent.type == FocusIn))
190- {
191-#define POOR_XIM
192-#ifdef POOR_XIM
193- if (xim_win != xid)
194- {
195- xim_win = xid;
196- XDestroyIC(fl_xim_ic);
197- fl_xim_ic = NULL;
198- fl_new_ic();
199- XSetICValues(fl_xim_ic,
200- XNFocusWindow, xevent.xclient.window,
201- XNClientWindow, xid,
202- NULL);
203- }
204- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
205-#else
206- if (Fl::first_window() && Fl::first_window()->modal()) {
207- Window x = fl_xid(Fl::first_window());
208- if (x != xim_win) {
209- xim_win = x;
210- XSetICValues(fl_xim_ic,
211- XNFocusWindow, xim_win,
212- XNClientWindow, xim_win,
213- NULL);
214- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
215- }
216- } else if (xim_win != xid && xid) {
217- xim_win = xid;
218- XSetICValues(fl_xim_ic,
219- XNFocusWindow, xevent.xclient.window,
220- XNClientWindow, xid,
221- //XNFocusWindow, xim_win,
222- //XNClientWindow, xim_win,
223- NULL);
224- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
225- }
226-#endif
227+ if (fl_xim_ic) {
228+ if (XFilterEvent((XEvent *)&xevent, 0))
229+ return 1;
230 }
231-
232- if ( XFilterEvent((XEvent *)&xevent, 0) )
233- return(1);
234
235 #if USE_XRANDR
236 if( XRRUpdateConfiguration_f && xevent.type == randrEventBase + RRScreenChangeNotify) {
237@@ -1326,15 +1347,15 @@
238 //static XComposeStatus compose;
239 len = XLookupString((XKeyEvent*)&(xevent.xkey),
240 buffer, buffer_len, &keysym, 0/*&compose*/);
241- if (keysym && keysym < 0x400) { // a character in latin-1,2,3,4 sets
242- // force it to type a character (not sure if this ever is needed):
243- // if (!len) {buffer[0] = char(keysym); len = 1;}
244- len = fl_utf8encode(XKeysymToUcs(keysym), buffer);
245- if (len < 1) len = 1;
246- // ignore all effects of shift on the keysyms, which makes it a lot
247- // easier to program shortcuts and is Windoze-compatible:
248- keysym = XKeycodeToKeysym(fl_display, keycode, 0);
249- }
250+ // XLookupString() is only defined to return Latin-1 (although it
251+ // often gives you more). To be safe, use our own lookups based on
252+ // keysym.
253+ len = fl_utf8encode(XKeysymToUcs(keysym), buffer);
254+ if (len < 1)
255+ len = 1;
256+ // ignore all effects of shift on the keysyms, which makes it a lot
257+ // easier to program shortcuts and is Windoze-compatable:
258+ keysym = XKeycodeToKeysym(fl_display, keycode, 0);
259 }
260 // MRS: Can't use Fl::event_state(FL_CTRL) since the state is not
261 // set until set_event_xy() is called later...
262diff -ur fltk-1.3.0r9619.org/src/xutf8/imKStoUCS.c fltk-1.3.0r9619/src/xutf8/imKStoUCS.c
263--- fltk-1.3.0r9619.org/src/xutf8/imKStoUCS.c 2009-03-13 23:43:43.000000000 +0100
264+++ fltk-1.3.0r9619/src/xutf8/imKStoUCS.c 2012-06-18 13:46:07.304320930 +0200
265@@ -266,6 +266,12 @@
266 0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */
267 };
268
269+static unsigned short const keysym_to_unicode_fe50_fe60[] = {
270+ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0306, 0x0307, 0x0308, /* 0xfe50-0xfe57 */
271+ 0x030a, 0x030b, 0x030c, 0x0327, 0x0328, 0x1da5, 0x3099, 0x309a, /* 0xfe58-0xfe5f */
272+ 0x0323 /* 0xfe60-0xfe67 */
273+};
274+
275 unsigned int
276 KeySymToUcs4(KeySym keysym)
277 {
278@@ -315,6 +321,8 @@
279 return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f];
280 else if (keysym > 0x209f && keysym < 0x20ad)
281 return keysym_to_unicode_20a0_20ac[keysym - 0x20a0];
282+ else if (keysym > 0xfe4f && keysym < 0xfe61)
283+ return keysym_to_unicode_fe50_fe60[keysym - 0xfe50];
284 else
285 return 0;
286 }