comparison src/input-method-xlib.c @ 398:74fd4e045ea6 r21-2-29

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