1 /* Various functions for X11R5+ input methods, using the Xlib interface.
2 Copyright (C) 1996 Sun Microsystems.
4 This file is part of XEmacs.
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Synched up with: Not in FSF. */
23 /* Written by Martin Buchholz. */
25 /* This file implements an interface to X input methods, available
26 with X11R5 and above. See O'Reilly, Xlib programmer's guide,
27 and X11 R6 release guide chapters on internationalized input,
28 for further details */
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.
36 1. Activate XICs on poor frames when the XIM is back.
37 2. Deactivate all the XICs when the XIM go down.
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.
46 - Catch the XIC when the frame is being initialized if XIM was available.
47 XIM_init_frame (f) { ... XCreateIC (); ... }
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
54 - Release all the XICs when the XIM was down accidentally.
56 DEVICE_FRAME_LOOP (...) { FRAME_X_XIC (f) = NULL; }
58 - Re-enable XIC for all the frames which doesn't have XIC when the XIM
60 In IMInstantiateCallback:
61 DEVICE_FRAME_LOOP (...) { XIM_init_frame (f); }
66 - Currently, we don't use XDestroyIC because of _XimProtoCloseIM
67 (internally registered as im->methods->close) does "Xfree (ic)".
73 #include <X11/Xlocale.h> /* More portable than <locale.h> ? */
78 #include "console-x.h"
79 #include "EmacsFrame.h"
83 #include <X11/IntrinsicP.h>
87 #error XIM_XLIB is not defined??
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);
95 /* Get/Set IC values for just one attribute */
97 #define XIC_Value(Get_Set, xic, name, attr, value) \
100 XVaNestedList list = XVaCreateNestedList (0, attr, value, NULL); \
101 if ((bad_arg = X##Get_Set##ICValues (xic, name, list, NULL)) != NULL) \
102 stderr_out ("X" #Get_Set "ICValues " "bad Arg: %s\n", bad_arg); \
105 #else /* ! DEBUG_XEMACS */
106 #define XIC_Value(Get_Set, xic, name, attr, value) \
108 XVaNestedList list = XVaCreateNestedList (0, attr, value, NULL); \
109 X##Get_Set##ICValues (xic, name, list, NULL); \
112 #endif /* DEBUG_XEMACS */
114 static char DefaultXIMStyles[] =
115 "XIMPreeditPosition|XIMStatusArea\n"
116 "XIMPreeditPosition|XIMStatusNone\n"
117 "XIMPreeditPosition|XIMStatusNothing\n"
118 "XIMPreeditNothing|XIMStatusArea\n"
119 "XIMPreeditNothing|XIMStatusNothing\n"
120 "XIMPreeditNothing|XIMStatusNone\n"
121 "XIMPreeditNone|XIMStatusArea\n"
122 "XIMPreeditNone|XIMStatusNothing\n"
123 "XIMPreeditNone|XIMStatusNone";
125 static Boolean xim_initted = False;
127 static XIMStyle best_style (XIMStyles *user, XIMStyles *xim);
130 Initialize_Locale (void)
134 /* dverna - Nov. 98: ### DON'T DO THIS !!! The default XtLanguageProc
135 routine calls setlocale(LC_ALL, lang) which fucks up our lower-level
136 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,
138 we should really do it manually and not use Xlib's dumb default routine */
139 /*XtSetLanguageProc (NULL, (XtLanguageProc) NULL, NULL);*/
140 if ((locale = setlocale (LC_ALL, "")) == NULL)
142 xim_warn ("Can't set locale.\n"
143 "Using C locale instead.\n");
146 if ((locale = setlocale (LC_ALL, "C")) == NULL)
148 xim_warn ("Can't even set locale to `C'!\n");
153 if (!XSupportsLocale ())
155 xim_warn1 ("X Windows does not support locale `%s'\n"
156 "Using C Locale instead\n", locale);
159 if ((locale = setlocale (LC_ALL, "C")) == NULL)
161 xim_warn ("Can't even set locale to `C'!\n");
164 if (!XSupportsLocale ())
166 xim_warn ("X Windows does not even support locale `C'!\n");
171 setlocale(LC_NUMERIC, "C");
173 if (XSetLocaleModifiers ("") == NULL)
175 xim_warn ("XSetLocaleModifiers(\"\") failed\n"
176 "Check the value of the XMODIFIERS environment variable.\n");
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... */
184 IMDestroyCallback (XIM im, XPointer client_data, XPointer call_data)
186 struct device *d = (struct device *)client_data;
189 DEVICE_FRAME_LOOP (tail, d)
191 struct frame *target_frame = XFRAME (XCAR (tail));
192 if (FRAME_X_P (target_frame) && FRAME_X_XIC (target_frame))
194 /* XDestroyIC (FRAME_X_XIC (target_frame)); */
195 FRAME_X_XIC (target_frame) = NULL;
199 DEVICE_X_XIM (d) = NULL;
204 /* This is registered in XIM_init_device (when DEVICE is initializing).
205 This activates XIM when XIM becomes available. */
207 IMInstantiateCallback (Display *dpy, XPointer client_data, XPointer call_data)
209 struct device *d = (struct device *)client_data;
212 XIMCallback ximcallback;
215 /* if no xim is presented, initialize xim ... */
216 if ( xim_initted == False )
219 XtGetApplicationNameAndClass (dpy, &name, &class);
220 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class);
222 /* destroy callback for im */
223 ximcallback.callback = IMDestroyCallback;
224 ximcallback.client_data = (XPointer) d;
225 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL);
228 /* activate XIC on all the X frames... */
229 DEVICE_FRAME_LOOP (tail, d)
231 struct frame *target_frame = XFRAME (XCAR (tail));
232 if (FRAME_X_P (target_frame) && !FRAME_X_XIC (target_frame))
234 XIM_init_frame (target_frame);
239 #endif /* if THIS_IS_X11R6 */
241 /* Initialize XIM for X device.
242 Register the use of XIM using XRegisterIMInstantiateCallback. */
244 XIM_init_device (struct device *d)
247 DEVICE_X_XIM (d) = NULL;
248 XRegisterIMInstantiateCallback (DEVICE_X_DISPLAY (d), NULL, NULL, NULL,
249 IMInstantiateCallback, (XPointer) d);
252 Display *dpy = DEVICE_X_DISPLAY (d);
256 XtGetApplicationNameAndClass (dpy, &name, &class);
257 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class);
260 xim_warn ("XOpenIM() failed...no input server available\n");
265 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES (d), NULL);
276 /* Callback for the deleting frame. */
278 XIM_delete_frame (Widget w, XtPointer client_data, XtPointer call_data)
280 struct frame *f = (struct frame *) client_data;
281 struct device *d = XDEVICE (FRAME_DEVICE (f));
283 if (DEVICE_X_XIM (d))
287 XDestroyIC (FRAME_X_XIC (f));
288 FRAME_X_XIC (f) = NULL;
294 /* Initialize XIC for new frame.
295 Create an X input context (XIC) for this frame. */
297 XIM_init_frame (struct frame *f)
299 struct device *d = XDEVICE (FRAME_DEVICE (f));
301 Widget w = FRAME_X_TEXT_WIDGET (f);
302 Window win = XtWindow (w);
303 XRectangle p_area = {0,0,1,1}, s_area = {0,0,1,1};
306 XVaNestedList p_list, s_list;
318 #define res(name, class, representation, field, default_value) \
319 { name, class, representation, sizeof(xic_vars.field), \
320 XtOffsetOf(xic_vars_t, field), XtRString, default_value }
322 static XtResource resources[] =
324 /* name class represent'n field default value */
325 res(XtNximStyles, XtCXimStyles, XtRXimStyles, styles, (XtPointer) DefaultXIMStyles),
326 res(XtNfontSet, XtCFontSet, XtRFontSet, fontset, (XtPointer) XtDefaultFontSet),
327 res(XtNximForeground, XtCForeground, XtRPixel, fg, (XtPointer) XtDefaultForeground),
328 res(XtNximBackground, XtCBackground, XtRPixel, bg, (XtPointer) XtDefaultBackground)
332 xim = DEVICE_X_XIM (d);
336 xim_info ("X Input Method open failed. Waiting for an XIM to be enabled.\n");
340 w = FRAME_X_TEXT_WIDGET (f);
345 if (FRAME_X_XIC (f)) return;
346 XtGetApplicationResources (w, &xic_vars,
347 resources, XtNumber (resources),
349 if (!xic_vars.fontset)
351 xim_warn ("Can't get fontset resource for Input Method\n");
352 FRAME_X_XIC (f) = NULL;
357 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES(d), NULL);
358 FRAME_X_XIC_STYLE (f) = style =
359 best_style (&xic_vars.styles, (XIMStyles *)DEVICE_X_XIM_STYLES(d));
361 p_list = XVaCreateNestedList (0,
363 XNSpotLocation, &spot,
364 XNForeground, xic_vars.fg,
365 XNBackground, xic_vars.bg,
366 XNFontSet, xic_vars.fontset,
369 s_list = XVaCreateNestedList (0,
371 XNForeground, xic_vars.fg,
372 XNBackground, xic_vars.bg,
373 XNFontSet, xic_vars.fontset,
376 FRAME_X_XIC (f) = xic =
381 XNPreeditAttributes, p_list,
382 XNStatusAttributes, s_list,
389 xim_warn ("Warning: XCreateIC failed.\n");
393 if (style & XIMPreeditPosition)
395 XPoint *frame_spot = &(FRAME_X_XIC_SPOT(f));
396 frame_spot->x = frame_spot->y = -1;
404 /* when frame is going to be destroyed (closed) */
405 XtAddCallback (FRAME_X_TEXT_WIDGET(f), XNDestroyCallback,
406 XIM_delete_frame, (XtPointer)f);
412 XIM_SetGeometry (struct frame *f)
414 XIC xic = FRAME_X_XIC (f);
415 XIMStyle style = FRAME_X_XIC_STYLE (f);
421 if (style & XIMStatusArea)
423 /* Place Status Area in bottom right corner */
424 /* Negotiate geometry of status area */
425 /* See O'Reilly Xlib XIM chapter (but beware, it's buggy) */
428 /* If input method has existing status area, use its current size */
429 /* The following at least works for Sun's htt */
430 area.x = area.y = area.width = area.height = 0;
431 XIC_Value (Set, xic, XNStatusAttributes, XNAreaNeeded, &area);
432 XIC_Value (Get, xic, XNStatusAttributes, XNAreaNeeded, &needed);
433 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
434 XIC_Value (Get, xic, XNStatusAttributes, XNArea, &needed);
436 area.width = needed->width;
437 area.height = needed->height;
438 area.x = FRAME_RIGHT_BORDER_START (f) - area.width;
439 area.y = FRAME_BOTTOM_BORDER_START (f) - area.height;
442 stderr_out ("Putting StatusArea in x=%d y=%d w=%d h=%d\n",
443 area.x, area.y, area.width, area.height);
444 #endif /* DEBUG_XIM */
446 XIC_Value (Set, xic, XNStatusAttributes, XNArea, &area);
449 if (style & XIMPreeditPosition)
451 /* Set Preedit Area to whole frame size (sans border) */
452 /* We include the border because Preedit window might be larger
453 than display line at edge. #### FIX: we should adjust to make
454 sure that there is always room for the spot sub-window */
455 area.x = FRAME_LEFT_BORDER_START (f);
456 area.y = FRAME_TOP_BORDER_START (f);
457 area.width = FRAME_RIGHT_BORDER_END (f) - area.x;
458 area.height = FRAME_BOTTOM_BORDER_END (f) - area.y;
459 XIC_Value(Set, xic, XNPreeditAttributes, XNArea, &area);
468 XIM_SetSpotLocation (struct frame *f, int x, int y)
470 XIC xic = FRAME_X_XIC (f);
471 XPoint *spot = &(FRAME_X_XIC_SPOT (f));
473 /* Only care if we have a valid XIC using Over the Spot in
474 * a different location */
476 !(FRAME_X_XIC_STYLE (f) & XIMPreeditPosition) ||
477 (spot->x == (short) x &&
478 spot->y == (short) y))
484 /* ### FIX: Must make sure spot fits within Preedit Area */
485 XIC_Value (Set, xic, XNPreeditAttributes, XNSpotLocation, spot);
487 stderr_out ("Spot: %d %d\n", spot->x, spot->y);
492 XIM_focus_event (struct frame *f, int in_p)
494 if (FRAME_X_XIC (f) /* && FRAME_X_XIM_REGISTERED(f) */)
495 (in_p ? XSetICFocus : XUnsetICFocus) (FRAME_X_XIC (f));
499 #define XIM_Composed_Text_BUFSIZE 64
500 typedef struct XIM_Composed_Text
503 wchar_t data [XIM_Composed_Text_BUFSIZE];
506 static XIM_Composed_Text composed_input_buf = {XIM_Composed_Text_BUFSIZE, {0}};
509 /* get_XIM_input -- Process results of input method composition.
511 This function copies the results of the input method composition to
512 composed_input_buf. Then for each character, a custom event of type
513 wc_atom is sent with the character as its data.
515 It is probably more efficient to copy the composition results to some
516 allocated memory and send a single event pointing to that memory.
517 That would cut down on the event processing as well as allow quick
518 insertion into the buffer of the whole string. It might require some
519 care, though, to avoid fragmenting memory through the allocation and
520 freeing of many small chunks. Maybe the existing system for
521 (single-byte) string allocation can be used, multiplying the length by
522 sizeof (wchar_t) to get the right size.
525 get_XIM_input (XKeyPressedEvent *x_key_event, XIC ic, Display *dpy)
531 XClientMessageEvent new_event;
534 len = XwcLookupString (ic, x_key_event, composed_input_buf.data,
535 composed_input_buf.size, &keysym, &status);
538 case XBufferOverflow:
539 /* GROW_WC_STRING (&composed_input_buf, 32); mrb */
547 new_event.type = ClientMessage;
548 new_event.display = x_key_event->display;
549 new_event.window = x_key_event->window;
550 new_event.message_type = wc_atom;
551 new_event.format = 32; /* 32-bit wide data */
552 new_event.data.l[2] = new_event.data.l[3] = new_event.data.l[4] = 0L;
553 new_event.data.l[0] = x_key_event->time;
554 for (i = 0; i < len; i++)
556 new_event.data.l[1] = ((wchar_t *) composed_input_buf.data)[i];
557 XSendEvent (display, main_window, False, 0L, (XEvent *) &new_event);
562 /* ============================================================== */
563 /* X input method style determination */
564 /* ============================================================== */
567 #define done(type, value) \
568 if (toVal->addr != NULL) { \
569 if (toVal->size < sizeof(type)) { \
570 toVal->size = sizeof(type); \
573 *(type*)toVal->addr = (value); \
575 static type static_val; \
576 static_val = (value); \
577 toVal->addr = (XPointer)&static_val; \
579 toVal->size = sizeof(type); \
580 return True /* Caller supplies `;' */
584 * This is a standard Xt type converter, except that the caller MUST
585 * supply a proper non-NULL toVal XIMStyles structure that we will
588 * fromVal points to a string like
590 "XIMPreeditPosition|XIMStatusArea,
591 XIMPreeditPosition|XIMStatusNothing
592 XIMPreeditNothing|XIMStatusNothing"
594 * This is converted in the obvious way to a XIMStyles structure.
596 * mrb: #### Fix this to handle Motif-style specifications for
597 * XIMStyles as well: overTheSpot, rootWindow, none */
599 /* XtTypeConverter */
601 EmacsXtCvtStringToXIMStyles (
607 XtPointer *converter_data)
609 #define STYLE_INFO(style) { style, #style, sizeof(#style) }
610 static struct XIMStyleInfo
612 CONST XIMStyle style;
613 CONST char * CONST name;
615 } emacs_XIMStyleInfo[] = {
616 STYLE_INFO (XIMPreeditPosition|XIMStatusArea),
617 STYLE_INFO (XIMPreeditPosition|XIMStatusNothing),
618 STYLE_INFO (XIMPreeditPosition|XIMStatusNone),
619 STYLE_INFO (XIMPreeditNothing|XIMStatusArea),
620 STYLE_INFO (XIMPreeditNothing|XIMStatusNothing),
621 STYLE_INFO (XIMPreeditNothing|XIMStatusNone),
622 STYLE_INFO (XIMPreeditNone|XIMStatusArea),
623 STYLE_INFO (XIMPreeditNone|XIMStatusNothing),
624 STYLE_INFO (XIMPreeditNone|XIMStatusNone)
628 char *s = (char *) fromVal->addr;
629 char *end = s + fromVal->size;
630 XIMStyles * CONST p = (XIMStyles *) toVal->addr;
631 CONST char * CONST delimiter = " \t\n\r:;," ;
632 CONST int max_styles = XtNumber(emacs_XIMStyleInfo);
637 stderr_out ("EmacsCvtStringToXIMStyles called with size=%d, string=\"%s\"\n",
638 fromVal->size, (char *) fromVal->addr);
639 #endif /* DEBUG_XIM */
643 XtAppContext the_app_con = XtDisplayToApplicationContext (dpy);
644 XtAppWarningMsg(the_app_con, "wrongParameters", "cvtStringToXIMStyle",
646 "String to XIMStyle conversion requires exactly 0 parameters",
647 (String *)NULL, (Cardinal *)NULL);
652 /* Make sure caller is giving us good data */
653 assert (fromVal->addr != NULL);
654 assert (fromVal->size == strlen(fromVal->addr)+1);
655 assert (toVal->addr != NULL);
656 assert (toVal->size == sizeof(XIMStyles));
657 #endif /* DEBUG_XEMACS */
660 p->supported_styles = xnew_array (XIMStyle, max_styles);
663 * The following routine assumes that the style name resource is
664 * identical with the programmatic name of style. For example,
665 * "XIMPreeditPosition|XIMStatusArea" means the
666 * XIMPreeditPosition|XIMStatusArea value is specified. If the
667 * style name is changed, such as "OverTheSpot|imDisplaysInClient",
668 * the parsing logic below should be modified as well. */
670 if ((c = strtok(s, delimiter)) == NULL)
675 for(i=0 ; i<max_styles ; i++)
677 struct XIMStyleInfo *rec = emacs_XIMStyleInfo + i;
678 if(!strncmp(c, rec->name, rec->namelen - 1)) {
679 p->supported_styles[p->count_styles] = rec->style;
684 if((c = strtok(NULL, delimiter)) == NULL) {
689 if (p->count_styles == 0)
690 { /* No valid styles? */
691 char *buf = (char *)alloca (strlen (fromVal->addr)
692 + strlen (DefaultXIMStyles)
695 XtAppContext the_app_con = XtDisplayToApplicationContext (dpy);
697 sprintf(buf, "Cannot convert string \"%s\" to type XIMStyles.\n"
698 "Using default string \"%s\" instead.\n",
699 fromVal->addr, DefaultXIMStyles);
700 XtAppWarningMsg(the_app_con, "wrongParameters", "cvtStringToXIMStyle",
702 buf, (String *)NULL, (Cardinal *)NULL);
703 new_from.addr = DefaultXIMStyles;
704 new_from.size = sizeof(DefaultXIMStyles);
705 return EmacsXtCvtStringToXIMStyles (dpy, args, num_args,
706 &new_from, toVal, converter_data);
708 XREALLOC_ARRAY (p->supported_styles, XIMStyle, p->count_styles);
709 *converter_data = (char *) True;
718 XtPointer converter_data,
723 stderr_out ("Converter data: %x\n", converter_data);
724 stderr_out ("EmacsFreeXIMStyles called\n");
725 #endif /* DEBUG_XIM */
729 XtAppWarningMsg(app, "wrongParameters","freeXIMStyles","XtToolkitError",
730 "Freeing an XIMStyles requires that zero arguments be passwd",
731 (String *)NULL, (Cardinal *)NULL);
737 Boolean free_p = (Boolean) (int) converter_data;
738 XIMStyles *styles = (XIMStyles *) toVal->addr;
740 XFree ( styles->supported_styles );
745 /* O'Reilly XLib Programming Manual, pg. 371 */
746 /* Much nicer implementation than O'Reilly */
747 /* Choose the more `complicated', hence nicer, XIM input style */
749 BetterStyle (XIMStyle s, XIMStyle t)
751 #define CHECK_XIMStyle_BIT(bit) \
752 if ((s ^ t) & bit) { return (s & bit) ? s : t; }
754 CHECK_XIMStyle_BIT (XIMPreeditCallbacks);
755 CHECK_XIMStyle_BIT (XIMPreeditPosition);
756 CHECK_XIMStyle_BIT (XIMPreeditArea);
757 CHECK_XIMStyle_BIT (XIMPreeditNothing);
758 CHECK_XIMStyle_BIT (XIMStatusCallbacks);
759 CHECK_XIMStyle_BIT (XIMStatusArea);
760 CHECK_XIMStyle_BIT (XIMStatusNothing);
761 #undef CHECK_XIMStyle_BIT
766 /* Choose the best style, given:
767 * - user preferences (already checked to be supported by XEmacs)
768 * - styles supported by the input method */
769 #define DEFAULTStyle (XIMPreeditNothing|XIMStatusNothing)
771 best_style (XIMStyles *user, XIMStyles *xim)
774 for (i=0 ; i<user->count_styles ; i++)
776 for (j=0 ; j<xim->count_styles ; j++)
778 if (user->supported_styles[i] == xim->supported_styles[j])
779 return user->supported_styles[i];
782 return DEFAULTStyle; /* Default Style */
785 /* These lisp-callable functions will be sealed until xim-leim is needed.
786 Oct 22 1999 - kazz */
789 * External callable function for XIM
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.
801 CHECK_LIVE_FRAME (frame);
804 return signal_simple_error ("This frame is not on X device", frame);
807 return FRAME_X_XIC (f) ? Qt : Qnil;
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.
821 CHECK_LIVE_FRAME (frame);
824 return signal_simple_error ("This frame is not on X device", frame);
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;
836 syms_of_input_method_xlib (void)
838 defsymbol (&Qxim_xlib, "xim-xlib");
839 #if 0 /* see above */
840 DEFSUBR (Fx_open_xim);
841 DEFSUBR (Fx_close_xim);
846 vars_of_input_method_xlib (void)
848 Fprovide (intern ("xim"));
852 /* ====================================================================== */
853 /* Internal Debugging Routines */
854 /* ====================================================================== */
858 describe_XIM (XIM xim)
862 /* Print locale of XIM */
863 stderr_out ("\nXIM Locale of IM: %s\n", XLocaleOfIM(xim));
865 /* List supported input method styles */
866 XGetIMValues(xim, XNQueryInputStyle, &styles, NULL);
868 stderr_out ("\n%d input style(s) supported by input method.\n",
869 styles->count_styles);
874 for (i=0; i < styles->count_styles; i++)
875 describe_XIMStyle (styles->supported_styles[i]);
877 #endif /* DEBUG_XIM */
882 describe_XFontSet (XFontSet fontset)
884 XFontStruct **font_struct_list;
885 char **font_name_list;
890 stderr_out ("NULL\n");
894 count = XFontsOfFontSet (fontset, &font_struct_list, &font_name_list);
895 stderr_out ( "%d font(s) available:\n", count);
896 for (i=0 ; i < count ; i++)
897 stderr_out ("Font: %s\n", *(font_name_list+i));
901 describe_Status (Status status)
903 #define DESCRIBE_STATUS(value) \
904 if (status == value) stderr_out ("Status: " #value "\n")
906 DESCRIBE_STATUS (XBufferOverflow);
907 DESCRIBE_STATUS (XLookupNone);
908 DESCRIBE_STATUS (XLookupKeySym);
909 DESCRIBE_STATUS (XLookupBoth);
910 DESCRIBE_STATUS (XLookupChars);
911 #undef DESCRIBE_STATUS
915 describe_Window (Window win)
918 sprintf (xwincmd, "xwininfo -id 0x%x >&2; xwininfo -events -id 0x%x >&2",
919 (int) win, (int) win);
924 describe_XIC (XIC xic)
927 Window client_win=0, focus_win=0;
928 char *resourceName = NULL;
929 char *resourceClass = NULL;
930 char *bad_arg = NULL;
931 unsigned long filter_mask = NoEventMask;
932 XVaNestedList p_list, s_list;
933 XFontSet p_fontset = NULL, s_fontset = NULL;
934 Pixel p_fg=0, p_bg = 0, s_fg=0, s_bg = 0;
935 XRectangle *p_area = NULL, *s_area = NULL;
936 XRectangle *p_needed = NULL, *s_needed = NULL;
937 XPoint *p_spot = NULL;
939 /* Check for valid input context and method */
941 stderr_out ("Input method is NULL\n");
944 stderr_out ("XIMOfIC() returns NULL\n");
946 /* Print out Input Context Attributes */
947 p_list = XVaCreateNestedList (0,
948 XNFontSet, &p_fontset,
950 XNAreaNeeded, &p_needed,
951 XNSpotLocation, &p_spot,
956 s_list = XVaCreateNestedList (0,
957 XNFontSet, &s_fontset,
959 XNAreaNeeded, &s_needed,
964 bad_arg = XGetICValues(xic,
965 XNInputStyle, &style,
966 XNFilterEvents, &filter_mask,
967 XNClientWindow, &client_win,
968 XNFocusWindow, &focus_win,
969 XNResourceName, &resourceName,
970 XNResourceClass, &resourceClass,
971 XNPreeditAttributes, p_list,
972 XNStatusAttributes, s_list,
978 stderr_out ("Couldn't get IC value: %s\n", bad_arg);
980 stderr_out ("\nInput method context attributes:\n");
981 stderr_out ("Style: "); describe_XIMStyle (style);
982 stderr_out ("Client window: %lx\n", (unsigned long int)client_win);
983 stderr_out ("Focus window: %lx\n", (unsigned long int)focus_win);
984 stderr_out ("Preedit:\n");
985 describe_XRectangle (" Area", p_area);
986 describe_XRectangle (" Area needed", p_needed);
987 stderr_out (" foreground: %lx\n", (unsigned long int)p_fg);
988 stderr_out (" background: %lx\n", (unsigned long int)p_bg);
989 stderr_out (" fontset: "); describe_XFontSet (p_fontset);
990 stderr_out ("Status:\n");
991 describe_XRectangle (" Area", s_area);
992 describe_XRectangle (" Area needed", s_needed);
993 stderr_out (" foreground: %lx\n", (unsigned long int)s_fg);
994 stderr_out (" background: %lx\n", (unsigned long int)s_bg);
995 stderr_out (" fontset: \n"); describe_XFontSet (s_fontset);
996 stderr_out ("XNResourceName: %s\n", resourceName ? resourceName : "NULL");
997 stderr_out ("XNResourceClass: %s\n", resourceClass ? resourceClass : "NULL");
998 stderr_out ("XNFilterEvents: "); describe_event_mask (filter_mask);
1002 describe_XRectangle (char *name, XRectangle *r)
1005 stderr_out ("%s: NULL\n", name);
1007 stderr_out ("%s: x=%d y=%d w=%d h=%d\n",
1008 name, r->x, r->y, r->width, r->height);
1011 /* Print out elements of Event mask */
1012 /* Defines from X11/X.h */
1014 describe_event_mask (unsigned long mask)
1016 #define DESCRIBE_EVENT_MASK(bit) if ((bit) & mask) stderr_out (#bit " ")
1017 DESCRIBE_EVENT_MASK (NoEventMask);
1018 DESCRIBE_EVENT_MASK (KeyPressMask);
1019 DESCRIBE_EVENT_MASK (KeyReleaseMask);
1020 DESCRIBE_EVENT_MASK (ButtonPressMask);
1021 DESCRIBE_EVENT_MASK (ButtonReleaseMask);
1022 DESCRIBE_EVENT_MASK (EnterWindowMask);
1023 DESCRIBE_EVENT_MASK (LeaveWindowMask);
1024 DESCRIBE_EVENT_MASK (PointerMotionMask);
1025 DESCRIBE_EVENT_MASK (PointerMotionHintMask);
1026 DESCRIBE_EVENT_MASK (Button1MotionMask);
1027 DESCRIBE_EVENT_MASK (Button2MotionMask);
1028 DESCRIBE_EVENT_MASK (Button3MotionMask);
1029 DESCRIBE_EVENT_MASK (Button4MotionMask);
1030 DESCRIBE_EVENT_MASK (Button5MotionMask);
1031 DESCRIBE_EVENT_MASK (ButtonMotionMask);
1032 DESCRIBE_EVENT_MASK (KeymapStateMask);
1033 DESCRIBE_EVENT_MASK (ExposureMask);
1034 DESCRIBE_EVENT_MASK (VisibilityChangeMask);
1035 DESCRIBE_EVENT_MASK (StructureNotifyMask);
1036 DESCRIBE_EVENT_MASK (ResizeRedirectMask);
1037 DESCRIBE_EVENT_MASK (SubstructureNotifyMask);
1038 DESCRIBE_EVENT_MASK (SubstructureRedirectMask);
1039 DESCRIBE_EVENT_MASK (FocusChangeMask);
1040 DESCRIBE_EVENT_MASK (PropertyChangeMask);
1041 DESCRIBE_EVENT_MASK (ColormapChangeMask);
1042 DESCRIBE_EVENT_MASK (OwnerGrabButtonMask);
1043 #undef DESCRIBE_EVENT_MASK
1048 describe_XIMStyle (XIMStyle style)
1050 #define DESCRIBE_STYLE(bit) \
1052 stderr_out (#bit " ");
1054 DESCRIBE_STYLE (XIMPreeditArea);
1055 DESCRIBE_STYLE (XIMPreeditCallbacks);
1056 DESCRIBE_STYLE (XIMPreeditPosition);
1057 DESCRIBE_STYLE (XIMPreeditNothing);
1058 DESCRIBE_STYLE (XIMPreeditNone);
1059 DESCRIBE_STYLE (XIMStatusArea);
1060 DESCRIBE_STYLE (XIMStatusCallbacks);
1061 DESCRIBE_STYLE (XIMStatusNothing);
1062 DESCRIBE_STYLE (XIMStatusNone);
1063 #undef DESCRIBE_STYLE
1068 describe_XIMStyles (XIMStyles *p)
1071 stderr_out ("%d Style(s):\n", p->count_styles);
1072 for (i=0; i<p->count_styles ; i++)
1074 describe_XIMStyle (p->supported_styles[i]);
1078 #endif /* DEBUG_XEMACS */
1080 /* Random cruft follows */
1084 Unit_Test (struct frame *f, char * s)
1085 /* mrb unit testing */
1087 XrmValue fromVal, toVal;
1090 fromVal.size = strlen (s);
1091 toVal.addr = (XtPointer) &user_preferred_XIMStyles;
1092 toVal.size = sizeof (XIMStyles);
1094 if (XtConvertAndStore (FRAME_X_TEXT_WIDGET (f), XtRString, &fromVal,
1095 XtRXimStyles, &toVal) != False)
1097 stderr_out ("Unit_Test: fromVal.addr=0x%x\n",fromVal.addr);
1098 stderr_out ("Unit_Test: fromVal.size=%d\n", fromVal.size);
1099 stderr_out ("Unit_Test: toVal.addr=0x%x\n", toVal.addr);
1100 stderr_out ("Unit_Test: toVal.size=%d\n", toVal.size);
1101 describe_XIMStyles ((XIMStyles *) toVal.addr);
1107 /* Get a fontset for IM to use */
1109 x_init_fontset (struct device *d)
1111 Display *dpy = DEVICE_X_DISPLAY (d);
1113 char ** missing_charsets;
1114 int num_missing_charsets;
1115 char * default_string;
1116 /* char * font_set_string = "-dt-interface user-medium-r-normal-s*-*-*-*-*-*-*-*-*";*/
1117 char * font_set_string = "-dt-interface user-medium-r-normal-s*-*-*-*-*-*-*-*-*, -misc-fixed-medium-r-normal--14-130-75-75-c-70-jisx0201.1976-0,-misc-fixed-medium-r-normal--14-130-75-75-c-140-jisx0208.1983-0, -misc-fixed-medium-r-normal--14-130-75-75-c-70-jisx0201.1976-0" ;
1119 DEVICE_X_FONTSET (d) = fontset =
1120 XCreateFontSet (dpy,
1123 &num_missing_charsets,
1126 if (fontset == NULL)
1128 stderr_out ("Unable to create fontset from string:\n%s\n", font_set_string);
1131 if (num_missing_charsets > 0)
1134 stderr_out ("\nMissing charsets for fontset %s:\n", font_set_string);
1135 for (i=0; i < num_missing_charsets; i++)
1137 stderr_out ("%s\n", missing_charsets[i]);
1139 XFreeStringList (missing_charsets);
1140 stderr_out ("Default string: %s\n", default_string);
1144 describe_XFontSet (fontset);