comparison src/input-method-xlib.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents b8cc9ab3f761
children 41dbb7a9d5f2
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
24 24
25 /* This file implements an interface to X input methods, available 25 /* This file implements an interface to X input methods, available
26 with X11R5 and above. See O'Reilly, Xlib programmer's guide, 26 with X11R5 and above. See O'Reilly, Xlib programmer's guide,
27 and X11 R6 release guide chapters on internationalized input, 27 and X11 R6 release guide chapters on internationalized input,
28 for further details */ 28 for further details */
29
30 /*
31 Policy:
32
33 The XIM is of the device, by the device, for the device.
34 The XIC is of each frame, by each frame, for each frame.
35 The exceptions are:
36 1. Activate XICs on poor frames when the XIM is back.
37 2. Deactivate all the XICs when the XIM go down.
38
39 Methods:
40
41 - Register a callback for an XIM when the X device is being initialized.
42 XIM_init_device (d) { XRegisterIMInstantiateCallback (); }
43 The "XRegisterIMInstantiateCallback" is called when an XIM become
44 available on the X display.
45
46 - Catch the XIC when the frame is being initialized if XIM was available.
47 XIM_init_frame (f) { ... XCreateIC (); ... }
48
49 - Release the XIC when the frame is being closed.
50 XIM_delete_frame (f) { ... FRAME_X_XIC (f) = NULL; ... }
51 "XIM_delete_frame" is a "DestroyCallback" function declared in
52 XIM_init_frame ();
53
54 - Release all the XICs when the XIM was down accidentally.
55 In IMDestroyCallback:
56 DEVICE_FRAME_LOOP (...) { FRAME_X_XIC (f) = NULL; }
57
58 - Re-enable XIC for all the frames which doesn't have XIC when the XIM
59 is back.
60 In IMInstantiateCallback:
61 DEVICE_FRAME_LOOP (...) { XIM_init_frame (f); }
62
63
64 Note:
65
66 - Currently, we don't use XDestroyIC because of _XimProtoCloseIM
67 (internally registered as im->methods->close) does "Xfree (ic)".
68
69 */
70 29
71 #include <config.h> 30 #include <config.h>
72 #include "lisp.h" 31 #include "lisp.h"
73 #include <X11/Xlocale.h> /* More portable than <locale.h> ? */ 32 #include <X11/Xlocale.h> /* More portable than <locale.h> ? */
74 #include "frame.h" 33 #include "frame.h"
77 #include "buffer.h" 36 #include "buffer.h"
78 #include "console-x.h" 37 #include "console-x.h"
79 #include "EmacsFrame.h" 38 #include "EmacsFrame.h"
80 #include "events.h" 39 #include "events.h"
81 40
82 #ifdef THIS_IS_X11R6
83 #include <X11/IntrinsicP.h>
84 #endif
85
86 #ifndef XIM_XLIB 41 #ifndef XIM_XLIB
87 #error XIM_XLIB is not defined?? 42 #error XIM_XLIB is not defined??
88 #endif 43 #endif
89
90 Lisp_Object Qxim_xlib;
91 #define xim_warn(str) warn_when_safe (Qxim_xlib, Qwarning, str);
92 #define xim_warn1(fmt, str) warn_when_safe (Qxim_xlib, Qwarning, fmt, str);
93 #define xim_info(str) warn_when_safe (Qxim_xlib, Qinfo, str);
94 44
95 /* Get/Set IC values for just one attribute */ 45 /* Get/Set IC values for just one attribute */
96 #ifdef DEBUG_XEMACS 46 #ifdef DEBUG_XEMACS
97 #define XIC_Value(Get_Set, xic, name, attr, value) \ 47 #define XIC_Value(Get_Set, xic, name, attr, value) \
98 do { \ 48 do { \
120 "XIMPreeditNothing|XIMStatusNone\n" 70 "XIMPreeditNothing|XIMStatusNone\n"
121 "XIMPreeditNone|XIMStatusArea\n" 71 "XIMPreeditNone|XIMStatusArea\n"
122 "XIMPreeditNone|XIMStatusNothing\n" 72 "XIMPreeditNone|XIMStatusNothing\n"
123 "XIMPreeditNone|XIMStatusNone"; 73 "XIMPreeditNone|XIMStatusNone";
124 74
125 static Boolean xim_initted = False;
126
127 static XIMStyle best_style (XIMStyles *user, XIMStyles *xim); 75 static XIMStyle best_style (XIMStyles *user, XIMStyles *xim);
128 76
129 void 77 void
130 Initialize_Locale (void) 78 Initialize_Locale (void)
131 { 79 {
132 char *locale; 80 char *locale;
133 81
134 /* dverna - Nov. 98: #### DON'T DO THIS !!! The default XtLanguageProc 82 /* dverna - Nov. 98: ### DON'T DO THIS !!! The default XtLanguageProc
135 routine calls setlocale(LC_ALL, lang) which fucks up our lower-level 83 routine calls setlocale(LC_ALL, lang) which fucks up our lower-level
136 locale management, and especially the value of LC_NUMERIC. Anyway, since 84 locale management, and especially the value of LC_NUMERIC. Anyway, since
137 at this point, we don't know yet whether we're gonna need an X11 frame, 85 at this point, we don't know yet whether we're gonna need an X11 frame,
138 we should really do it manually and not use Xlib's dumb default routine */ 86 we should really do it manually and not use Xlib's dumb default routine */
139 /*XtSetLanguageProc (NULL, (XtLanguageProc) NULL, NULL);*/ 87 /*XtSetLanguageProc (NULL, (XtLanguageProc) NULL, NULL);*/
140 if ((locale = setlocale (LC_ALL, "")) == NULL) 88 if ((locale = setlocale (LC_ALL, "")) == NULL)
141 { 89 {
142 xim_warn ("Can't set locale.\n" 90 stderr_out ("Can't set locale.\n");
143 "Using C locale instead.\n"); 91 stderr_out ("Using C locale instead.\n");
144 putenv ("LANG=C"); 92 putenv ("LANG=C");
145 putenv ("LC_ALL=C"); 93 putenv ("LC_ALL=C");
146 if ((locale = setlocale (LC_ALL, "C")) == NULL) 94 if ((locale = setlocale (LC_ALL, "C")) == NULL)
147 { 95 {
148 xim_warn ("Can't even set locale to `C'!\n"); 96 stderr_out ("Can't even set locale to `C'!\n");
149 return; 97 return;
150 } 98 }
151 } 99 }
152 100
153 if (!XSupportsLocale ()) 101 if (!XSupportsLocale ())
154 { 102 {
155 xim_warn1 ("X Windows does not support locale `%s'\n" 103 stderr_out ("X Windows does not support locale `%s'\n", locale);
156 "Using C Locale instead\n", locale); 104 stderr_out ("Using C Locale instead\n");
157 putenv ("LANG=C"); 105 putenv ("LANG=C");
158 putenv ("LC_ALL=C"); 106 putenv ("LC_ALL=C");
159 if ((locale = setlocale (LC_ALL, "C")) == NULL) 107 if ((locale = setlocale (LC_ALL, "C")) == NULL)
160 { 108 {
161 xim_warn ("Can't even set locale to `C'!\n"); 109 stderr_out ("Can't even set locale to `C'!\n");
162 return; 110 return;
163 } 111 }
164 if (!XSupportsLocale ()) 112 if (!XSupportsLocale ())
165 { 113 {
166 xim_warn ("X Windows does not even support locale `C'!\n"); 114 stderr_out ("X Windows does not even support locale `C'!\n");
167 return; 115 return;
168 } 116 }
169 } 117 }
170 118
171 setlocale(LC_NUMERIC, "C"); 119 setlocale(LC_NUMERIC, "C");
172 120
173 if (XSetLocaleModifiers ("") == NULL) 121 if (XSetLocaleModifiers ("") == NULL)
174 { 122 {
175 xim_warn ("XSetLocaleModifiers(\"\") failed\n" 123 stderr_out ("XSetLocaleModifiers(\"\") failed\n");
176 "Check the value of the XMODIFIERS environment variable.\n"); 124 stderr_out ("Check the value of the XMODIFIERS environment variable.\n");
177 } 125 }
178 } 126 }
179 127
180 #ifdef THIS_IS_X11R6 /* Callbacks for IM are supported from X11R6 or later. */ 128 /* Create X input method for device */
181 /* Called from when XIM is destroying.
182 Clear all the XIC when the XIM was destroying... */
183 static void
184 IMDestroyCallback (XIM im, XPointer client_data, XPointer call_data)
185 {
186 struct device *d = (struct device *)client_data;
187 Lisp_Object tail;
188
189 DEVICE_FRAME_LOOP (tail, d)
190 {
191 struct frame *target_frame = XFRAME (XCAR (tail));
192 if (FRAME_X_P (target_frame) && FRAME_X_XIC (target_frame))
193 {
194 /* XDestroyIC (FRAME_X_XIC (target_frame)); */
195 FRAME_X_XIC (target_frame) = NULL;
196 }
197 }
198
199 DEVICE_X_XIM (d) = NULL;
200 xim_initted = False;
201 return;
202 }
203
204 /* This is registered in XIM_init_device (when DEVICE is initializing).
205 This activates XIM when XIM becomes available. */
206 static void
207 IMInstantiateCallback (Display *dpy, XPointer client_data, XPointer call_data)
208 {
209 struct device *d = (struct device *)client_data;
210 XIM xim;
211 char *name, *class;
212 XIMCallback ximcallback;
213 Lisp_Object tail;
214
215 /* if no xim is presented, initialize xim ... */
216 if ( xim_initted == False )
217 {
218 xim_initted = True;
219 XtGetApplicationNameAndClass (dpy, &name, &class);
220 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class);
221
222 /* destroy callback for im */
223 ximcallback.callback = IMDestroyCallback;
224 ximcallback.client_data = (XPointer) d;
225 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL);
226 }
227
228 /* activate XIC on all the X frames... */
229 DEVICE_FRAME_LOOP (tail, d)
230 {
231 struct frame *target_frame = XFRAME (XCAR (tail));
232 if (FRAME_X_P (target_frame) && !FRAME_X_XIC (target_frame))
233 {
234 XIM_init_frame (target_frame);
235 }
236 }
237 return;
238 }
239 #endif /* if THIS_IS_X11R6 */
240
241 /* Initialize XIM for X device.
242 Register the use of XIM using XRegisterIMInstantiateCallback. */
243 void 129 void
244 XIM_init_device (struct device *d) 130 XIM_init_device (struct device *d)
245 { 131 {
246 #ifdef THIS_IS_X11R6
247 DEVICE_X_XIM (d) = NULL;
248 XRegisterIMInstantiateCallback (DEVICE_X_DISPLAY (d), NULL, NULL, NULL,
249 IMInstantiateCallback, (XPointer) d);
250 return;
251 #else
252 Display *dpy = DEVICE_X_DISPLAY (d); 132 Display *dpy = DEVICE_X_DISPLAY (d);
253 char *name, *class; 133 char *name, *class;
254 XIM xim; 134 XIM xim;
255 135
256 XtGetApplicationNameAndClass (dpy, &name, &class); 136 XtGetApplicationNameAndClass (dpy, &name, &class);
137
257 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class); 138 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class);
139
258 if (xim == NULL) 140 if (xim == NULL)
259 { 141 {
260 xim_warn ("XOpenIM() failed...no input server available\n"); 142 stderr_out ("Warning: XOpenIM() failed...no input server available\n");
261 return; 143 return;
262 } 144 }
263 else 145 else
264 { 146 {
147 /* Get supported styles */
265 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES (d), NULL); 148 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES (d), NULL);
266 return; 149 #ifdef DEBUG_XIM
267 } 150 describe_XIM (xim);
268 #endif 151 #endif
269 } 152 }
270 153 }
271 154
272 /* 155 /* Create an X input context for this frame. */
273 * For the frames 156 void
274 */ 157 XIM_init_frame (struct frame *f)
275 158 {
276 /* Callback for the deleting frame. */
277 static void
278 XIM_delete_frame (Widget w, XtPointer client_data, XtPointer call_data)
279 {
280 struct frame *f = (struct frame *) client_data;
281 struct device *d = XDEVICE (FRAME_DEVICE (f)); 159 struct device *d = XDEVICE (FRAME_DEVICE (f));
282 160 XIM xim = DEVICE_X_XIM (d);
283 if (DEVICE_X_XIM (d)) 161 XIC xic;
284 {
285 if (FRAME_X_XIC (f))
286 {
287 XDestroyIC (FRAME_X_XIC (f));
288 FRAME_X_XIC (f) = NULL;
289 }
290 }
291 return;
292 }
293
294 /* Initialize XIC for new frame.
295 Create an X input context (XIC) for this frame. */
296 void
297 XIM_init_frame (struct frame *f)
298 {
299 struct device *d = XDEVICE (FRAME_DEVICE (f));
300 XIM xim;
301 Widget w = FRAME_X_TEXT_WIDGET (f); 162 Widget w = FRAME_X_TEXT_WIDGET (f);
302 Window win = XtWindow (w); 163 Window win = XtWindow (w);
303 XRectangle p_area = {0,0,1,1}, s_area = {0,0,1,1}; 164 XRectangle p_area = {0,0,1,1}, s_area={0,0,1,1};
304 XPoint spot = {0,0}; 165 XPoint spot = {0,0};
305 XIMStyle style; 166 XIMStyle style;
306 XVaNestedList p_list, s_list; 167 XVaNestedList p_list, s_list;
168
307 typedef struct 169 typedef struct
308 { 170 {
309 XIMStyles styles; 171 XIMStyles styles;
310 XFontSet fontset; 172 XFontSet fontset;
311 Pixel fg; 173 Pixel fg;
312 Pixel bg; 174 Pixel bg;
313 char *inputmethod;
314 } xic_vars_t; 175 } xic_vars_t;
176
315 xic_vars_t xic_vars; 177 xic_vars_t xic_vars;
316 XIC xic; 178
179 /* mrb: #### Fix so that background and foreground is set from
180 default face, rather than foreground and background resources, or
181 that the user can use set-frame-parameters to set xic attributes */
317 182
318 #define res(name, class, representation, field, default_value) \ 183 #define res(name, class, representation, field, default_value) \
319 { name, class, representation, sizeof(xic_vars.field), \ 184 { name, class, representation, sizeof(xic_vars.field), \
320 XtOffsetOf(xic_vars_t, field), XtRString, default_value } 185 XtOffsetOf(xic_vars_t, field), XtRString, default_value }
321 186
326 res(XtNfontSet, XtCFontSet, XtRFontSet, fontset, (XtPointer) XtDefaultFontSet), 191 res(XtNfontSet, XtCFontSet, XtRFontSet, fontset, (XtPointer) XtDefaultFontSet),
327 res(XtNximForeground, XtCForeground, XtRPixel, fg, (XtPointer) XtDefaultForeground), 192 res(XtNximForeground, XtCForeground, XtRPixel, fg, (XtPointer) XtDefaultForeground),
328 res(XtNximBackground, XtCBackground, XtRPixel, bg, (XtPointer) XtDefaultBackground) 193 res(XtNximBackground, XtCBackground, XtRPixel, bg, (XtPointer) XtDefaultBackground)
329 }; 194 };
330 195
331 196 assert (win != 0 && w != NULL && d != NULL);
332 xim = DEVICE_X_XIM (d);
333 197
334 if (!xim) 198 if (!xim)
335 { 199 { /* No input method? */
200 FRAME_X_XIC (f) = NULL;
336 return; 201 return;
337 } 202 }
338 203
339 w = FRAME_X_TEXT_WIDGET (f);
340
341 /*
342 * initialize XIC
343 */
344 if (FRAME_X_XIC (f)) return;
345 XtGetApplicationResources (w, &xic_vars, 204 XtGetApplicationResources (w, &xic_vars,
346 resources, XtNumber (resources), 205 resources, XtNumber (resources),
347 NULL, 0); 206 NULL, 0);
207
348 if (!xic_vars.fontset) 208 if (!xic_vars.fontset)
349 { 209 {
350 xim_warn ("Can't get fontset resource for Input Method\n"); 210 stderr_out ("Can't get fontset resource for Input Method\n");
351 FRAME_X_XIC (f) = NULL; 211 FRAME_X_XIC (f) = NULL;
352 return; 212 return;
353 } 213 }
354 214
355 /* construct xic */
356 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES(d), NULL);
357 FRAME_X_XIC_STYLE (f) = style = 215 FRAME_X_XIC_STYLE (f) = style =
358 best_style (&xic_vars.styles, (XIMStyles *)DEVICE_X_XIM_STYLES(d)); 216 best_style (&xic_vars.styles, DEVICE_X_XIM_STYLES (d));
359 217
218 /* Hopefully we don't have to conditionalize the following based on
219 style; the IM should ignore values it doesn't use */
360 p_list = XVaCreateNestedList (0, 220 p_list = XVaCreateNestedList (0,
361 XNArea, &p_area, 221 XNArea, &p_area,
362 XNSpotLocation, &spot, 222 XNSpotLocation, &spot,
363 XNForeground, xic_vars.fg, 223 XNForeground, xic_vars.fg,
364 XNBackground, xic_vars.bg, 224 XNBackground, xic_vars.bg,
365 XNFontSet, xic_vars.fontset, 225 XNFontSet, xic_vars.fontset,
366 NULL); 226 NULL);
367 227
368 s_list = XVaCreateNestedList (0, 228 s_list = XVaCreateNestedList (0,
369 XNArea, &s_area, 229 XNArea, &s_area,
370 XNForeground, xic_vars.fg, 230 XNForeground, xic_vars.fg,
371 XNBackground, xic_vars.bg, 231 XNBackground, xic_vars.bg,
372 XNFontSet, xic_vars.fontset, 232 XNFontSet, xic_vars.fontset,
373 NULL); 233 NULL);
374
375 FRAME_X_XIC (f) = xic = 234 FRAME_X_XIC (f) = xic =
376 XCreateIC (xim, 235 XCreateIC (xim,
377 XNInputStyle, style, 236 XNInputStyle, style,
378 XNClientWindow, win, 237 XNClientWindow, win,
379 XNFocusWindow, win, 238 XNFocusWindow, win,
380 XNPreeditAttributes, p_list, 239 XNPreeditAttributes, p_list,
381 XNStatusAttributes, s_list, 240 XNStatusAttributes, s_list,
382 NULL); 241 NULL);
383 XFree (p_list); 242 XFree (p_list);
384 XFree (s_list); 243 XFree (s_list);
385 244
386 if (!xic) 245 if (!xic)
387 { 246 {
388 xim_warn ("Warning: XCreateIC failed.\n"); 247 stderr_out ("Warning: XCreateIC failed\n");
389 return; 248 return;
390 } 249 }
391 250
392 if (style & XIMPreeditPosition) 251 if (style & XIMPreeditPosition)
393 { 252 { /* Init spot to invalid values */
394 XPoint *frame_spot = &(FRAME_X_XIC_SPOT(f)); 253 XPoint *frame_spot = &(FRAME_X_XIC_SPOT (f));
395 frame_spot->x = frame_spot->y = -1; 254 frame_spot->x = frame_spot->y = -1;
396 } 255 }
397 256
398 XIM_SetGeometry (f); 257 XIM_SetGeometry (f);
399 258
400 XSetICFocus (xic); 259 XSetICFocus (xic);
401 260
402 #ifdef THIS_IS_X11R6 261 #ifdef DEBUG_XIM
403 /* when frame is going to be destroyed (closed) */ 262 describe_XIC (xic);
404 XtAddCallback (FRAME_X_TEXT_WIDGET(f), XNDestroyCallback,
405 XIM_delete_frame, (XtPointer)f);
406 #endif 263 #endif
407 } 264 }
408
409 265
410 void 266 void
411 XIM_SetGeometry (struct frame *f) 267 XIM_SetGeometry (struct frame *f)
412 { 268 {
413 XIC xic = FRAME_X_XIC (f); 269 XIC xic = FRAME_X_XIC (f);
478 return; 334 return;
479 335
480 spot->x = (short) x; 336 spot->x = (short) x;
481 spot->y = (short) y; 337 spot->y = (short) y;
482 338
483 /* #### FIX: Must make sure spot fits within Preedit Area */ 339 /* ### FIX: Must make sure spot fits within Preedit Area */
484 XIC_Value (Set, xic, XNPreeditAttributes, XNSpotLocation, spot); 340 XIC_Value (Set, xic, XNPreeditAttributes, XNSpotLocation, spot);
485 #ifdef DEBUG_XIM 341 #ifdef DEBUG_XIM
486 stderr_out ("Spot: %d %d\n", spot->x, spot->y); 342 stderr_out ("Spot: %d %d\n", spot->x, spot->y);
487 #endif 343 #endif
488 } 344 }
489 345
490 void 346 void
491 XIM_focus_event (struct frame *f, int in_p) 347 XIM_focus_event (struct frame *f, int in_p)
492 { 348 {
493 if (FRAME_X_XIC (f) /* && FRAME_X_XIM_REGISTERED(f) */) 349 if (FRAME_X_XIC (f))
494 (in_p ? XSetICFocus : XUnsetICFocus) (FRAME_X_XIC (f)); 350 (in_p ? XSetICFocus : XUnsetICFocus) (FRAME_X_XIC (f));
495 } 351 }
496 352
497 #if 0 353 #if 0
498 #define XIM_Composed_Text_BUFSIZE 64 354 #define XIM_Composed_Text_BUFSIZE 64
606 XtPointer *converter_data) 462 XtPointer *converter_data)
607 { 463 {
608 #define STYLE_INFO(style) { style, #style, sizeof(#style) } 464 #define STYLE_INFO(style) { style, #style, sizeof(#style) }
609 static struct XIMStyleInfo 465 static struct XIMStyleInfo
610 { 466 {
611 const XIMStyle style; 467 CONST XIMStyle style;
612 const char * const name; 468 CONST char * CONST name;
613 const int namelen; 469 CONST int namelen;
614 } emacs_XIMStyleInfo[] = { 470 } emacs_XIMStyleInfo[] = {
615 STYLE_INFO (XIMPreeditPosition|XIMStatusArea), 471 STYLE_INFO (XIMPreeditPosition|XIMStatusArea),
616 STYLE_INFO (XIMPreeditPosition|XIMStatusNothing), 472 STYLE_INFO (XIMPreeditPosition|XIMStatusNothing),
617 STYLE_INFO (XIMPreeditPosition|XIMStatusNone), 473 STYLE_INFO (XIMPreeditPosition|XIMStatusNone),
618 STYLE_INFO (XIMPreeditNothing|XIMStatusArea), 474 STYLE_INFO (XIMPreeditNothing|XIMStatusArea),
624 }; 480 };
625 #undef STYLE_INFO 481 #undef STYLE_INFO
626 482
627 char *s = (char *) fromVal->addr; 483 char *s = (char *) fromVal->addr;
628 char *end = s + fromVal->size; 484 char *end = s + fromVal->size;
629 XIMStyles * const p = (XIMStyles *) toVal->addr; 485 XIMStyles * CONST p = (XIMStyles *) toVal->addr;
630 const char * const delimiter = " \t\n\r:;," ; 486 CONST char * CONST delimiter = " \t\n\r:;," ;
631 const int max_styles = XtNumber(emacs_XIMStyleInfo); 487 CONST int max_styles = XtNumber(emacs_XIMStyleInfo);
632 int i; 488 int i;
633 char *c; 489 char *c;
634 490
635 #ifdef DEBUG_XIM 491 #ifdef DEBUG_XIM
636 stderr_out ("EmacsCvtStringToXIMStyles called with size=%d, string=\"%s\"\n", 492 stderr_out ("EmacsCvtStringToXIMStyles called with size=%d, string=\"%s\"\n",
779 } 635 }
780 } 636 }
781 return DEFAULTStyle; /* Default Style */ 637 return DEFAULTStyle; /* Default Style */
782 } 638 }
783 639
784 /* These lisp-callable functions will be sealed until xim-leim is needed.
785 Oct 22 1999 - kazz */
786 #if 0
787 /*
788 * External callable function for XIM
789 */
790 DEFUN ("x-open-xim", Fx_open_xim, 1, 1, 0, /*
791 Open the XIC on the frame if XIM is available.
792 Commonly, use this as \(x-open-xim \(selected-frame)).
793 If the frame is not on X device, return signal.
794 If XIC is created successfully return t. If not return nil.
795 */
796 (frame))
797 {
798 struct frame *f;
799
800 CHECK_LIVE_FRAME (frame);
801 f = XFRAME (frame);
802 if (!FRAME_X_P (f))
803 return signal_simple_error ("This frame is not on X device", frame);
804
805 XIM_init_frame (f);
806 return FRAME_X_XIC (f) ? Qt : Qnil;
807 }
808
809 DEFUN ("x-close-xim", Fx_close_xim, 1, 1, 0, /*
810 Close the XIC on the frame if it exists.
811 Commonly, use this as \(x-close-xim \(selected-frame)).
812 If the frame is not on X device, return signal.
813 Otherwise, it destroys the XIC if it exists, then returns t anyway.
814 */
815 (frame))
816 {
817 struct frame *f;
818 struct device *d;
819
820 CHECK_LIVE_FRAME (frame);
821 f = XFRAME (frame);
822 if (!FRAME_X_P (f))
823 return signal_simple_error ("This frame is not on X device", frame);
824
825 d = XDEVICE (FRAME_DEVICE (f));
826 if (DEVICE_X_XIM (d)) {
827 /* XDestroyIC (FRAME_X_XIC (XFRAME (f))); */
828 FRAME_X_XIC (XFRAME (f)) = NULL;
829 }
830 return Qt;
831 }
832 #endif /* if 0 */
833
834 void
835 syms_of_input_method_xlib (void)
836 {
837 defsymbol (&Qxim_xlib, "xim-xlib");
838 #if 0 /* see above */
839 DEFSUBR (Fx_open_xim);
840 DEFSUBR (Fx_close_xim);
841 #endif
842 }
843 640
844 void 641 void
845 vars_of_input_method_xlib (void) 642 vars_of_input_method_xlib (void)
846 { 643 {
847 Fprovide (intern ("xim")); 644 Fprovide (intern ("xim"));