comparison src/input-method-xlib.c @ 420:41dbb7a9d5f2 r21-2-18

Import from CVS: tag r21-2-18
author cvs
date Mon, 13 Aug 2007 11:24:09 +0200
parents 697ef44129c6
children 11054d720c21
comparison
equal deleted inserted replaced
419:66615b78f1a5 420:41dbb7a9d5f2
35 #include "window.h" 35 #include "window.h"
36 #include "buffer.h" 36 #include "buffer.h"
37 #include "console-x.h" 37 #include "console-x.h"
38 #include "EmacsFrame.h" 38 #include "EmacsFrame.h"
39 #include "events.h" 39 #include "events.h"
40
41 #include <X11/IntrinsicP.h>
42 #include <X11/Xaw/XawImP.h>
40 43
41 #ifndef XIM_XLIB 44 #ifndef XIM_XLIB
42 #error XIM_XLIB is not defined?? 45 #error XIM_XLIB is not defined??
43 #endif 46 #endif
44 47
70 "XIMPreeditNothing|XIMStatusNone\n" 73 "XIMPreeditNothing|XIMStatusNone\n"
71 "XIMPreeditNone|XIMStatusArea\n" 74 "XIMPreeditNone|XIMStatusArea\n"
72 "XIMPreeditNone|XIMStatusNothing\n" 75 "XIMPreeditNone|XIMStatusNothing\n"
73 "XIMPreeditNone|XIMStatusNone"; 76 "XIMPreeditNone|XIMStatusNone";
74 77
78 static Boolean xim_initted = False;
79
75 static XIMStyle best_style (XIMStyles *user, XIMStyles *xim); 80 static XIMStyle best_style (XIMStyles *user, XIMStyles *xim);
76 81
77 void 82 void
78 Initialize_Locale (void) 83 Initialize_Locale (void)
79 { 84 {
123 stderr_out ("XSetLocaleModifiers(\"\") failed\n"); 128 stderr_out ("XSetLocaleModifiers(\"\") failed\n");
124 stderr_out ("Check the value of the XMODIFIERS environment variable.\n"); 129 stderr_out ("Check the value of the XMODIFIERS environment variable.\n");
125 } 130 }
126 } 131 }
127 132
128 /* Create X input method for device */ 133 /******************************************************************/
129 void 134 /* Input method using xlib */
130 XIM_init_device (struct device *d) 135 /******************************************************************/
131 { 136
132 Display *dpy = DEVICE_X_DISPLAY (d); 137 /*
133 char *name, *class; 138 * called from when XIM is destroying
139 */
140 static void
141 IMDestroyCallback (XIM im, XPointer client_data, XPointer call_data)
142 {
143 struct frame *f = (struct frame *)client_data;
144 struct device *d = XDEVICE (FRAME_DEVICE ((struct frame *)client_data));
145 Lisp_Object frame_list = DEVICE_FRAME_LIST (XDEVICE (FRAME_DEVICE (f)));
146 Lisp_Object tail;
147 struct frame *target_frame = NULL;
148
149 LIST_LOOP (tail, frame_list)
150 {
151 if (target_frame = XFRAME (XCAR (tail)))
152 {
153 if ( FRAME_X_XIC(target_frame) )
154 {
155 XDestroyIC (FRAME_X_XIC(target_frame));
156 FRAME_X_XIC (target_frame) = NULL;
157 }
158 }
159 }
160
161 #if 0
162 if ( DEVICE_X_XIM (d) )
163 {
164 stderr_out ("NULLing d->xim...\n");
165 /* DEVICE_X_XIM (d) = NULL; */
166 }
167 #endif
168
169 xim_initted = False;
170 return;
171 }
172
173 /*
174 * called from when FRAME is initializing
175 */
176 static void
177 IMInstantiateCallback (Display *dpy, XPointer client_data, XPointer call_data)
178 {
179 struct frame *f = (struct frame *)client_data;
180 struct device *d = XDEVICE (FRAME_DEVICE ((struct frame *)client_data));
134 XIM xim; 181 XIM xim;
135 182 Widget w = FRAME_X_TEXT_WIDGET ((struct frame *)client_data);
136 XtGetApplicationNameAndClass (dpy, &name, &class);
137
138 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class);
139
140 if (xim == NULL)
141 {
142 stderr_out ("Warning: XOpenIM() failed...no input server available\n");
143 return;
144 }
145 else
146 {
147 /* Get supported styles */
148 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES (d), NULL);
149 #ifdef DEBUG_XIM
150 describe_XIM (xim);
151 #endif
152 }
153 }
154
155 /* Create an X input context for this frame. */
156 void
157 XIM_init_frame (struct frame *f)
158 {
159 struct device *d = XDEVICE (FRAME_DEVICE (f));
160 XIM xim = DEVICE_X_XIM (d);
161 XIC xic;
162 Widget w = FRAME_X_TEXT_WIDGET (f);
163 Window win = XtWindow (w); 183 Window win = XtWindow (w);
164 XRectangle p_area = {0,0,1,1}, s_area={0,0,1,1}; 184 XRectangle p_area = {0,0,1,1}, s_area = {0,0,1,1};
165 XPoint spot = {0,0}; 185 XPoint spot = {0,0};
166 XIMStyle style; 186 XIMStyle style;
167 XVaNestedList p_list, s_list; 187 XVaNestedList p_list, s_list;
168 188 char *name, *class;
169 typedef struct 189 typedef struct
170 { 190 {
171 XIMStyles styles; 191 XIMStyles styles;
172 XFontSet fontset; 192 XFontSet fontset;
173 Pixel fg; 193 Pixel fg;
174 Pixel bg; 194 Pixel bg;
195 char *inputmethod;
175 } xic_vars_t; 196 } xic_vars_t;
176
177 xic_vars_t xic_vars; 197 xic_vars_t xic_vars;
178 198 XIMCallback ximcallback;
179 /* mrb: #### Fix so that background and foreground is set from 199 XIC xic;
180 default face, rather than foreground and background resources, or
181 that the user can use set-frame-parameters to set xic attributes */
182 200
183 #define res(name, class, representation, field, default_value) \ 201 #define res(name, class, representation, field, default_value) \
184 { name, class, representation, sizeof(xic_vars.field), \ 202 { name, class, representation, sizeof(xic_vars.field), \
185 XtOffsetOf(xic_vars_t, field), XtRString, default_value } 203 XtOffsetOf(xic_vars_t, field), XtRString, default_value }
186 204
188 { 206 {
189 /* name class represent'n field default value */ 207 /* name class represent'n field default value */
190 res(XtNximStyles, XtCXimStyles, XtRXimStyles, styles, (XtPointer) DefaultXIMStyles), 208 res(XtNximStyles, XtCXimStyles, XtRXimStyles, styles, (XtPointer) DefaultXIMStyles),
191 res(XtNfontSet, XtCFontSet, XtRFontSet, fontset, (XtPointer) XtDefaultFontSet), 209 res(XtNfontSet, XtCFontSet, XtRFontSet, fontset, (XtPointer) XtDefaultFontSet),
192 res(XtNximForeground, XtCForeground, XtRPixel, fg, (XtPointer) XtDefaultForeground), 210 res(XtNximForeground, XtCForeground, XtRPixel, fg, (XtPointer) XtDefaultForeground),
193 res(XtNximBackground, XtCBackground, XtRPixel, bg, (XtPointer) XtDefaultBackground) 211 res(XtNximBackground, XtCBackground, XtRPixel, bg, (XtPointer) XtDefaultBackground),
212 res(XtNinputMethod, XtCInputMethod, XtRString, inputmethod, (XtPointer) NULL)
194 }; 213 };
195 214
196 assert (win != 0 && w != NULL && d != NULL); 215 /* ---------- beginning of the action ---------- */
197 216
198 if (!xim) 217 /*
199 { /* No input method? */ 218 * if no xim is presented, initialize xim ...
200 FRAME_X_XIC (f) = NULL; 219 */
201 return; 220 if ( xim_initted == False )
202 } 221 {
203 222 xim_initted = True;
223 XtGetApplicationNameAndClass (dpy, &name, &class);
224 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class);
225
226 /* destroy callback for im */
227 ximcallback.callback = IMDestroyCallback;
228 ximcallback.client_data = (XPointer)f;
229 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL);
230 }
231 else
232 {
233 xim = DEVICE_X_XIM (d);
234 }
235
236 w = FRAME_X_TEXT_WIDGET (f);
237
238 /*
239 * initialize XIC
240 */
241 if ( FRAME_X_XIC (f) ) return;
204 XtGetApplicationResources (w, &xic_vars, 242 XtGetApplicationResources (w, &xic_vars,
205 resources, XtNumber (resources), 243 resources, XtNumber (resources),
206 NULL, 0); 244 NULL, 0);
207
208 if (!xic_vars.fontset) 245 if (!xic_vars.fontset)
209 { 246 {
210 stderr_out ("Can't get fontset resource for Input Method\n"); 247 stderr_out ("Can't get fontset resource for Input Method\n");
211 FRAME_X_XIC (f) = NULL; 248 FRAME_X_XIC (f) = NULL;
212 return; 249 return;
213 } 250 }
214 251
252 /* construct xic */
253 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES(d), NULL);
215 FRAME_X_XIC_STYLE (f) = style = 254 FRAME_X_XIC_STYLE (f) = style =
216 best_style (&xic_vars.styles, DEVICE_X_XIM_STYLES (d)); 255 best_style (&xic_vars.styles, (XIMStyles *)DEVICE_X_XIM_STYLES(d));
217 256
218 /* Hopefully we don't have to conditionalize the following based on
219 style; the IM should ignore values it doesn't use */
220 p_list = XVaCreateNestedList (0, 257 p_list = XVaCreateNestedList (0,
221 XNArea, &p_area, 258 XNArea, &p_area,
222 XNSpotLocation, &spot, 259 XNSpotLocation, &spot,
223 XNForeground, xic_vars.fg, 260 XNForeground, xic_vars.fg,
224 XNBackground, xic_vars.bg, 261 XNBackground, xic_vars.bg,
225 XNFontSet, xic_vars.fontset, 262 XNFontSet, xic_vars.fontset,
226 NULL); 263 NULL);
227 264
228 s_list = XVaCreateNestedList (0, 265 s_list = XVaCreateNestedList (0,
229 XNArea, &s_area, 266 XNArea, &s_area,
230 XNForeground, xic_vars.fg, 267 XNForeground, xic_vars.fg,
231 XNBackground, xic_vars.bg, 268 XNBackground, xic_vars.bg,
232 XNFontSet, xic_vars.fontset, 269 XNFontSet, xic_vars.fontset,
233 NULL); 270 NULL);
271
234 FRAME_X_XIC (f) = xic = 272 FRAME_X_XIC (f) = xic =
235 XCreateIC (xim, 273 XCreateIC (xim,
236 XNInputStyle, style, 274 XNInputStyle, style,
237 XNClientWindow, win, 275 XNClientWindow, win,
238 XNFocusWindow, win, 276 XNFocusWindow, win,
239 XNPreeditAttributes, p_list, 277 XNPreeditAttributes, p_list,
240 XNStatusAttributes, s_list, 278 XNStatusAttributes, s_list,
241 NULL); 279 NULL);
242 XFree (p_list); 280 XFree (p_list);
243 XFree (s_list); 281 XFree (s_list);
244 282
245 if (!xic) 283 if (!xic)
246 { 284 {
247 stderr_out ("Warning: XCreateIC failed\n"); 285 stderr_out ("Warning: XCreateIC failed.\n");
248 return; 286 return;
249 } 287 }
250 288
251 if (style & XIMPreeditPosition) 289 if (style & XIMPreeditPosition)
252 { /* Init spot to invalid values */ 290 {
253 XPoint *frame_spot = &(FRAME_X_XIC_SPOT (f)); 291 XPoint *frame_spot = &(FRAME_X_XIC_SPOT(f));
254 frame_spot->x = frame_spot->y = -1; 292 frame_spot->x = frame_spot->y = -1;
255 } 293 }
256 294
257 XIM_SetGeometry (f); 295 XIM_SetGeometry (f);
258 296
259 XSetICFocus (xic); 297 XSetICFocus (xic);
260 298
261 #ifdef DEBUG_XIM 299 return;
262 describe_XIC (xic); 300 }
301
302 /* Create X input method for device */
303 void
304 XIM_init_device (struct device *d)
305 {
306 /* do nothing here */
307 return;
308 }
309
310 /* Callback for when the frame was deleted (closed) */
311 static void
312 XIM_delete_frame (Widget w, XtPointer client_data, XtPointer call_data)
313 {
314 struct frame *f = (struct frame *)client_data;
315 struct device *d = XDEVICE (FRAME_DEVICE ((struct frame *)client_data));
316 Display *dpy = DEVICE_X_DISPLAY (d);
317
318 XUnregisterIMInstantiateCallback (dpy, NULL, NULL, NULL,
319 IMInstantiateCallback, (XtPointer)f);
320
321 if ( FRAME_X_XIC (f) )
322 {
323 XDestroyIC (FRAME_X_XIC(f));
324 FRAME_X_XIC (f) = NULL;
325 }
326 return;
327 }
328
329 /* Create an X input context for this frame.
330 - Register the IM to be initiated later using XRegisterIMInstantiateCallback
331 */
332 void
333 XIM_init_frame (struct frame *f)
334 {
335 struct device *d = XDEVICE (FRAME_DEVICE (f));
336
337 XRegisterIMInstantiateCallback (DEVICE_X_DISPLAY (d), NULL, NULL, NULL,
338 IMInstantiateCallback, (XtPointer)f);
339
340 #if 0
341 if ( FRAME_X_XIC (f) )
342 return;
263 #endif 343 #endif
264 } 344 if ( ! DEVICE_X_XIM (d) )
345 {
346 stderr_out ("X Input Method open failed. Waiting IM to be enabled.\n");
347 }
348
349 /* when frame is going to be destroyed (closed) */
350 XtAddCallback (FRAME_X_TEXT_WIDGET(f), XNDestroyCallback,
351 XIM_delete_frame, (XtPointer)f);
352 return;
353 }
354
265 355
266 void 356 void
267 XIM_SetGeometry (struct frame *f) 357 XIM_SetGeometry (struct frame *f)
268 { 358 {
269 XIC xic = FRAME_X_XIC (f); 359 XIC xic = FRAME_X_XIC (f);
344 } 434 }
345 435
346 void 436 void
347 XIM_focus_event (struct frame *f, int in_p) 437 XIM_focus_event (struct frame *f, int in_p)
348 { 438 {
349 if (FRAME_X_XIC (f)) 439 if (FRAME_X_XIC (f) /* && FRAME_X_XIM_REGISTERED(f) */)
350 (in_p ? XSetICFocus : XUnsetICFocus) (FRAME_X_XIC (f)); 440 (in_p ? XSetICFocus : XUnsetICFocus) (FRAME_X_XIC (f));
351 } 441 }
352 442
353 #if 0 443 #if 0
354 #define XIM_Composed_Text_BUFSIZE 64 444 #define XIM_Composed_Text_BUFSIZE 64