Makefile: Beautify compilation messages
[wmaker-crm.git] / WINGs / winputmethod.c
blob79b17fece8d9af72d0b6e2446507212dbb159274
3 #include <X11/Xlib.h>
5 #include "WINGsP.h"
8 typedef struct W_IMContext {
9 XIM xim;
10 XIMStyle ximstyle;
11 } WMIMContext;
15 static void
16 instantiateIM_cb(Display *display, XPointer client_data, XPointer call_data)
18 W_InitIM((W_Screen *)client_data);
22 static void
23 destroyIM_cb(XIM xim, XPointer client_data, XPointer call_data)
25 W_Screen *scr = (W_Screen *)client_data;
26 W_View *target;
28 if (scr->imctx->xim != xim)
29 return;
31 target = scr->rootView->childrenList;
32 while (target!=NULL) {
33 W_DestroyIC(target);
34 target = target->nextSister;
37 wfree(scr->imctx);
38 scr->imctx = NULL;
40 XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL,
41 instantiateIM_cb, (XPointer)scr);
45 void
46 W_InitIM(W_Screen *scr)
48 XIM xim;
50 if (scr->imctx)
51 return;
53 xim = XOpenIM(scr->display, NULL, NULL, NULL);
55 if (xim) {
56 XIMStyles *im_styles;
57 XIMCallback cb;
58 int i;
60 scr->imctx = wmalloc(sizeof(WMIMContext));
61 scr->imctx->xim = xim;
63 cb.callback = destroyIM_cb;
64 cb.client_data = (XPointer)scr;
65 if (XSetIMValues(scr->imctx->xim, XNDestroyCallback, &cb, NULL))
66 wwarning("could not add destroy callback for input method");
67 XUnregisterIMInstantiateCallback(scr->display, NULL, NULL, NULL,
68 instantiateIM_cb, (XPointer)scr);
69 /* Get available input style */
70 XGetIMValues(scr->imctx->xim, XNQueryInputStyle, &im_styles, NULL);
72 scr->imctx->ximstyle = 0;
74 for (i=0; i<im_styles->count_styles && scr->imctx->ximstyle==0; i++) {
75 if ((im_styles->supported_styles[i] & XIMPreeditPosition) &&
76 (im_styles->supported_styles[i] & XIMStatusNothing)) {
77 scr->imctx->ximstyle = XIMPreeditPosition | XIMStatusNothing;
78 } else if ((im_styles->supported_styles[i] & XIMPreeditNothing) &&
79 (im_styles->supported_styles[i] & XIMStatusNothing)) {
80 scr->imctx->ximstyle = XIMPreeditNothing | XIMStatusNothing;
83 XFree(im_styles);
84 } else {
85 XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL,
86 instantiateIM_cb, (XPointer)scr);
91 void
92 W_CreateIC(WMView *view)
94 WMScreen *scr = W_VIEW_SCREEN(view);
95 XVaNestedList preedit_attr = NULL;
97 if (view->xic || !view->flags.realized || !scr->imctx)
98 return;
100 if (scr->imctx->ximstyle & XIMPreeditPosition) {
101 XPoint spot;
102 XRectangle rect;
103 int ofs;
105 ofs = (view->size.height - WMFontHeight(scr->normalFont))/2;
107 rect.x = ofs;
108 rect.y = ofs;
109 rect.height = WMFontHeight(scr->normalFont);
110 rect.width = view->size.width - ofs*2;
111 spot.x = rect.x;
112 spot.y = rect.y + rect.height;
114 // this really needs to be changed, but I don't know how yet -Dan
115 // it used to be like this with fontsets, but no longer applies to xft
116 preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot,
117 XNArea, &rect, XNFontInfo,
118 scr->normalFont->font, NULL);
121 view->xic = XCreateIC(scr->imctx->xim, XNInputStyle, scr->imctx->ximstyle,
122 XNClientWindow, view->window,
123 preedit_attr ? XNPreeditAttributes : NULL, preedit_attr,
124 NULL);
126 if (preedit_attr)
127 XFree(preedit_attr);
129 if (view->xic) {
130 unsigned long fevent = 0;
131 XGetICValues(view->xic, XNFilterEvents, &fevent, NULL);
132 XSelectInput(scr->display, view->window,
133 ButtonPressMask | ButtonReleaseMask | ExposureMask |
134 KeyPressMask | FocusChangeMask| ButtonMotionMask |fevent);
139 void
140 W_DestroyIC(WMView *view)
142 if (view->xic) {
143 XDestroyIC(view->xic);
144 view->xic = 0;
149 static void
150 setPreeditArea(W_View *view)
152 WMScreen *scr = W_VIEW_SCREEN(view);
153 XVaNestedList preedit_attr = NULL;
155 if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) {
156 XRectangle rect;
157 int ofs;
159 ofs = (view->size.height - WMFontHeight(scr->normalFont))/2;
160 rect.x = ofs;
161 rect.y = ofs;
162 rect.height = WMFontHeight(scr->normalFont);
163 rect.width = view->size.width - ofs*2;
165 preedit_attr = XVaCreateNestedList(0, XNArea, &rect, NULL);
166 XSetICValues(view->xic, XNPreeditAttributes, preedit_attr, NULL);
168 if (preedit_attr) {
169 XFree(preedit_attr);
175 void
176 W_FocusIC(WMView *view)
178 WMScreen *scr = W_VIEW_SCREEN(view);
180 if (view->xic) {
181 XSetICFocus(view->xic);
182 XSetICValues(view->xic, XNFocusWindow, view->window, NULL);
184 if (scr->imctx->ximstyle & XIMPreeditPosition) {
185 setPreeditArea(view);
191 void
192 W_UnFocusIC(WMView *view)
194 if (view->xic) {
195 XUnsetICFocus(view->xic);
200 void
201 W_SetPreeditPositon(W_View *view, int x, int y)
203 WMScreen *scr = W_VIEW_SCREEN(view);
204 XVaNestedList preedit_attr = NULL;
206 if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) {
207 XPoint spot;
208 int ofs;
210 ofs = (view->size.height - WMFontHeight(scr->normalFont))/2;
211 spot.x = x;
212 spot.y = y + view->size.height - ofs - 3;
213 preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
214 XSetICValues(view->xic, XNPreeditAttributes, preedit_attr, NULL);
215 if (preedit_attr) {
216 XFree(preedit_attr);
223 W_LookupString(W_View *view, XKeyPressedEvent *event, char *buffer, int buflen,
224 KeySym *keysym, Status *status)
226 WMScreen *scr = W_VIEW_SCREEN(view);
228 XSetInputFocus(scr->display, view->window, RevertToParent, CurrentTime);
230 if (view->xic) {
231 #ifdef X_HAVE_UTF8_STRING
232 return Xutf8LookupString(view->xic, event, buffer, buflen, keysym, status);
233 #else
234 return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *)status);
235 #endif
236 } else {
237 return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *)status);