1 /*
2  * SPDX-FileCopyrightText: 2014 Weng Xuetian <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-only
5  *
6  */
7 #ifndef _XCB_IMDKIT_IMDKIT_H_
8 #define _XCB_IMDKIT_IMDKIT_H_
9 
10 #include "ximcommon.h"
11 #include "ximproto.h"
12 #include <stdbool.h>
13 #include <stdint.h>
14 #include <xcb/xcb.h>
15 #include <xcb/xproto.h>
16 
17 XCBIMDKIT_DECL_BEGIN
18 
19 /*
20  * `C' and `no' are additional one which cannot be obtained from modern
21  * locale.gen. `no' is obsolete, but we keep it here for compatible reason.
22  */
23 #define XCB_IM_ALL_LOCALES                                                     \
24     "aa,af,am,an,ar,as,ast,az,be,bem,ber,bg,bho,bn,bo,br,brx,bs,byn,"          \
25     "C,ca,crh,cs,csb,cv,cy,da,de,dv,dz,el,en,es,et,eu,fa,ff,fi,fil,fo,"        \
26     "fr,fur,fy,ga,gd,gez,gl,gu,gv,ha,he,hi,hne,hr,hsb,ht,hu,hy,id,ig,"         \
27     "ik,is,it,iu,iw,ja,ka,kk,kl,km,kn,ko,kok,ks,ku,kw,ky,lb,lg,li,lij,"        \
28     "lo,lt,lv,mag,mai,mg,mhr,mi,mk,ml,mn,mr,ms,mt,my,nan,nb,nds,ne,nl,"        \
29     "nn,no,nr,nso,oc,om,or,os,pa,pap,pl,ps,pt,ro,ru,rw,sa,sc,sd,se,shs,"       \
30     "si,sid,sk,sl,so,sq,sr,ss,st,sv,sw,ta,te,tg,th,ti,tig,tk,tl,tn,tr,"        \
31     "ts,tt,ug,uk,unm,ur,uz,ve,vi,wa,wae,wal,wo,xh,yi,yo,yue,zh,zu"
32 
33 typedef struct _xcb_im_styles_t {
34     uint32_t nStyles;
35     uint32_t *styles;
36 } xcb_im_styles_t;
37 
38 typedef char *xcb_im_encoding_t;
39 
40 typedef struct _xcb_im_encodings_t {
41     unsigned short nEncodings;
42     xcb_im_encoding_t *encodings;
43 } xcb_im_encodings_t;
44 
45 typedef struct _xcb_im_t xcb_im_t;
46 typedef struct _xcb_im_input_context_t xcb_im_input_context_t;
47 typedef struct _xcb_im_client_t xcb_im_client_t;
48 
49 // Mask to check if the attribute is set.
50 typedef enum _xcb_im_attr_mask_t {
51     XCB_XIM_XNArea_MASK = (1 << 0),
52     XCB_XIM_XNAreaNeeded_MASK = (1 << 1),
53     XCB_XIM_XNSpotLocation_MASK = (1 << 2),
54     XCB_XIM_XNColormap_MASK = (1 << 3),
55     XCB_XIM_XNForeground_MASK = (1 << 4),
56     XCB_XIM_XNBackground_MASK = (1 << 5),
57     XCB_XIM_XNBackgroundPixmap_MASK = (1 << 7),
58     XCB_XIM_XNLineSpace_MASK = (1 << 8),
59 } xcb_im_attr_mask_t;
60 
61 typedef struct _xcb_im_preedit_attr_t {
62     xcb_rectangle_t area;
63     xcb_rectangle_t area_needed;
64     xcb_point_t spot_location;
65     xcb_colormap_t colormap;
66     uint32_t foreground;
67     uint32_t background;
68     xcb_window_t bg_pixmap;
69     uint32_t line_space;
70 } xcb_im_preedit_attr_t;
71 
72 typedef struct _xcb_im_status_attr_t {
73     xcb_rectangle_t area;
74     xcb_rectangle_t area_needed;
75     xcb_point_t spot_location;
76     xcb_colormap_t colormap;
77     uint32_t foreground;
78     uint32_t background;
79     xcb_window_t bg_pixmap;
80     uint32_t line_space;
81 } xcb_im_status_attr_t;
82 
83 typedef void (*xcb_im_callback)(xcb_im_t *im, xcb_im_client_t *client,
84                                 xcb_im_input_context_t *ic,
85                                 const xcb_im_packet_header_fr_t *hdr,
86                                 void *frame, void *arg, void *user_data);
87 
88 typedef void (*xcb_im_free_function)(void *memory);
89 
90 /**
91  * Create a XIM server.
92  *
93  * @param conn xcb connection to be used.
94  * @param screen xcb screen to be used.
95  * @param serverWindow A server window.
96  * @param serverName server name, need to be consistent with XMODIFIERS
97  * @param locale locale supported. You may want to use XCB_IM_ALL_LOCALES.
98  * @param inputStyles XIM Styles supported by XIM server.
99  * @param onKeysList Trigger on key to send to client.
100  * @param offKeysList Trigger off key to send to cilent.
101  * @param encodingList XIM encoding list.
102  * @param event_mask if 0, XCB_EVENT_MASK_KEY_PRESS will be used.
103  * @param callback Callback function
104  * @param user_data user data to callback function.
105  * @return xcb_im_t*
106  */
107 XCBIMDKIT_EXPORT xcb_im_t *
108 xcb_im_create(xcb_connection_t *conn, int screen, xcb_window_t serverWindow,
109               const char *serverName, const char *locale,
110               const xcb_im_styles_t *inputStyles,
111               const xcb_im_trigger_keys_t *onKeysList,
112               const xcb_im_trigger_keys_t *offKeysList,
113               const xcb_im_encodings_t *encodingList, uint32_t event_mask,
114               xcb_im_callback callback, void *user_data);
115 
116 /**
117  * @brief Set a logger handler.
118  *
119  * @param im XIM server.
120  * @param logger logger function.
121  */
122 XCBIMDKIT_EXPORT void xcb_im_set_log_handler(xcb_im_t *im,
123                                              void (*logger)(const char *, ...));
124 
125 /**
126  * Whether to use sync mode, it will affect certain behavior of XIM.
127  *
128  * Forward event and commit string behavior will be changed. If sync mode is
129  * true, every request need to be replied with sync_reply. The library is still
130  * working under async mode, just no more request will be send to client.
131  *
132  * @param im XIM server
133  * @param sync sync mode or not.
134  */
135 XCBIMDKIT_EXPORT void xcb_im_set_use_sync_mode(xcb_im_t *im, bool sync);
136 
137 /**
138  * Set whether the event defined by event mask is handled in a synchronous way.
139  *
140  * @param im XIM server
141  * @param sync sync on event or not.
142  */
143 XCBIMDKIT_EXPORT void xcb_im_set_use_sync_event(xcb_im_t *im, bool sync);
144 
145 /**
146  * Start a XIM server synchronously.
147  *
148  * It only does the minimum initialization and try to grab the server name. When
149  * it fails, it means there might be another server with the same name running.
150  *
151  * To finish the initialization, you will need to use xcb_im_filter_event on all
152  * the event recevied.
153  *
154  * You may also call this function again if it fails or after xcb_im_close_im.
155  *
156  * @param im XIM server.
157  * @return whether XIM server is started successfully.
158  */
159 XCBIMDKIT_EXPORT bool xcb_im_open_im(xcb_im_t *im);
160 
161 /**
162  * Handle XIM related event, most relevant event will be client message.
163  *
164  * @param im XIM server
165  * @param event X event.
166  * @return Whether the event is handled by XIM.
167  */
168 XCBIMDKIT_EXPORT bool xcb_im_filter_event(xcb_im_t *im,
169                                           xcb_generic_event_t *event);
170 
171 /**
172  * Shutdown the XIM server and free all the resources.
173  *
174  * @param im XIM server
175  *
176  * @see xcb_im_open_im
177  */
178 XCBIMDKIT_EXPORT void xcb_im_close_im(xcb_im_t *im);
179 /**
180  * Destroy the XIM server.
181  *
182  * xcb_im_close_im need to be called if it is opened successfully.
183  *
184  * @param im XIM server.
185  */
186 XCBIMDKIT_EXPORT void xcb_im_destroy(xcb_im_t *im);
187 
188 /**
189  * Send a key event to the client.
190  *
191  * @param im XIM server
192  * @param ic Input context.
193  * @param event key event.
194  */
195 XCBIMDKIT_EXPORT void xcb_im_forward_event(xcb_im_t *im,
196                                            xcb_im_input_context_t *ic,
197                                            xcb_key_press_event_t *event);
198 
199 /**
200  * Commit a string to the client.
201  *
202  * @param im XIM server
203  * @param ic Input Context
204  * @param flag a bit flag of xcb_xim_lookup_flags_t, XCB_XIM_LOOKUP_CHARS is the
205  * most common value to be used.
206  * @param str string to be committed, encoding is usually COMPOUND_TEXT.
207  * @param length byte length of the string
208  * @param keysym key symbol.
209  *
210  * @see xcb_xim_lookup_flags_t
211  * @see xcb_utf8_to_compound_text
212  */
213 XCBIMDKIT_EXPORT void xcb_im_commit_string(xcb_im_t *im,
214                                            xcb_im_input_context_t *ic,
215                                            uint32_t flag, const char *str,
216                                            uint32_t length, uint32_t keysym);
217 
218 /**
219  * Start geometry negotiation, if XIMStyle has XIMPreeditArea or XIMStatusArea
220  * set.
221  *
222  * This is rarely used nowadays. Xlib doesn't have relevant code for it.
223  *
224  * @param im XIM server
225  * @param ic Input context
226  */
227 XCBIMDKIT_EXPORT void xcb_im_geometry_callback(xcb_im_t *im,
228                                                xcb_im_input_context_t *ic);
229 
230 /**
231  * Sends XIM_PREEDIT_START message to call the XIMPreeditStartCallback function.
232  *
233  * @param im XIM server
234  * @param ic Input context
235  */
236 XCBIMDKIT_EXPORT void xcb_im_preedit_start_callback(xcb_im_t *im,
237                                                     xcb_im_input_context_t *ic);
238 
239 /**
240  * Sends XIM_PREEDIT_DRAW message to call the XIMPreeditDrawCallback function.
241  *
242  * @param im XIM server
243  * @param ic Input context
244  * @param frame information about preedit string.
245  */
246 XCBIMDKIT_EXPORT void
247 xcb_im_preedit_draw_callback(xcb_im_t *im, xcb_im_input_context_t *ic,
248                              xcb_im_preedit_draw_fr_t *frame);
249 
250 /**
251  * Sends XIM_PREEDIT_CARET message to call the PreeditCaretCallback function.
252  *
253  * @param im XIM server
254  * @param ic Input context
255  * @param frame information about preedit caret.
256  */
257 XCBIMDKIT_EXPORT void
258 xcb_im_preedit_caret_callback(xcb_im_t *im, xcb_im_input_context_t *ic,
259                               xcb_im_preedit_caret_fr_t *frame);
260 
261 /**
262  * sends XIM_PREEDIT_DONE message to call the XIMPreeditDoneCallback function.
263  *
264  * This should only be called after calling xcb_im_preedit_start_callback.
265  *
266  * @param im XIM server
267  * @param ic Input context
268  */
269 XCBIMDKIT_EXPORT void xcb_im_preedit_done_callback(xcb_im_t *im,
270                                                    xcb_im_input_context_t *ic);
271 
272 /**
273  * Sends XIM_STATUS_START message to call the XIMStatusStartCallback function.
274  *
275  * @param im XIM server
276  * @param ic Input context
277  */
278 XCBIMDKIT_EXPORT void xcb_im_status_start_callback(xcb_im_t *im,
279                                                    xcb_im_input_context_t *ic);
280 
281 /**
282  * Sends XIM_STATUS_DRAW message to call the XIMStatusDrawCallback function with
283  * text.
284  *
285  * @param im XIM server
286  * @param ic Input context
287  * @param frame text to be drawn by client.
288  */
289 XCBIMDKIT_EXPORT void
290 xcb_im_status_draw_text_callback(xcb_im_t *im, xcb_im_input_context_t *ic,
291                                  xcb_im_status_draw_text_fr_t *frame);
292 
293 /**
294  * Sends XIM_STATUS_DRAW message to call the XIMStatusDrawCallback function with
295  * bitmap.
296  *
297  * @param im XIM server
298  * @param ic Input context
299  * @param frame bitmap to be drawn by client.
300  */
301 XCBIMDKIT_EXPORT void
302 xcb_im_status_draw_bitmap_callback(xcb_im_t *im, xcb_im_input_context_t *ic,
303                                    xcb_im_status_draw_bitmap_fr_t *frame);
304 
305 /**
306  * Sends XIM_STATUS_DONE message to call the XIMStatusDoneCallback function.
307  *
308  * @param im XIM server
309  * @param ic Input context
310  */
311 XCBIMDKIT_EXPORT void xcb_im_status_done_callback(xcb_im_t *im,
312                                                   xcb_im_input_context_t *ic);
313 XCBIMDKIT_EXPORT void xcb_im_preedit_start(xcb_im_t *im,
314                                            xcb_im_input_context_t *ic);
315 XCBIMDKIT_EXPORT void xcb_im_preedit_end(xcb_im_t *im,
316                                          xcb_im_input_context_t *ic);
317 XCBIMDKIT_EXPORT void xcb_im_sync_xlib(xcb_im_t *im,
318                                        xcb_im_input_context_t *ic);
319 XCBIMDKIT_EXPORT bool xcb_im_support_extension(xcb_im_t *im,
320                                                uint16_t major_code,
321                                                uint16_t minor_code);
322 XCBIMDKIT_EXPORT void
323 xcb_im_input_context_set_data(xcb_im_input_context_t *ic, void *data,
324                               xcb_im_free_function free_data_function);
325 XCBIMDKIT_EXPORT void *
326 xcb_im_input_context_get_data(xcb_im_input_context_t *ic);
327 XCBIMDKIT_EXPORT uint32_t
328 xcb_im_input_context_get_input_style(xcb_im_input_context_t *ic);
329 XCBIMDKIT_EXPORT xcb_window_t
330 xcb_im_input_context_get_client_window(xcb_im_input_context_t *ic);
331 XCBIMDKIT_EXPORT xcb_window_t
332 xcb_im_input_context_get_focus_window(xcb_im_input_context_t *ic);
333 XCBIMDKIT_EXPORT const xcb_im_preedit_attr_t *
334 xcb_im_input_context_get_preedit_attr(xcb_im_input_context_t *ic);
335 XCBIMDKIT_EXPORT const xcb_im_status_attr_t *
336 xcb_im_input_context_get_status_attr(xcb_im_input_context_t *ic);
337 XCBIMDKIT_EXPORT uint32_t
338 xcb_im_input_context_get_preedit_attr_mask(xcb_im_input_context_t *ic);
339 XCBIMDKIT_EXPORT uint32_t
340 xcb_im_input_context_get_status_attr_mask(xcb_im_input_context_t *ic);
341 
342 XCBIMDKIT_DECL_END
343 
344 #endif // _XCB_IMDKIT_IMDKIT_H_
345