8 typedef struct W_IMContext
{
13 static void instantiateIM_cb(Display
* display
, XPointer client_data
, XPointer call_data
)
15 /* Parameter not used, but tell the compiler that it is ok */
19 W_InitIM((W_Screen
*) client_data
);
22 static void destroyIM_cb(XIM xim
, XPointer client_data
, XPointer call_data
)
24 W_Screen
*scr
= (W_Screen
*) client_data
;
27 /* Parameter not used, but tell the compiler that it is ok */
30 if (scr
->imctx
->xim
!= xim
)
33 target
= scr
->rootView
->childrenList
;
34 while (target
!= NULL
) {
36 target
= target
->nextSister
;
42 XRegisterIMInstantiateCallback(scr
->display
, NULL
, NULL
, NULL
, instantiateIM_cb
, (XPointer
) scr
);
45 void W_InitIM(W_Screen
* scr
)
52 xim
= XOpenIM(scr
->display
, NULL
, NULL
, NULL
);
59 scr
->imctx
= wmalloc(sizeof(WMIMContext
));
60 scr
->imctx
->xim
= xim
;
62 cb
.callback
= destroyIM_cb
;
63 cb
.client_data
= (XPointer
) scr
;
64 if (XSetIMValues(scr
->imctx
->xim
, XNDestroyCallback
, &cb
, NULL
))
65 wwarning(_("could not add destroy callback for XIM input method"));
66 XUnregisterIMInstantiateCallback(scr
->display
, NULL
, NULL
, NULL
, instantiateIM_cb
, (XPointer
) scr
);
67 /* Get available input style */
68 XGetIMValues(scr
->imctx
->xim
, XNQueryInputStyle
, &im_styles
, NULL
);
70 scr
->imctx
->ximstyle
= 0;
72 for (i
= 0; i
< im_styles
->count_styles
&& scr
->imctx
->ximstyle
== 0; i
++) {
73 if ((im_styles
->supported_styles
[i
] & XIMPreeditPosition
) &&
74 (im_styles
->supported_styles
[i
] & XIMStatusNothing
)) {
75 scr
->imctx
->ximstyle
= XIMPreeditPosition
| XIMStatusNothing
;
76 } else if ((im_styles
->supported_styles
[i
] & XIMPreeditNothing
) &&
77 (im_styles
->supported_styles
[i
] & XIMStatusNothing
)) {
78 scr
->imctx
->ximstyle
= XIMPreeditNothing
| XIMStatusNothing
;
83 XRegisterIMInstantiateCallback(scr
->display
, NULL
, NULL
, NULL
, instantiateIM_cb
, (XPointer
) scr
);
87 void W_CreateIC(WMView
* view
)
89 WMScreen
*scr
= W_VIEW_SCREEN(view
);
90 XVaNestedList preedit_attr
= NULL
;
92 if (view
->xic
|| !view
->flags
.realized
|| !scr
->imctx
)
95 if (scr
->imctx
->ximstyle
& XIMPreeditPosition
) {
100 ofs
= (view
->size
.height
- WMFontHeight(scr
->normalFont
)) / 2;
104 rect
.height
= WMFontHeight(scr
->normalFont
);
105 rect
.width
= view
->size
.width
- ofs
* 2;
107 spot
.y
= rect
.y
+ rect
.height
;
109 // this really needs to be changed, but I don't know how yet -Dan
110 // it used to be like this with fontsets, but no longer applies to xft
111 preedit_attr
= XVaCreateNestedList(0, XNSpotLocation
, &spot
,
112 XNArea
, &rect
, XNFontInfo
, scr
->normalFont
->font
, NULL
);
115 view
->xic
= XCreateIC(scr
->imctx
->xim
, XNInputStyle
, scr
->imctx
->ximstyle
,
116 XNClientWindow
, view
->window
,
117 preedit_attr
? XNPreeditAttributes
: NULL
, preedit_attr
, NULL
);
123 unsigned long fevent
= 0;
124 XGetICValues(view
->xic
, XNFilterEvents
, &fevent
, NULL
);
125 XSelectInput(scr
->display
, view
->window
,
126 ButtonPressMask
| ButtonReleaseMask
| ExposureMask
|
127 KeyPressMask
| FocusChangeMask
| ButtonMotionMask
| fevent
);
131 void W_DestroyIC(WMView
* view
)
134 XDestroyIC(view
->xic
);
139 static void setPreeditArea(W_View
* view
)
141 WMScreen
*scr
= W_VIEW_SCREEN(view
);
142 XVaNestedList preedit_attr
= NULL
;
144 if (view
->xic
&& (scr
->imctx
->ximstyle
& XIMPreeditPosition
)) {
148 ofs
= (view
->size
.height
- WMFontHeight(scr
->normalFont
)) / 2;
151 rect
.height
= WMFontHeight(scr
->normalFont
);
152 rect
.width
= view
->size
.width
- ofs
* 2;
154 preedit_attr
= XVaCreateNestedList(0, XNArea
, &rect
, NULL
);
155 XSetICValues(view
->xic
, XNPreeditAttributes
, preedit_attr
, NULL
);
163 void W_FocusIC(WMView
* view
)
165 WMScreen
*scr
= W_VIEW_SCREEN(view
);
168 XSetICFocus(view
->xic
);
169 XSetICValues(view
->xic
, XNFocusWindow
, view
->window
, NULL
);
171 if (scr
->imctx
->ximstyle
& XIMPreeditPosition
) {
172 setPreeditArea(view
);
177 void W_UnFocusIC(WMView
* view
)
180 XUnsetICFocus(view
->xic
);
184 void W_SetPreeditPositon(W_View
* view
, int x
, int y
)
186 WMScreen
*scr
= W_VIEW_SCREEN(view
);
187 XVaNestedList preedit_attr
= NULL
;
189 if (view
->xic
&& (scr
->imctx
->ximstyle
& XIMPreeditPosition
)) {
193 ofs
= (view
->size
.height
- WMFontHeight(scr
->normalFont
)) / 2;
195 spot
.y
= y
+ view
->size
.height
- ofs
- 3;
196 preedit_attr
= XVaCreateNestedList(0, XNSpotLocation
, &spot
, NULL
);
197 XSetICValues(view
->xic
, XNPreeditAttributes
, preedit_attr
, NULL
);
204 int W_LookupString(W_View
*view
, XKeyPressedEvent
*event
, char *buffer
, int buflen
, KeySym
*keysym
, Status
*status
)
206 WMScreen
*scr
= W_VIEW_SCREEN(view
);
208 XSetInputFocus(scr
->display
, view
->window
, RevertToParent
, CurrentTime
);
210 #ifdef X_HAVE_UTF8_STRING
212 return Xutf8LookupString(view
->xic
, event
, buffer
, buflen
, keysym
, status
);
214 return XLookupString(event
, buffer
, buflen
, keysym
, (XComposeStatus
*) status
);
218 * Map a keycode to the corresponding keysym
219 * To replace the deprecated X11 function XKeycodeToKeysym
221 KeySym
W_KeycodeToKeysym(Display
*display
, KeyCode keycode
, int index
)
223 static int min_kc
= -1;
229 XDisplayKeycodes(display
, &min_kc
, &max_kc
);
230 if (keycode
< min_kc
|| keycode
> max_kc
|| index
< 0) {
234 key_syms
= XGetKeyboardMapping(display
, keycode
, 1, &num_syms
);
235 if (index
>= num_syms
) {
240 ks
= key_syms
[index
];