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
);