Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / winputmethod.c
blob01ecdc703f2c8f003d15c87e659f31df00934616
2 #include <X11/Xlib.h>
4 #include "WINGsP.h"
6 typedef struct W_IMContext {
7 XIM xim;
8 XIMStyle ximstyle;
9 } WMIMContext;
11 static void instantiateIM_cb(Display * display, XPointer client_data, XPointer call_data)
12 {
13 W_InitIM((W_Screen *) client_data);
14 }
16 static void destroyIM_cb(XIM xim, XPointer client_data, XPointer call_data)
17 {
18 W_Screen *scr = (W_Screen *) client_data;
19 W_View *target;
21 if (scr->imctx->xim != xim)
22 return;
24 target = scr->rootView->childrenList;
25 while (target != NULL) {
26 W_DestroyIC(target);
27 target = target->nextSister;
28 }
30 wfree(scr->imctx);
31 scr->imctx = NULL;
33 XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, instantiateIM_cb, (XPointer) scr);
34 }
36 void W_InitIM(W_Screen * scr)
37 {
38 XIM xim;
40 if (scr->imctx)
41 return;
43 xim = XOpenIM(scr->display, NULL, NULL, NULL);
45 if (xim) {
46 XIMStyles *im_styles;
47 XIMCallback cb;
48 int i;
50 scr->imctx = wmalloc(sizeof(WMIMContext));
51 scr->imctx->xim = xim;
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);
61 scr->imctx->ximstyle = 0;
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 }
76 }
78 void W_CreateIC(WMView * view)
79 {
80 WMScreen *scr = W_VIEW_SCREEN(view);
81 XVaNestedList preedit_attr = NULL;
83 if (view->xic || !view->flags.realized || !scr->imctx)
84 return;
86 if (scr->imctx->ximstyle & XIMPreeditPosition) {
87 XPoint spot;
88 XRectangle rect;
89 int ofs;
91 ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2;
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;
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);
106 view->xic = XCreateIC(scr->imctx->xim, XNInputStyle, scr->imctx->ximstyle,
107 XNClientWindow, view->window,
108 preedit_attr ? XNPreeditAttributes : NULL, preedit_attr, NULL);
110 if (preedit_attr)
111 XFree(preedit_attr);
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);
122 void W_DestroyIC(WMView * view)
124 if (view->xic) {
125 XDestroyIC(view->xic);
126 view->xic = 0;
130 static void setPreeditArea(W_View * view)
132 WMScreen *scr = W_VIEW_SCREEN(view);
133 XVaNestedList preedit_attr = NULL;
135 if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) {
136 XRectangle rect;
137 int ofs;
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;
145 preedit_attr = XVaCreateNestedList(0, XNArea, &rect, NULL);
146 XSetICValues(view->xic, XNPreeditAttributes, preedit_attr, NULL);
148 if (preedit_attr) {
149 XFree(preedit_attr);
154 void W_FocusIC(WMView * view)
156 WMScreen *scr = W_VIEW_SCREEN(view);
158 if (view->xic) {
159 XSetICFocus(view->xic);
160 XSetICValues(view->xic, XNFocusWindow, view->window, NULL);
162 if (scr->imctx->ximstyle & XIMPreeditPosition) {
163 setPreeditArea(view);
168 void W_UnFocusIC(WMView * view)
170 if (view->xic) {
171 XUnsetICFocus(view->xic);
175 void W_SetPreeditPositon(W_View * view, int x, int y)
177 WMScreen *scr = W_VIEW_SCREEN(view);
178 XVaNestedList preedit_attr = NULL;
180 if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) {
181 XPoint spot;
182 int ofs;
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);
195 int
196 W_LookupString(W_View * view, XKeyPressedEvent * event, char *buffer, int buflen, KeySym * keysym, Status * status)
198 WMScreen *scr = W_VIEW_SCREEN(view);
200 XSetInputFocus(scr->display, view->window, RevertToParent, CurrentTime);
202 if (view->xic) {
203 #ifdef X_HAVE_UTF8_STRING
204 return Xutf8LookupString(view->xic, event, buffer, buflen, keysym, status);
205 #else
206 return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status);
207 #endif
208 } else {
209 return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status);