comparison src/input-method-xlib.c @ 371:cc15677e0335 r21-2b1

Import from CVS: tag r21-2b1
author cvs
date Mon, 13 Aug 2007 11:03:08 +0200
parents 8e84bee8ddd0
children d883f39b8495
comparison
equal deleted inserted replaced
370:bd866891f083 371:cc15677e0335
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 #include <X11/Xaw/XawImP.h>
85 #endif
86
87 #ifndef XIM_XLIB 41 #ifndef XIM_XLIB
88 #error XIM_XLIB is not defined?? 42 #error XIM_XLIB is not defined??
89 #endif 43 #endif
90
91 Lisp_Object Qxim_xlib;
92 #define xim_warn(str) warn_when_safe (Qxim_xlib, Qwarning, str);
93 #define xim_warn1(fmt, str) warn_when_safe (Qxim_xlib, Qwarning, fmt, str);
94 #define xim_info(str) warn_when_safe (Qxim_xlib, Qinfo, str);
95 44
96 /* Get/Set IC values for just one attribute */ 45 /* Get/Set IC values for just one attribute */
97 #ifdef DEBUG_XEMACS 46 #ifdef DEBUG_XEMACS
98 #define XIC_Value(Get_Set, xic, name, attr, value) \ 47 #define XIC_Value(Get_Set, xic, name, attr, value) \
99 do { \ 48 do { \
121 "XIMPreeditNothing|XIMStatusNone\n" 70 "XIMPreeditNothing|XIMStatusNone\n"
122 "XIMPreeditNone|XIMStatusArea\n" 71 "XIMPreeditNone|XIMStatusArea\n"
123 "XIMPreeditNone|XIMStatusNothing\n" 72 "XIMPreeditNone|XIMStatusNothing\n"
124 "XIMPreeditNone|XIMStatusNone"; 73 "XIMPreeditNone|XIMStatusNone";
125 74
126 static Boolean xim_initted = False;
127
128 static XIMStyle best_style (XIMStyles *user, XIMStyles *xim); 75 static XIMStyle best_style (XIMStyles *user, XIMStyles *xim);
129 76
130 void 77 void
131 Initialize_Locale (void) 78 Initialize_Locale (void)
132 { 79 {
133 char *locale; 80 char *locale;
134 81
135 /* dverna - Nov. 98: ### DON'T DO THIS !!! The default XtLanguageProc 82 XtSetLanguageProc (NULL, (XtLanguageProc) NULL, NULL);
136 routine calls setlocale(LC_ALL, lang) which fucks up our lower-level
137 locale management, and especially the value of LC_NUMERIC. Anyway, since
138 at this point, we don't know yet whether we're gonna need an X11 frame,
139 we should really do it manually and not use Xlib's dumb default routine */
140 /*XtSetLanguageProc (NULL, (XtLanguageProc) NULL, NULL);*/
141 if ((locale = setlocale (LC_ALL, "")) == NULL) 83 if ((locale = setlocale (LC_ALL, "")) == NULL)
142 { 84 {
143 xim_warn ("Can't set locale.\n" 85 stderr_out ("Can't set locale.\n");
144 "Using C locale instead.\n"); 86 stderr_out ("Using C locale instead.\n");
145 putenv ("LANG=C"); 87 putenv ("LANG=C");
146 putenv ("LC_ALL=C"); 88 putenv ("LC_ALL=C");
147 if ((locale = setlocale (LC_ALL, "C")) == NULL) 89 if ((locale = setlocale (LC_ALL, "C")) == NULL)
148 { 90 {
149 xim_warn ("Can't even set locale to `C'!\n"); 91 stderr_out ("Can't even set locale to `C'!\n");
150 return; 92 return;
151 } 93 }
152 } 94 }
153 95
154 if (!XSupportsLocale ()) 96 if (!XSupportsLocale ())
155 { 97 {
156 xim_warn1 ("X Windows does not support locale `%s'\n" 98 stderr_out ("X Windows does not support locale `%s'\n", locale);
157 "Using C Locale instead\n", locale); 99 stderr_out ("Using C Locale instead\n");
158 putenv ("LANG=C"); 100 putenv ("LANG=C");
159 putenv ("LC_ALL=C"); 101 putenv ("LC_ALL=C");
160 if ((locale = setlocale (LC_ALL, "C")) == NULL) 102 if ((locale = setlocale (LC_ALL, "C")) == NULL)
161 { 103 {
162 xim_warn ("Can't even set locale to `C'!\n"); 104 stderr_out ("Can't even set locale to `C'!\n");
163 return; 105 return;
164 } 106 }
165 if (!XSupportsLocale ()) 107 if (!XSupportsLocale ())
166 { 108 {
167 xim_warn ("X Windows does not even support locale `C'!\n"); 109 stderr_out ("X Windows does not even support locale `C'!\n");
168 return; 110 return;
169 } 111 }
170 } 112 }
171 113
172 setlocale(LC_NUMERIC, "C"); 114 setlocale(LC_NUMERIC, "C");
173 115
174 if (XSetLocaleModifiers ("") == NULL) 116 if (XSetLocaleModifiers ("") == NULL)
175 { 117 {
176 xim_warn ("XSetLocaleModifiers(\"\") failed\n" 118 stderr_out ("XSetLocaleModifiers(\"\") failed\n");
177 "Check the value of the XMODIFIERS environment variable.\n"); 119 stderr_out ("Check the value of the XMODIFIERS environment variable.\n");
178 } 120 }
179 } 121 }
180 122
181 #ifdef THIS_IS_X11R6 /* Callbacks for IM are supported from X11R6 or later. */ 123 /* Create X input method for device */
182 /* Called from when XIM is destroying.
183 Clear all the XIC when the XIM was destroying... */
184 static void
185 IMDestroyCallback (XIM im, XPointer client_data, XPointer call_data)
186 {
187 struct device *d = (struct device *)client_data;
188 Lisp_Object tail;
189
190 DEVICE_FRAME_LOOP (tail, d)
191 {
192 struct frame *target_frame = XFRAME (XCAR (tail));
193 if (FRAME_X_P (target_frame) && FRAME_X_XIC (target_frame))
194 {
195 /* XDestroyIC (FRAME_X_XIC (target_frame)); */
196 FRAME_X_XIC (target_frame) = NULL;
197 }
198 }
199
200 DEVICE_X_XIM (d) = NULL;
201 xim_initted = False;
202 return;
203 }
204
205 /* This is registered in XIM_init_device (when DEVICE is initializing).
206 This activates XIM when XIM becomes available. */
207 static void
208 IMInstantiateCallback (Display *dpy, XPointer client_data, XPointer call_data)
209 {
210 struct device *d = (struct device *)client_data;
211 XIM xim;
212 char *name, *class;
213 XIMCallback ximcallback;
214 Lisp_Object tail;
215
216 /* if no xim is presented, initialize xim ... */
217 if ( xim_initted == False )
218 {
219 xim_initted = True;
220 XtGetApplicationNameAndClass (dpy, &name, &class);
221 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class);
222
223 /* destroy callback for im */
224 ximcallback.callback = IMDestroyCallback;
225 ximcallback.client_data = (XPointer) d;
226 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL);
227 }
228
229 /* activate XIC on all the X frames... */
230 DEVICE_FRAME_LOOP (tail, d)
231 {
232 struct frame *target_frame = XFRAME (XCAR (tail));
233 if (FRAME_X_P (target_frame) && !FRAME_X_XIC (target_frame))
234 {
235 XIM_init_frame (target_frame);
236 }
237 }
238 return;
239 }
240 #endif /* if THIS_IS_X11R6 */
241
242 /* Initialize XIM for X device.
243 Register the use of XIM using XRegisterIMInstantiateCallback. */
244 void 124 void
245 XIM_init_device (struct device *d) 125 XIM_init_device (struct device *d)
246 { 126 {
247 #ifdef THIS_IS_X11R6
248 DEVICE_X_XIM (d) = NULL;
249 XRegisterIMInstantiateCallback (DEVICE_X_DISPLAY (d), NULL, NULL, NULL,
250 IMInstantiateCallback, (XPointer) d);
251 return;
252 #else
253 Display *dpy = DEVICE_X_DISPLAY (d); 127 Display *dpy = DEVICE_X_DISPLAY (d);
254 char *name, *class; 128 char *name, *class;
255 XIM xim; 129 XIM xim;
256 130
257 XtGetApplicationNameAndClass (dpy, &name, &class); 131 XtGetApplicationNameAndClass (dpy, &name, &class);
132
258 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class); 133 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class);
134
259 if (xim == NULL) 135 if (xim == NULL)
260 { 136 {
261 xim_warn ("XOpenIM() failed...no input server available\n"); 137 stderr_out ("Warning: XOpenIM() failed...no input server available\n");
262 return; 138 return;
263 } 139 }
264 else 140 else
265 { 141 {
142 /* Get supported styles */
266 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES (d), NULL); 143 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES (d), NULL);
267 return; 144 #ifdef DEBUG_XIM
268 } 145 describe_XIM (xim);
269 #endif 146 #endif
270 } 147 }
271 148 }
272 149
273 /* 150 /* Create an X input context for this frame. */
274 * For the frames 151 void
275 */ 152 XIM_init_frame (struct frame *f)
276 153 {
277 /* Callback for the deleting frame. */
278 static void
279 XIM_delete_frame (Widget w, XtPointer client_data, XtPointer call_data)
280 {
281 struct frame *f = (struct frame *) client_data;
282 struct device *d = XDEVICE (FRAME_DEVICE (f)); 154 struct device *d = XDEVICE (FRAME_DEVICE (f));
283 155 XIM xim = DEVICE_X_XIM (d);
284 if (DEVICE_X_XIM (d)) 156 XIC xic;
285 {
286 if (FRAME_X_XIC (f))
287 {
288 XDestroyIC (FRAME_X_XIC (f));
289 FRAME_X_XIC (f) = NULL;
290 }
291 }
292 return;
293 }
294
295 /* Initialize XIC for new frame.
296 Create an X input context (XIC) for this frame. */
297 void
298 XIM_init_frame (struct frame *f)
299 {
300 struct device *d = XDEVICE (FRAME_DEVICE (f));
301 XIM xim;
302 Widget w = FRAME_X_TEXT_WIDGET (f); 157 Widget w = FRAME_X_TEXT_WIDGET (f);
303 Window win = XtWindow (w); 158 Window win = XtWindow (w);
304 XRectangle p_area = {0,0,1,1}, s_area = {0,0,1,1}; 159 XRectangle p_area = {0,0,1,1}, s_area={0,0,1,1};
305 XPoint spot = {0,0}; 160 XPoint spot = {0,0};
306 XIMStyle style; 161 XIMStyle style;
307 XVaNestedList p_list, s_list; 162 XVaNestedList p_list, s_list;
163
308 typedef struct 164 typedef struct
309 { 165 {
310 XIMStyles styles; 166 XIMStyles styles;
311 XFontSet fontset; 167 XFontSet fontset;
312 Pixel fg; 168 Pixel fg;
313 Pixel bg; 169 Pixel bg;
314 char *inputmethod;
315 } xic_vars_t; 170 } xic_vars_t;
171
316 xic_vars_t xic_vars; 172 xic_vars_t xic_vars;
317 XIC xic; 173
174 /* mrb: #### Fix so that background and foreground is set from
175 default face, rather than foreground and background resources, or
176 that the user can use set-frame-parameters to set xic attributes */
318 177
319 #define res(name, class, representation, field, default_value) \ 178 #define res(name, class, representation, field, default_value) \
320 { name, class, representation, sizeof(xic_vars.field), \ 179 { name, class, representation, sizeof(xic_vars.field), \
321 XtOffsetOf(xic_vars_t, field), XtRString, default_value } 180 XtOffsetOf(xic_vars_t, field), XtRString, default_value }
322 181
323 static XtResource resources[] = 182 static XtResource resources[] =
324 { 183 {
325 /* name class represent'n field default value */ 184 /* name class represent'n field default value */
326 #ifdef THIS_IS_X11R6 185 res(XtNximStyles, XtCXimStyles, XtRXimStyles, styles, DefaultXIMStyles),
327 res(XtNinputMethod, XtCInputMethod, XtRString, inputmethod, (XtPointer) NULL), 186 res(XtNfontSet, XtCFontSet, XtRFontSet, fontset, XtDefaultFontSet),
328 #endif 187 res(XtNximForeground, XtCForeground, XtRPixel, fg, XtDefaultForeground),
329 res(XtNximStyles, XtCXimStyles, XtRXimStyles, styles, (XtPointer) DefaultXIMStyles), 188 res(XtNximBackground, XtCBackground, XtRPixel, bg, XtDefaultBackground)
330 res(XtNfontSet, XtCFontSet, XtRFontSet, fontset, (XtPointer) XtDefaultFontSet),
331 res(XtNximForeground, XtCForeground, XtRPixel, fg, (XtPointer) XtDefaultForeground),
332 res(XtNximBackground, XtCBackground, XtRPixel, bg, (XtPointer) XtDefaultBackground)
333 }; 189 };
334 190
335 191 assert (win != 0 && w != NULL && d != NULL);
336 xim = DEVICE_X_XIM (d);
337 192
338 if (!xim) 193 if (!xim)
339 { 194 { /* No input method? */
340 xim_info ("X Input Method open failed. Waiting for an XIM to be enabled.\n"); 195 FRAME_X_XIC (f) = NULL;
341 return; 196 return;
342 } 197 }
343 198
344 w = FRAME_X_TEXT_WIDGET (f);
345
346 /*
347 * initialize XIC
348 */
349 if (FRAME_X_XIC (f)) return;
350 XtGetApplicationResources (w, &xic_vars, 199 XtGetApplicationResources (w, &xic_vars,
351 resources, XtNumber (resources), 200 resources, XtNumber (resources),
352 NULL, 0); 201 NULL, 0);
202
353 if (!xic_vars.fontset) 203 if (!xic_vars.fontset)
354 { 204 {
355 xim_warn ("Can't get fontset resource for Input Method\n"); 205 stderr_out ("Can't get fontset resource for Input Method\n");
356 FRAME_X_XIC (f) = NULL; 206 FRAME_X_XIC (f) = NULL;
357 return; 207 return;
358 } 208 }
359 209
360 /* construct xic */
361 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES(d), NULL);
362 FRAME_X_XIC_STYLE (f) = style = 210 FRAME_X_XIC_STYLE (f) = style =
363 best_style (&xic_vars.styles, (XIMStyles *)DEVICE_X_XIM_STYLES(d)); 211 best_style (&xic_vars.styles, DEVICE_X_XIM_STYLES (d));
364 212
213 /* Hopefully we don't have to conditionalize the following based on
214 style; the IM should ignore values it doesn't use */
365 p_list = XVaCreateNestedList (0, 215 p_list = XVaCreateNestedList (0,
366 XNArea, &p_area, 216 XNArea, &p_area,
367 XNSpotLocation, &spot, 217 XNSpotLocation, &spot,
368 XNForeground, xic_vars.fg, 218 XNForeground, xic_vars.fg,
369 XNBackground, xic_vars.bg, 219 XNBackground, xic_vars.bg,
370 XNFontSet, xic_vars.fontset, 220 XNFontSet, xic_vars.fontset,
371 NULL); 221 NULL);
372 222
373 s_list = XVaCreateNestedList (0, 223 s_list = XVaCreateNestedList (0,
374 XNArea, &s_area, 224 XNArea, &s_area,
375 XNForeground, xic_vars.fg, 225 XNForeground, xic_vars.fg,
376 XNBackground, xic_vars.bg, 226 XNBackground, xic_vars.bg,
377 XNFontSet, xic_vars.fontset, 227 XNFontSet, xic_vars.fontset,
378 NULL); 228 NULL);
379
380 FRAME_X_XIC (f) = xic = 229 FRAME_X_XIC (f) = xic =
381 XCreateIC (xim, 230 XCreateIC (xim,
382 XNInputStyle, style, 231 XNInputStyle, style,
383 XNClientWindow, win, 232 XNClientWindow, win,
384 XNFocusWindow, win, 233 XNFocusWindow, win,
385 XNPreeditAttributes, p_list, 234 XNPreeditAttributes, p_list,
386 XNStatusAttributes, s_list, 235 XNStatusAttributes, s_list,
387 NULL); 236 NULL);
388 XFree (p_list); 237 XFree (p_list);
389 XFree (s_list); 238 XFree (s_list);
390 239
391 if (!xic) 240 if (!xic)
392 { 241 {
393 xim_warn ("Warning: XCreateIC failed.\n"); 242 stderr_out ("Warning: XCreateIC failed\n");
394 return; 243 return;
395 } 244 }
396 245
397 if (style & XIMPreeditPosition) 246 if (style & XIMPreeditPosition)
398 { 247 { /* Init spot to invalid values */
399 XPoint *frame_spot = &(FRAME_X_XIC_SPOT(f)); 248 XPoint *frame_spot = &(FRAME_X_XIC_SPOT (f));
400 frame_spot->x = frame_spot->y = -1; 249 frame_spot->x = frame_spot->y = -1;
401 } 250 }
402 251
403 XIM_SetGeometry (f); 252 XIM_SetGeometry (f);
404 253
405 XSetICFocus (xic); 254 XSetICFocus (xic);
406 255
407 #ifdef THIS_IS_X11R6 256 #ifdef DEBUG_XIM
408 /* when frame is going to be destroyed (closed) */ 257 describe_XIC (xic);
409 XtAddCallback (FRAME_X_TEXT_WIDGET(f), XNDestroyCallback,
410 XIM_delete_frame, (XtPointer)f);
411 #endif 258 #endif
412 } 259 }
413
414 260
415 void 261 void
416 XIM_SetGeometry (struct frame *f) 262 XIM_SetGeometry (struct frame *f)
417 { 263 {
418 XIC xic = FRAME_X_XIC (f); 264 XIC xic = FRAME_X_XIC (f);
493 } 339 }
494 340
495 void 341 void
496 XIM_focus_event (struct frame *f, int in_p) 342 XIM_focus_event (struct frame *f, int in_p)
497 { 343 {
498 if (FRAME_X_XIC (f) /* && FRAME_X_XIM_REGISTERED(f) */) 344 if (FRAME_X_XIC (f))
499 (in_p ? XSetICFocus : XUnsetICFocus) (FRAME_X_XIC (f)); 345 (in_p ? XSetICFocus : XUnsetICFocus) (FRAME_X_XIC (f));
500 } 346 }
501 347
502 #if 0 348 #if 0
503 #define XIM_Composed_Text_BUFSIZE 64 349 #define XIM_Composed_Text_BUFSIZE 64
532 Status status; 378 Status status;
533 int len; 379 int len;
534 int i; 380 int i;
535 XClientMessageEvent new_event; 381 XClientMessageEvent new_event;
536 382
537 retry: 383 try_again:
538 len = XwcLookupString (ic, x_key_event, composed_input_buf.data, 384 len = XwcLookupString (ic, x_key_event, composed_input_buf.data,
539 composed_input_buf.size, &keysym, &status); 385 composed_input_buf.size, &keysym, &status);
540 switch (status) 386 switch (status)
541 { 387 {
542 case XBufferOverflow: 388 case XBufferOverflow:
543 /* GROW_WC_STRING (&composed_input_buf, 32); mrb */ 389 /* GROW_WC_STRING (&composed_input_buf, 32); mrb */
544 goto retry; 390 goto try_again;
545 case XLookupChars: 391 case XLookupChars:
546 break; 392 break;
547 default: 393 default:
548 abort (); 394 abort ();
549 } 395 }
784 } 630 }
785 } 631 }
786 return DEFAULTStyle; /* Default Style */ 632 return DEFAULTStyle; /* Default Style */
787 } 633 }
788 634
789 /* These lisp-callable functions will be sealed until xim-leim is needed.
790 Oct 22 1999 - kazz */
791 #if 0
792 /*
793 * External callable function for XIM
794 */
795 DEFUN ("x-open-xim", Fx_open_xim, 1, 1, 0, /*
796 Open the XIC on the frame if XIM is available.
797 Commonly, use this as \(x-open-xim \(selected-frame)).
798 If the frame is not on X device, return signal.
799 If XIC is created successfully return t. If not return nil.
800 */
801 (frame))
802 {
803 struct frame *f;
804
805 CHECK_LIVE_FRAME (frame);
806 f = XFRAME (frame);
807 if (!FRAME_X_P (f))
808 return signal_simple_error ("This frame is not on X device", frame);
809
810 XIM_init_frame (f);
811 return FRAME_X_XIC (f) ? Qt : Qnil;
812 }
813
814 DEFUN ("x-close-xim", Fx_close_xim, 1, 1, 0, /*
815 Close the XIC on the frame if it exists.
816 Commonly, use this as \(x-close-xim \(selected-frame)).
817 If the frame is not on X device, return signal.
818 Otherwise, it destroys the XIC if it exists, then returns t anyway.
819 */
820 (frame))
821 {
822 struct frame *f;
823 struct device *d;
824
825 CHECK_LIVE_FRAME (frame);
826 f = XFRAME (frame);
827 if (!FRAME_X_P (f))
828 return signal_simple_error ("This frame is not on X device", frame);
829
830 d = XDEVICE (FRAME_DEVICE (f));
831 if (DEVICE_X_XIM (d)) {
832 /* XDestroyIC (FRAME_X_XIC (XFRAME (f))); */
833 FRAME_X_XIC (XFRAME (f)) = NULL;
834 }
835 return Qt;
836 }
837 #endif /* if 0 */
838
839 void
840 syms_of_input_method_xlib (void)
841 {
842 defsymbol (&Qxim_xlib, "xim-xlib");
843 #if 0 /* see above */
844 DEFSUBR (Fx_open_xim);
845 DEFSUBR (Fx_close_xim);
846 #endif
847 }
848 635
849 void 636 void
850 vars_of_input_method_xlib (void) 637 vars_of_input_method_xlib (void)
851 { 638 {
852 Fprovide (intern ("xim")); 639 Fprovide (intern ("xim"));