22
22
#include "XICClient.h"
24
#include "NuxCore/Logger.h"
26
DECLARE_LOGGER(logger, "xic.client");
33
int const FEEDBACK_MASK = (XIMUnderline | XIMReverse);
27
35
XICClient::XICClient()
34
void XICClient::ResetXIC(XIM xim, Window window)
42
void XICClient::ResetXIC(XIM xim, Window window, Display* display)
37
45
SetupXIMStyle(xim);
39
SetupXIC(xim, window);
42
void XICClient::SetupXIC(XIM xim, Window window)
47
SetupXIC(xim, window, display);
50
void XICClient::SetCurrentTextEntry(TextEntry* text_entry)
52
text_entry_ = text_entry;
55
static int preedit_caret_callback(XIC xic,
57
XIMPreeditCaretCallbackStruct* call_data)
62
static int status_start_callback(XIC xic,
64
XIMPreeditDrawCallbackStruct* call_data)
69
static void status_draw_callback(XIC xic,
75
static void status_done_callback(XIC xic,
81
XVaNestedList XICClient::GetPreeditCallbacks()
83
preedit_start_cb_.callback = (XIMProc)XICClient::PreeditStartCallback;
84
preedit_start_cb_.client_data = nullptr;
86
preedit_done_cb_.callback = (XIMProc)XICClient::PreeditDoneCallback;
87
preedit_done_cb_.client_data = (XPointer)text_entry_;
89
preedit_draw_cb_.callback = (XIMProc)XICClient::PreeditDrawCallback;
90
preedit_draw_cb_.client_data = (XPointer)text_entry_;
92
preedit_caret_cb_.callback = (XIMProc)preedit_caret_callback;
93
preedit_caret_cb_.client_data = nullptr;
95
XVaNestedList p_list = nullptr;
96
p_list = XVaCreateNestedList(0,
97
XNPreeditStartCallback, &preedit_start_cb_,
98
XNPreeditDoneCallback, &preedit_done_cb_,
99
XNPreeditDrawCallback, &preedit_draw_cb_,
100
XNPreeditCaretCallback, &preedit_caret_cb_,
106
XVaNestedList XICClient::GetStatusCallbacks()
108
status_start_cb_.callback = (XIMProc)status_start_callback;
109
status_start_cb_.client_data = nullptr;
111
status_done_cb_.callback = (XIMProc)status_done_callback;
112
status_done_cb_.client_data = nullptr;
114
status_draw_cb_.callback = (XIMProc)status_draw_callback;
115
status_draw_cb_.client_data = nullptr;
117
XVaNestedList s_list = nullptr;
118
s_list = XVaCreateNestedList(0,
119
XNStatusStartCallback, &status_start_callback,
120
XNStatusDoneCallback, &status_done_callback,
121
XNStatusDrawCallback, &status_draw_callback,
127
XIMStyle XICClient::FilterXIMStyle()
131
if (xim_style_ & XIMPreeditCallbacks)
133
style |= XIMPreeditCallbacks;
135
else if (xim_style_ & XIMPreeditNone)
137
style |= XIMPreeditNone;
141
style |= XIMPreeditNothing;
144
if (xim_style_ & XIMStatusCallbacks)
146
style |= XIMStatusCallbacks;
148
else if (xim_style_ & XIMStatusNone)
150
style |= XIMStatusNone;
154
style |= XIMStatusNothing;
160
void XICClient::SetupXIC(XIM xim, Window window, Display* display)
47
xic_ = XCreateIC(xim, XNInputStyle, xim_style_, XNClientWindow, window, XNFocusWindow, window, NULL);
165
XIMStyle style = FilterXIMStyle();
167
const char* p_name = nullptr;
168
XVaNestedList p_list = nullptr;
169
if (style & XIMPreeditCallbacks)
171
p_list = GetPreeditCallbacks();
172
p_name = XNPreeditAttributes;
175
const char* s_name = nullptr;
176
XVaNestedList s_list = nullptr;
177
if (style & XIMStatusCallbacks)
179
s_list = GetStatusCallbacks();
180
s_name = XNStatusAttributes;
183
xic_ = XCreateIC(xim, XNInputStyle, style,
184
XNClientWindow, window,
197
XIMStyle ChooseBetterStyle(XIMStyle style1, XIMStyle style2)
200
XIMStyle preedit = XIMPreeditArea | XIMPreeditCallbacks |
201
XIMPreeditPosition | XIMPreeditNothing | XIMPreeditNone;
203
XIMStyle status = XIMStatusArea | XIMStatusCallbacks |
204
XIMStatusNothing | XIMStatusNone;
212
if ((style1 & (preedit | status)) == (style2 & (preedit | status)))
215
s = style1 & preedit;
216
t = style2 & preedit;
219
if (s | t | XIMPreeditCallbacks)
220
return (s == XIMPreeditCallbacks) ? style1 : style2;
221
else if (s | t | XIMPreeditPosition)
222
return (s == XIMPreeditPosition) ? style1 : style2;
223
else if (s | t | XIMPreeditArea)
224
return (s == XIMPreeditArea) ? style1 : style2;
225
else if (s | t | XIMPreeditNothing)
226
return (s == XIMPreeditNothing) ? style1 : style2;
227
else if (s | t | XIMPreeditNone)
228
return (s == XIMPreeditNone) ? style1 : style2;
235
if (s | t | XIMStatusCallbacks)
236
return (s == XIMStatusCallbacks) ? style1 : style2;
237
else if (s | t | XIMStatusArea)
238
return (s == XIMStatusArea) ? style1 : style2;
239
else if (s | t | XIMStatusNothing)
240
return (s == XIMStatusNothing) ? style1 : style2;
241
else if (s | t | XIMStatusNone)
242
return (s == XIMStatusNone) ? style1 : style2;
50
246
void XICClient::SetupXIMStyle(XIM xim)
53
XIMStyles *xim_styles = NULL;
54
XIMStyle root_style = (XIMPreeditNothing|XIMStatusNothing);
56
XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL);
249
XIMStyles *xim_styles = nullptr;
250
XIMStyle prefered_style = XIMPreeditCallbacks | XIMStatusCallbacks;
252
XGetIMValues(xim, XNQueryInputStyle, &xim_styles, nullptr);
254
XIMStyle best = 0, style = 0;
58
255
for (i = 0; i < xim_styles->count_styles; ++i)
59
if (xim_styles->supported_styles[i] == root_style)
257
style = xim_styles->supported_styles[i];
259
if ((style & prefered_style) == style)
261
best = ChooseBetterStyle(style, best);
266
best = ChooseBetterStyle(style, best);
62
if (i >= xim_styles->count_styles)
64
xim_style_ = root_style;
66
272
XFree(xim_styles);
69
275
bool XICClient::HasXIC() const
277
return xic_ != nullptr;
74
280
XIC XICClient::GetXIC() const