6 typedef struct W_IMContext {
11 static void instantiateIM_cb(Display * display, XPointer client_data, XPointer call_data)
13 W_InitIM((W_Screen *) client_data);
16 static void destroyIM_cb(XIM xim, XPointer client_data, XPointer call_data)
18 W_Screen *scr = (W_Screen *) client_data;
21 if (scr->imctx->xim != xim)
24 target = scr->rootView->childrenList;
25 while (target != NULL) {
27 target = target->nextSister;
33 XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, instantiateIM_cb, (XPointer) scr);
36 void W_InitIM(W_Screen * scr)
43 xim = XOpenIM(scr->display, NULL, NULL, NULL);
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;
74 XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, instantiateIM_cb, (XPointer) scr);
78 void W_CreateIC(WMView * view)
80 WMScreen *scr = W_VIEW_SCREEN(view);
81 XVaNestedList preedit_attr = NULL;
83 if (view->xic || !view->flags.realized || !scr->imctx)
86 if (scr->imctx->ximstyle & XIMPreeditPosition) {
91 ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2;
95 rect.height = WMFontHeight(scr->normalFont);
96 rect.width = view->size.width - ofs * 2;
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);
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)
125 XDestroyIC(view->xic);
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)) {
139 ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2;
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);
154 void W_FocusIC(WMView * view)
156 WMScreen *scr = W_VIEW_SCREEN(view);
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)
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)) {
184 ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2;
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);
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);
203 #ifdef X_HAVE_UTF8_STRING
204 return Xutf8LookupString(view->xic, event, buffer, buflen, keysym, status);
206 return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status);
209 return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status);