Merge lp:~brandontschaefer/nux/xim-preedit-support into lp:nux
- xim-preedit-support
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Christopher Townsend | ||||
Approved revision: | 840 | ||||
Merged at revision: | 833 | ||||
Proposed branch: | lp:~brandontschaefer/nux/xim-preedit-support | ||||
Merge into: | lp:nux | ||||
Diff against target: |
1203 lines (+584/-103) 17 files modified
Nux/MainLoopGLib.cpp (+7/-4) Nux/Makefile.am (+8/-3) Nux/TextEntry.cpp (+31/-2) Nux/TextEntry.h (+5/-0) Nux/WindowThread.cpp (+37/-1) Nux/WindowThread.h (+15/-0) Nux/XICClient.cpp (+226/-20) Nux/XICClient.h (+25/-3) Nux/XIMCallbacks.cpp (+189/-0) Nux/XIMController.cpp (+14/-5) Nux/XIMController.h (+3/-1) NuxGraphics/GraphicsDisplayX11.cpp (+10/-45) NuxGraphics/GraphicsDisplayX11.h (+2/-6) NuxGraphics/Makefile.am (+2/-6) NuxGraphics/XInputWindow.cpp (+0/-5) configure.ac (+2/-2) debian/changelog (+8/-0) |
||||
To merge this branch: | bzr merge lp:~brandontschaefer/nux/xim-preedit-support | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Christopher Townsend | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+199569@code.launchpad.net |
Commit message
Adds preedit support to XIM. Such as preedit rendering in the TextEntry.
Move XIM support from GraphicsDisplayX11 to WindowThread.
Description of the change
Add preedit support to XIM.
Had to move XIM support from GraphicsDisplayX11 to WindowThread
This should land when this branch lands:
https:/
- 834. By Brandon Schaefer
-
* Don't need that header
PS Jenkins bot (ps-jenkins) wrote : | # |
Christopher Townsend (townsend) wrote : | # |
Couple of things right off the bat.
1. Need a commit message :)
2. Is there a bug associated with this work?
3. How do you test this? What is the old behavior and what am I expecting with this change?
Thanks!
Brandon Schaefer (brandontschaefer) wrote : | # |
Hey Chris,
So there are some AP tests in unity. The old bevaior should be the same, ie. type in the an IM and text gets commited. Whats changed is they style, now preedit gets rendered to the TextEntry while the user types in they IM. Some IMs such as fctix doesn't support it by default (for some reason). So to test it out you'll need to go into:
$HOME/.
Then set:
UseOnTheSpotSty
- 835. By Brandon Schaefer
-
[ Brandon Schaefer ]
Add XIM preedit supportUpdate the deb change log
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:835
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Christopher Townsend (townsend) wrote : | # |
If $XMODIFIERS is blank, I get a seg fault crash. I don't think is default, but I'm sure it will happen.
Also,
839 +//#include "Nux.h"
840 +//#include "TextEntry.h"
841 +
needs to be removed since it's commented out.
- 836. By Brandon Schaefer
-
* Fix a crash when XMOD was blank. We need to make sure we are passing in a NULL
name if we don't have any callbacks!
Brandon Schaefer (brandontschaefer) wrote : | # |
Fixed issue, I was passing in XNPreeditAttributes and XNStatusAttributes to XCreateIC even when p_list and s_list was NULL. If they were NULL I can't pass in XNPreeditAttrib
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:836
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Christopher Townsend (townsend) wrote : | # |
I think the Nux version should be bumped to 4.0.5. As I mentioned in https:/
- 837. By Brandon Schaefer
-
* Bump to 4.0.5
- 838. By Brandon Schaefer
-
[ Brandon Schaefer ]
* Add XIM preedit support
* Bump version to 4.0.5Update changelog
- 839. By Brandon Schaefer
-
* Add missing space
- 840. By Brandon Schaefer
-
* Back to 1
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:837
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Christopher Townsend (townsend) wrote : | # |
Great, this all looks good now!
Preview Diff
1 | === modified file 'Nux/MainLoopGLib.cpp' |
2 | --- Nux/MainLoopGLib.cpp 2013-11-06 13:56:07 +0000 |
3 | +++ Nux/MainLoopGLib.cpp 2014-01-03 16:37:28 +0000 |
4 | @@ -43,6 +43,11 @@ |
5 | unsigned int id; |
6 | } TimeoutData; |
7 | |
8 | + Event GetSystemEvent(WindowThread* window_thread) |
9 | + { |
10 | + return window_thread->GetNextEvent(); |
11 | + } |
12 | + |
13 | gboolean nux_timeout_dispatch(gpointer user_data) |
14 | { |
15 | bool repeat = false; |
16 | @@ -59,8 +64,7 @@ |
17 | } |
18 | else |
19 | { |
20 | - Event event; |
21 | - dd->window_thread->GetGraphicsDisplay().GetSystemEvent(&event); |
22 | + Event event = GetSystemEvent(dd->window_thread); |
23 | return_code = dd->window_thread->ProcessEvent(event); |
24 | } |
25 | |
26 | @@ -128,8 +132,7 @@ |
27 | nux_glib_threads_lock(); |
28 | WindowThread *window_thread = NUX_STATIC_CAST(WindowThread *, user_data); |
29 | |
30 | - Event event; |
31 | - window_thread->GetGraphicsDisplay().GetSystemEvent(&event); |
32 | + Event event = GetSystemEvent(window_thread); |
33 | unsigned int return_code = window_thread->ProcessEvent(event); |
34 | |
35 | if (return_code == 0 && !window_thread->IsEmbeddedWindow()) |
36 | |
37 | === modified file 'Nux/Makefile.am' |
38 | --- Nux/Makefile.am 2013-04-18 13:28:09 +0000 |
39 | +++ Nux/Makefile.am 2014-01-03 16:37:28 +0000 |
40 | @@ -129,7 +129,10 @@ |
41 | |
42 | if USE_X11 |
43 | source_cpp += \ |
44 | - $(srcdir)/InputMethodIBus.cpp |
45 | + $(srcdir)/InputMethodIBus.cpp \ |
46 | + $(srcdir)/XICClient.cpp \ |
47 | + $(srcdir)/XIMCallbacks.cpp \ |
48 | + $(srcdir)/XIMController.cpp |
49 | endif |
50 | |
51 | if HAVE_GEIS |
52 | @@ -243,8 +246,10 @@ |
53 | endif |
54 | |
55 | if USE_X11 |
56 | -source_cpp += \ |
57 | - $(srcdir)/InputMethodIBus.h |
58 | +source_h += \ |
59 | + $(srcdir)/InputMethodIBus.h \ |
60 | + $(srcdir)/XICClient.h \ |
61 | + $(srcdir)/XIMController.h |
62 | endif |
63 | |
64 | if HAVE_GEIS |
65 | |
66 | === modified file 'Nux/TextEntry.cpp' |
67 | --- Nux/TextEntry.cpp 2013-11-04 14:59:20 +0000 |
68 | +++ Nux/TextEntry.cpp 2014-01-03 16:37:28 +0000 |
69 | @@ -884,7 +884,7 @@ |
70 | need_im_reset_ = true; |
71 | #if defined(USE_X11) |
72 | ime_->Focus(); |
73 | - nux::GetWindowThread()->GetGraphicsDisplay().XICFocus(); |
74 | + nux::GetWindowThread()->XICFocus(this); |
75 | #endif |
76 | //gtk_im_context_focus_in(im_context_); |
77 | //UpdateIMCursorLocation(); |
78 | @@ -907,7 +907,7 @@ |
79 | need_im_reset_ = true; |
80 | #if defined(USE_X11) |
81 | ime_->Blur(); |
82 | - nux::GetWindowThread()->GetGraphicsDisplay().XICUnFocus(); |
83 | + nux::GetWindowThread()->XICUnFocus(); |
84 | #endif |
85 | //gtk_im_context_focus_out(im_context_); |
86 | } |
87 | @@ -1033,6 +1033,35 @@ |
88 | } |
89 | } |
90 | |
91 | + void TextEntry::PreeditStarted() |
92 | + { |
93 | + ime_active_ = true; |
94 | + } |
95 | + |
96 | + void TextEntry::UpdatePreedit(std::string const& preedit, int cursor) |
97 | + { |
98 | + preedit_ = preedit; |
99 | + preedit_cursor_ = cursor; |
100 | + QueueRefresh(true, true); |
101 | + } |
102 | + |
103 | + void TextEntry::UpdatePreeditAttribs(PangoAttrList* list) |
104 | + { |
105 | + if (preedit_attrs_) |
106 | + { |
107 | + pango_attr_list_unref(preedit_attrs_); |
108 | + preedit_attrs_ = NULL; |
109 | + } |
110 | + |
111 | + preedit_attrs_ = list; |
112 | + } |
113 | + |
114 | + void TextEntry::ClearPreedit() |
115 | + { |
116 | + ResetPreedit(); |
117 | + QueueRefresh(true, true); |
118 | + } |
119 | + |
120 | void TextEntry::DrawText(CairoGraphics *canvas) |
121 | { |
122 | PangoLayout *layout = EnsureLayout(); |
123 | |
124 | === modified file 'Nux/TextEntry.h' |
125 | --- Nux/TextEntry.h 2013-11-04 14:59:20 +0000 |
126 | +++ Nux/TextEntry.h 2014-01-03 16:37:28 +0000 |
127 | @@ -227,6 +227,11 @@ |
128 | bool PasswordMode() const; |
129 | std::string GetPasswordChar(); |
130 | |
131 | + void PreeditStarted(); |
132 | + void UpdatePreedit(std::string const& preedit, int cursor); |
133 | + void UpdatePreeditAttribs(PangoAttrList* list); |
134 | + void ClearPreedit(); |
135 | + |
136 | protected: |
137 | bool _block_focus; // used to selectively ignore focus keyevents |
138 | |
139 | |
140 | === modified file 'Nux/WindowThread.cpp' |
141 | --- Nux/WindowThread.cpp 2013-11-07 11:53:10 +0000 |
142 | +++ Nux/WindowThread.cpp 2014-01-03 16:37:28 +0000 |
143 | @@ -118,6 +118,7 @@ |
144 | WindowThread::~WindowThread() |
145 | { |
146 | #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) |
147 | + xim_controller_.reset(); |
148 | CleanupGlibLoop(); |
149 | #endif |
150 | |
151 | @@ -521,6 +522,24 @@ |
152 | |
153 | extern EventToNameStruct EventToName[]; |
154 | |
155 | + Event WindowThread::GetNextEvent() |
156 | + { |
157 | + Event event; |
158 | + graphics_display_->GetSystemEvent(&event); |
159 | + |
160 | +#if defined(NUX_OS_LINUX) && defined(USE_X11) |
161 | + // Make sure the current xic is synced up with the current event window |
162 | + if ((event.type == KeyPress || event.type == KeyRelease) && |
163 | + event.x11_window && xim_controller_->GetCurrentWindow() != event.x11_window) |
164 | + { |
165 | + xim_controller_->SetFocusedWindow(event.x11_window); |
166 | + graphics_display_->SetCurrentXIC(xim_controller_->GetXIC()); |
167 | + } |
168 | +#endif |
169 | + |
170 | + return event; |
171 | + } |
172 | + |
173 | #if (!defined(NUX_OS_LINUX) && !defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) || defined(NUX_DISABLE_GLIB_LOOP) |
174 | #ifdef NUX_GESTURES_SUPPORT |
175 | Event *WindowThread::FetchNextEvent() |
176 | @@ -1148,6 +1167,8 @@ |
177 | timer_manager_ = new TimerHandler(this); |
178 | window_compositor_ = new WindowCompositor(this); |
179 | |
180 | + xim_controller_ = std::make_shared<XIMController>(graphics_display_->GetX11Display()); |
181 | + |
182 | SetThreadState(THREADRUNNING); |
183 | thread_ctor_called_ = true; |
184 | return true; |
185 | @@ -1245,7 +1266,7 @@ |
186 | x11display_ = XOpenDisplay(NULL); |
187 | ownx11display_ = true; |
188 | } |
189 | - |
190 | + |
191 | graphics_display_ = gGLWindowManager.CreateFromForeignWindow(x11display_, X11Window, OpenGLContext); |
192 | |
193 | if (graphics_display_ == 0) |
194 | @@ -1264,6 +1285,8 @@ |
195 | timer_manager_ = new TimerHandler(this); |
196 | window_compositor_ = new WindowCompositor(this); |
197 | |
198 | + xim_controller_ = std::make_shared<XIMController>(graphics_display_->GetX11Display()); |
199 | + |
200 | SetThreadState(THREADRUNNING); |
201 | thread_ctor_called_ = true; |
202 | |
203 | @@ -1776,6 +1799,19 @@ |
204 | _external_fds.erase (it); |
205 | } |
206 | } |
207 | +#if defined(NUX_OS_LINUX) && defined(USE_X11) |
208 | + void WindowThread::XICFocus(TextEntry* text_entry) |
209 | + { |
210 | + xim_controller_->FocusInXIC(); |
211 | + xim_controller_->SetCurrentTextEntry(text_entry); |
212 | + graphics_display_->SetCurrentXIC(xim_controller_->GetXIC()); |
213 | + } |
214 | + |
215 | + void WindowThread::XICUnFocus() |
216 | + { |
217 | + xim_controller_->FocusOutXIC(); |
218 | + } |
219 | +#endif |
220 | |
221 | GraphicsDisplay& WindowThread::GetGraphicsDisplay() const |
222 | { |
223 | |
224 | === modified file 'Nux/WindowThread.h' |
225 | --- Nux/WindowThread.h 2013-10-30 23:26:54 +0000 |
226 | +++ Nux/WindowThread.h 2014-01-03 16:37:28 +0000 |
227 | @@ -29,6 +29,10 @@ |
228 | #include "GeisAdapter.h" |
229 | #endif |
230 | |
231 | +#if defined(NUX_OS_LINUX) && defined(USE_X11) |
232 | +#include "XIMController.h" |
233 | +#endif |
234 | + |
235 | namespace nux |
236 | { |
237 | |
238 | @@ -358,6 +362,8 @@ |
239 | |
240 | std::vector<Geometry> GetPresentationListGeometries() const; |
241 | |
242 | + Event GetNextEvent(); |
243 | + |
244 | #ifdef NUX_GESTURES_SUPPORT |
245 | /*! |
246 | Simple wrapper for ProcessEvent for connection with GeisAdapter::event_ready |
247 | @@ -371,6 +377,11 @@ |
248 | void WatchFdForEvents(int fd, const FdWatchCallback &); |
249 | void UnwatchFd(int fd); |
250 | |
251 | +#if defined(NUX_OS_LINUX) && defined(USE_X11) |
252 | + void XICFocus(TextEntry* text_entry); |
253 | + void XICUnFocus(); |
254 | +#endif |
255 | + |
256 | protected: |
257 | |
258 | /*! |
259 | @@ -709,6 +720,10 @@ |
260 | std::unique_ptr<GeisAdapter> geis_adapter_; |
261 | #endif |
262 | |
263 | +#if defined(NUX_OS_LINUX) && defined(USE_X11) |
264 | + std::shared_ptr<XIMController> xim_controller_; |
265 | +#endif |
266 | + |
267 | /*! |
268 | Add a timeout and return the timeout index. |
269 | This function is used internally by Nux. |
270 | |
271 | === renamed file 'NuxGraphics/XICClient.cpp' => 'Nux/XICClient.cpp' |
272 | --- NuxGraphics/XICClient.cpp 2013-07-18 00:09:46 +0000 |
273 | +++ Nux/XICClient.cpp 2014-01-03 16:37:28 +0000 |
274 | @@ -1,5 +1,5 @@ |
275 | /* |
276 | -* Copyright 2012 Inalogic® Inc. |
277 | +* Copyright 2012-2013 Inalogic® Inc. |
278 | * |
279 | * This program is free software: you can redistribute it and/or modify it |
280 | * under the terms of the GNU Lesser General Public License, as |
281 | @@ -21,54 +21,260 @@ |
282 | |
283 | #include "XICClient.h" |
284 | |
285 | +#include "NuxCore/Logger.h" |
286 | + |
287 | +DECLARE_LOGGER(logger, "xic.client"); |
288 | + |
289 | +using namespace std; |
290 | + |
291 | namespace nux |
292 | { |
293 | |
294 | +int const FEEDBACK_MASK = (XIMUnderline | XIMReverse); |
295 | + |
296 | XICClient::XICClient() |
297 | - : xic_(NULL) |
298 | + : xic_(nullptr) |
299 | , xim_style_(0) |
300 | , focused_(false) |
301 | { |
302 | } |
303 | |
304 | -void XICClient::ResetXIC(XIM xim, Window window) |
305 | +void XICClient::ResetXIC(XIM xim, Window window, Display* display) |
306 | { |
307 | if (!xim_style_) |
308 | SetupXIMStyle(xim); |
309 | |
310 | - SetupXIC(xim, window); |
311 | -} |
312 | - |
313 | -void XICClient::SetupXIC(XIM xim, Window window) |
314 | + SetupXIC(xim, window, display); |
315 | +} |
316 | + |
317 | +void XICClient::SetCurrentTextEntry(TextEntry* text_entry) |
318 | +{ |
319 | + text_entry_ = text_entry; |
320 | +} |
321 | + |
322 | +static int preedit_caret_callback(XIC xic, |
323 | + XPointer clientdata, |
324 | + XIMPreeditCaretCallbackStruct* call_data) |
325 | +{ |
326 | + return 0; |
327 | +} |
328 | + |
329 | +static int status_start_callback(XIC xic, |
330 | + XPointer clientdata, |
331 | + XIMPreeditDrawCallbackStruct* call_data) |
332 | +{ |
333 | + return 0; |
334 | +} |
335 | + |
336 | +static void status_draw_callback(XIC xic, |
337 | + XPointer clientdata, |
338 | + XPointer* call_data) |
339 | +{ |
340 | +} |
341 | + |
342 | +static void status_done_callback(XIC xic, |
343 | + XPointer clientdata, |
344 | + XPointer* call_data) |
345 | +{ |
346 | +} |
347 | + |
348 | +XVaNestedList XICClient::GetPreeditCallbacks() |
349 | +{ |
350 | + preedit_start_cb_.callback = (XIMProc)XICClient::PreeditStartCallback; |
351 | + preedit_start_cb_.client_data = nullptr; |
352 | + |
353 | + preedit_done_cb_.callback = (XIMProc)XICClient::PreeditDoneCallback; |
354 | + preedit_done_cb_.client_data = (XPointer)text_entry_; |
355 | + |
356 | + preedit_draw_cb_.callback = (XIMProc)XICClient::PreeditDrawCallback; |
357 | + preedit_draw_cb_.client_data = (XPointer)text_entry_; |
358 | + |
359 | + preedit_caret_cb_.callback = (XIMProc)preedit_caret_callback; |
360 | + preedit_caret_cb_.client_data = nullptr; |
361 | + |
362 | + XVaNestedList p_list = nullptr; |
363 | + p_list = XVaCreateNestedList(0, |
364 | + XNPreeditStartCallback, &preedit_start_cb_, |
365 | + XNPreeditDoneCallback, &preedit_done_cb_, |
366 | + XNPreeditDrawCallback, &preedit_draw_cb_, |
367 | + XNPreeditCaretCallback, &preedit_caret_cb_, |
368 | + nullptr); |
369 | + |
370 | + return p_list; |
371 | +} |
372 | + |
373 | +XVaNestedList XICClient::GetStatusCallbacks() |
374 | +{ |
375 | + status_start_cb_.callback = (XIMProc)status_start_callback; |
376 | + status_start_cb_.client_data = nullptr; |
377 | + |
378 | + status_done_cb_.callback = (XIMProc)status_done_callback; |
379 | + status_done_cb_.client_data = nullptr; |
380 | + |
381 | + status_draw_cb_.callback = (XIMProc)status_draw_callback; |
382 | + status_draw_cb_.client_data = nullptr; |
383 | + |
384 | + XVaNestedList s_list = nullptr; |
385 | + s_list = XVaCreateNestedList(0, |
386 | + XNStatusStartCallback, &status_start_callback, |
387 | + XNStatusDoneCallback, &status_done_callback, |
388 | + XNStatusDrawCallback, &status_draw_callback, |
389 | + nullptr); |
390 | + |
391 | + return s_list; |
392 | +} |
393 | + |
394 | +XIMStyle XICClient::FilterXIMStyle() |
395 | +{ |
396 | + XIMStyle style = 0; |
397 | + |
398 | + if (xim_style_ & XIMPreeditCallbacks) |
399 | + { |
400 | + style |= XIMPreeditCallbacks; |
401 | + } |
402 | + else if (xim_style_ & XIMPreeditNone) |
403 | + { |
404 | + style |= XIMPreeditNone; |
405 | + } |
406 | + else |
407 | + { |
408 | + style |= XIMPreeditNothing; |
409 | + } |
410 | + |
411 | + if (xim_style_ & XIMStatusCallbacks) |
412 | + { |
413 | + style |= XIMStatusCallbacks; |
414 | + } |
415 | + else if (xim_style_ & XIMStatusNone) |
416 | + { |
417 | + style |= XIMStatusNone; |
418 | + } |
419 | + else |
420 | + { |
421 | + style |= XIMStatusNothing; |
422 | + } |
423 | + |
424 | + return style; |
425 | +} |
426 | + |
427 | +void XICClient::SetupXIC(XIM xim, Window window, Display* display) |
428 | { |
429 | if (xic_) |
430 | DestroyXIC(); |
431 | |
432 | - xic_ = XCreateIC(xim, XNInputStyle, xim_style_, XNClientWindow, window, XNFocusWindow, window, NULL); |
433 | + XIMStyle style = FilterXIMStyle(); |
434 | + |
435 | + const char* p_name = nullptr; |
436 | + XVaNestedList p_list = nullptr; |
437 | + if (style & XIMPreeditCallbacks) |
438 | + { |
439 | + p_list = GetPreeditCallbacks(); |
440 | + p_name = XNPreeditAttributes; |
441 | + } |
442 | + |
443 | + const char* s_name = nullptr; |
444 | + XVaNestedList s_list = nullptr; |
445 | + if (style & XIMStatusCallbacks) |
446 | + { |
447 | + s_list = GetStatusCallbacks(); |
448 | + s_name = XNStatusAttributes; |
449 | + } |
450 | + |
451 | + xic_ = XCreateIC(xim, XNInputStyle, style, |
452 | + XNClientWindow, window, |
453 | + p_name, p_list, |
454 | + s_name, s_list, |
455 | + nullptr); |
456 | + |
457 | + if (p_list) |
458 | + XFree(p_list); |
459 | + if (s_list) |
460 | + XFree(s_list); |
461 | + |
462 | + xim_style_ = style; |
463 | +} |
464 | + |
465 | +XIMStyle ChooseBetterStyle(XIMStyle style1, XIMStyle style2) |
466 | +{ |
467 | + XIMStyle s,t; |
468 | + XIMStyle preedit = XIMPreeditArea | XIMPreeditCallbacks | |
469 | + XIMPreeditPosition | XIMPreeditNothing | XIMPreeditNone; |
470 | + |
471 | + XIMStyle status = XIMStatusArea | XIMStatusCallbacks | |
472 | + XIMStatusNothing | XIMStatusNone; |
473 | + |
474 | + if (style1 == 0) |
475 | + return style2; |
476 | + |
477 | + if (style2 == 0) |
478 | + return style1; |
479 | + |
480 | + if ((style1 & (preedit | status)) == (style2 & (preedit | status))) |
481 | + return style1; |
482 | + |
483 | + s = style1 & preedit; |
484 | + t = style2 & preedit; |
485 | + if (s != t) |
486 | + { |
487 | + if (s | t | XIMPreeditCallbacks) |
488 | + return (s == XIMPreeditCallbacks) ? style1 : style2; |
489 | + else if (s | t | XIMPreeditPosition) |
490 | + return (s == XIMPreeditPosition) ? style1 : style2; |
491 | + else if (s | t | XIMPreeditArea) |
492 | + return (s == XIMPreeditArea) ? style1 : style2; |
493 | + else if (s | t | XIMPreeditNothing) |
494 | + return (s == XIMPreeditNothing) ? style1 : style2; |
495 | + else if (s | t | XIMPreeditNone) |
496 | + return (s == XIMPreeditNone) ? style1 : style2; |
497 | + } |
498 | + else |
499 | + { |
500 | + s = style1 & status; |
501 | + t = style2 & status; |
502 | + |
503 | + if (s | t | XIMStatusCallbacks) |
504 | + return (s == XIMStatusCallbacks) ? style1 : style2; |
505 | + else if (s | t | XIMStatusArea) |
506 | + return (s == XIMStatusArea) ? style1 : style2; |
507 | + else if (s | t | XIMStatusNothing) |
508 | + return (s == XIMStatusNothing) ? style1 : style2; |
509 | + else if (s | t | XIMStatusNone) |
510 | + return (s == XIMStatusNone) ? style1 : style2; |
511 | + } |
512 | } |
513 | |
514 | void XICClient::SetupXIMStyle(XIM xim) |
515 | { |
516 | int i; |
517 | - XIMStyles *xim_styles = NULL; |
518 | - XIMStyle root_style = (XIMPreeditNothing|XIMStatusNothing); |
519 | - |
520 | - XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL); |
521 | - |
522 | + XIMStyles *xim_styles = nullptr; |
523 | + XIMStyle prefered_style = XIMPreeditCallbacks | XIMStatusCallbacks; |
524 | + |
525 | + XGetIMValues(xim, XNQueryInputStyle, &xim_styles, nullptr); |
526 | + |
527 | + XIMStyle best = 0, style = 0; |
528 | for (i = 0; i < xim_styles->count_styles; ++i) |
529 | - if (xim_styles->supported_styles[i] == root_style) |
530 | + { |
531 | + style = xim_styles->supported_styles[i]; |
532 | + |
533 | + if ((style & prefered_style) == style) |
534 | + { |
535 | + best = ChooseBetterStyle(style, best); |
536 | break; |
537 | + } |
538 | + else |
539 | + { |
540 | + best = ChooseBetterStyle(style, best); |
541 | + } |
542 | + } |
543 | |
544 | - if (i >= xim_styles->count_styles) |
545 | - xim_style_ = 0; |
546 | - xim_style_ = root_style; |
547 | + xim_style_ = best; |
548 | |
549 | XFree(xim_styles); |
550 | } |
551 | |
552 | bool XICClient::HasXIC() const |
553 | { |
554 | - return xic_ != NULL; |
555 | + return xic_ != nullptr; |
556 | } |
557 | |
558 | XIC XICClient::GetXIC() const |
559 | @@ -78,7 +284,7 @@ |
560 | |
561 | void XICClient::Reinitialize() |
562 | { |
563 | - xic_ = NULL; |
564 | + xic_ = nullptr; |
565 | xim_style_ = 0; |
566 | focused_ = false; |
567 | } |
568 | @@ -111,7 +317,7 @@ |
569 | if (xic_) |
570 | { |
571 | XDestroyIC(xic_); |
572 | - xic_ = NULL; |
573 | + xic_ = nullptr; |
574 | } |
575 | } |
576 | |
577 | |
578 | === renamed file 'NuxGraphics/XICClient.h' => 'Nux/XICClient.h' |
579 | --- NuxGraphics/XICClient.h 2012-11-27 19:30:57 +0000 |
580 | +++ Nux/XICClient.h 2014-01-03 16:37:28 +0000 |
581 | @@ -1,5 +1,5 @@ |
582 | /* |
583 | -* Copyright 2012 Inalogic® Inc. |
584 | +* Copyright 2012-2013 Inalogic® Inc. |
585 | * |
586 | * This program is free software: you can redistribute it and/or modify it |
587 | * under the terms of the GNU Lesser General Public License, as |
588 | @@ -27,13 +27,15 @@ |
589 | |
590 | namespace nux |
591 | { |
592 | + class TextEntry; |
593 | |
594 | class XICClient |
595 | { |
596 | public: |
597 | XICClient(); |
598 | |
599 | - void ResetXIC(XIM xim, Window window); |
600 | + void ResetXIC(XIM xim, Window window, Display* display); |
601 | + void SetCurrentTextEntry(TextEntry* text_entry_); |
602 | |
603 | bool HasXIC() const; |
604 | XIC GetXIC() const; |
605 | @@ -46,12 +48,32 @@ |
606 | |
607 | void DestroyXIC(); |
608 | private: |
609 | - void SetupXIC(XIM xim, Window window); |
610 | + void SetupXIC(XIM xim, Window window, Display* display); |
611 | void SetupXIMStyle(XIM xim); |
612 | |
613 | + XVaNestedList GetPreeditCallbacks(); |
614 | + XVaNestedList GetStatusCallbacks(); |
615 | + XIMStyle FilterXIMStyle(); |
616 | + |
617 | + static int PreeditStartCallback(XIC xic, XPointer clientdata, XPointer data); |
618 | + static int PreeditDoneCallback(XIC xic, XPointer clientdata, XPointer data); |
619 | + |
620 | + static int PreeditDrawCallback(XIC xic, XPointer clientdata, |
621 | + XIMPreeditDrawCallbackStruct* call_data); |
622 | + |
623 | + TextEntry* text_entry_; |
624 | XIC xic_; |
625 | XIMStyle xim_style_; |
626 | |
627 | + XIMCallback preedit_start_cb_; |
628 | + XIMCallback preedit_done_cb_; |
629 | + XIMCallback preedit_draw_cb_; |
630 | + XIMCallback preedit_caret_cb_; |
631 | + |
632 | + XIMCallback status_start_cb_; |
633 | + XIMCallback status_done_cb_; |
634 | + XIMCallback status_draw_cb_; |
635 | + |
636 | bool focused_; |
637 | }; |
638 | |
639 | |
640 | === added file 'Nux/XIMCallbacks.cpp' |
641 | --- Nux/XIMCallbacks.cpp 1970-01-01 00:00:00 +0000 |
642 | +++ Nux/XIMCallbacks.cpp 2014-01-03 16:37:28 +0000 |
643 | @@ -0,0 +1,189 @@ |
644 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
645 | +/* |
646 | + * Copyright 2013 Inalogic® Inc. |
647 | + * |
648 | + * This program is free software: you can redistribute it and/or modify it |
649 | + * under the terms of the GNU Lesser General Public License, as |
650 | + * published by the Free Software Foundation; either version 2.1 or 3.0 |
651 | + * of the License. |
652 | + * |
653 | + * This program is distributed in the hope that it will be useful, but |
654 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
655 | + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
656 | + * PURPOSE. See the applicable version of the GNU Lesser General Public |
657 | + * License for more details. |
658 | + * |
659 | + * You should have received a copy of both the GNU Lesser General Public |
660 | + * License along with this program. If not, see <http://www.gnu.org/licenses/> |
661 | + * |
662 | + * Authored by: Brandon Schaefer |
663 | + * |
664 | + */ |
665 | + |
666 | + |
667 | +#include "Nux.h" |
668 | +#include "TextEntry.h" |
669 | +#include "XICClient.h" |
670 | + |
671 | +#include <string> |
672 | + |
673 | +#include "NuxCore/Logger.h" |
674 | + |
675 | +DECLARE_LOGGER(logger, "xim.callbacks"); |
676 | + |
677 | +using namespace std; |
678 | + |
679 | +namespace nux |
680 | +{ |
681 | + |
682 | +int const FEEDBACK_MASK = (XIMUnderline | XIMReverse); |
683 | + |
684 | +int XICClient::PreeditStartCallback(XIC xic, |
685 | + XPointer clientdata, |
686 | + XPointer call_data) |
687 | +{ |
688 | + TextEntry* text_entry = (TextEntry*)clientdata; |
689 | + if (text_entry) |
690 | + { |
691 | + text_entry->PreeditStarted(); |
692 | + } |
693 | + |
694 | + return 0; |
695 | +} |
696 | + |
697 | +int XICClient::PreeditDoneCallback(XIC xic, |
698 | + XPointer clientdata, |
699 | + XPointer call_data) |
700 | +{ |
701 | + TextEntry* text_entry = (TextEntry*)clientdata; |
702 | + if (text_entry) |
703 | + { |
704 | + text_entry->ClearPreedit(); |
705 | + } |
706 | + |
707 | + return 0; |
708 | +} |
709 | + |
710 | +void add_feedback_attr(PangoAttrList* attrs, |
711 | + char const* str, |
712 | + XIMFeedback feedback, |
713 | + int start, |
714 | + int end) |
715 | +{ |
716 | + PangoAttribute* attr; |
717 | + |
718 | + int start_index = g_utf8_offset_to_pointer(str, start) - str; |
719 | + int end_index = g_utf8_offset_to_pointer(str, end) - str; |
720 | + |
721 | + if (feedback & XIMUnderline) |
722 | + { |
723 | + attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); |
724 | + attr->start_index = start_index; |
725 | + attr->end_index = end_index; |
726 | + |
727 | + pango_attr_list_insert (attrs, attr); |
728 | + } |
729 | + |
730 | + if (feedback & XIMReverse) |
731 | + { |
732 | + attr = pango_attr_foreground_new(0xFFFF, 0xFFFF, 0xFFFF); |
733 | + attr->start_index = start_index; |
734 | + attr->end_index = end_index; |
735 | + |
736 | + pango_attr_list_insert (attrs, attr); |
737 | + |
738 | + attr = pango_attr_background_new(0x0, 0x0, 0x0); |
739 | + |
740 | + attr->start_index = start_index; |
741 | + attr->end_index = end_index; |
742 | + |
743 | + pango_attr_list_insert (attrs, attr); |
744 | + } |
745 | + |
746 | + if (feedback & ~FEEDBACK_MASK) |
747 | + { |
748 | + LOG_WARN(logger) << "Unrenderer feedback: " << (feedback & ~FEEDBACK_MASK); |
749 | + } |
750 | +} |
751 | + |
752 | +void feedback_to_pango_list(PangoAttrList** attrs, |
753 | + char const* str, |
754 | + int nfeedbacks, |
755 | + XIMFeedback* feedbacks) |
756 | +{ |
757 | + XIMFeedback last_feedback = 0; |
758 | + int start = -1; |
759 | + int i = 0; |
760 | + |
761 | + if (attrs) |
762 | + { |
763 | + *attrs = pango_attr_list_new(); |
764 | + |
765 | + for (i = 0; i < nfeedbacks; ++i) |
766 | + { |
767 | + XIMFeedback new_feedback = (feedbacks[i] & FEEDBACK_MASK); |
768 | + if (new_feedback != last_feedback) |
769 | + { |
770 | + last_feedback = new_feedback; |
771 | + start = i; |
772 | + } |
773 | + else |
774 | + { |
775 | + PangoAttribute* attr; |
776 | + |
777 | + int start_index = g_utf8_offset_to_pointer(str, start) - str; |
778 | + int end_index = g_utf8_offset_to_pointer(str, i) - str; |
779 | + |
780 | + attr = pango_attr_foreground_new(0x0, 0x0, 0x0); |
781 | + attr->start_index = start_index; |
782 | + attr->end_index = end_index; |
783 | + |
784 | + pango_attr_list_insert (*attrs, attr); |
785 | + |
786 | + attr = pango_attr_background_new(0xFFFF, 0xFFFF, 0xFFFF); |
787 | + |
788 | + attr->start_index = start_index; |
789 | + attr->end_index = end_index; |
790 | + |
791 | + pango_attr_list_insert (*attrs, attr); |
792 | + } |
793 | + } |
794 | + |
795 | + if (start >= 0) |
796 | + add_feedback_attr(*attrs, str, last_feedback, start, i); |
797 | + } |
798 | +} |
799 | + |
800 | +int XICClient::PreeditDrawCallback(XIC xic, |
801 | + XPointer clientdata, |
802 | + XIMPreeditDrawCallbackStruct* call_data) |
803 | +{ |
804 | + TextEntry* text_entry = (TextEntry*)clientdata; |
805 | + |
806 | + if (call_data->text && text_entry) |
807 | + { |
808 | + string preedit; |
809 | + |
810 | + // TODO Actually handle this correctly... |
811 | + if (call_data->text->encoding_is_wchar) |
812 | + { |
813 | + preedit = string(""); |
814 | + } |
815 | + else |
816 | + { |
817 | + preedit = string(call_data->text->string.multi_byte); |
818 | + } |
819 | + |
820 | + PangoAttrList* preedit_attr; |
821 | + feedback_to_pango_list(&preedit_attr, preedit.c_str(), |
822 | + call_data->text->length, |
823 | + call_data->text->feedback); |
824 | + |
825 | + text_entry->UpdatePreeditAttribs(preedit_attr); |
826 | + text_entry->UpdatePreedit(preedit, call_data->caret); |
827 | + } |
828 | + |
829 | + return 0; |
830 | +} |
831 | + |
832 | +} |
833 | |
834 | === renamed file 'NuxGraphics/XIMController.cpp' => 'Nux/XIMController.cpp' |
835 | --- NuxGraphics/XIMController.cpp 2013-10-10 23:36:28 +0000 |
836 | +++ Nux/XIMController.cpp 2014-01-03 16:37:28 +0000 |
837 | @@ -1,5 +1,5 @@ |
838 | /* |
839 | -* Copyright 2012 Inalogic® Inc. |
840 | +* Copyright 2012-2013 Inalogic® Inc. |
841 | * |
842 | * This program is free software: you can redistribute it and/or modify it |
843 | * under the terms of the GNU Lesser General Public License, as |
844 | @@ -32,7 +32,7 @@ |
845 | XIMController::XIMController(Display* display) |
846 | : display_(display) |
847 | , window_(0) |
848 | - , xim_(NULL) |
849 | + , xim_(nullptr) |
850 | { |
851 | InitXIMCallback(); |
852 | } |
853 | @@ -51,7 +51,15 @@ |
854 | window_ = window; |
855 | |
856 | if (xim_) |
857 | - xic_client_.ResetXIC(xim_, window); |
858 | + xic_client_.ResetXIC(xim_, window, display_); |
859 | +} |
860 | + |
861 | +void XIMController::SetCurrentTextEntry(TextEntry* text_entry) |
862 | +{ |
863 | + xic_client_.SetCurrentTextEntry(text_entry); |
864 | + |
865 | + if (xim_) |
866 | + xic_client_.ResetXIC(xim_, window_, display_); |
867 | } |
868 | |
869 | void XIMController::RemoveFocusedWindow() |
870 | @@ -78,7 +86,7 @@ |
871 | void XIMController::FocusOutXIC() |
872 | { |
873 | xic_client_.FocusOutXIC(); |
874 | - xic_client_.DestroyXIC(); |
875 | + xic_client_.SetCurrentTextEntry(nullptr); |
876 | } |
877 | |
878 | Window XIMController::GetCurrentWindow() const |
879 | @@ -131,12 +139,13 @@ |
880 | void XIMController::SetupXIM() |
881 | { |
882 | xim_ = XOpenIM(display_, NULL, NULL, NULL); |
883 | + |
884 | if (xim_) |
885 | { |
886 | SetupXIMDestroyedCallback(); |
887 | |
888 | if (window_) |
889 | - xic_client_.ResetXIC(xim_, window_); |
890 | + xic_client_.ResetXIC(xim_, window_, display_); |
891 | |
892 | XUnregisterIMInstantiateCallback (display_, NULL, NULL, NULL, |
893 | XIMController::SetupXIMClientCallback, |
894 | |
895 | === renamed file 'NuxGraphics/XIMController.h' => 'Nux/XIMController.h' |
896 | --- NuxGraphics/XIMController.h 2013-10-10 23:36:28 +0000 |
897 | +++ Nux/XIMController.h 2014-01-03 16:37:28 +0000 |
898 | @@ -1,5 +1,5 @@ |
899 | /* |
900 | -* Copyright 2012 Inalogic® Inc. |
901 | +* Copyright 2012-2013 Inalogic® Inc. |
902 | * |
903 | * This program is free software: you can redistribute it and/or modify it |
904 | * under the terms of the GNU Lesser General Public License, as |
905 | @@ -29,6 +29,7 @@ |
906 | |
907 | namespace nux |
908 | { |
909 | + class TextEntry; |
910 | |
911 | class XIMController |
912 | { |
913 | @@ -37,6 +38,7 @@ |
914 | ~XIMController(); |
915 | |
916 | void SetFocusedWindow(Window window); |
917 | + void SetCurrentTextEntry(TextEntry* text_entry_); |
918 | void RemoveFocusedWindow(); |
919 | |
920 | bool IsXICValid() const; |
921 | |
922 | === modified file 'NuxGraphics/GraphicsDisplayX11.cpp' |
923 | --- NuxGraphics/GraphicsDisplayX11.cpp 2013-10-11 13:07:50 +0000 |
924 | +++ NuxGraphics/GraphicsDisplayX11.cpp 2014-01-03 16:37:28 +0000 |
925 | @@ -108,6 +108,7 @@ |
926 | , m_X11Screen(0) |
927 | , m_X11Window(0) |
928 | , m_X11VisualInfo(NULL) |
929 | + , m_current_xic(NULL) |
930 | , parent_window_(0) |
931 | , m_GLCtx(NULL) |
932 | #ifndef NUX_OPENGLES_20 |
933 | @@ -172,9 +173,6 @@ |
934 | NUX_SAFE_DELETE( m_GraphicsContext ); |
935 | NUX_SAFE_DELETE( m_DeviceFactory ); |
936 | |
937 | - // The XIM Controller needs to clean up before ~GraphicsDisplayX11 |
938 | - m_xim_controller.reset(); |
939 | - |
940 | if (m_CreatedFromForeignWindow == false) |
941 | { |
942 | DestroyOpenGLWindow(); |
943 | @@ -258,16 +256,6 @@ |
944 | } |
945 | #endif |
946 | |
947 | - void GraphicsDisplay::XICFocus() |
948 | - { |
949 | - m_xim_controller->FocusInXIC(); |
950 | - } |
951 | - |
952 | - void GraphicsDisplay::XICUnFocus() |
953 | - { |
954 | - m_xim_controller->FocusOutXIC(); |
955 | - } |
956 | - |
957 | // TODO: change windowWidth, windowHeight, to window_size; |
958 | static NCriticalSection CreateOpenGLWindow_CriticalSection; |
959 | bool GraphicsDisplay::CreateOpenGLWindow(const char* window_title, |
960 | @@ -659,16 +647,6 @@ |
961 | //XMapRaised(m_X11Display, m_X11Window); |
962 | } |
963 | |
964 | - m_xim_controller = std::make_shared<XIMController>(m_X11Display); |
965 | - m_xim_controller->SetFocusedWindow(m_X11Window); |
966 | - |
967 | - if (m_xim_controller->IsXICValid()) |
968 | - { |
969 | - long im_event_mask=0; |
970 | - XGetICValues(m_xim_controller->GetXIC(), XNFilterEvents, &im_event_mask, NULL); |
971 | - m_X11Attr.event_mask |= im_event_mask; |
972 | - } |
973 | - |
974 | #ifndef NUX_OPENGLES_20 |
975 | if (_has_glx_13) |
976 | { |
977 | @@ -778,8 +756,6 @@ |
978 | |
979 | gfx_interface_created_ = true; |
980 | |
981 | - m_xim_controller = std::make_shared<XIMController>(m_X11Display); |
982 | - |
983 | // m_DeviceFactory = new GpuDevice(viewport_size_.GetWidth(), viewport_size_.GetHeight(), BITFMT_R8G8B8A8); |
984 | m_DeviceFactory = new GpuDevice(viewport_size_.width, viewport_size_.height, BITFMT_R8G8B8A8, |
985 | m_X11Display, |
986 | @@ -811,14 +787,9 @@ |
987 | return m_DeviceFactory; |
988 | } |
989 | |
990 | - void GraphicsDisplay::SetFocusedWindowForXIMController(Window window) |
991 | - { |
992 | - m_xim_controller->SetFocusedWindow(window); |
993 | - } |
994 | - |
995 | - void GraphicsDisplay::RemoveFocusedWindowForXIMController() |
996 | - { |
997 | - m_xim_controller->RemoveFocusedWindow(); |
998 | + void GraphicsDisplay::SetCurrentXIC(XIC xic) |
999 | + { |
1000 | + m_current_xic = xic; |
1001 | } |
1002 | |
1003 | int GraphicsDisplay::GetGlXMajor() const |
1004 | @@ -1359,14 +1330,10 @@ |
1005 | bool bProcessEvent = true; |
1006 | XNextEvent(m_X11Display, &xevent); |
1007 | |
1008 | - if ((xevent.type == KeyPress || xevent.type == KeyRelease) && |
1009 | - m_xim_controller->GetCurrentWindow() != xevent.xkey.window) |
1010 | - { |
1011 | - m_xim_controller->SetFocusedWindow(xevent.xkey.window); |
1012 | - } |
1013 | - |
1014 | if (XFilterEvent(&xevent, None) == True) |
1015 | + { |
1016 | return true; |
1017 | + } |
1018 | |
1019 | if (!_event_filters.empty()) |
1020 | { |
1021 | @@ -1687,7 +1654,6 @@ |
1022 | m_pEvent->virtual_code = 0; |
1023 | //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: FocusIn event."); |
1024 | |
1025 | - m_xim_controller->FocusInXIC(); |
1026 | break; |
1027 | } |
1028 | |
1029 | @@ -1704,7 +1670,6 @@ |
1030 | m_pEvent->virtual_code = 0; |
1031 | //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: FocusOut event."); |
1032 | |
1033 | - m_xim_controller->FocusOutXIC(); |
1034 | break; |
1035 | } |
1036 | |
1037 | @@ -1731,20 +1696,20 @@ |
1038 | (keysym == NUX_VK_ESCAPE)) |
1039 | { |
1040 | //temporary fix for TextEntry widget: filter some keys |
1041 | - skip = true; |
1042 | + skip = true; |
1043 | } |
1044 | |
1045 | if (!skip) |
1046 | { |
1047 | int num_char_stored = 0; |
1048 | |
1049 | - if (m_xim_controller->IsXICValid()) |
1050 | + if (m_current_xic) |
1051 | { |
1052 | delete[] m_pEvent->dtext; |
1053 | m_pEvent->dtext = nullptr; |
1054 | Status status; |
1055 | |
1056 | - num_char_stored = XmbLookupString(m_xim_controller->GetXIC(), &xevent.xkey, nullptr, |
1057 | + num_char_stored = XmbLookupString(m_current_xic, &xevent.xkey, nullptr, |
1058 | 0, (KeySym*) &m_pEvent->x11_keysym, &status); |
1059 | |
1060 | if (status == XLookupKeySym) |
1061 | @@ -1755,7 +1720,7 @@ |
1062 | { |
1063 | int buf_len = num_char_stored + 1; |
1064 | m_pEvent->dtext = new char[buf_len]; |
1065 | - num_char_stored = XmbLookupString(m_xim_controller->GetXIC(), &xevent.xkey, m_pEvent->dtext, |
1066 | + num_char_stored = XmbLookupString(m_current_xic, &xevent.xkey, m_pEvent->dtext, |
1067 | buf_len, (KeySym*) &m_pEvent->x11_keysym, nullptr); |
1068 | |
1069 | m_pEvent->dtext[num_char_stored] = 0; |
1070 | |
1071 | === modified file 'NuxGraphics/GraphicsDisplayX11.h' |
1072 | --- NuxGraphics/GraphicsDisplayX11.h 2012-12-17 19:04:50 +0000 |
1073 | +++ NuxGraphics/GraphicsDisplayX11.h 2014-01-03 16:37:28 +0000 |
1074 | @@ -27,7 +27,6 @@ |
1075 | #include "GLTimer.h" |
1076 | #include "GLDeviceObjects.h" |
1077 | #include "GLRenderStates.h" |
1078 | -#include "XIMController.h" |
1079 | |
1080 | /* Xlib.h is the default header that is included and has the core functionallity */ |
1081 | #include <X11/Xlib.h> |
1082 | @@ -85,7 +84,7 @@ |
1083 | Window m_X11Window; |
1084 | XVisualInfo *m_X11VisualInfo; |
1085 | |
1086 | - std::shared_ptr<XIMController> m_xim_controller; |
1087 | + XIC m_current_xic; |
1088 | |
1089 | int parent_window_; |
1090 | #ifndef NUX_OPENGLES_20 |
1091 | @@ -286,8 +285,7 @@ |
1092 | |
1093 | GpuDevice* GetGpuDevice() const; |
1094 | |
1095 | - void SetFocusedWindowForXIMController(Window window); |
1096 | - void RemoveFocusedWindowForXIMController(); |
1097 | + void SetCurrentXIC(XIC xic); |
1098 | |
1099 | // Dialog |
1100 | /*bool StartOpenFileDialog(FileDialogOption& fdo); |
1101 | @@ -348,8 +346,6 @@ |
1102 | |
1103 | void * KeyboardGrabData() { return _global_keyboard_grab_data; } |
1104 | void * PointerGrabData() { return _global_pointer_grab_data; } |
1105 | - void XICFocus(); |
1106 | - void XICUnFocus(); |
1107 | |
1108 | private: |
1109 | void InitGlobalGrabWindow(); |
1110 | |
1111 | === modified file 'NuxGraphics/Makefile.am' |
1112 | --- NuxGraphics/Makefile.am 2012-12-05 19:22:13 +0000 |
1113 | +++ NuxGraphics/Makefile.am 2014-01-03 16:37:28 +0000 |
1114 | @@ -93,9 +93,7 @@ |
1115 | source_h += \ |
1116 | $(srcdir)/GraphicsDisplayX11.h \ |
1117 | $(srcdir)/VirtualKeyCodesX11.h \ |
1118 | - $(srcdir)/XInputWindow.h \ |
1119 | - $(srcdir)/XICClient.h \ |
1120 | - $(srcdir)/XIMController.h |
1121 | + $(srcdir)/XInputWindow.h |
1122 | endif |
1123 | |
1124 | if !NUX_OPENGLES_20 |
1125 | @@ -170,9 +168,7 @@ |
1126 | if USE_X11 |
1127 | source_cpp += \ |
1128 | $(srcdir)/GraphicsDisplayX11.cpp \ |
1129 | - $(srcdir)/XInputWindow.cpp \ |
1130 | - $(srcdir)/XICClient.cpp \ |
1131 | - $(srcdir)/XIMController.cpp |
1132 | + $(srcdir)/XInputWindow.cpp |
1133 | endif |
1134 | |
1135 | if !NUX_OPENGLES_20 |
1136 | |
1137 | === modified file 'NuxGraphics/XInputWindow.cpp' |
1138 | --- NuxGraphics/XInputWindow.cpp 2013-07-18 23:07:45 +0000 |
1139 | +++ NuxGraphics/XInputWindow.cpp 2014-01-03 16:37:28 +0000 |
1140 | @@ -22,7 +22,6 @@ |
1141 | #include "XInputWindow.h" |
1142 | #include "GraphicsDisplayX11.h" |
1143 | #include "GLThread.h" |
1144 | -#include "XIMController.h" |
1145 | |
1146 | namespace nux |
1147 | { |
1148 | @@ -396,8 +395,6 @@ |
1149 | |
1150 | void XInputWindow::Hide() |
1151 | { |
1152 | - GetGraphicsDisplay()->RemoveFocusedWindowForXIMController(); |
1153 | - |
1154 | XMoveResizeWindow(display_, window_, |
1155 | -100 - geometry_.width, |
1156 | -100 - geometry_.height, |
1157 | @@ -408,8 +405,6 @@ |
1158 | |
1159 | void XInputWindow::Show() |
1160 | { |
1161 | - GetGraphicsDisplay()->SetFocusedWindowForXIMController(window_); |
1162 | - |
1163 | shown_ = true; |
1164 | if (!mapped_) |
1165 | { |
1166 | |
1167 | === modified file 'configure.ac' |
1168 | --- configure.ac 2013-10-29 22:13:58 +0000 |
1169 | +++ configure.ac 2014-01-03 16:37:28 +0000 |
1170 | @@ -15,7 +15,7 @@ |
1171 | # |
1172 | m4_define([nux_major_version], [4]) |
1173 | m4_define([nux_minor_version], [0]) |
1174 | -m4_define([nux_micro_version], [4]) |
1175 | +m4_define([nux_micro_version], [5]) |
1176 | |
1177 | m4_define([nux_api_version], [4.0]) |
1178 | # Increase the number (to the current date) everytime you propose a branch that breaks the API or ABI |
1179 | @@ -23,7 +23,7 @@ |
1180 | # e.g.: december 5th, 2011 is: 20111205 |
1181 | # To make more than one API change in a day, add a number to the date. Like 20111205.xx |
1182 | |
1183 | -m4_define([nux_abi_version], [20131029.0]) |
1184 | +m4_define([nux_abi_version], [20131203.0]) |
1185 | m4_define([nux_version], |
1186 | [nux_major_version.nux_minor_version.nux_micro_version]) |
1187 | |
1188 | |
1189 | === modified file 'debian/changelog' |
1190 | --- debian/changelog 2013-10-29 22:13:58 +0000 |
1191 | +++ debian/changelog 2014-01-03 16:37:28 +0000 |
1192 | @@ -1,3 +1,11 @@ |
1193 | +nux (4.0.5-0ubuntu1) UNRELEASED; urgency=low |
1194 | + |
1195 | + [ Brandon Schaefer ] |
1196 | + * Add XIM preedit support |
1197 | + * Bump version to 4.0.5 |
1198 | + |
1199 | + -- Brandon Schaefer <brandon.schaefer@canonical.com> Fri, 03 Jan 2014 08:31:35 -0800 |
1200 | + |
1201 | nux (4.0.4-0ubuntu1) UNRELEASED; urgency=low |
1202 | |
1203 | [ Sam Spilsbury ] |
FAILED: Continuous integration, rev:834 /code.launchpad .net/~brandonts chaefer/ nux/xim- preedit- support/ +merge/ 199569/ +edit-commit- message
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http:// jenkins. qa.ubuntu. com/job/ nux-ci/ 97/ jenkins. qa.ubuntu. com/job/ nux-trusty- amd64-ci/ 19/console jenkins. qa.ubuntu. com/job/ nux-trusty- armhf-ci/ 19 jenkins. qa.ubuntu. com/job/ nux-trusty- i386-ci/ 19/console
Executed test runs:
FAILURE: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/nux- ci/97/rebuild
http://