Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / winputmethod.c
Commit [+]AuthorDateLineData
92232f3a kojima2001-08-23 22:40:46 +00001
92232f3a kojima2001-08-23 22:40:46 +00002#include <X11/Xlib.h>
3
4#include "WINGsP.h"
5
92232f3a kojima2001-08-23 22:40:46 +00006typedef struct W_IMContext {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02007 XIM xim;
8 XIMStyle ximstyle;
92232f3a kojima2001-08-23 22:40:46 +00009} WMIMContext;
10
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020011static void instantiateIM_cb(Display * display, XPointer client_data, XPointer call_data)
ca616755 dan2004-10-28 04:17:18 +000012{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020013 W_InitIM((W_Screen *) client_data);
ca616755 dan2004-10-28 04:17:18 +000014}
92232f3a kojima2001-08-23 22:40:46 +000015
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020016static void destroyIM_cb(XIM xim, XPointer client_data, XPointer call_data)
92232f3a kojima2001-08-23 22:40:46 +000017{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020018 W_Screen *scr = (W_Screen *) client_data;
19 W_View *target;
6830b057 dan2004-10-12 21:28:27 +000020
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020021 if (scr->imctx->xim != xim)
22 return;
6830b057 dan2004-10-12 21:28:27 +000023
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020024 target = scr->rootView->childrenList;
25 while (target != NULL) {
26 W_DestroyIC(target);
27 target = target->nextSister;
28 }
6830b057 dan2004-10-12 21:28:27 +000029
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020030 wfree(scr->imctx);
31 scr->imctx = NULL;
ca616755 dan2004-10-28 04:17:18 +000032
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020033 XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, instantiateIM_cb, (XPointer) scr);
92232f3a kojima2001-08-23 22:40:46 +000034}
35
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020036void W_InitIM(W_Screen * scr)
92232f3a kojima2001-08-23 22:40:46 +000037{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020038 XIM xim;
39
40 if (scr->imctx)
41 return;
42
43 xim = XOpenIM(scr->display, NULL, NULL, NULL);
44
45 if (xim) {
46 XIMStyles *im_styles;
47 XIMCallback cb;
48 int i;
49
50 scr->imctx = wmalloc(sizeof(WMIMContext));
51 scr->imctx->xim = xim;
52
53 cb.callback = destroyIM_cb;
54 cb.client_data = (XPointer) scr;
55 if (XSetIMValues(scr->imctx->xim, XNDestroyCallback, &cb, NULL))
56 wwarning("could not add destroy callback for input method");
57 XUnregisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, instantiateIM_cb, (XPointer) scr);
58 /* Get available input style */
59 XGetIMValues(scr->imctx->xim, XNQueryInputStyle, &im_styles, NULL);
60
61 scr->imctx->ximstyle = 0;
62
63 for (i = 0; i < im_styles->count_styles && scr->imctx->ximstyle == 0; i++) {
64 if ((im_styles->supported_styles[i] & XIMPreeditPosition) &&
65 (im_styles->supported_styles[i] & XIMStatusNothing)) {
66 scr->imctx->ximstyle = XIMPreeditPosition | XIMStatusNothing;
67 } else if ((im_styles->supported_styles[i] & XIMPreeditNothing) &&
68 (im_styles->supported_styles[i] & XIMStatusNothing)) {
69 scr->imctx->ximstyle = XIMPreeditNothing | XIMStatusNothing;
70 }
71 }
72 XFree(im_styles);
73 } else {
74 XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, instantiateIM_cb, (XPointer) scr);
75 }
92232f3a kojima2001-08-23 22:40:46 +000076}
77
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020078void W_CreateIC(WMView * view)
92232f3a kojima2001-08-23 22:40:46 +000079{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020080 WMScreen *scr = W_VIEW_SCREEN(view);
81 XVaNestedList preedit_attr = NULL;
82
83 if (view->xic || !view->flags.realized || !scr->imctx)
84 return;
85
86 if (scr->imctx->ximstyle & XIMPreeditPosition) {
87 XPoint spot;
88 XRectangle rect;
89 int ofs;
90
91 ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2;
92
93 rect.x = ofs;
94 rect.y = ofs;
95 rect.height = WMFontHeight(scr->normalFont);
96 rect.width = view->size.width - ofs * 2;
97 spot.x = rect.x;
98 spot.y = rect.y + rect.height;
99
100 // this really needs to be changed, but I don't know how yet -Dan
101 // it used to be like this with fontsets, but no longer applies to xft
102 preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot,
103 XNArea, &rect, XNFontInfo, scr->normalFont->font, NULL);
104 }
105
106 view->xic = XCreateIC(scr->imctx->xim, XNInputStyle, scr->imctx->ximstyle,
107 XNClientWindow, view->window,
108 preedit_attr ? XNPreeditAttributes : NULL, preedit_attr, NULL);
109
110 if (preedit_attr)
111 XFree(preedit_attr);
112
113 if (view->xic) {
114 unsigned long fevent = 0;
115 XGetICValues(view->xic, XNFilterEvents, &fevent, NULL);
116 XSelectInput(scr->display, view->window,
117 ButtonPressMask | ButtonReleaseMask | ExposureMask |
118 KeyPressMask | FocusChangeMask | ButtonMotionMask | fevent);
119 }
ca616755 dan2004-10-28 04:17:18 +0000120}
121
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200122void W_DestroyIC(WMView * view)
ca616755 dan2004-10-28 04:17:18 +0000123{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200124 if (view->xic) {
125 XDestroyIC(view->xic);
126 view->xic = 0;
127 }
ca616755 dan2004-10-28 04:17:18 +0000128}
129
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200130static void setPreeditArea(W_View * view)
ca616755 dan2004-10-28 04:17:18 +0000131{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200132 WMScreen *scr = W_VIEW_SCREEN(view);
133 XVaNestedList preedit_attr = NULL;
134
135 if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) {
136 XRectangle rect;
137 int ofs;
138
139 ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2;
140 rect.x = ofs;
141 rect.y = ofs;
142 rect.height = WMFontHeight(scr->normalFont);
143 rect.width = view->size.width - ofs * 2;
144
145 preedit_attr = XVaCreateNestedList(0, XNArea, &rect, NULL);
146 XSetICValues(view->xic, XNPreeditAttributes, preedit_attr, NULL);
147
148 if (preedit_attr) {
149 XFree(preedit_attr);
150 }
151 }
92232f3a kojima2001-08-23 22:40:46 +0000152}
153
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200154void W_FocusIC(WMView * view)
92232f3a kojima2001-08-23 22:40:46 +0000155{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200156 WMScreen *scr = W_VIEW_SCREEN(view);
6830b057 dan2004-10-12 21:28:27 +0000157
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200158 if (view->xic) {
159 XSetICFocus(view->xic);
160 XSetICValues(view->xic, XNFocusWindow, view->window, NULL);
6830b057 dan2004-10-12 21:28:27 +0000161
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200162 if (scr->imctx->ximstyle & XIMPreeditPosition) {
163 setPreeditArea(view);
164 }
165 }
92232f3a kojima2001-08-23 22:40:46 +0000166}
167
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200168void W_UnFocusIC(WMView * view)
92232f3a kojima2001-08-23 22:40:46 +0000169{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200170 if (view->xic) {
171 XUnsetICFocus(view->xic);
172 }
ca616755 dan2004-10-28 04:17:18 +0000173}
174
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200175void W_SetPreeditPositon(W_View * view, int x, int y)
ca616755 dan2004-10-28 04:17:18 +0000176{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200177 WMScreen *scr = W_VIEW_SCREEN(view);
178 XVaNestedList preedit_attr = NULL;
179
180 if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) {
181 XPoint spot;
182 int ofs;
183
184 ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2;
185 spot.x = x;
186 spot.y = y + view->size.height - ofs - 3;
187 preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
188 XSetICValues(view->xic, XNPreeditAttributes, preedit_attr, NULL);
189 if (preedit_attr) {
190 XFree(preedit_attr);
191 }
192 }
92232f3a kojima2001-08-23 22:40:46 +0000193}
194
ca616755 dan2004-10-28 04:17:18 +0000195int
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200196W_LookupString(W_View * view, XKeyPressedEvent * event, char *buffer, int buflen, KeySym * keysym, Status * status)
ca616755 dan2004-10-28 04:17:18 +0000197{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200198 WMScreen *scr = W_VIEW_SCREEN(view);
ca616755 dan2004-10-28 04:17:18 +0000199
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200200 XSetInputFocus(scr->display, view->window, RevertToParent, CurrentTime);
ca616755 dan2004-10-28 04:17:18 +0000201
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200202 if (view->xic) {
ca616755 dan2004-10-28 04:17:18 +0000203#ifdef X_HAVE_UTF8_STRING
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200204 return Xutf8LookupString(view->xic, event, buffer, buflen, keysym, status);
ca616755 dan2004-10-28 04:17:18 +0000205#else
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200206 return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status);
ca616755 dan2004-10-28 04:17:18 +0000207#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200208 } else {
209 return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status);
210 }
ca616755 dan2004-10-28 04:17:18 +0000211}