Merge lp:~brandontschaefer/nux/xim-support-12-04-SRU into lp:nux/2.0
- xim-support-12-04-SRU
- Merge into 2.0
Proposed by
Brandon Schaefer
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Andrea Azzarone | ||||||||||||
Approved revision: | 626 | ||||||||||||
Merged at revision: | 621 | ||||||||||||
Proposed branch: | lp:~brandontschaefer/nux/xim-support-12-04-SRU | ||||||||||||
Merge into: | lp:nux/2.0 | ||||||||||||
Diff against target: |
733 lines (+494/-19) 11 files modified
Nux/TextEntry.cpp (+2/-0) NuxGraphics/Events.cpp (+5/-4) NuxGraphics/Events.h (+5/-1) NuxGraphics/GraphicsDisplayX11.cpp (+87/-9) NuxGraphics/GraphicsDisplayX11.h (+4/-1) NuxGraphics/Makefile.am (+7/-3) NuxGraphics/XICClient.cpp (+112/-0) NuxGraphics/XICClient.h (+60/-0) NuxGraphics/XIMController.cpp (+146/-0) NuxGraphics/XIMController.h (+62/-0) NuxGraphics/XInputWindow.cpp (+4/-1) |
||||||||||||
To merge this branch: | bzr merge lp:~brandontschaefer/nux/xim-support-12-04-SRU | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrea Azzarone (community) | Approve | ||
Review via email: mp+163577@code.launchpad.net |
Commit message
Allocates the correct size of the texts that come in from input methods. Also allows for XIM support to be done iff IBus is not active.
Description of the change
To post a comment you must log in.
Revision history for this message
Stephen M. Webb (bregma) wrote : | # |
- 626. By Brandon Schaefer
-
* Revert back to the old configure...
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Nux/TextEntry.cpp' |
2 | --- Nux/TextEntry.cpp 2012-04-25 13:59:25 +0000 |
3 | +++ Nux/TextEntry.cpp 2013-05-24 18:35:29 +0000 |
4 | @@ -842,6 +842,7 @@ |
5 | need_im_reset_ = true; |
6 | #if defined(NUX_OS_LINUX) |
7 | ime_->Focus(); |
8 | + nux::GetWindowThread()->GetGraphicsDisplay().XICFocus(); |
9 | #endif |
10 | //gtk_im_context_focus_in(im_context_); |
11 | //UpdateIMCursorLocation(); |
12 | @@ -864,6 +865,7 @@ |
13 | need_im_reset_ = true; |
14 | #if defined(NUX_OS_LINUX) |
15 | ime_->Blur(); |
16 | + nux::GetWindowThread()->GetGraphicsDisplay().XICUnFocus(); |
17 | #endif |
18 | //gtk_im_context_focus_out(im_context_); |
19 | } |
20 | |
21 | === modified file 'NuxGraphics/Events.cpp' |
22 | --- NuxGraphics/Events.cpp 2012-01-30 07:53:02 +0000 |
23 | +++ NuxGraphics/Events.cpp 2013-05-24 18:35:29 +0000 |
24 | @@ -22,7 +22,6 @@ |
25 | #include "GLResource.h" |
26 | #include "Events.h" |
27 | |
28 | - |
29 | namespace nux |
30 | { |
31 | MouseButton GetEventButton(unsigned long button_state) |
32 | @@ -60,7 +59,7 @@ |
33 | |
34 | Event::Event() |
35 | { |
36 | - Memset(text, 0, sizeof(text)); |
37 | + dtext = nullptr; |
38 | |
39 | for (int i = 0; i < NUX_MAX_VK; i++) |
40 | { |
41 | @@ -101,7 +100,6 @@ |
42 | void Event::Reset() |
43 | { |
44 | type = NUX_NO_EVENT; |
45 | - Memset(text, 0, sizeof(text)); |
46 | #if defined(NUX_OS_WINDOWS) |
47 | win32_keycode = 0; |
48 | win32_keysym = 0; |
49 | @@ -113,6 +111,9 @@ |
50 | x11_key_state = 0; |
51 | #endif |
52 | |
53 | + delete[] dtext; |
54 | + dtext = nullptr; |
55 | + |
56 | key_repeat_count = 0; |
57 | key_modifiers = 0; |
58 | wheel_delta = 0; |
59 | @@ -210,7 +211,7 @@ |
60 | |
61 | const char* Event::GetText() const |
62 | { |
63 | - return text; |
64 | + return dtext; |
65 | } |
66 | |
67 | |
68 | |
69 | === modified file 'NuxGraphics/Events.h' |
70 | --- NuxGraphics/Events.h 2012-02-07 22:51:46 +0000 |
71 | +++ NuxGraphics/Events.h 2013-05-24 18:35:29 +0000 |
72 | @@ -401,7 +401,11 @@ |
73 | |
74 | int wheel_delta; //!< Wheel delta. |
75 | |
76 | - char text[NUX_EVENT_TEXT_BUFFER_SIZE]; |
77 | + // To avoid an ABI break |
78 | + union { |
79 | + char text[NUX_EVENT_TEXT_BUFFER_SIZE]; |
80 | + char* dtext; //!< Dynamicly allocated text |
81 | + }; |
82 | unsigned long key_modifiers; //!< Key modifiers. A bitwise inclusive OR of values in KeyModifier. |
83 | unsigned long mouse_state; |
84 | unsigned short key_repeat_count; //!< Number of time a key is repeated; |
85 | |
86 | === modified file 'NuxGraphics/GraphicsDisplayX11.cpp' |
87 | --- NuxGraphics/GraphicsDisplayX11.cpp 2012-07-20 17:48:02 +0000 |
88 | +++ NuxGraphics/GraphicsDisplayX11.cpp 2013-05-24 18:35:29 +0000 |
89 | @@ -35,6 +35,12 @@ |
90 | |
91 | #include <X11/extensions/shape.h> |
92 | |
93 | +#include "XIMController.h" |
94 | +#include <memory> |
95 | + |
96 | +// To avoid an ABI break... |
97 | +std::shared_ptr<nux::XIMController> m_xim_controller; |
98 | + |
99 | namespace nux |
100 | { |
101 | int GraphicsDisplay::double_click_time_delay = 400; // milliseconds |
102 | @@ -184,7 +190,17 @@ |
103 | return(event->type == MapNotify) && (event->xmap.window == (Window) arg); |
104 | } |
105 | |
106 | -// TODO: change windowWidth, windowHeight, to window_size; |
107 | + void GraphicsDisplay::XICFocus() |
108 | + { |
109 | + m_xim_controller->FocusInXIC(); |
110 | + } |
111 | + |
112 | + void GraphicsDisplay::XICUnFocus() |
113 | + { |
114 | + m_xim_controller->FocusOutXIC(); |
115 | + } |
116 | + |
117 | + // TODO: change windowWidth, windowHeight, to window_size; |
118 | static NCriticalSection CreateOpenGLWindow_CriticalSection; |
119 | bool GraphicsDisplay::CreateOpenGLWindow(const char *WindowTitle, |
120 | unsigned int WindowWidth, |
121 | @@ -568,6 +584,16 @@ |
122 | //XMapRaised(m_X11Display, m_X11Window); |
123 | } |
124 | |
125 | + m_xim_controller = std::make_shared<XIMController>(m_X11Display); |
126 | + m_xim_controller->SetFocusedWindow(m_X11Window); |
127 | + |
128 | + if (m_xim_controller->IsXICValid()) |
129 | + { |
130 | + long im_event_mask=0; |
131 | + XGetICValues(m_xim_controller->GetXIC(), XNFilterEvents, &im_event_mask, NULL); |
132 | + m_X11Attr.event_mask |= im_event_mask; |
133 | + } |
134 | + |
135 | #ifndef NUX_OPENGLES_20 |
136 | if (_has_glx_13) |
137 | { |
138 | @@ -673,6 +699,16 @@ |
139 | |
140 | m_GfxInterfaceCreated = true; |
141 | |
142 | + m_xim_controller = std::make_shared<XIMController>(m_X11Display); |
143 | + m_xim_controller->SetFocusedWindow(m_X11Window); |
144 | + |
145 | + if (m_xim_controller->IsXICValid()) |
146 | + { |
147 | + long im_event_mask=0; |
148 | + XGetICValues(m_xim_controller->GetXIC(), XNFilterEvents, &im_event_mask, NULL); |
149 | + m_X11Attr.event_mask |= im_event_mask; |
150 | + } |
151 | + |
152 | // m_DeviceFactory = new GpuDevice(m_ViewportSize.GetWidth(), m_ViewportSize.GetHeight(), BITFMT_R8G8B8A8); |
153 | m_DeviceFactory = new GpuDevice(m_ViewportSize.width, m_ViewportSize.height, BITFMT_R8G8B8A8, |
154 | m_X11Display, |
155 | @@ -700,6 +736,11 @@ |
156 | return m_DeviceFactory; |
157 | } |
158 | |
159 | + void GraphicsDisplay::SetFocusedWindowForXIMController(Window window) |
160 | + { |
161 | + m_xim_controller->SetFocusedWindow(window); |
162 | + } |
163 | + |
164 | int GraphicsDisplay::GetGlXMajor() const |
165 | { |
166 | return _glx_major; |
167 | @@ -1230,6 +1271,9 @@ |
168 | { |
169 | XNextEvent(m_X11Display, &xevent); |
170 | |
171 | + if (XFilterEvent(&xevent, None) == True) |
172 | + return; |
173 | + |
174 | if (!_event_filters.empty()) |
175 | { |
176 | for (auto filter : _event_filters) |
177 | @@ -1535,6 +1579,8 @@ |
178 | m_pEvent->dy = 0; |
179 | m_pEvent->virtual_code = 0; |
180 | //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: FocusIn event."); |
181 | + |
182 | + m_xim_controller->FocusInXIC(); |
183 | break; |
184 | } |
185 | |
186 | @@ -1550,6 +1596,8 @@ |
187 | m_pEvent->dy = 0; |
188 | m_pEvent->virtual_code = 0; |
189 | //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: FocusOut event."); |
190 | + |
191 | + m_xim_controller->FocusOutXIC(); |
192 | break; |
193 | } |
194 | |
195 | @@ -1579,14 +1627,44 @@ |
196 | //temporary fix for TextEntry widget: filter some keys |
197 | skip = true; |
198 | } |
199 | - |
200 | - int num_char_stored = XLookupString(&xevent.xkey, buffer, NUX_EVENT_TEXT_BUFFER_SIZE, (KeySym*) &m_pEvent->x11_keysym, NULL); |
201 | - if (num_char_stored && (!skip)) |
202 | - { |
203 | - Memcpy(m_pEvent->text, buffer, num_char_stored); |
204 | - } |
205 | - |
206 | - break; |
207 | + |
208 | + if (!skip) |
209 | + { |
210 | + int num_char_stored = 0; |
211 | + if (m_xim_controller->IsXICValid()) |
212 | + { |
213 | + delete[] m_pEvent->dtext; |
214 | + m_pEvent->dtext = nullptr; |
215 | + |
216 | + num_char_stored = XmbLookupString(m_xim_controller->GetXIC(), &xevent.xkey, nullptr, |
217 | + 0, (KeySym*) &m_pEvent->x11_keysym, nullptr); |
218 | + |
219 | + if (num_char_stored > 0) |
220 | + { |
221 | + int buf_len = num_char_stored + 1; |
222 | + m_pEvent->dtext = new char[buf_len]; |
223 | + num_char_stored = XmbLookupString(m_xim_controller->GetXIC(), &xevent.xkey, m_pEvent->dtext, |
224 | + buf_len, (KeySym*) &m_pEvent->x11_keysym, nullptr); |
225 | + |
226 | + m_pEvent->dtext[num_char_stored] = 0; |
227 | + } |
228 | + } |
229 | + else |
230 | + { |
231 | + m_pEvent->dtext = new char[NUX_EVENT_TEXT_BUFFER_SIZE]; |
232 | + num_char_stored = XLookupString(&xevent.xkey, m_pEvent->dtext, NUX_EVENT_TEXT_BUFFER_SIZE, |
233 | + (KeySym*) &m_pEvent->x11_keysym, nullptr); |
234 | + |
235 | + m_pEvent->dtext[num_char_stored] = 0; |
236 | + } |
237 | + } |
238 | + |
239 | + if (m_pEvent->dtext == nullptr) |
240 | + { |
241 | + m_pEvent->dtext = new char[NUX_EVENT_TEXT_BUFFER_SIZE]; |
242 | + m_pEvent->dtext[0] = 0; |
243 | + } |
244 | + break; |
245 | } |
246 | |
247 | case KeyRelease: |
248 | |
249 | === modified file 'NuxGraphics/GraphicsDisplayX11.h' |
250 | --- NuxGraphics/GraphicsDisplayX11.h 2012-01-26 23:01:57 +0000 |
251 | +++ NuxGraphics/GraphicsDisplayX11.h 2013-05-24 18:35:29 +0000 |
252 | @@ -35,7 +35,6 @@ |
253 | /* keysym.h contains keysymbols which we use to resolv what keys that are being pressed */ |
254 | #include <X11/keysym.h> |
255 | |
256 | - |
257 | #include <X11/extensions/xf86vmode.h> |
258 | #include <X11/extensions/Xinerama.h> |
259 | |
260 | @@ -283,6 +282,8 @@ |
261 | |
262 | GpuDevice* GetGpuDevice() const; |
263 | |
264 | + void SetFocusedWindowForXIMController(Window window); |
265 | + |
266 | // Dialog |
267 | /*bool StartOpenFileDialog(FileDialogOption& fdo); |
268 | bool StartSaveFileDialog(FileDialogOption& fdo); |
269 | @@ -342,6 +343,8 @@ |
270 | |
271 | void * KeyboardGrabData() { return _global_keyboard_grab_data; } |
272 | void * PointerGrabData() { return _global_pointer_grab_data; } |
273 | + void XICFocus(); |
274 | + void XICUnFocus(); |
275 | |
276 | private: |
277 | void InitGlobalGrabWindow(); |
278 | |
279 | === modified file 'NuxGraphics/Makefile.am' |
280 | --- NuxGraphics/Makefile.am 2012-03-23 12:19:32 +0000 |
281 | +++ NuxGraphics/Makefile.am 2013-05-24 18:35:29 +0000 |
282 | @@ -1,4 +1,4 @@ |
283 | -CLEANFILES = |
284 | +CLEANFILES = |
285 | DISTCLEANFILES = |
286 | EXTRA_DIST = $(srcdir)/GraphicsDisplayWin.cpp \ |
287 | $(srcdir)/GraphicsDisplayWin.h |
288 | @@ -85,7 +85,9 @@ |
289 | $(srcdir)/RenderingPipeTextureBlendShaderSource.h \ |
290 | $(srcdir)/RunTimeStats.h \ |
291 | $(srcdir)/VirtualKeyCodesX11.h \ |
292 | - $(srcdir)/XInputWindow.h |
293 | + $(srcdir)/XICClient.h \ |
294 | + $(srcdir)/XInputWindow.h \ |
295 | + $(srcdir)/XIMController.h |
296 | |
297 | source_cpp = \ |
298 | $(srcdir)/Events.cpp \ |
299 | @@ -143,7 +145,9 @@ |
300 | $(srcdir)/RenderingPipeTextureBlend.cpp \ |
301 | $(srcdir)/GLRenderingAPI.cpp \ |
302 | $(srcdir)/RunTimeStats.cpp \ |
303 | - $(srcdir)/XInputWindow.cpp |
304 | + $(srcdir)/XICClient.cpp \ |
305 | + $(srcdir)/XInputWindow.cpp \ |
306 | + $(srcdir)/XIMController.cpp |
307 | |
308 | libnux_graphics_@NUX_API_VERSION@_la_SOURCES = \ |
309 | $(source_cpp) \ |
310 | |
311 | === added file 'NuxGraphics/XICClient.cpp' |
312 | --- NuxGraphics/XICClient.cpp 1970-01-01 00:00:00 +0000 |
313 | +++ NuxGraphics/XICClient.cpp 2013-05-24 18:35:29 +0000 |
314 | @@ -0,0 +1,112 @@ |
315 | +/* |
316 | +* Copyright 2012-2013 Inalogic® Inc. |
317 | +* |
318 | +* This program is free software: you can redistribute it and/or modify it |
319 | +* under the terms of the GNU Lesser General Public License, as |
320 | +* published by the Free Software Foundation; either version 2.1 or 3.0 |
321 | +* of the License. |
322 | +* |
323 | +* This program is distributed in the hope that it will be useful, but |
324 | +* WITHOUT ANY WARRANTY; without even the implied warranties of |
325 | +* MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
326 | +* PURPOSE. See the applicable version of the GNU Lesser General Public |
327 | +* License for more details. |
328 | +* |
329 | +* You should have received a copy of both the GNU Lesser General Public |
330 | +* License along with this program. If not, see <http://www.gnu.org/licenses/> |
331 | +* |
332 | +* Authored by: Brandon Schaefer <brandon.schaefer@canonical.com> |
333 | +* |
334 | +*/ |
335 | + |
336 | +#include "XICClient.h" |
337 | + |
338 | +namespace nux |
339 | +{ |
340 | + |
341 | +XICClient::XICClient() |
342 | + : xic_(NULL) |
343 | + , xim_style_(0) |
344 | + , focused_(false) |
345 | +{ |
346 | +} |
347 | + |
348 | +void XICClient::ResetXIC(XIM xim, Window window) |
349 | +{ |
350 | + if (!xim_style_) |
351 | + SetupXIMStyle(xim); |
352 | + SetupXIC(xim, window); |
353 | +} |
354 | + |
355 | +void XICClient::SetupXIC(XIM xim, Window window) |
356 | +{ |
357 | + xic_ = XCreateIC(xim, XNInputStyle, xim_style_, XNClientWindow, window, XNFocusWindow, window, NULL); |
358 | +} |
359 | + |
360 | +void XICClient::SetupXIMStyle(XIM xim) |
361 | +{ |
362 | + int i; |
363 | + XIMStyles *xim_styles = NULL; |
364 | + XIMStyle root_style = (XIMPreeditNothing|XIMStatusNothing); |
365 | + |
366 | + XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL); |
367 | + |
368 | + for (i = 0; i < xim_styles->count_styles; ++i) |
369 | + if (xim_styles->supported_styles[i] == root_style) |
370 | + break; |
371 | + |
372 | + if (i >= xim_styles->count_styles) |
373 | + xim_style_ = 0; |
374 | + xim_style_ = root_style; |
375 | +} |
376 | + |
377 | +bool XICClient::HasXIC() const |
378 | +{ |
379 | + return xic_ != NULL; |
380 | +} |
381 | + |
382 | +XIC XICClient::GetXIC() const |
383 | +{ |
384 | + return xic_; |
385 | +} |
386 | + |
387 | +void XICClient::Reinitialize() |
388 | +{ |
389 | + xic_ = NULL; |
390 | + xim_style_ = 0; |
391 | + focused_ = false; |
392 | +} |
393 | + |
394 | +void XICClient::FocusInXIC() |
395 | +{ |
396 | + if (xic_ && !focused_) |
397 | + { |
398 | + XSetICFocus(xic_); |
399 | + focused_ = true; |
400 | + } |
401 | +} |
402 | + |
403 | +void XICClient::FocusOutXIC() |
404 | +{ |
405 | + if (xic_ && focused_) |
406 | + { |
407 | + XUnsetICFocus(xic_); |
408 | + focused_ = false; |
409 | + } |
410 | +} |
411 | + |
412 | +bool XICClient::IsFocused() const |
413 | +{ |
414 | + return focused_; |
415 | +} |
416 | + |
417 | +void XICClient::DestroyXIC() |
418 | +{ |
419 | + if (xic_) |
420 | + { |
421 | + XDestroyIC(xic_); |
422 | + xic_ = NULL; |
423 | + } |
424 | +} |
425 | + |
426 | +} //namespace nux |
427 | |
428 | === added file 'NuxGraphics/XICClient.h' |
429 | --- NuxGraphics/XICClient.h 1970-01-01 00:00:00 +0000 |
430 | +++ NuxGraphics/XICClient.h 2013-05-24 18:35:29 +0000 |
431 | @@ -0,0 +1,60 @@ |
432 | +/* |
433 | +* Copyright 2012-2013 Inalogic® Inc. |
434 | +* |
435 | +* This program is free software: you can redistribute it and/or modify it |
436 | +* under the terms of the GNU Lesser General Public License, as |
437 | +* published by the Free Software Foundation; either version 2.1 or 3.0 |
438 | +* of the License. |
439 | +* |
440 | +* This program is distributed in the hope that it will be useful, but |
441 | +* WITHOUT ANY WARRANTY; without even the implied warranties of |
442 | +* MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
443 | +* PURPOSE. See the applicable version of the GNU Lesser General Public |
444 | +* License for more details. |
445 | +* |
446 | +* You should have received a copy of both the GNU Lesser General Public |
447 | +* License along with this program. If not, see <http://www.gnu.org/licenses/> |
448 | +* |
449 | +* Authored by: Brandon Schaefer <brandon.schaefer@canonical.com> |
450 | +* |
451 | +*/ |
452 | + |
453 | +#ifndef XICCLIENT_H |
454 | +#define XICCLIENT_H |
455 | + |
456 | +/* Xlib.h is the default header that is included and has the core functionallity */ |
457 | +#include <X11/Xlib.h> |
458 | + |
459 | +namespace nux |
460 | +{ |
461 | + |
462 | +class XICClient |
463 | +{ |
464 | +public: |
465 | + XICClient(); |
466 | + |
467 | + void ResetXIC(XIM xim, Window window); |
468 | + |
469 | + bool HasXIC() const; |
470 | + XIC GetXIC() const; |
471 | + |
472 | + void Reinitialize(); |
473 | + |
474 | + void FocusInXIC(); |
475 | + void FocusOutXIC(); |
476 | + bool IsFocused() const; |
477 | + |
478 | + void DestroyXIC(); |
479 | +private: |
480 | + void SetupXIC(XIM xim, Window window); |
481 | + void SetupXIMStyle(XIM xim); |
482 | + |
483 | + XIC xic_; |
484 | + XIMStyle xim_style_; |
485 | + |
486 | + bool focused_; |
487 | +}; |
488 | + |
489 | +} //namespace nux |
490 | + |
491 | +#endif // XICClient.h |
492 | |
493 | === added file 'NuxGraphics/XIMController.cpp' |
494 | --- NuxGraphics/XIMController.cpp 1970-01-01 00:00:00 +0000 |
495 | +++ NuxGraphics/XIMController.cpp 2013-05-24 18:35:29 +0000 |
496 | @@ -0,0 +1,146 @@ |
497 | +/* |
498 | +* Copyright 2012-2013 Inalogic® Inc. |
499 | +* |
500 | +* This program is free software: you can redistribute it and/or modify it |
501 | +* under the terms of the GNU Lesser General Public License, as |
502 | +* published by the Free Software Foundation; either version 2.1 or 3.0 |
503 | +* of the License. |
504 | +* |
505 | +* This program is distributed in the hope that it will be useful, but |
506 | +* WITHOUT ANY WARRANTY; without even the implied warranties of |
507 | +* MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
508 | +* PURPOSE. See the applicable version of the GNU Lesser General Public |
509 | +* License for more details. |
510 | +* |
511 | +* You should have received a copy of both the GNU Lesser General Public |
512 | +* License along with this program. If not, see <http://www.gnu.org/licenses/> |
513 | +* |
514 | +* Authored by: Brandon Schaefer <brandon.schaefer@canonical.com> |
515 | +* |
516 | +*/ |
517 | + |
518 | +#include <string.h> |
519 | + |
520 | +#include "XIMController.h" |
521 | +#include "NuxCore/Logger.h" |
522 | + |
523 | +namespace nux |
524 | +{ |
525 | + |
526 | +logging::Logger logger("xim.controller"); |
527 | + |
528 | +XIMController::XIMController(Display* display) |
529 | + : display_(display) |
530 | + , window_(0) |
531 | + , xim_(NULL) |
532 | +{ |
533 | + InitXIMCallback(); |
534 | +} |
535 | + |
536 | +XIMController::~XIMController() |
537 | +{ |
538 | + // The XIC must be destroyed before the XIM |
539 | + if (xic_client_.HasXIC()) |
540 | + xic_client_.DestroyXIC(); |
541 | + |
542 | + if (xim_) |
543 | + XCloseIM(xim_); |
544 | +} |
545 | + |
546 | +void XIMController::SetFocusedWindow(Window window) |
547 | +{ |
548 | + window_ = window; |
549 | + if (xim_) |
550 | + xic_client_.ResetXIC(xim_, window); |
551 | +} |
552 | + |
553 | +bool XIMController::IsXICValid() const |
554 | +{ |
555 | + return xic_client_.HasXIC(); |
556 | +} |
557 | + |
558 | +XIC XIMController::GetXIC() const |
559 | +{ |
560 | + return xic_client_.GetXIC(); |
561 | +} |
562 | + |
563 | +void XIMController::FocusInXIC() |
564 | +{ |
565 | + xic_client_.FocusInXIC(); |
566 | +} |
567 | + |
568 | +void XIMController::FocusOutXIC() |
569 | +{ |
570 | + xic_client_.FocusOutXIC(); |
571 | +} |
572 | + |
573 | +void XIMController::InitXIMCallback() |
574 | +{ |
575 | + char* const xmodifier = getenv("XMODIFIERS"); |
576 | + |
577 | + if (xmodifier && strstr(xmodifier,"ibus") != NULL) |
578 | + { |
579 | + LOG_WARN(logger) << "IBus natively supported."; |
580 | + return; |
581 | + } |
582 | + |
583 | + if (setlocale(LC_ALL, "") == NULL) |
584 | + { |
585 | + LOG_WARN(logger) << "Cannot setlocale."; |
586 | + } |
587 | + |
588 | + if (XSupportsLocale()) |
589 | + { |
590 | + if (XSetLocaleModifiers("") == NULL) |
591 | + { |
592 | + LOG_WARN(logger) << "XSetLocalModifiers Failed."; |
593 | + } |
594 | + XRegisterIMInstantiateCallback(display_, NULL, NULL, NULL, |
595 | + XIMController::SetupXIMClientCallback, |
596 | + (XPointer)this); |
597 | + } |
598 | +} |
599 | + |
600 | +void XIMController::SetupXIMClientCallback(Display* dpy, XPointer client_data, XPointer call_data) |
601 | +{ |
602 | + XIMController* self = (XIMController*)client_data; |
603 | + self->SetupXIM(); |
604 | +} |
605 | + |
606 | +void XIMController::EndXIMClientCallback(Display* dpy, XPointer client_data, XPointer call_data) |
607 | +{ |
608 | + XIMController* self = (XIMController*)client_data; |
609 | + self->xim_ = NULL; |
610 | + self->xic_client_.Reinitialize(); |
611 | + self->InitXIMCallback(); |
612 | +} |
613 | + |
614 | +void XIMController::SetupXIM() |
615 | +{ |
616 | + xim_ = XOpenIM(display_, NULL, NULL, NULL); |
617 | + if (xim_) |
618 | + { |
619 | + SetupXIMDestroyedCallback(); |
620 | + |
621 | + if (window_) |
622 | + xic_client_.ResetXIC(xim_, window_); |
623 | + |
624 | + XUnregisterIMInstantiateCallback (display_, NULL, NULL, NULL, |
625 | + XIMController::SetupXIMClientCallback, |
626 | + (XPointer)this); |
627 | + } |
628 | + else |
629 | + { |
630 | + LOG_WARN(logger) << "Failed to open IM."; |
631 | + } |
632 | +} |
633 | + |
634 | +void XIMController::SetupXIMDestroyedCallback() |
635 | +{ |
636 | + XIMCallback destroy_callback; |
637 | + destroy_callback.callback = (XIMProc)XIMController::EndXIMClientCallback; |
638 | + destroy_callback.client_data = (XPointer)this; |
639 | + XSetIMValues (xim_, XNDestroyCallback, &destroy_callback, NULL); |
640 | +} |
641 | + |
642 | +} //namespace nux |
643 | |
644 | === added file 'NuxGraphics/XIMController.h' |
645 | --- NuxGraphics/XIMController.h 1970-01-01 00:00:00 +0000 |
646 | +++ NuxGraphics/XIMController.h 2013-05-24 18:35:29 +0000 |
647 | @@ -0,0 +1,62 @@ |
648 | +/* |
649 | +* Copyright 2012-2013 Inalogic® Inc. |
650 | +* |
651 | +* This program is free software: you can redistribute it and/or modify it |
652 | +* under the terms of the GNU Lesser General Public License, as |
653 | +* published by the Free Software Foundation; either version 2.1 or 3.0 |
654 | +* of the License. |
655 | +* |
656 | +* This program is distributed in the hope that it will be useful, but |
657 | +* WITHOUT ANY WARRANTY; without even the implied warranties of |
658 | +* MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
659 | +* PURPOSE. See the applicable version of the GNU Lesser General Public |
660 | +* License for more details. |
661 | +* |
662 | +* You should have received a copy of both the GNU Lesser General Public |
663 | +* License along with this program. If not, see <http://www.gnu.org/licenses/> |
664 | +* |
665 | +* Authored by: Brandon Schaefer <brandon.schaefer@canonical.com> |
666 | +* |
667 | +*/ |
668 | + |
669 | +#ifndef XIMCONTROLLER_H |
670 | +#define XIMCONTROLLER_H |
671 | + |
672 | +#include "XICClient.h" |
673 | + |
674 | +/* Xlib.h is the default header that is included and has the core functionallity */ |
675 | +#include <X11/Xlib.h> |
676 | + |
677 | +namespace nux |
678 | +{ |
679 | + |
680 | +class XIMController |
681 | +{ |
682 | +public: |
683 | + XIMController(Display* display); |
684 | + ~XIMController(); |
685 | + |
686 | + void SetFocusedWindow(Window window); |
687 | + |
688 | + bool IsXICValid() const; |
689 | + XIC GetXIC() const; |
690 | + |
691 | + void FocusInXIC(); |
692 | + void FocusOutXIC(); |
693 | +private: |
694 | + void InitXIMCallback(); |
695 | + static void SetupXIMClientCallback(Display* dpy, XPointer client_data, XPointer call_data); |
696 | + static void EndXIMClientCallback(Display* dpy, XPointer client_data, XPointer call_data); |
697 | + |
698 | + void SetupXIM(); |
699 | + void SetupXIMDestroyedCallback(); |
700 | + |
701 | + Display* display_; |
702 | + Window window_; |
703 | + XIM xim_; |
704 | + XICClient xic_client_; |
705 | +}; |
706 | + |
707 | +} //namespace nux |
708 | + |
709 | +#endif // XIMController.h |
710 | |
711 | === modified file 'NuxGraphics/XInputWindow.cpp' |
712 | --- NuxGraphics/XInputWindow.cpp 2012-01-18 21:08:29 +0000 |
713 | +++ NuxGraphics/XInputWindow.cpp 2013-05-24 18:35:29 +0000 |
714 | @@ -22,6 +22,8 @@ |
715 | #include "XInputWindow.h" |
716 | #include "GraphicsDisplayX11.h" |
717 | #include "GLThread.h" |
718 | +#include "XIMController.h" |
719 | + |
720 | |
721 | // Jay, what is this for? It isn't referenced anywhere. |
722 | #define xdnd_version 5 |
723 | @@ -374,8 +376,9 @@ |
724 | |
725 | void XInputWindow::Show() |
726 | { |
727 | + GetGraphicsDisplay()->SetFocusedWindowForXIMController(window_); |
728 | + |
729 | shown_ = true; |
730 | - |
731 | if (!mapped_) |
732 | { |
733 | XMapRaised(display_, window_); |
(1) Does this handle the case of no IM present? You removed the XLookupString() case.
(2) Are you sure there is no leak here?
208 + m_pEvent->dtext = nullptr;