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 (f));
147 DEVICE_FRAME_LOOP (tail, d)
149 struct frame *target_frame = XFRAME (XCAR (tail));
150 if (FRAME_X_XIC (target_frame))
152 XDestroyIC (FRAME_X_XIC (target_frame));
153 FRAME_X_XIC (target_frame) = NULL;
158 if ( DEVICE_X_XIM (d) )
160 stderr_out ("NULLing d->xim...\n");
161 /* DEVICE_X_XIM (d) = NULL; */
170 * called from when FRAME is initializing
173 IMInstantiateCallback (Display *dpy, XPointer client_data, XPointer call_data)
175 struct frame *f = (struct frame *) client_data;
176 struct device *d = XDEVICE (FRAME_DEVICE (f));
178 Widget w = FRAME_X_TEXT_WIDGET (f);
179 Window win = XtWindow (w);
180 XRectangle p_area = {0,0,1,1}, s_area = {0,0,1,1};
183 XVaNestedList p_list, s_list;
194 XIMCallback ximcallback;
197 #define res(name, class, representation, field, default_value) \
198 { name, class, representation, sizeof(xic_vars.field), \
199 XtOffsetOf(xic_vars_t, field), XtRString, default_value }
201 static XtResource resources[] =
203 /* name class represent'n field default value */
204 res(XtNximStyles, XtCXimStyles, XtRXimStyles, styles, (XtPointer) DefaultXIMStyles),
205 res(XtNfontSet, XtCFontSet, XtRFontSet, fontset, (XtPointer) XtDefaultFontSet),
206 res(XtNximForeground, XtCForeground, XtRPixel, fg, (XtPointer) XtDefaultForeground),
207 res(XtNximBackground, XtCBackground, XtRPixel, bg, (XtPointer) XtDefaultBackground),
208 res(XtNinputMethod, XtCInputMethod, XtRString, inputmethod, (XtPointer) NULL)
211 /* ---------- beginning of the action ---------- */
214 * 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) f;
225 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL);
229 xim = DEVICE_X_XIM (d);
232 w = FRAME_X_TEXT_WIDGET (f);
237 if ( FRAME_X_XIC (f) ) return;
238 XtGetApplicationResources (w, &xic_vars,
239 resources, XtNumber (resources),
241 if (!xic_vars.fontset)
243 stderr_out ("Can't get fontset resource for Input Method\n");
244 FRAME_X_XIC (f) = NULL;
249 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES(d), NULL);
250 FRAME_X_XIC_STYLE (f) = style =
251 best_style (&xic_vars.styles, (XIMStyles *)DEVICE_X_XIM_STYLES(d));
253 p_list = XVaCreateNestedList (0,
255 XNSpotLocation, &spot,
256 XNForeground, xic_vars.fg,
257 XNBackground, xic_vars.bg,
258 XNFontSet, xic_vars.fontset,
261 s_list = XVaCreateNestedList (0,
263 XNForeground, xic_vars.fg,
264 XNBackground, xic_vars.bg,
265 XNFontSet, xic_vars.fontset,
268 FRAME_X_XIC (f) = xic =
273 XNPreeditAttributes, p_list,
274 XNStatusAttributes, s_list,
281 stderr_out ("Warning: XCreateIC failed.\n");
285 if (style & XIMPreeditPosition)
287 XPoint *frame_spot = &(FRAME_X_XIC_SPOT(f));
288 frame_spot->x = frame_spot->y = -1;
298 /* Create X input method for device */
300 XIM_init_device (struct device *d)
302 /* do nothing here */
306 /* Callback for when the frame was deleted (closed) */
308 XIM_delete_frame (Widget w, XtPointer client_data, XtPointer call_data)
310 struct frame *f = (struct frame *) client_data;
311 struct device *d = XDEVICE (FRAME_DEVICE (f));
312 Display *dpy = DEVICE_X_DISPLAY (d);
314 XUnregisterIMInstantiateCallback (dpy, NULL, NULL, NULL,
315 IMInstantiateCallback, (XPointer) f);
319 XDestroyIC (FRAME_X_XIC (f));
320 FRAME_X_XIC (f) = NULL;
325 /* Create an X input context for this frame.
326 - Register the IM to be initiated later using XRegisterIMInstantiateCallback
329 XIM_init_frame (struct frame *f)
331 struct device *d = XDEVICE (FRAME_DEVICE (f));
333 XRegisterIMInstantiateCallback (DEVICE_X_DISPLAY (d), NULL, NULL, NULL,
334 IMInstantiateCallback, (XPointer) f);
337 if ( FRAME_X_XIC (f) )
340 if ( ! DEVICE_X_XIM (d) )
342 stderr_out ("X Input Method open failed. Waiting IM to be enabled.\n");
345 /* when frame is going to be destroyed (closed) */
346 XtAddCallback (FRAME_X_TEXT_WIDGET(f), XNDestroyCallback,
347 XIM_delete_frame, (XtPointer)f);
353 XIM_SetGeometry (struct frame *f)
355 XIC xic = FRAME_X_XIC (f);
356 XIMStyle style = FRAME_X_XIC_STYLE (f);
362 if (style & XIMStatusArea)
364 /* Place Status Area in bottom right corner */
365 /* Negotiate geometry of status area */
366 /* See O'Reilly Xlib XIM chapter (but beware, it's buggy) */
369 /* If input method has existing status area, use its current size */
370 /* The following at least works for Sun's htt */
371 area.x = area.y = area.width = area.height = 0;
372 XIC_Value (Set, xic, XNStatusAttributes, XNAreaNeeded, &area);
373 XIC_Value (Get, xic, XNStatusAttributes, XNAreaNeeded, &needed);
374 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
375 XIC_Value (Get, xic, XNStatusAttributes, XNArea, &needed);
377 area.width = needed->width;
378 area.height = needed->height;
379 area.x = FRAME_RIGHT_BORDER_START (f) - area.width;
380 area.y = FRAME_BOTTOM_BORDER_START (f) - area.height;
383 stderr_out ("Putting StatusArea in x=%d y=%d w=%d h=%d\n",
384 area.x, area.y, area.width, area.height);
385 #endif /* DEBUG_XIM */
387 XIC_Value (Set, xic, XNStatusAttributes, XNArea, &area);
390 if (style & XIMPreeditPosition)
392 /* Set Preedit Area to whole frame size (sans border) */
393 /* We include the border because Preedit window might be larger
394 than display line at edge. #### FIX: we should adjust to make
395 sure that there is always room for the spot sub-window */
396 area.x = FRAME_LEFT_BORDER_START (f);
397 area.y = FRAME_TOP_BORDER_START (f);
398 area.width = FRAME_RIGHT_BORDER_END (f) - area.x;
399 area.height = FRAME_BOTTOM_BORDER_END (f) - area.y;
400 XIC_Value(Set, xic, XNPreeditAttributes, XNArea, &area);
409 XIM_SetSpotLocation (struct frame *f, int x, int y)
411 XIC xic = FRAME_X_XIC (f);
412 XPoint *spot = &(FRAME_X_XIC_SPOT (f));
414 /* Only care if we have a valid XIC using Over the Spot in
415 * a different location */
417 !(FRAME_X_XIC_STYLE (f) & XIMPreeditPosition) ||
418 (spot->x == (short) x &&
419 spot->y == (short) y))
425 /* ### FIX: Must make sure spot fits within Preedit Area */
426 XIC_Value (Set, xic, XNPreeditAttributes, XNSpotLocation, spot);
428 stderr_out ("Spot: %d %d\n", spot->x, spot->y);
433 XIM_focus_event (struct frame *f, int in_p)
435 if (FRAME_X_XIC (f) /* && FRAME_X_XIM_REGISTERED(f) */)
436 (in_p ? XSetICFocus : XUnsetICFocus) (FRAME_X_XIC (f));
440 #define XIM_Composed_Text_BUFSIZE 64
441 typedef struct XIM_Composed_Text
444 wchar_t data [XIM_Composed_Text_BUFSIZE];
447 static XIM_Composed_Text composed_input_buf = {XIM_Composed_Text_BUFSIZE, {0}};
450 /* get_XIM_input -- Process results of input method composition.
452 This function copies the results of the input method composition to
453 composed_input_buf. Then for each character, a custom event of type
454 wc_atom is sent with the character as its data.
456 It is probably more efficient to copy the composition results to some
457 allocated memory and send a single event pointing to that memory.
458 That would cut down on the event processing as well as allow quick
459 insertion into the buffer of the whole string. It might require some
460 care, though, to avoid fragmenting memory through the allocation and
461 freeing of many small chunks. Maybe the existing system for
462 (single-byte) string allocation can be used, multiplying the length by
463 sizeof (wchar_t) to get the right size.
466 get_XIM_input (XKeyPressedEvent *x_key_event, XIC ic, Display *dpy)
472 XClientMessageEvent new_event;
475 len = XwcLookupString (ic, x_key_event, composed_input_buf.data,
476 composed_input_buf.size, &keysym, &status);
479 case XBufferOverflow:
480 /* GROW_WC_STRING (&composed_input_buf, 32); mrb */
488 new_event.type = ClientMessage;
489 new_event.display = x_key_event->display;
490 new_event.window = x_key_event->window;
491 new_event.message_type = wc_atom;
492 new_event.format = 32; /* 32-bit wide data */
493 new_event.data.l[2] = new_event.data.l[3] = new_event.data.l[4] = 0L;
494 new_event.data.l[0] = x_key_event->time;
495 for (i = 0; i < len; i++)
497 new_event.data.l[1] = ((wchar_t *) composed_input_buf.data)[i];
498 XSendEvent (display, main_window, False, 0L, (XEvent *) &new_event);
503 /* ============================================================== */
504 /* X input method style determination */
505 /* ============================================================== */
508 #define done(type, value) \
509 if (toVal->addr != NULL) { \
510 if (toVal->size < sizeof(type)) { \
511 toVal->size = sizeof(type); \
514 *(type*)toVal->addr = (value); \
516 static type static_val; \
517 static_val = (value); \
518 toVal->addr = (XPointer)&static_val; \
520 toVal->size = sizeof(type); \
521 return True /* Caller supplies `;' */
525 * This is a standard Xt type converter, except that the caller MUST
526 * supply a proper non-NULL toVal XIMStyles structure that we will
529 * fromVal points to a string like
531 "XIMPreeditPosition|XIMStatusArea,
532 XIMPreeditPosition|XIMStatusNothing
533 XIMPreeditNothing|XIMStatusNothing"
535 * This is converted in the obvious way to a XIMStyles structure.
537 * mrb: #### Fix this to handle Motif-style specifications for
538 * XIMStyles as well: overTheSpot, rootWindow, none */
540 /* XtTypeConverter */
542 EmacsXtCvtStringToXIMStyles (
548 XtPointer *converter_data)
550 #define STYLE_INFO(style) { style, #style, sizeof(#style) }
551 static struct XIMStyleInfo
553 CONST XIMStyle style;
554 CONST char * CONST name;
556 } emacs_XIMStyleInfo[] = {
557 STYLE_INFO (XIMPreeditPosition|XIMStatusArea),
558 STYLE_INFO (XIMPreeditPosition|XIMStatusNothing),
559 STYLE_INFO (XIMPreeditPosition|XIMStatusNone),
560 STYLE_INFO (XIMPreeditNothing|XIMStatusArea),
561 STYLE_INFO (XIMPreeditNothing|XIMStatusNothing),
562 STYLE_INFO (XIMPreeditNothing|XIMStatusNone),
563 STYLE_INFO (XIMPreeditNone|XIMStatusArea),
564 STYLE_INFO (XIMPreeditNone|XIMStatusNothing),
565 STYLE_INFO (XIMPreeditNone|XIMStatusNone)
569 char *s = (char *) fromVal->addr;
570 char *end = s + fromVal->size;
571 XIMStyles * CONST p = (XIMStyles *) toVal->addr;
572 CONST char * CONST delimiter = " \t\n\r:;," ;
573 CONST int max_styles = XtNumber(emacs_XIMStyleInfo);
578 stderr_out ("EmacsCvtStringToXIMStyles called with size=%d, string=\"%s\"\n",
579 fromVal->size, (char *) fromVal->addr);
580 #endif /* DEBUG_XIM */
584 XtAppContext the_app_con = XtDisplayToApplicationContext (dpy);
585 XtAppWarningMsg(the_app_con, "wrongParameters", "cvtStringToXIMStyle",
587 "String to XIMStyle conversion requires exactly 0 parameters",
588 (String *)NULL, (Cardinal *)NULL);
593 /* Make sure caller is giving us good data */
594 assert (fromVal->addr != NULL);
595 assert (fromVal->size == strlen(fromVal->addr)+1);
596 assert (toVal->addr != NULL);
597 assert (toVal->size == sizeof(XIMStyles));
598 #endif /* DEBUG_XEMACS */
601 p->supported_styles = xnew_array (XIMStyle, max_styles);
604 * The following routine assumes that the style name resource is
605 * identical with the programmatic name of style. For example,
606 * "XIMPreeditPosition|XIMStatusArea" means the
607 * XIMPreeditPosition|XIMStatusArea value is specified. If the
608 * style name is changed, such as "OverTheSpot|imDisplaysInClient",
609 * the parsing logic below should be modified as well. */
611 if ((c = strtok(s, delimiter)) == NULL)
616 for(i=0 ; i<max_styles ; i++)
618 struct XIMStyleInfo *rec = emacs_XIMStyleInfo + i;
619 if(!strncmp(c, rec->name, rec->namelen - 1)) {
620 p->supported_styles[p->count_styles] = rec->style;
625 if((c = strtok(NULL, delimiter)) == NULL) {
630 if (p->count_styles == 0)
631 { /* No valid styles? */
632 char *buf = (char *)alloca (strlen (fromVal->addr)
633 + strlen (DefaultXIMStyles)
636 XtAppContext the_app_con = XtDisplayToApplicationContext (dpy);
638 sprintf(buf, "Cannot convert string \"%s\" to type XIMStyles.\n"
639 "Using default string \"%s\" instead.\n",
640 fromVal->addr, DefaultXIMStyles);
641 XtAppWarningMsg(the_app_con, "wrongParameters", "cvtStringToXIMStyle",
643 buf, (String *)NULL, (Cardinal *)NULL);
644 new_from.addr = DefaultXIMStyles;
645 new_from.size = sizeof(DefaultXIMStyles);
646 return EmacsXtCvtStringToXIMStyles (dpy, args, num_args,
647 &new_from, toVal, converter_data);
649 XREALLOC_ARRAY (p->supported_styles, XIMStyle, p->count_styles);
650 *converter_data = (char *) True;
659 XtPointer converter_data,
664 stderr_out ("Converter data: %x\n", converter_data);
665 stderr_out ("EmacsFreeXIMStyles called\n");
666 #endif /* DEBUG_XIM */
670 XtAppWarningMsg(app, "wrongParameters","freeXIMStyles","XtToolkitError",
671 "Freeing an XIMStyles requires that zero arguments be passwd",
672 (String *)NULL, (Cardinal *)NULL);
678 Boolean free_p = (Boolean) (int) converter_data;
679 XIMStyles *styles = (XIMStyles *) toVal->addr;
681 XFree ( styles->supported_styles );
686 /* O'Reilly XLib Programming Manual, pg. 371 */
687 /* Much nicer implementation than O'Reilly */
688 /* Choose the more `complicated', hence nicer, XIM input style */
690 BetterStyle (XIMStyle s, XIMStyle t)
692 #define CHECK_XIMStyle_BIT(bit) \
693 if ((s ^ t) & bit) { return (s & bit) ? s : t; }
695 CHECK_XIMStyle_BIT (XIMPreeditCallbacks);
696 CHECK_XIMStyle_BIT (XIMPreeditPosition);
697 CHECK_XIMStyle_BIT (XIMPreeditArea);
698 CHECK_XIMStyle_BIT (XIMPreeditNothing);
699 CHECK_XIMStyle_BIT (XIMStatusCallbacks);
700 CHECK_XIMStyle_BIT (XIMStatusArea);
701 CHECK_XIMStyle_BIT (XIMStatusNothing);
702 #undef CHECK_XIMStyle_BIT
707 /* Choose the best style, given:
708 * - user preferences (already checked to be supported by XEmacs)
709 * - styles supported by the input method */
710 #define DEFAULTStyle (XIMPreeditNothing|XIMStatusNothing)
712 best_style (XIMStyles *user, XIMStyles *xim)
715 for (i=0 ; i<user->count_styles ; i++)
717 for (j=0 ; j<xim->count_styles ; j++)
719 if (user->supported_styles[i] == xim->supported_styles[j])
720 return user->supported_styles[i];
723 return DEFAULTStyle; /* Default Style */
728 vars_of_input_method_xlib (void)
730 Fprovide (intern ("xim"));
734 /* ====================================================================== */
735 /* Internal Debugging Routines */
736 /* ====================================================================== */
740 describe_XIM (XIM xim)
744 /* Print locale of XIM */
745 stderr_out ("\nXIM Locale of IM: %s\n", XLocaleOfIM(xim));
747 /* List supported input method styles */
748 XGetIMValues(xim, XNQueryInputStyle, &styles, NULL);
750 stderr_out ("\n%d input style(s) supported by input method.\n",
751 styles->count_styles);
756 for (i=0; i < styles->count_styles; i++)
757 describe_XIMStyle (styles->supported_styles[i]);
759 #endif /* DEBUG_XIM */
764 describe_XFontSet (XFontSet fontset)
766 XFontStruct **font_struct_list;
767 char **font_name_list;
772 stderr_out ("NULL\n");
776 count = XFontsOfFontSet (fontset, &font_struct_list, &font_name_list);
777 stderr_out ( "%d font(s) available:\n", count);
778 for (i=0 ; i < count ; i++)
779 stderr_out ("Font: %s\n", *(font_name_list+i));
783 describe_Status (Status status)
785 #define DESCRIBE_STATUS(value) \
786 if (status == value) stderr_out ("Status: " #value "\n")
788 DESCRIBE_STATUS (XBufferOverflow);
789 DESCRIBE_STATUS (XLookupNone);
790 DESCRIBE_STATUS (XLookupKeySym);
791 DESCRIBE_STATUS (XLookupBoth);
792 DESCRIBE_STATUS (XLookupChars);
793 #undef DESCRIBE_STATUS
797 describe_Window (Window win)
800 sprintf (xwincmd, "xwininfo -id 0x%x >&2; xwininfo -events -id 0x%x >&2",
801 (int) win, (int) win);
806 describe_XIC (XIC xic)
809 Window client_win=0, focus_win=0;
810 char *resourceName = NULL;
811 char *resourceClass = NULL;
812 char *bad_arg = NULL;
813 unsigned long filter_mask = NoEventMask;
814 XVaNestedList p_list, s_list;
815 XFontSet p_fontset = NULL, s_fontset = NULL;
816 Pixel p_fg=0, p_bg = 0, s_fg=0, s_bg = 0;
817 XRectangle *p_area = NULL, *s_area = NULL;
818 XRectangle *p_needed = NULL, *s_needed = NULL;
819 XPoint *p_spot = NULL;
821 /* Check for valid input context and method */
823 stderr_out ("Input method is NULL\n");
826 stderr_out ("XIMOfIC() returns NULL\n");
828 /* Print out Input Context Attributes */
829 p_list = XVaCreateNestedList (0,
830 XNFontSet, &p_fontset,
832 XNAreaNeeded, &p_needed,
833 XNSpotLocation, &p_spot,
838 s_list = XVaCreateNestedList (0,
839 XNFontSet, &s_fontset,
841 XNAreaNeeded, &s_needed,
846 bad_arg = XGetICValues(xic,
847 XNInputStyle, &style,
848 XNFilterEvents, &filter_mask,
849 XNClientWindow, &client_win,
850 XNFocusWindow, &focus_win,
851 XNResourceName, &resourceName,
852 XNResourceClass, &resourceClass,
853 XNPreeditAttributes, p_list,
854 XNStatusAttributes, s_list,
860 stderr_out ("Couldn't get IC value: %s\n", bad_arg);
862 stderr_out ("\nInput method context attributes:\n");
863 stderr_out ("Style: "); describe_XIMStyle (style);
864 stderr_out ("Client window: %lx\n", (unsigned long int)client_win);
865 stderr_out ("Focus window: %lx\n", (unsigned long int)focus_win);
866 stderr_out ("Preedit:\n");
867 describe_XRectangle (" Area", p_area);
868 describe_XRectangle (" Area needed", p_needed);
869 stderr_out (" foreground: %lx\n", (unsigned long int)p_fg);
870 stderr_out (" background: %lx\n", (unsigned long int)p_bg);
871 stderr_out (" fontset: "); describe_XFontSet (p_fontset);
872 stderr_out ("Status:\n");
873 describe_XRectangle (" Area", s_area);
874 describe_XRectangle (" Area needed", s_needed);
875 stderr_out (" foreground: %lx\n", (unsigned long int)s_fg);
876 stderr_out (" background: %lx\n", (unsigned long int)s_bg);
877 stderr_out (" fontset: \n"); describe_XFontSet (s_fontset);
878 stderr_out ("XNResourceName: %s\n", resourceName ? resourceName : "NULL");
879 stderr_out ("XNResourceClass: %s\n", resourceClass ? resourceClass : "NULL");
880 stderr_out ("XNFilterEvents: "); describe_event_mask (filter_mask);
884 describe_XRectangle (char *name, XRectangle *r)
887 stderr_out ("%s: NULL\n", name);
889 stderr_out ("%s: x=%d y=%d w=%d h=%d\n",
890 name, r->x, r->y, r->width, r->height);
893 /* Print out elements of Event mask */
894 /* Defines from X11/X.h */
896 describe_event_mask (unsigned long mask)
898 #define DESCRIBE_EVENT_MASK(bit) if ((bit) & mask) stderr_out (#bit " ")
899 DESCRIBE_EVENT_MASK (NoEventMask);
900 DESCRIBE_EVENT_MASK (KeyPressMask);
901 DESCRIBE_EVENT_MASK (KeyReleaseMask);
902 DESCRIBE_EVENT_MASK (ButtonPressMask);
903 DESCRIBE_EVENT_MASK (ButtonReleaseMask);
904 DESCRIBE_EVENT_MASK (EnterWindowMask);
905 DESCRIBE_EVENT_MASK (LeaveWindowMask);
906 DESCRIBE_EVENT_MASK (PointerMotionMask);
907 DESCRIBE_EVENT_MASK (PointerMotionHintMask);
908 DESCRIBE_EVENT_MASK (Button1MotionMask);
909 DESCRIBE_EVENT_MASK (Button2MotionMask);
910 DESCRIBE_EVENT_MASK (Button3MotionMask);
911 DESCRIBE_EVENT_MASK (Button4MotionMask);
912 DESCRIBE_EVENT_MASK (Button5MotionMask);
913 DESCRIBE_EVENT_MASK (ButtonMotionMask);
914 DESCRIBE_EVENT_MASK (KeymapStateMask);
915 DESCRIBE_EVENT_MASK (ExposureMask);
916 DESCRIBE_EVENT_MASK (VisibilityChangeMask);
917 DESCRIBE_EVENT_MASK (StructureNotifyMask);
918 DESCRIBE_EVENT_MASK (ResizeRedirectMask);
919 DESCRIBE_EVENT_MASK (SubstructureNotifyMask);
920 DESCRIBE_EVENT_MASK (SubstructureRedirectMask);
921 DESCRIBE_EVENT_MASK (FocusChangeMask);
922 DESCRIBE_EVENT_MASK (PropertyChangeMask);
923 DESCRIBE_EVENT_MASK (ColormapChangeMask);
924 DESCRIBE_EVENT_MASK (OwnerGrabButtonMask);
925 #undef DESCRIBE_EVENT_MASK
930 describe_XIMStyle (XIMStyle style)
932 #define DESCRIBE_STYLE(bit) \
934 stderr_out (#bit " ");
936 DESCRIBE_STYLE (XIMPreeditArea);
937 DESCRIBE_STYLE (XIMPreeditCallbacks);
938 DESCRIBE_STYLE (XIMPreeditPosition);
939 DESCRIBE_STYLE (XIMPreeditNothing);
940 DESCRIBE_STYLE (XIMPreeditNone);
941 DESCRIBE_STYLE (XIMStatusArea);
942 DESCRIBE_STYLE (XIMStatusCallbacks);
943 DESCRIBE_STYLE (XIMStatusNothing);
944 DESCRIBE_STYLE (XIMStatusNone);
945 #undef DESCRIBE_STYLE
950 describe_XIMStyles (XIMStyles *p)
953 stderr_out ("%d Style(s):\n", p->count_styles);
954 for (i=0; i<p->count_styles ; i++)
956 describe_XIMStyle (p->supported_styles[i]);
960 #endif /* DEBUG_XEMACS */
962 /* Random cruft follows */
966 Unit_Test (struct frame *f, char * s)
967 /* mrb unit testing */
969 XrmValue fromVal, toVal;
972 fromVal.size = strlen (s);
973 toVal.addr = (XtPointer) &user_preferred_XIMStyles;
974 toVal.size = sizeof (XIMStyles);
976 if (XtConvertAndStore (FRAME_X_TEXT_WIDGET (f), XtRString, &fromVal,
977 XtRXimStyles, &toVal) != False)
979 stderr_out ("Unit_Test: fromVal.addr=0x%x\n",fromVal.addr);
980 stderr_out ("Unit_Test: fromVal.size=%d\n", fromVal.size);
981 stderr_out ("Unit_Test: toVal.addr=0x%x\n", toVal.addr);
982 stderr_out ("Unit_Test: toVal.size=%d\n", toVal.size);
983 describe_XIMStyles ((XIMStyles *) toVal.addr);
989 /* Get a fontset for IM to use */
991 x_init_fontset (struct device *d)
993 Display *dpy = DEVICE_X_DISPLAY (d);
995 char ** missing_charsets;
996 int num_missing_charsets;
997 char * default_string;
998 /* char * font_set_string = "-dt-interface user-medium-r-normal-s*-*-*-*-*-*-*-*-*";*/
999 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" ;
1001 DEVICE_X_FONTSET (d) = fontset =
1002 XCreateFontSet (dpy,
1005 &num_missing_charsets,
1008 if (fontset == NULL)
1010 stderr_out ("Unable to create fontset from string:\n%s\n", font_set_string);
1013 if (num_missing_charsets > 0)
1016 stderr_out ("\nMissing charsets for fontset %s:\n", font_set_string);
1017 for (i=0; i < num_missing_charsets; i++)
1019 stderr_out ("%s\n", missing_charsets[i]);
1021 XFreeStringList (missing_charsets);
1022 stderr_out ("Default string: %s\n", default_string);
1026 describe_XFontSet (fontset);