utils: Added a few missing attributes to local variables
[wmaker-crm.git] / WINGs / winputmethod.c
blob7d3aae008b2f644d185842fc5996965b55a55b1e
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)
13 /* Parameter not used, but tell the compiler that it is ok */
14 (void) display;
15 (void) call_data;
17 W_InitIM((W_Screen *) client_data);
20 static void destroyIM_cb(XIM xim, XPointer client_data, XPointer call_data)
22 W_Screen *scr = (W_Screen *) client_data;
23 W_View *target;
25 /* Parameter not used, but tell the compiler that it is ok */
26 (void) call_data;
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, instantiateIM_cb, (XPointer) scr);
43 void W_InitIM(W_Screen * scr)
45 XIM xim;
47 if (scr->imctx)
48 return;
50 xim = XOpenIM(scr->display, NULL, NULL, NULL);
52 if (xim) {
53 XIMStyles *im_styles;
54 XIMCallback cb;
55 int i;
57 scr->imctx = wmalloc(sizeof(WMIMContext));
58 scr->imctx->xim = xim;
60 cb.callback = destroyIM_cb;
61 cb.client_data = (XPointer) scr;
62 if (XSetIMValues(scr->imctx->xim, XNDestroyCallback, &cb, NULL))
63 wwarning("could not add destroy callback for input method");
64 XUnregisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, instantiateIM_cb, (XPointer) scr);
65 /* Get available input style */
66 XGetIMValues(scr->imctx->xim, XNQueryInputStyle, &im_styles, NULL);
68 scr->imctx->ximstyle = 0;
70 for (i = 0; i < im_styles->count_styles && scr->imctx->ximstyle == 0; i++) {
71 if ((im_styles->supported_styles[i] & XIMPreeditPosition) &&
72 (im_styles->supported_styles[i] & XIMStatusNothing)) {
73 scr->imctx->ximstyle = XIMPreeditPosition | XIMStatusNothing;
74 } else if ((im_styles->supported_styles[i] & XIMPreeditNothing) &&
75 (im_styles->supported_styles[i] & XIMStatusNothing)) {
76 scr->imctx->ximstyle = XIMPreeditNothing | XIMStatusNothing;
79 XFree(im_styles);
80 } else {
81 XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, instantiateIM_cb, (XPointer) scr);
85 void W_CreateIC(WMView * view)
87 WMScreen *scr = W_VIEW_SCREEN(view);
88 XVaNestedList preedit_attr = NULL;
90 if (view->xic || !view->flags.realized || !scr->imctx)
91 return;
93 if (scr->imctx->ximstyle & XIMPreeditPosition) {
94 XPoint spot;
95 XRectangle rect;
96 int ofs;
98 ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2;
100 rect.x = ofs;
101 rect.y = ofs;
102 rect.height = WMFontHeight(scr->normalFont);
103 rect.width = view->size.width - ofs * 2;
104 spot.x = rect.x;
105 spot.y = rect.y + rect.height;
107 // this really needs to be changed, but I don't know how yet -Dan
108 // it used to be like this with fontsets, but no longer applies to xft
109 preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot,
110 XNArea, &rect, XNFontInfo, scr->normalFont->font, NULL);
113 view->xic = XCreateIC(scr->imctx->xim, XNInputStyle, scr->imctx->ximstyle,
114 XNClientWindow, view->window,
115 preedit_attr ? XNPreeditAttributes : NULL, preedit_attr, NULL);
117 if (preedit_attr)
118 XFree(preedit_attr);
120 if (view->xic) {
121 unsigned long fevent = 0;
122 XGetICValues(view->xic, XNFilterEvents, &fevent, NULL);
123 XSelectInput(scr->display, view->window,
124 ButtonPressMask | ButtonReleaseMask | ExposureMask |
125 KeyPressMask | FocusChangeMask | ButtonMotionMask | fevent);
129 void W_DestroyIC(WMView * view)
131 if (view->xic) {
132 XDestroyIC(view->xic);
133 view->xic = 0;
137 static void setPreeditArea(W_View * view)
139 WMScreen *scr = W_VIEW_SCREEN(view);
140 XVaNestedList preedit_attr = NULL;
142 if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) {
143 XRectangle rect;
144 int ofs;
146 ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2;
147 rect.x = ofs;
148 rect.y = ofs;
149 rect.height = WMFontHeight(scr->normalFont);
150 rect.width = view->size.width - ofs * 2;
152 preedit_attr = XVaCreateNestedList(0, XNArea, &rect, NULL);
153 XSetICValues(view->xic, XNPreeditAttributes, preedit_attr, NULL);
155 if (preedit_attr) {
156 XFree(preedit_attr);
161 void W_FocusIC(WMView * view)
163 WMScreen *scr = W_VIEW_SCREEN(view);
165 if (view->xic) {
166 XSetICFocus(view->xic);
167 XSetICValues(view->xic, XNFocusWindow, view->window, NULL);
169 if (scr->imctx->ximstyle & XIMPreeditPosition) {
170 setPreeditArea(view);
175 void W_UnFocusIC(WMView * view)
177 if (view->xic) {
178 XUnsetICFocus(view->xic);
182 void W_SetPreeditPositon(W_View * view, int x, int y)
184 WMScreen *scr = W_VIEW_SCREEN(view);
185 XVaNestedList preedit_attr = NULL;
187 if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) {
188 XPoint spot;
189 int ofs;
191 ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2;
192 spot.x = x;
193 spot.y = y + view->size.height - ofs - 3;
194 preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
195 XSetICValues(view->xic, XNPreeditAttributes, preedit_attr, NULL);
196 if (preedit_attr) {
197 XFree(preedit_attr);
203 W_LookupString(W_View * view, XKeyPressedEvent * event, char *buffer, int buflen, KeySym * keysym, Status * status)
205 WMScreen *scr = W_VIEW_SCREEN(view);
207 XSetInputFocus(scr->display, view->window, RevertToParent, CurrentTime);
209 if (view->xic) {
210 #ifdef X_HAVE_UTF8_STRING
211 return Xutf8LookupString(view->xic, event, buffer, buflen, keysym, status);
212 #else
213 return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status);
214 #endif
215 } else {
216 return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status);