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 */
32 #include <X11/Xlocale.h> /* More portable than <locale.h> ? */
37 #include "console-x.h"
38 #include "EmacsFrame.h"
41 #include <X11/IntrinsicP.h>
42 #include <X11/Xaw/XawImP.h>
45 #error XIM_XLIB is not defined??
48 /* Get/Set IC values for just one attribute */
50 #define XIC_Value(Get_Set, xic, name, attr, value) \
53 XVaNestedList list = XVaCreateNestedList (0, attr, value, NULL); \
54 if ((bad_arg = X##Get_Set##ICValues (xic, name, list, NULL)) != NULL) \
55 stderr_out ("X" #Get_Set "ICValues " "bad Arg: %s\n", bad_arg); \
58 #else /* ! DEBUG_XEMACS */
59 #define XIC_Value(Get_Set, xic, name, attr, value) \
61 XVaNestedList list = XVaCreateNestedList (0, attr, value, NULL); \
62 X##Get_Set##ICValues (xic, name, list, NULL); \
65 #endif /* DEBUG_XEMACS */
67 static char DefaultXIMStyles[] =
68 "XIMPreeditPosition|XIMStatusArea\n"
69 "XIMPreeditPosition|XIMStatusNone\n"
70 "XIMPreeditPosition|XIMStatusNothing\n"
71 "XIMPreeditNothing|XIMStatusArea\n"
72 "XIMPreeditNothing|XIMStatusNothing\n"
73 "XIMPreeditNothing|XIMStatusNone\n"
74 "XIMPreeditNone|XIMStatusArea\n"
75 "XIMPreeditNone|XIMStatusNothing\n"
76 "XIMPreeditNone|XIMStatusNone";
78 static Boolean xim_initted = False;
80 static XIMStyle best_style (XIMStyles *user, XIMStyles *xim);
83 Initialize_Locale (void)
87 /* dverna - Nov. 98: ### DON'T DO THIS !!! The default XtLanguageProc
88 routine calls setlocale(LC_ALL, lang) which fucks up our lower-level
89 locale management, and especially the value of LC_NUMERIC. Anyway, since
90 at this point, we don't know yet whether we're gonna need an X11 frame,
91 we should really do it manually and not use Xlib's dumb default routine */
92 /*XtSetLanguageProc (NULL, (XtLanguageProc) NULL, NULL);*/
93 if ((locale = setlocale (LC_ALL, "")) == NULL)
95 stderr_out ("Can't set locale.\n");
96 stderr_out ("Using C locale instead.\n");
99 if ((locale = setlocale (LC_ALL, "C")) == NULL)
101 stderr_out ("Can't even set locale to `C'!\n");
106 if (!XSupportsLocale ())
108 stderr_out ("X Windows does not support locale `%s'\n", locale);
109 stderr_out ("Using C Locale instead\n");
112 if ((locale = setlocale (LC_ALL, "C")) == NULL)
114 stderr_out ("Can't even set locale to `C'!\n");
117 if (!XSupportsLocale ())
119 stderr_out ("X Windows does not even support locale `C'!\n");
124 setlocale(LC_NUMERIC, "C");
126 if (XSetLocaleModifiers ("") == NULL)
128 stderr_out ("XSetLocaleModifiers(\"\") failed\n");
129 stderr_out ("Check the value of the XMODIFIERS environment variable.\n");
133 /******************************************************************/
134 /* Input method using xlib */
135 /******************************************************************/
138 * called from when XIM is destroying
141 IMDestroyCallback (XIM im, XPointer client_data, XPointer call_data)
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)));
147 struct frame *target_frame = NULL;
149 LIST_LOOP (tail, frame_list)
151 if (target_frame = XFRAME (XCAR (tail)))
153 if ( FRAME_X_XIC(target_frame) )
155 XDestroyIC (FRAME_X_XIC(target_frame));
156 FRAME_X_XIC (target_frame) = NULL;
162 if ( DEVICE_X_XIM (d) )
164 stderr_out ("NULLing d->xim...\n");
165 /* DEVICE_X_XIM (d) = NULL; */
174 * called from when FRAME is initializing
177 IMInstantiateCallback (Display *dpy, XPointer client_data, XPointer call_data)
179 struct frame *f = (struct frame *)client_data;
180 struct device *d = XDEVICE (FRAME_DEVICE ((struct frame *)client_data));
182 Widget w = FRAME_X_TEXT_WIDGET ((struct frame *)client_data);
183 Window win = XtWindow (w);
184 XRectangle p_area = {0,0,1,1}, s_area = {0,0,1,1};
187 XVaNestedList p_list, s_list;
198 XIMCallback ximcallback;
201 #define res(name, class, representation, field, default_value) \
202 { name, class, representation, sizeof(xic_vars.field), \
203 XtOffsetOf(xic_vars_t, field), XtRString, default_value }
205 static XtResource resources[] =
207 /* name class represent'n field default value */
208 res(XtNximStyles, XtCXimStyles, XtRXimStyles, styles, (XtPointer) DefaultXIMStyles),
209 res(XtNfontSet, XtCFontSet, XtRFontSet, fontset, (XtPointer) XtDefaultFontSet),
210 res(XtNximForeground, XtCForeground, XtRPixel, fg, (XtPointer) XtDefaultForeground),
211 res(XtNximBackground, XtCBackground, XtRPixel, bg, (XtPointer) XtDefaultBackground),
212 res(XtNinputMethod, XtCInputMethod, XtRString, inputmethod, (XtPointer) NULL)
215 /* ---------- beginning of the action ---------- */
218 * if no xim is presented, initialize xim ...
220 if ( xim_initted == False )
223 XtGetApplicationNameAndClass (dpy, &name, &class);
224 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class);
226 /* destroy callback for im */
227 ximcallback.callback = IMDestroyCallback;
228 ximcallback.client_data = (XPointer)f;
229 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL);
233 xim = DEVICE_X_XIM (d);
236 w = FRAME_X_TEXT_WIDGET (f);
241 if ( FRAME_X_XIC (f) ) return;
242 XtGetApplicationResources (w, &xic_vars,
243 resources, XtNumber (resources),
245 if (!xic_vars.fontset)
247 stderr_out ("Can't get fontset resource for Input Method\n");
248 FRAME_X_XIC (f) = NULL;
253 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES(d), NULL);
254 FRAME_X_XIC_STYLE (f) = style =
255 best_style (&xic_vars.styles, (XIMStyles *)DEVICE_X_XIM_STYLES(d));
257 p_list = XVaCreateNestedList (0,
259 XNSpotLocation, &spot,
260 XNForeground, xic_vars.fg,
261 XNBackground, xic_vars.bg,
262 XNFontSet, xic_vars.fontset,
265 s_list = XVaCreateNestedList (0,
267 XNForeground, xic_vars.fg,
268 XNBackground, xic_vars.bg,
269 XNFontSet, xic_vars.fontset,
272 FRAME_X_XIC (f) = xic =
277 XNPreeditAttributes, p_list,
278 XNStatusAttributes, s_list,
285 stderr_out ("Warning: XCreateIC failed.\n");
289 if (style & XIMPreeditPosition)
291 XPoint *frame_spot = &(FRAME_X_XIC_SPOT(f));
292 frame_spot->x = frame_spot->y = -1;
302 /* Create X input method for device */
304 XIM_init_device (struct device *d)
306 /* do nothing here */
310 /* Callback for when the frame was deleted (closed) */
312 XIM_delete_frame (Widget w, XtPointer client_data, XtPointer call_data)
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);
318 XUnregisterIMInstantiateCallback (dpy, NULL, NULL, NULL,
319 IMInstantiateCallback, (XtPointer)f);
321 if ( FRAME_X_XIC (f) )
323 XDestroyIC (FRAME_X_XIC(f));
324 FRAME_X_XIC (f) = NULL;
329 /* Create an X input context for this frame.
330 - Register the IM to be initiated later using XRegisterIMInstantiateCallback
333 XIM_init_frame (struct frame *f)
335 struct device *d = XDEVICE (FRAME_DEVICE (f));
337 XRegisterIMInstantiateCallback (DEVICE_X_DISPLAY (d), NULL, NULL, NULL,
338 IMInstantiateCallback, (XtPointer)f);
341 if ( FRAME_X_XIC (f) )
344 if ( ! DEVICE_X_XIM (d) )
346 stderr_out ("X Input Method open failed. Waiting IM to be enabled.\n");
349 /* when frame is going to be destroyed (closed) */
350 XtAddCallback (FRAME_X_TEXT_WIDGET(f), XNDestroyCallback,
351 XIM_delete_frame, (XtPointer)f);
357 XIM_SetGeometry (struct frame *f)
359 XIC xic = FRAME_X_XIC (f);
360 XIMStyle style = FRAME_X_XIC_STYLE (f);
366 if (style & XIMStatusArea)
368 /* Place Status Area in bottom right corner */
369 /* Negotiate geometry of status area */
370 /* See O'Reilly Xlib XIM chapter (but beware, it's buggy) */
373 /* If input method has existing status area, use its current size */
374 /* The following at least works for Sun's htt */
375 area.x = area.y = area.width = area.height = 0;
376 XIC_Value (Set, xic, XNStatusAttributes, XNAreaNeeded, &area);
377 XIC_Value (Get, xic, XNStatusAttributes, XNAreaNeeded, &needed);
378 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
379 XIC_Value (Get, xic, XNStatusAttributes, XNArea, &needed);
381 area.width = needed->width;
382 area.height = needed->height;
383 area.x = FRAME_RIGHT_BORDER_START (f) - area.width;
384 area.y = FRAME_BOTTOM_BORDER_START (f) - area.height;
387 stderr_out ("Putting StatusArea in x=%d y=%d w=%d h=%d\n",
388 area.x, area.y, area.width, area.height);
389 #endif /* DEBUG_XIM */
391 XIC_Value (Set, xic, XNStatusAttributes, XNArea, &area);
394 if (style & XIMPreeditPosition)
396 /* Set Preedit Area to whole frame size (sans border) */
397 /* We include the border because Preedit window might be larger
398 than display line at edge. #### FIX: we should adjust to make
399 sure that there is always room for the spot sub-window */
400 area.x = FRAME_LEFT_BORDER_START (f);
401 area.y = FRAME_TOP_BORDER_START (f);
402 area.width = FRAME_RIGHT_BORDER_END (f) - area.x;
403 area.height = FRAME_BOTTOM_BORDER_END (f) - area.y;
404 XIC_Value(Set, xic, XNPreeditAttributes, XNArea, &area);
413 XIM_SetSpotLocation (struct frame *f, int x, int y)
415 XIC xic = FRAME_X_XIC (f);
416 XPoint *spot = &(FRAME_X_XIC_SPOT (f));
418 /* Only care if we have a valid XIC using Over the Spot in
419 * a different location */
421 !(FRAME_X_XIC_STYLE (f) & XIMPreeditPosition) ||
422 (spot->x == (short) x &&
423 spot->y == (short) y))
429 /* ### FIX: Must make sure spot fits within Preedit Area */
430 XIC_Value (Set, xic, XNPreeditAttributes, XNSpotLocation, spot);
432 stderr_out ("Spot: %d %d\n", spot->x, spot->y);
437 XIM_focus_event (struct frame *f, int in_p)
439 if (FRAME_X_XIC (f) /* && FRAME_X_XIM_REGISTERED(f) */)
440 (in_p ? XSetICFocus : XUnsetICFocus) (FRAME_X_XIC (f));
444 #define XIM_Composed_Text_BUFSIZE 64
445 typedef struct XIM_Composed_Text
448 wchar_t data [XIM_Composed_Text_BUFSIZE];
451 static XIM_Composed_Text composed_input_buf = {XIM_Composed_Text_BUFSIZE, {0}};
454 /* get_XIM_input -- Process results of input method composition.
456 This function copies the results of the input method composition to
457 composed_input_buf. Then for each character, a custom event of type
458 wc_atom is sent with the character as its data.
460 It is probably more efficient to copy the composition results to some
461 allocated memory and send a single event pointing to that memory.
462 That would cut down on the event processing as well as allow quick
463 insertion into the buffer of the whole string. It might require some
464 care, though, to avoid fragmenting memory through the allocation and
465 freeing of many small chunks. Maybe the existing system for
466 (single-byte) string allocation can be used, multiplying the length by
467 sizeof (wchar_t) to get the right size.
470 get_XIM_input (XKeyPressedEvent *x_key_event, XIC ic, Display *dpy)
476 XClientMessageEvent new_event;
479 len = XwcLookupString (ic, x_key_event, composed_input_buf.data,
480 composed_input_buf.size, &keysym, &status);
483 case XBufferOverflow:
484 /* GROW_WC_STRING (&composed_input_buf, 32); mrb */
492 new_event.type = ClientMessage;
493 new_event.display = x_key_event->display;
494 new_event.window = x_key_event->window;
495 new_event.message_type = wc_atom;
496 new_event.format = 32; /* 32-bit wide data */
497 new_event.data.l[2] = new_event.data.l[3] = new_event.data.l[4] = 0L;
498 new_event.data.l[0] = x_key_event->time;
499 for (i = 0; i < len; i++)
501 new_event.data.l[1] = ((wchar_t *) composed_input_buf.data)[i];
502 XSendEvent (display, main_window, False, 0L, (XEvent *) &new_event);
507 /* ============================================================== */
508 /* X input method style determination */
509 /* ============================================================== */
512 #define done(type, value) \
513 if (toVal->addr != NULL) { \
514 if (toVal->size < sizeof(type)) { \
515 toVal->size = sizeof(type); \
518 *(type*)toVal->addr = (value); \
520 static type static_val; \
521 static_val = (value); \
522 toVal->addr = (XPointer)&static_val; \
524 toVal->size = sizeof(type); \
525 return True /* Caller supplies `;' */
529 * This is a standard Xt type converter, except that the caller MUST
530 * supply a proper non-NULL toVal XIMStyles structure that we will
533 * fromVal points to a string like
535 "XIMPreeditPosition|XIMStatusArea,
536 XIMPreeditPosition|XIMStatusNothing
537 XIMPreeditNothing|XIMStatusNothing"
539 * This is converted in the obvious way to a XIMStyles structure.
541 * mrb: #### Fix this to handle Motif-style specifications for
542 * XIMStyles as well: overTheSpot, rootWindow, none */
544 /* XtTypeConverter */
546 EmacsXtCvtStringToXIMStyles (
552 XtPointer *converter_data)
554 #define STYLE_INFO(style) { style, #style, sizeof(#style) }
555 static struct XIMStyleInfo
557 CONST XIMStyle style;
558 CONST char * CONST name;
560 } emacs_XIMStyleInfo[] = {
561 STYLE_INFO (XIMPreeditPosition|XIMStatusArea),
562 STYLE_INFO (XIMPreeditPosition|XIMStatusNothing),
563 STYLE_INFO (XIMPreeditPosition|XIMStatusNone),
564 STYLE_INFO (XIMPreeditNothing|XIMStatusArea),
565 STYLE_INFO (XIMPreeditNothing|XIMStatusNothing),
566 STYLE_INFO (XIMPreeditNothing|XIMStatusNone),
567 STYLE_INFO (XIMPreeditNone|XIMStatusArea),
568 STYLE_INFO (XIMPreeditNone|XIMStatusNothing),
569 STYLE_INFO (XIMPreeditNone|XIMStatusNone)
573 char *s = (char *) fromVal->addr;
574 char *end = s + fromVal->size;
575 XIMStyles * CONST p = (XIMStyles *) toVal->addr;
576 CONST char * CONST delimiter = " \t\n\r:;," ;
577 CONST int max_styles = XtNumber(emacs_XIMStyleInfo);
582 stderr_out ("EmacsCvtStringToXIMStyles called with size=%d, string=\"%s\"\n",
583 fromVal->size, (char *) fromVal->addr);
584 #endif /* DEBUG_XIM */
588 XtAppContext the_app_con = XtDisplayToApplicationContext (dpy);
589 XtAppWarningMsg(the_app_con, "wrongParameters", "cvtStringToXIMStyle",
591 "String to XIMStyle conversion requires exactly 0 parameters",
592 (String *)NULL, (Cardinal *)NULL);
597 /* Make sure caller is giving us good data */
598 assert (fromVal->addr != NULL);
599 assert (fromVal->size == strlen(fromVal->addr)+1);
600 assert (toVal->addr != NULL);
601 assert (toVal->size == sizeof(XIMStyles));
602 #endif /* DEBUG_XEMACS */
605 p->supported_styles = xnew_array (XIMStyle, max_styles);
608 * The following routine assumes that the style name resource is
609 * identical with the programmatic name of style. For example,
610 * "XIMPreeditPosition|XIMStatusArea" means the
611 * XIMPreeditPosition|XIMStatusArea value is specified. If the
612 * style name is changed, such as "OverTheSpot|imDisplaysInClient",
613 * the parsing logic below should be modified as well. */
615 if ((c = strtok(s, delimiter)) == NULL)
620 for(i=0 ; i<max_styles ; i++)
622 struct XIMStyleInfo *rec = emacs_XIMStyleInfo + i;
623 if(!strncmp(c, rec->name, rec->namelen - 1)) {
624 p->supported_styles[p->count_styles] = rec->style;
629 if((c = strtok(NULL, delimiter)) == NULL) {
634 if (p->count_styles == 0)
635 { /* No valid styles? */
636 char *buf = (char *)alloca (strlen (fromVal->addr)
637 + strlen (DefaultXIMStyles)
640 XtAppContext the_app_con = XtDisplayToApplicationContext (dpy);
642 sprintf(buf, "Cannot convert string \"%s\" to type XIMStyles.\n"
643 "Using default string \"%s\" instead.\n",
644 fromVal->addr, DefaultXIMStyles);
645 XtAppWarningMsg(the_app_con, "wrongParameters", "cvtStringToXIMStyle",
647 buf, (String *)NULL, (Cardinal *)NULL);
648 new_from.addr = DefaultXIMStyles;
649 new_from.size = sizeof(DefaultXIMStyles);
650 return EmacsXtCvtStringToXIMStyles (dpy, args, num_args,
651 &new_from, toVal, converter_data);
653 XREALLOC_ARRAY (p->supported_styles, XIMStyle, p->count_styles);
654 *converter_data = (char *) True;
663 XtPointer converter_data,
668 stderr_out ("Converter data: %x\n", converter_data);
669 stderr_out ("EmacsFreeXIMStyles called\n");
670 #endif /* DEBUG_XIM */
674 XtAppWarningMsg(app, "wrongParameters","freeXIMStyles","XtToolkitError",
675 "Freeing an XIMStyles requires that zero arguments be passwd",
676 (String *)NULL, (Cardinal *)NULL);
682 Boolean free_p = (Boolean) (int) converter_data;
683 XIMStyles *styles = (XIMStyles *) toVal->addr;
685 XFree ( styles->supported_styles );
690 /* O'Reilly XLib Programming Manual, pg. 371 */
691 /* Much nicer implementation than O'Reilly */
692 /* Choose the more `complicated', hence nicer, XIM input style */
694 BetterStyle (XIMStyle s, XIMStyle t)
696 #define CHECK_XIMStyle_BIT(bit) \
697 if ((s ^ t) & bit) { return (s & bit) ? s : t; }
699 CHECK_XIMStyle_BIT (XIMPreeditCallbacks);
700 CHECK_XIMStyle_BIT (XIMPreeditPosition);
701 CHECK_XIMStyle_BIT (XIMPreeditArea);
702 CHECK_XIMStyle_BIT (XIMPreeditNothing);
703 CHECK_XIMStyle_BIT (XIMStatusCallbacks);
704 CHECK_XIMStyle_BIT (XIMStatusArea);
705 CHECK_XIMStyle_BIT (XIMStatusNothing);
706 #undef CHECK_XIMStyle_BIT
711 /* Choose the best style, given:
712 * - user preferences (already checked to be supported by XEmacs)
713 * - styles supported by the input method */
714 #define DEFAULTStyle (XIMPreeditNothing|XIMStatusNothing)
716 best_style (XIMStyles *user, XIMStyles *xim)
719 for (i=0 ; i<user->count_styles ; i++)
721 for (j=0 ; j<xim->count_styles ; j++)
723 if (user->supported_styles[i] == xim->supported_styles[j])
724 return user->supported_styles[i];
727 return DEFAULTStyle; /* Default Style */
732 vars_of_input_method_xlib (void)
734 Fprovide (intern ("xim"));
738 /* ====================================================================== */
739 /* Internal Debugging Routines */
740 /* ====================================================================== */
744 describe_XIM (XIM xim)
748 /* Print locale of XIM */
749 stderr_out ("\nXIM Locale of IM: %s\n", XLocaleOfIM(xim));
751 /* List supported input method styles */
752 XGetIMValues(xim, XNQueryInputStyle, &styles, NULL);
754 stderr_out ("\n%d input style(s) supported by input method.\n",
755 styles->count_styles);
760 for (i=0; i < styles->count_styles; i++)
761 describe_XIMStyle (styles->supported_styles[i]);
763 #endif /* DEBUG_XIM */
768 describe_XFontSet (XFontSet fontset)
770 XFontStruct **font_struct_list;
771 char **font_name_list;
776 stderr_out ("NULL\n");
780 count = XFontsOfFontSet (fontset, &font_struct_list, &font_name_list);
781 stderr_out ( "%d font(s) available:\n", count);
782 for (i=0 ; i < count ; i++)
783 stderr_out ("Font: %s\n", *(font_name_list+i));
787 describe_Status (Status status)
789 #define DESCRIBE_STATUS(value) \
790 if (status == value) stderr_out ("Status: " #value "\n")
792 DESCRIBE_STATUS (XBufferOverflow);
793 DESCRIBE_STATUS (XLookupNone);
794 DESCRIBE_STATUS (XLookupKeySym);
795 DESCRIBE_STATUS (XLookupBoth);
796 DESCRIBE_STATUS (XLookupChars);
797 #undef DESCRIBE_STATUS
801 describe_Window (Window win)
804 sprintf (xwincmd, "xwininfo -id 0x%x >&2; xwininfo -events -id 0x%x >&2",
805 (int) win, (int) win);
810 describe_XIC (XIC xic)
813 Window client_win=0, focus_win=0;
814 char *resourceName = NULL;
815 char *resourceClass = NULL;
816 char *bad_arg = NULL;
817 unsigned long filter_mask = NoEventMask;
818 XVaNestedList p_list, s_list;
819 XFontSet p_fontset = NULL, s_fontset = NULL;
820 Pixel p_fg=0, p_bg = 0, s_fg=0, s_bg = 0;
821 XRectangle *p_area = NULL, *s_area = NULL;
822 XRectangle *p_needed = NULL, *s_needed = NULL;
823 XPoint *p_spot = NULL;
825 /* Check for valid input context and method */
827 stderr_out ("Input method is NULL\n");
830 stderr_out ("XIMOfIC() returns NULL\n");
832 /* Print out Input Context Attributes */
833 p_list = XVaCreateNestedList (0,
834 XNFontSet, &p_fontset,
836 XNAreaNeeded, &p_needed,
837 XNSpotLocation, &p_spot,
842 s_list = XVaCreateNestedList (0,
843 XNFontSet, &s_fontset,
845 XNAreaNeeded, &s_needed,
850 bad_arg = XGetICValues(xic,
851 XNInputStyle, &style,
852 XNFilterEvents, &filter_mask,
853 XNClientWindow, &client_win,
854 XNFocusWindow, &focus_win,
855 XNResourceName, &resourceName,
856 XNResourceClass, &resourceClass,
857 XNPreeditAttributes, p_list,
858 XNStatusAttributes, s_list,
864 stderr_out ("Couldn't get IC value: %s\n", bad_arg);
866 stderr_out ("\nInput method context attributes:\n");
867 stderr_out ("Style: "); describe_XIMStyle (style);
868 stderr_out ("Client window: %lx\n", (unsigned long int)client_win);
869 stderr_out ("Focus window: %lx\n", (unsigned long int)focus_win);
870 stderr_out ("Preedit:\n");
871 describe_XRectangle (" Area", p_area);
872 describe_XRectangle (" Area needed", p_needed);
873 stderr_out (" foreground: %lx\n", (unsigned long int)p_fg);
874 stderr_out (" background: %lx\n", (unsigned long int)p_bg);
875 stderr_out (" fontset: "); describe_XFontSet (p_fontset);
876 stderr_out ("Status:\n");
877 describe_XRectangle (" Area", s_area);
878 describe_XRectangle (" Area needed", s_needed);
879 stderr_out (" foreground: %lx\n", (unsigned long int)s_fg);
880 stderr_out (" background: %lx\n", (unsigned long int)s_bg);
881 stderr_out (" fontset: \n"); describe_XFontSet (s_fontset);
882 stderr_out ("XNResourceName: %s\n", resourceName ? resourceName : "NULL");
883 stderr_out ("XNResourceClass: %s\n", resourceClass ? resourceClass : "NULL");
884 stderr_out ("XNFilterEvents: "); describe_event_mask (filter_mask);
888 describe_XRectangle (char *name, XRectangle *r)
891 stderr_out ("%s: NULL\n", name);
893 stderr_out ("%s: x=%d y=%d w=%d h=%d\n",
894 name, r->x, r->y, r->width, r->height);
897 /* Print out elements of Event mask */
898 /* Defines from X11/X.h */
900 describe_event_mask (unsigned long mask)
902 #define DESCRIBE_EVENT_MASK(bit) if ((bit) & mask) stderr_out (#bit " ")
903 DESCRIBE_EVENT_MASK (NoEventMask);
904 DESCRIBE_EVENT_MASK (KeyPressMask);
905 DESCRIBE_EVENT_MASK (KeyReleaseMask);
906 DESCRIBE_EVENT_MASK (ButtonPressMask);
907 DESCRIBE_EVENT_MASK (ButtonReleaseMask);
908 DESCRIBE_EVENT_MASK (EnterWindowMask);
909 DESCRIBE_EVENT_MASK (LeaveWindowMask);
910 DESCRIBE_EVENT_MASK (PointerMotionMask);
911 DESCRIBE_EVENT_MASK (PointerMotionHintMask);
912 DESCRIBE_EVENT_MASK (Button1MotionMask);
913 DESCRIBE_EVENT_MASK (Button2MotionMask);
914 DESCRIBE_EVENT_MASK (Button3MotionMask);
915 DESCRIBE_EVENT_MASK (Button4MotionMask);
916 DESCRIBE_EVENT_MASK (Button5MotionMask);
917 DESCRIBE_EVENT_MASK (ButtonMotionMask);
918 DESCRIBE_EVENT_MASK (KeymapStateMask);
919 DESCRIBE_EVENT_MASK (ExposureMask);
920 DESCRIBE_EVENT_MASK (VisibilityChangeMask);
921 DESCRIBE_EVENT_MASK (StructureNotifyMask);
922 DESCRIBE_EVENT_MASK (ResizeRedirectMask);
923 DESCRIBE_EVENT_MASK (SubstructureNotifyMask);
924 DESCRIBE_EVENT_MASK (SubstructureRedirectMask);
925 DESCRIBE_EVENT_MASK (FocusChangeMask);
926 DESCRIBE_EVENT_MASK (PropertyChangeMask);
927 DESCRIBE_EVENT_MASK (ColormapChangeMask);
928 DESCRIBE_EVENT_MASK (OwnerGrabButtonMask);
929 #undef DESCRIBE_EVENT_MASK
934 describe_XIMStyle (XIMStyle style)
936 #define DESCRIBE_STYLE(bit) \
938 stderr_out (#bit " ");
940 DESCRIBE_STYLE (XIMPreeditArea);
941 DESCRIBE_STYLE (XIMPreeditCallbacks);
942 DESCRIBE_STYLE (XIMPreeditPosition);
943 DESCRIBE_STYLE (XIMPreeditNothing);
944 DESCRIBE_STYLE (XIMPreeditNone);
945 DESCRIBE_STYLE (XIMStatusArea);
946 DESCRIBE_STYLE (XIMStatusCallbacks);
947 DESCRIBE_STYLE (XIMStatusNothing);
948 DESCRIBE_STYLE (XIMStatusNone);
949 #undef DESCRIBE_STYLE
954 describe_XIMStyles (XIMStyles *p)
957 stderr_out ("%d Style(s):\n", p->count_styles);
958 for (i=0; i<p->count_styles ; i++)
960 describe_XIMStyle (p->supported_styles[i]);
964 #endif /* DEBUG_XEMACS */
966 /* Random cruft follows */
970 Unit_Test (struct frame *f, char * s)
971 /* mrb unit testing */
973 XrmValue fromVal, toVal;
976 fromVal.size = strlen (s);
977 toVal.addr = (XtPointer) &user_preferred_XIMStyles;
978 toVal.size = sizeof (XIMStyles);
980 if (XtConvertAndStore (FRAME_X_TEXT_WIDGET (f), XtRString, &fromVal,
981 XtRXimStyles, &toVal) != False)
983 stderr_out ("Unit_Test: fromVal.addr=0x%x\n",fromVal.addr);
984 stderr_out ("Unit_Test: fromVal.size=%d\n", fromVal.size);
985 stderr_out ("Unit_Test: toVal.addr=0x%x\n", toVal.addr);
986 stderr_out ("Unit_Test: toVal.size=%d\n", toVal.size);
987 describe_XIMStyles ((XIMStyles *) toVal.addr);
993 /* Get a fontset for IM to use */
995 x_init_fontset (struct device *d)
997 Display *dpy = DEVICE_X_DISPLAY (d);
999 char ** missing_charsets;
1000 int num_missing_charsets;
1001 char * default_string;
1002 /* char * font_set_string = "-dt-interface user-medium-r-normal-s*-*-*-*-*-*-*-*-*";*/
1003 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" ;
1005 DEVICE_X_FONTSET (d) = fontset =
1006 XCreateFontSet (dpy,
1009 &num_missing_charsets,
1012 if (fontset == NULL)
1014 stderr_out ("Unable to create fontset from string:\n%s\n", font_set_string);
1017 if (num_missing_charsets > 0)
1020 stderr_out ("\nMissing charsets for fontset %s:\n", font_set_string);
1021 for (i=0; i < num_missing_charsets; i++)
1023 stderr_out ("%s\n", missing_charsets[i]);
1025 XFreeStringList (missing_charsets);
1026 stderr_out ("Default string: %s\n", default_string);
1030 describe_XFontSet (fontset);