428
+ − 1 /* Various functions for X11R5+ input methods, using the Xlib interface.
+ − 2 Copyright (C) 1996 Sun Microsystems.
793
+ − 3 Copyright (C) 2002 Ben Wing.
428
+ − 4
+ − 5 This file is part of XEmacs.
+ − 6
+ − 7 XEmacs is free software; you can redistribute it and/or modify it
+ − 8 under the terms of the GNU General Public License as published by the
+ − 9 Free Software Foundation; either version 2, or (at your option) any
+ − 10 later version.
+ − 11
+ − 12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 15 for more details.
+ − 16
+ − 17 You should have received a copy of the GNU General Public License
+ − 18 along with XEmacs; see the file COPYING. If not, write to
+ − 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 20 Boston, MA 02111-1307, USA. */
+ − 21
+ − 22 /* Synched up with: Not in FSF. */
+ − 23
+ − 24 /* Written by Martin Buchholz. */
+ − 25
+ − 26 /* This file implements an interface to X input methods, available
+ − 27 with X11R5 and above. See O'Reilly, Xlib programmer's guide,
+ − 28 and X11 R6 release guide chapters on internationalized input,
+ − 29 for further details */
+ − 30
+ − 31 /*
+ − 32 Policy:
+ − 33
+ − 34 The XIM is of the device, by the device, for the device.
+ − 35 The XIC is of each frame, by each frame, for each frame.
+ − 36 The exceptions are:
+ − 37 1. Activate XICs on poor frames when the XIM is back.
444
+ − 38 2. Deactivate all the XICs when the XIM goes down.
428
+ − 39
444
+ − 40 Implementation:
428
+ − 41
+ − 42 - Register a callback for an XIM when the X device is being initialized.
+ − 43 XIM_init_device (d) { XRegisterIMInstantiateCallback (); }
+ − 44 The "XRegisterIMInstantiateCallback" is called when an XIM become
+ − 45 available on the X display.
+ − 46
+ − 47 - Catch the XIC when the frame is being initialized if XIM was available.
+ − 48 XIM_init_frame (f) { ... XCreateIC (); ... }
+ − 49
+ − 50 - Release the XIC when the frame is being closed.
+ − 51 XIM_delete_frame (f) { ... FRAME_X_XIC (f) = NULL; ... }
+ − 52 "XIM_delete_frame" is a "DestroyCallback" function declared in
+ − 53 XIM_init_frame ();
+ − 54
+ − 55 - Release all the XICs when the XIM was down accidentally.
+ − 56 In IMDestroyCallback:
+ − 57 DEVICE_FRAME_LOOP (...) { FRAME_X_XIC (f) = NULL; }
+ − 58
444
+ − 59 - Re-enable XIC for all the frames which don't have XIC when the XIM
428
+ − 60 is back.
+ − 61 In IMInstantiateCallback:
+ − 62 DEVICE_FRAME_LOOP (...) { XIM_init_frame (f); }
+ − 63
+ − 64
+ − 65 Note:
+ − 66
+ − 67 - Currently, we don't use XDestroyIC because of _XimProtoCloseIM
+ − 68 (internally registered as im->methods->close) does "Xfree (ic)".
+ − 69
+ − 70 */
+ − 71
+ − 72 #include <config.h>
+ − 73 #include "lisp.h"
872
+ − 74
+ − 75 #include "buffer.h"
+ − 76 #include "device-impl.h"
+ − 77 #include "events.h"
+ − 78 #include "frame-impl.h"
+ − 79 #include "window-impl.h"
+ − 80
+ − 81 #include "console-x-impl.h"
+ − 82 #include "EmacsFrame.h"
+ − 83
428
+ − 84 #include <X11/Xlocale.h> /* More portable than <locale.h> ? */
444
+ − 85 #include <X11/Xlib.h>
428
+ − 86
448
+ − 87 #if !defined (XIM_XLIB) && !defined (USE_XFONTSET)
+ − 88 #error neither XIM_XLIB nor USE_XFONTSET is defined??
428
+ − 89 #endif
+ − 90
771
+ − 91 #ifdef XIM_XLIB /* XIM_XLIB specific */
428
+ − 92
+ − 93 /* Get/Set IC values for just one attribute */
+ − 94 #ifdef DEBUG_XEMACS
+ − 95 #define XIC_Value(Get_Set, xic, name, attr, value) \
+ − 96 do { \
+ − 97 char *bad_arg; \
+ − 98 XVaNestedList list = XVaCreateNestedList (0, attr, value, NULL); \
+ − 99 if ((bad_arg = X##Get_Set##ICValues (xic, name, list, NULL)) != NULL) \
+ − 100 stderr_out ("X" #Get_Set "ICValues " "bad Arg: %s\n", bad_arg); \
+ − 101 XFree (list); \
+ − 102 } while (0)
+ − 103 #else /* ! DEBUG_XEMACS */
+ − 104 #define XIC_Value(Get_Set, xic, name, attr, value) \
+ − 105 do { \
+ − 106 XVaNestedList list = XVaCreateNestedList (0, attr, value, NULL); \
+ − 107 X##Get_Set##ICValues (xic, name, list, NULL); \
+ − 108 XFree (list); \
+ − 109 } while (0)
+ − 110 #endif /* DEBUG_XEMACS */
+ − 111
+ − 112 static char DefaultXIMStyles[] =
+ − 113 "XIMPreeditPosition|XIMStatusArea\n"
+ − 114 "XIMPreeditPosition|XIMStatusNone\n"
+ − 115 "XIMPreeditPosition|XIMStatusNothing\n"
+ − 116 "XIMPreeditNothing|XIMStatusArea\n"
+ − 117 "XIMPreeditNothing|XIMStatusNothing\n"
+ − 118 "XIMPreeditNothing|XIMStatusNone\n"
+ − 119 "XIMPreeditNone|XIMStatusArea\n"
+ − 120 "XIMPreeditNone|XIMStatusNothing\n"
+ − 121 "XIMPreeditNone|XIMStatusNone";
+ − 122
+ − 123 static XIMStyle best_style (XIMStyles *user, XIMStyles *xim);
771
+ − 124
448
+ − 125 #endif /* XIM_XLIB only */
428
+ − 126
444
+ − 127 /* This function is documented, but no prototype in the header files */
+ − 128 EXTERN_C char * XSetIMValues(XIM, ...);
442
+ − 129
448
+ − 130 #ifdef XIM_XLIB /* starting XIM specific codes */
+ − 131
444
+ − 132 /* Callbacks for IM are supported from X11R6 or later. */
+ − 133 #ifdef HAVE_XREGISTERIMINSTANTIATECALLBACK
+ − 134
+ − 135 static Boolean xim_initted = False;
+ − 136
428
+ − 137 /* Called from when XIM is destroying.
+ − 138 Clear all the XIC when the XIM was destroying... */
+ − 139 static void
2286
+ − 140 IMDestroyCallback (XIM UNUSED (im), XPointer client_data,
+ − 141 XPointer UNUSED (call_data))
428
+ − 142 {
+ − 143 struct device *d = (struct device *)client_data;
+ − 144 Lisp_Object tail;
+ − 145
+ − 146 DEVICE_FRAME_LOOP (tail, d)
+ − 147 {
+ − 148 struct frame *target_frame = XFRAME (XCAR (tail));
+ − 149 if (FRAME_X_P (target_frame) && FRAME_X_XIC (target_frame))
+ − 150 {
+ − 151 /* XDestroyIC (FRAME_X_XIC (target_frame)); */
+ − 152 FRAME_X_XIC (target_frame) = NULL;
+ − 153 }
+ − 154 }
+ − 155
+ − 156 DEVICE_X_XIM (d) = NULL;
+ − 157 xim_initted = False;
+ − 158 return;
+ − 159 }
+ − 160
+ − 161 /* This is registered in XIM_init_device (when DEVICE is initializing).
+ − 162 This activates XIM when XIM becomes available. */
+ − 163 static void
2286
+ − 164 IMInstantiateCallback (Display *dpy, XPointer client_data,
+ − 165 XPointer UNUSED (call_data))
428
+ − 166 {
+ − 167 struct device *d = (struct device *)client_data;
+ − 168 XIM xim;
1204
+ − 169 char *name, *class_;
428
+ − 170 XIMCallback ximcallback;
+ − 171 Lisp_Object tail;
+ − 172
+ − 173 /* if no xim is presented, initialize xim ... */
+ − 174 if ( xim_initted == False )
+ − 175 {
+ − 176 xim_initted = True;
1204
+ − 177 XtGetApplicationNameAndClass (dpy, &name, &class_);
+ − 178 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class_);
428
+ − 179
+ − 180 /* destroy callback for im */
444
+ − 181 ximcallback.callback = (XIMProc) IMDestroyCallback;
428
+ − 182 ximcallback.client_data = (XPointer) d;
+ − 183 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL);
+ − 184 }
+ − 185
+ − 186 /* activate XIC on all the X frames... */
+ − 187 DEVICE_FRAME_LOOP (tail, d)
+ − 188 {
+ − 189 struct frame *target_frame = XFRAME (XCAR (tail));
+ − 190 if (FRAME_X_P (target_frame) && !FRAME_X_XIC (target_frame))
+ − 191 {
+ − 192 XIM_init_frame (target_frame);
+ − 193 }
+ − 194 }
+ − 195 return;
+ − 196 }
444
+ − 197 #endif /* HAVE_XREGISTERIMINSTANTIATECALLBACK */
428
+ − 198
+ − 199 /* Initialize XIM for X device.
+ − 200 Register the use of XIM using XRegisterIMInstantiateCallback. */
+ − 201 void
+ − 202 XIM_init_device (struct device *d)
+ − 203 {
444
+ − 204 #ifdef HAVE_XREGISTERIMINSTANTIATECALLBACK /* X11R6+ */
428
+ − 205 DEVICE_X_XIM (d) = NULL;
+ − 206 XRegisterIMInstantiateCallback (DEVICE_X_DISPLAY (d), NULL, NULL, NULL,
444
+ − 207 #ifdef XREGISTERIMINSTANTIATECALLBACK_NONSTANDARD_PROTOTYPE
442
+ − 208 /* The sixth parameter is of type
+ − 209 XPointer in XFree86 but (XPointer *)
+ − 210 on most other X11's. */
444
+ − 211 (XIDProc) IMInstantiateCallback,
+ − 212 (XPointer) d
+ − 213 #else /* X Consortium prototype */
+ − 214 (XIMProc) IMInstantiateCallback,
+ − 215 (XPointer *) d
+ − 216 #endif /* XREGISTERIMINSTANTIATECALLBACK_NONSTANDARD_PROTOTYPE */
+ − 217 );
428
+ − 218 return;
444
+ − 219 #else /* pre-X11R6 */
428
+ − 220 Display *dpy = DEVICE_X_DISPLAY (d);
1204
+ − 221 char *name, *class_;
428
+ − 222 XIM xim;
+ − 223
1204
+ − 224 XtGetApplicationNameAndClass (dpy, &name, &class_);
+ − 225 DEVICE_X_XIM (d) = xim = XOpenIM (dpy, XtDatabase (dpy), name, class_);
428
+ − 226 if (xim == NULL)
+ − 227 {
793
+ − 228 warn_when_safe
+ − 229 (Qxintl, Qerror,
+ − 230 "Can't initialize XIM: XOpenIM() failed, no input server available");
428
+ − 231 return;
+ − 232 }
+ − 233 else
+ − 234 {
+ − 235 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES (d), NULL);
+ − 236 return;
+ − 237 }
444
+ − 238 #endif /* HAVE_XREGISTERIMINSTANTIATECALLBACK */
428
+ − 239 }
+ − 240
+ − 241
+ − 242 /*
+ − 243 * For the frames
+ − 244 */
+ − 245
+ − 246 /* Callback for the deleting frame. */
+ − 247 static void
2286
+ − 248 XIM_delete_frame (Widget UNUSED (w), XtPointer client_data,
+ − 249 XtPointer UNUSED (call_data))
428
+ − 250 {
+ − 251 struct frame *f = (struct frame *) client_data;
+ − 252 struct device *d = XDEVICE (FRAME_DEVICE (f));
+ − 253
+ − 254 if (DEVICE_X_XIM (d))
+ − 255 {
+ − 256 if (FRAME_X_XIC (f))
+ − 257 {
+ − 258 XDestroyIC (FRAME_X_XIC (f));
+ − 259 FRAME_X_XIC (f) = NULL;
+ − 260 }
+ − 261 }
+ − 262 return;
+ − 263 }
+ − 264
+ − 265 /* Initialize XIC for new frame.
+ − 266 Create an X input context (XIC) for this frame. */
+ − 267 void
+ − 268 XIM_init_frame (struct frame *f)
+ − 269 {
+ − 270 struct device *d = XDEVICE (FRAME_DEVICE (f));
+ − 271 XIM xim;
+ − 272 Widget w = FRAME_X_TEXT_WIDGET (f);
+ − 273 Window win = XtWindow (w);
+ − 274 XRectangle p_area = {0,0,1,1}, s_area = {0,0,1,1};
+ − 275 XPoint spot = {0,0};
+ − 276 XIMStyle style;
+ − 277 XVaNestedList p_list, s_list;
+ − 278 typedef struct
+ − 279 {
+ − 280 XIMStyles styles;
+ − 281 XFontSet fontset;
+ − 282 Pixel fg;
+ − 283 Pixel bg;
+ − 284 char *inputmethod;
+ − 285 } xic_vars_t;
+ − 286 xic_vars_t xic_vars;
+ − 287 XIC xic;
+ − 288
1204
+ − 289 #define res(name, class_, representation, field, default_value) \
+ − 290 { name, class_, representation, sizeof(xic_vars.field), \
428
+ − 291 XtOffsetOf(xic_vars_t, field), XtRString, default_value }
+ − 292
+ − 293 static XtResource resources[] =
+ − 294 {
+ − 295 /* name class represent'n field default value */
+ − 296 res(XtNximStyles, XtCXimStyles, XtRXimStyles, styles, (XtPointer) DefaultXIMStyles),
+ − 297 res(XtNfontSet, XtCFontSet, XtRFontSet, fontset, (XtPointer) XtDefaultFontSet),
+ − 298 res(XtNximForeground, XtCForeground, XtRPixel, fg, (XtPointer) XtDefaultForeground),
+ − 299 res(XtNximBackground, XtCBackground, XtRPixel, bg, (XtPointer) XtDefaultBackground)
+ − 300 };
+ − 301
+ − 302
+ − 303 xim = DEVICE_X_XIM (d);
+ − 304
+ − 305 if (!xim)
+ − 306 {
+ − 307 return;
+ − 308 }
+ − 309
+ − 310 w = FRAME_X_TEXT_WIDGET (f);
+ − 311
+ − 312 /*
+ − 313 * initialize XIC
+ − 314 */
+ − 315 if (FRAME_X_XIC (f)) return;
+ − 316 XtGetApplicationResources (w, &xic_vars,
+ − 317 resources, XtNumber (resources),
+ − 318 NULL, 0);
+ − 319 if (!xic_vars.fontset)
+ − 320 {
793
+ − 321 warn_when_safe
+ − 322 (Qxintl, Qerror,
+ − 323 "Can't initialize XIM: Can't get fontset resource for Input Method");
428
+ − 324 FRAME_X_XIC (f) = NULL;
+ − 325 return;
+ − 326 }
+ − 327
+ − 328 /* construct xic */
+ − 329 XGetIMValues (xim, XNQueryInputStyle, &DEVICE_X_XIM_STYLES(d), NULL);
+ − 330 FRAME_X_XIC_STYLE (f) = style =
+ − 331 best_style (&xic_vars.styles, (XIMStyles *)DEVICE_X_XIM_STYLES(d));
+ − 332
+ − 333 p_list = XVaCreateNestedList (0,
+ − 334 XNArea, &p_area,
+ − 335 XNSpotLocation, &spot,
+ − 336 XNForeground, xic_vars.fg,
+ − 337 XNBackground, xic_vars.bg,
+ − 338 XNFontSet, xic_vars.fontset,
+ − 339 NULL);
+ − 340
+ − 341 s_list = XVaCreateNestedList (0,
+ − 342 XNArea, &s_area,
+ − 343 XNForeground, xic_vars.fg,
+ − 344 XNBackground, xic_vars.bg,
+ − 345 XNFontSet, xic_vars.fontset,
+ − 346 NULL);
+ − 347
+ − 348 FRAME_X_XIC (f) = xic =
+ − 349 XCreateIC (xim,
+ − 350 XNInputStyle, style,
+ − 351 XNClientWindow, win,
+ − 352 XNFocusWindow, win,
+ − 353 XNPreeditAttributes, p_list,
+ − 354 XNStatusAttributes, s_list,
+ − 355 NULL);
+ − 356 XFree (p_list);
+ − 357 XFree (s_list);
+ − 358
+ − 359 if (!xic)
+ − 360 {
793
+ − 361 warn_when_safe (Qxintl, Qerror,
+ − 362 "Can't initialize XIM: XCreateIC failed");
428
+ − 363 return;
+ − 364 }
+ − 365
+ − 366 if (style & XIMPreeditPosition)
+ − 367 {
+ − 368 XPoint *frame_spot = &(FRAME_X_XIC_SPOT(f));
+ − 369 frame_spot->x = frame_spot->y = -1;
+ − 370 }
+ − 371
+ − 372 XIM_SetGeometry (f);
+ − 373
+ − 374 XSetICFocus (xic);
+ − 375
444
+ − 376 #ifdef HAVE_XREGISTERIMINSTANTIATECALLBACK
428
+ − 377 /* when frame is going to be destroyed (closed) */
793
+ − 378 XtAddCallback (FRAME_X_TEXT_WIDGET (f), XNDestroyCallback,
+ − 379 XIM_delete_frame, (XtPointer)f );
428
+ − 380 #endif
+ − 381 }
+ − 382
+ − 383
+ − 384 void
+ − 385 XIM_SetGeometry (struct frame *f)
+ − 386 {
3462
+ − 387 XIC xic;
+ − 388 XIMStyle style;
428
+ − 389 XRectangle area;
+ − 390
3462
+ − 391 if (!f)
428
+ − 392 return;
+ − 393
3462
+ − 394 xic = FRAME_X_XIC (f);
+ − 395 if (!xic)
+ − 396 return;
+ − 397
+ − 398 style = FRAME_X_XIC_STYLE (f);
428
+ − 399 if (style & XIMStatusArea)
+ − 400 {
+ − 401 /* Place Status Area in bottom right corner */
+ − 402 /* Negotiate geometry of status area */
+ − 403 /* See O'Reilly Xlib XIM chapter (but beware, it's buggy) */
+ − 404 XRectangle *needed;
+ − 405
+ − 406 /* If input method has existing status area, use its current size */
+ − 407 /* The following at least works for Sun's htt */
+ − 408 area.x = area.y = area.width = area.height = 0;
+ − 409 XIC_Value (Set, xic, XNStatusAttributes, XNAreaNeeded, &area);
+ − 410 XIC_Value (Get, xic, XNStatusAttributes, XNAreaNeeded, &needed);
+ − 411 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
+ − 412 XIC_Value (Get, xic, XNStatusAttributes, XNArea, &needed);
+ − 413
+ − 414 area.width = needed->width;
+ − 415 area.height = needed->height;
+ − 416 area.x = FRAME_RIGHT_BORDER_START (f) - area.width;
+ − 417 area.y = FRAME_BOTTOM_BORDER_START (f) - area.height;
+ − 418
+ − 419 #ifdef DEBUG_XIM
+ − 420 stderr_out ("Putting StatusArea in x=%d y=%d w=%d h=%d\n",
+ − 421 area.x, area.y, area.width, area.height);
+ − 422 #endif /* DEBUG_XIM */
+ − 423
+ − 424 XIC_Value (Set, xic, XNStatusAttributes, XNArea, &area);
+ − 425 }
+ − 426
+ − 427 if (style & XIMPreeditPosition)
+ − 428 {
+ − 429 /* Set Preedit Area to whole frame size (sans border) */
+ − 430 /* We include the border because Preedit window might be larger
+ − 431 than display line at edge. #### FIX: we should adjust to make
+ − 432 sure that there is always room for the spot sub-window */
+ − 433 area.x = FRAME_LEFT_BORDER_START (f);
+ − 434 area.y = FRAME_TOP_BORDER_START (f);
+ − 435 area.width = FRAME_RIGHT_BORDER_END (f) - area.x;
+ − 436 area.height = FRAME_BOTTOM_BORDER_END (f) - area.y;
+ − 437 XIC_Value(Set, xic, XNPreeditAttributes, XNArea, &area);
+ − 438 }
+ − 439
+ − 440 #ifdef DEBUG_XIM
+ − 441 describe_XIC (xic);
+ − 442 #endif
+ − 443 }
+ − 444
+ − 445 void
+ − 446 XIM_SetSpotLocation (struct frame *f, int x, int y)
+ − 447 {
+ − 448 XIC xic = FRAME_X_XIC (f);
+ − 449 XPoint *spot = &(FRAME_X_XIC_SPOT (f));
+ − 450
+ − 451 /* Only care if we have a valid XIC using Over the Spot in
+ − 452 * a different location */
+ − 453 if (!xic ||
+ − 454 !(FRAME_X_XIC_STYLE (f) & XIMPreeditPosition) ||
+ − 455 (spot->x == (short) x &&
+ − 456 spot->y == (short) y))
+ − 457 return;
+ − 458
+ − 459 spot->x = (short) x;
+ − 460 spot->y = (short) y;
+ − 461
440
+ − 462 /* #### FIX: Must make sure spot fits within Preedit Area */
428
+ − 463 XIC_Value (Set, xic, XNPreeditAttributes, XNSpotLocation, spot);
+ − 464 #ifdef DEBUG_XIM
+ − 465 stderr_out ("Spot: %d %d\n", spot->x, spot->y);
+ − 466 #endif
+ − 467 }
+ − 468
+ − 469 void
+ − 470 XIM_focus_event (struct frame *f, int in_p)
+ − 471 {
+ − 472 if (FRAME_X_XIC (f) /* && FRAME_X_XIM_REGISTERED(f) */)
+ − 473 (in_p ? XSetICFocus : XUnsetICFocus) (FRAME_X_XIC (f));
+ − 474 }
+ − 475
+ − 476 #if 0
+ − 477 #define XIM_Composed_Text_BUFSIZE 64
+ − 478 typedef struct XIM_Composed_Text
+ − 479 {
+ − 480 int size;
+ − 481 wchar_t data [XIM_Composed_Text_BUFSIZE];
+ − 482 } XIM_Composed_Text;
+ − 483
+ − 484 static XIM_Composed_Text composed_input_buf = {XIM_Composed_Text_BUFSIZE, {0}};
+ − 485 Window main_window;
+ − 486
+ − 487 /* get_XIM_input -- Process results of input method composition.
+ − 488
+ − 489 This function copies the results of the input method composition to
+ − 490 composed_input_buf. Then for each character, a custom event of type
+ − 491 wc_atom is sent with the character as its data.
+ − 492
+ − 493 It is probably more efficient to copy the composition results to some
+ − 494 allocated memory and send a single event pointing to that memory.
+ − 495 That would cut down on the event processing as well as allow quick
+ − 496 insertion into the buffer of the whole string. It might require some
+ − 497 care, though, to avoid fragmenting memory through the allocation and
+ − 498 freeing of many small chunks. Maybe the existing system for
+ − 499 (single-byte) string allocation can be used, multiplying the length by
+ − 500 sizeof (wchar_t) to get the right size.
+ − 501 */
+ − 502 void
+ − 503 get_XIM_input (XKeyPressedEvent *x_key_event, XIC ic, Display *dpy)
+ − 504 {
+ − 505 KeySym keysym;
+ − 506 Status status;
+ − 507 int len;
+ − 508 int i;
+ − 509 XClientMessageEvent new_event;
+ − 510
+ − 511 retry:
+ − 512 len = XwcLookupString (ic, x_key_event, composed_input_buf.data,
+ − 513 composed_input_buf.size, &keysym, &status);
+ − 514 switch (status)
+ − 515 {
+ − 516 case XBufferOverflow:
+ − 517 /* GROW_WC_STRING (&composed_input_buf, 32); mrb */
+ − 518 goto retry;
+ − 519 case XLookupChars:
+ − 520 break;
+ − 521 default:
2500
+ − 522 ABORT ();
428
+ − 523 }
+ − 524
+ − 525 new_event.type = ClientMessage;
+ − 526 new_event.display = x_key_event->display;
+ − 527 new_event.window = x_key_event->window;
+ − 528 new_event.message_type = wc_atom;
+ − 529 new_event.format = 32; /* 32-bit wide data */
+ − 530 new_event.data.l[2] = new_event.data.l[3] = new_event.data.l[4] = 0L;
+ − 531 new_event.data.l[0] = x_key_event->time;
+ − 532 for (i = 0; i < len; i++)
+ − 533 {
+ − 534 new_event.data.l[1] = ((wchar_t *) composed_input_buf.data)[i];
+ − 535 XSendEvent (display, main_window, False, 0L, (XEvent *) &new_event);
+ − 536 }
+ − 537 }
+ − 538 #endif /* 0 */
+ − 539
+ − 540 /* ============================================================== */
+ − 541 /* X input method style determination */
+ − 542 /* ============================================================== */
+ − 543
+ − 544 #if 0
+ − 545 #define done(type, value) \
+ − 546 if (toVal->addr != NULL) { \
+ − 547 if (toVal->size < sizeof(type)) { \
+ − 548 toVal->size = sizeof(type); \
+ − 549 return False; \
+ − 550 } \
+ − 551 *(type*)toVal->addr = (value); \
+ − 552 } else { \
+ − 553 static type static_val; \
+ − 554 static_val = (value); \
+ − 555 toVal->addr = (XPointer)&static_val; \
+ − 556 } \
+ − 557 toVal->size = sizeof(type); \
+ − 558 return True /* Caller supplies `;' */
+ − 559 #endif /* 0 */
+ − 560
+ − 561 /*
+ − 562 * This is a standard Xt type converter, except that the caller MUST
+ − 563 * supply a proper non-NULL toVal XIMStyles structure that we will
+ − 564 * fill in.
+ − 565 *
+ − 566 * fromVal points to a string like
+ − 567 *
+ − 568 "XIMPreeditPosition|XIMStatusArea,
+ − 569 XIMPreeditPosition|XIMStatusNothing
+ − 570 XIMPreeditNothing|XIMStatusNothing"
+ − 571 *
+ − 572 * This is converted in the obvious way to a XIMStyles structure.
+ − 573 *
+ − 574 * mrb: #### Fix this to handle Motif-style specifications for
+ − 575 * XIMStyles as well: overTheSpot, rootWindow, none */
+ − 576
+ − 577 /* XtTypeConverter */
+ − 578 Boolean
+ − 579 EmacsXtCvtStringToXIMStyles (
+ − 580 Display *dpy,
+ − 581 XrmValuePtr args,
+ − 582 Cardinal *num_args,
+ − 583 XrmValuePtr fromVal,
+ − 584 XrmValuePtr toVal,
+ − 585 XtPointer *converter_data)
+ − 586 {
+ − 587 #define STYLE_INFO(style) { style, #style, sizeof(#style) }
+ − 588 static struct XIMStyleInfo
+ − 589 {
442
+ − 590 const XIMStyle style;
+ − 591 const char * const name;
+ − 592 const int namelen;
428
+ − 593 } emacs_XIMStyleInfo[] = {
+ − 594 STYLE_INFO (XIMPreeditPosition|XIMStatusArea),
+ − 595 STYLE_INFO (XIMPreeditPosition|XIMStatusNothing),
+ − 596 STYLE_INFO (XIMPreeditPosition|XIMStatusNone),
+ − 597 STYLE_INFO (XIMPreeditNothing|XIMStatusArea),
+ − 598 STYLE_INFO (XIMPreeditNothing|XIMStatusNothing),
+ − 599 STYLE_INFO (XIMPreeditNothing|XIMStatusNone),
+ − 600 STYLE_INFO (XIMPreeditNone|XIMStatusArea),
+ − 601 STYLE_INFO (XIMPreeditNone|XIMStatusNothing),
+ − 602 STYLE_INFO (XIMPreeditNone|XIMStatusNone)
+ − 603 };
+ − 604 #undef STYLE_INFO
+ − 605
+ − 606 char *s = (char *) fromVal->addr;
+ − 607 char *end = s + fromVal->size;
442
+ − 608 XIMStyles * const p = (XIMStyles *) toVal->addr;
+ − 609 const char * const delimiter = " \t\n\r:;," ;
+ − 610 const int max_styles = XtNumber(emacs_XIMStyleInfo);
428
+ − 611 int i;
+ − 612 char *c;
+ − 613
+ − 614 #ifdef DEBUG_XIM
+ − 615 stderr_out ("EmacsCvtStringToXIMStyles called with size=%d, string=\"%s\"\n",
+ − 616 fromVal->size, (char *) fromVal->addr);
+ − 617 #endif /* DEBUG_XIM */
+ − 618
+ − 619 if (*num_args != 0)
+ − 620 {
+ − 621 XtAppContext the_app_con = XtDisplayToApplicationContext (dpy);
+ − 622 XtAppWarningMsg(the_app_con, "wrongParameters", "cvtStringToXIMStyle",
+ − 623 "XtToolkitError",
+ − 624 "String to XIMStyle conversion requires exactly 0 parameters",
+ − 625 (String *)NULL, (Cardinal *)NULL);
+ − 626 return False;
+ − 627 }
+ − 628
+ − 629 #ifdef DEBUG_XEMACS
+ − 630 /* Make sure caller is giving us good data */
+ − 631 assert (fromVal->addr != NULL);
+ − 632 assert (fromVal->size == strlen(fromVal->addr)+1);
+ − 633 assert (toVal->addr != NULL);
+ − 634 assert (toVal->size == sizeof(XIMStyles));
+ − 635 #endif /* DEBUG_XEMACS */
+ − 636
+ − 637 p->count_styles = 0;
+ − 638 p->supported_styles = xnew_array (XIMStyle, max_styles);
+ − 639
+ − 640 /*
+ − 641 * The following routine assumes that the style name resource is
+ − 642 * identical with the programmatic name of style. For example,
+ − 643 * "XIMPreeditPosition|XIMStatusArea" means the
+ − 644 * XIMPreeditPosition|XIMStatusArea value is specified. If the
+ − 645 * style name is changed, such as "OverTheSpot|imDisplaysInClient",
+ − 646 * the parsing logic below should be modified as well. */
+ − 647
+ − 648 if ((c = strtok(s, delimiter)) == NULL)
+ − 649 c = end;
+ − 650
+ − 651 while (c < end)
+ − 652 {
+ − 653 for(i=0 ; i<max_styles ; i++)
+ − 654 {
+ − 655 struct XIMStyleInfo *rec = emacs_XIMStyleInfo + i;
+ − 656 if(!strncmp(c, rec->name, rec->namelen - 1)) {
+ − 657 p->supported_styles[p->count_styles] = rec->style;
+ − 658 p->count_styles++;
+ − 659 break;
+ − 660 }
+ − 661 }
+ − 662 if((c = strtok(NULL, delimiter)) == NULL) {
+ − 663 break ;
+ − 664 }
+ − 665 }
+ − 666
+ − 667 if (p->count_styles == 0)
+ − 668 { /* No valid styles? */
2367
+ − 669 /* !!#### */
+ − 670 char *buf = (char *) ALLOCA (strlen (fromVal->addr)
+ − 671 + strlen (DefaultXIMStyles)
+ − 672 + 100);
428
+ − 673 XrmValue new_from;
+ − 674 XtAppContext the_app_con = XtDisplayToApplicationContext (dpy);
+ − 675
+ − 676 sprintf(buf, "Cannot convert string \"%s\" to type XIMStyles.\n"
+ − 677 "Using default string \"%s\" instead.\n",
+ − 678 fromVal->addr, DefaultXIMStyles);
+ − 679 XtAppWarningMsg(the_app_con, "wrongParameters", "cvtStringToXIMStyle",
+ − 680 "XtToolkitError",
+ − 681 buf, (String *)NULL, (Cardinal *)NULL);
+ − 682 new_from.addr = DefaultXIMStyles;
+ − 683 new_from.size = sizeof(DefaultXIMStyles);
+ − 684 return EmacsXtCvtStringToXIMStyles (dpy, args, num_args,
+ − 685 &new_from, toVal, converter_data);
+ − 686 }
+ − 687 XREALLOC_ARRAY (p->supported_styles, XIMStyle, p->count_styles);
+ − 688 *converter_data = (char *) True;
+ − 689 return True;
+ − 690 }
+ − 691
+ − 692 /* XtDestructor */
+ − 693 void
+ − 694 EmacsFreeXIMStyles (
+ − 695 XtAppContext app,
+ − 696 XrmValuePtr toVal,
+ − 697 XtPointer converter_data,
2286
+ − 698 XrmValuePtr UNUSED (args),
428
+ − 699 Cardinal *num_args)
+ − 700 {
+ − 701 #ifdef DEBUG_XIM
+ − 702 stderr_out ("Converter data: %x\n", converter_data);
+ − 703 stderr_out ("EmacsFreeXIMStyles called\n");
+ − 704 #endif /* DEBUG_XIM */
+ − 705
+ − 706 if (*num_args != 0)
+ − 707 {
+ − 708 XtAppWarningMsg(app, "wrongParameters","freeXIMStyles","XtToolkitError",
+ − 709 "Freeing an XIMStyles requires that zero arguments be passwd",
+ − 710 (String *)NULL, (Cardinal *)NULL);
+ − 711 return;
+ − 712 }
+ − 713
+ − 714 if (converter_data)
+ − 715 {
4123
+ − 716 Boolean free_p = (Boolean) (EMACS_INT) converter_data;
428
+ − 717 XIMStyles *styles = (XIMStyles *) toVal->addr;
+ − 718 if (free_p)
+ − 719 XFree ( styles->supported_styles );
+ − 720 }
+ − 721 }
+ − 722
+ − 723 #if 0
+ − 724 /* O'Reilly XLib Programming Manual, pg. 371 */
+ − 725 /* Much nicer implementation than O'Reilly */
+ − 726 /* Choose the more `complicated', hence nicer, XIM input style */
+ − 727 static XIMStyle
+ − 728 BetterStyle (XIMStyle s, XIMStyle t)
+ − 729 {
+ − 730 #define CHECK_XIMStyle_BIT(bit) \
+ − 731 if ((s ^ t) & bit) { return (s & bit) ? s : t; }
+ − 732
+ − 733 CHECK_XIMStyle_BIT (XIMPreeditCallbacks);
+ − 734 CHECK_XIMStyle_BIT (XIMPreeditPosition);
+ − 735 CHECK_XIMStyle_BIT (XIMPreeditArea);
+ − 736 CHECK_XIMStyle_BIT (XIMPreeditNothing);
+ − 737 CHECK_XIMStyle_BIT (XIMStatusCallbacks);
+ − 738 CHECK_XIMStyle_BIT (XIMStatusArea);
+ − 739 CHECK_XIMStyle_BIT (XIMStatusNothing);
+ − 740 #undef CHECK_XIMStyle_BIT
+ − 741 return s ? s : t ;
+ − 742 }
+ − 743 #endif /* 0 */
+ − 744
+ − 745 /* Choose the best style, given:
+ − 746 * - user preferences (already checked to be supported by XEmacs)
+ − 747 * - styles supported by the input method */
+ − 748 #define DEFAULTStyle (XIMPreeditNothing|XIMStatusNothing)
+ − 749 static XIMStyle
+ − 750 best_style (XIMStyles *user, XIMStyles *xim)
+ − 751 {
+ − 752 REGISTER int i, j;
+ − 753 for (i=0 ; i<user->count_styles ; i++)
+ − 754 {
+ − 755 for (j=0 ; j<xim->count_styles ; j++)
+ − 756 {
+ − 757 if (user->supported_styles[i] == xim->supported_styles[j])
+ − 758 return user->supported_styles[i];
+ − 759 }
+ − 760 }
+ − 761 return DEFAULTStyle; /* Default Style */
+ − 762 }
+ − 763
+ − 764 /* These lisp-callable functions will be sealed until xim-leim is needed.
+ − 765 Oct 22 1999 - kazz */
+ − 766 #if 0
+ − 767 /*
+ − 768 * External callable function for XIM
+ − 769 */
+ − 770 DEFUN ("x-open-xim", Fx_open_xim, 1, 1, 0, /*
+ − 771 Open the XIC on the frame if XIM is available.
+ − 772 Commonly, use this as \(x-open-xim \(selected-frame)).
+ − 773 If the frame is not on X device, return signal.
+ − 774 If XIC is created successfully return t. If not return nil.
+ − 775 */
+ − 776 (frame))
+ − 777 {
+ − 778 struct frame *f;
+ − 779
+ − 780 CHECK_LIVE_FRAME (frame);
+ − 781 f = XFRAME (frame);
+ − 782 if (!FRAME_X_P (f))
563
+ − 783 invalid_argument ("This frame is not on X device", frame);
428
+ − 784
+ − 785 XIM_init_frame (f);
+ − 786 return FRAME_X_XIC (f) ? Qt : Qnil;
+ − 787 }
+ − 788
+ − 789 DEFUN ("x-close-xim", Fx_close_xim, 1, 1, 0, /*
+ − 790 Close the XIC on the frame if it exists.
+ − 791 Commonly, use this as \(x-close-xim \(selected-frame)).
+ − 792 If the frame is not on X device, return signal.
+ − 793 Otherwise, it destroys the XIC if it exists, then returns t anyway.
+ − 794 */
+ − 795 (frame))
+ − 796 {
+ − 797 struct frame *f;
+ − 798 struct device *d;
+ − 799
+ − 800 CHECK_LIVE_FRAME (frame);
+ − 801 f = XFRAME (frame);
+ − 802 if (!FRAME_X_P (f))
563
+ − 803 invalid_argument ("This frame is not on X device", frame);
428
+ − 804
+ − 805 d = XDEVICE (FRAME_DEVICE (f));
+ − 806 if (DEVICE_X_XIM (d)) {
+ − 807 /* XDestroyIC (FRAME_X_XIC (XFRAME (f))); */
+ − 808 FRAME_X_XIC (XFRAME (f)) = NULL;
+ − 809 }
+ − 810 return Qt;
+ − 811 }
+ − 812 #endif /* if 0 */
+ − 813
+ − 814 void
+ − 815 syms_of_input_method_xlib (void)
+ − 816 {
+ − 817 #if 0 /* see above */
+ − 818 DEFSUBR (Fx_open_xim);
+ − 819 DEFSUBR (Fx_close_xim);
+ − 820 #endif
+ − 821 }
+ − 822
+ − 823 void
+ − 824 vars_of_input_method_xlib (void)
+ − 825 {
+ − 826 Fprovide (intern ("xim"));
+ − 827 }
+ − 828
+ − 829
+ − 830 /* ====================================================================== */
+ − 831 /* Internal Debugging Routines */
+ − 832 /* ====================================================================== */
+ − 833 #ifdef DEBUG_XEMACS
+ − 834
+ − 835 void
+ − 836 describe_XIM (XIM xim)
+ − 837 {
+ − 838 XIMStyles *styles;
+ − 839
+ − 840 /* Print locale of XIM */
+ − 841 stderr_out ("\nXIM Locale of IM: %s\n", XLocaleOfIM(xim));
+ − 842
+ − 843 /* List supported input method styles */
+ − 844 XGetIMValues(xim, XNQueryInputStyle, &styles, NULL);
+ − 845
+ − 846 stderr_out ("\n%d input style(s) supported by input method.\n",
+ − 847 styles->count_styles);
+ − 848
+ − 849 #ifdef DEBUG_XIM
+ − 850 {
+ − 851 int i;
+ − 852 for (i=0; i < styles->count_styles; i++)
+ − 853 describe_XIMStyle (styles->supported_styles[i]);
+ − 854 }
+ − 855 #endif /* DEBUG_XIM */
+ − 856 XFree(styles);
+ − 857 }
+ − 858
+ − 859 void
+ − 860 describe_XFontSet (XFontSet fontset)
+ − 861 {
+ − 862 XFontStruct **font_struct_list;
+ − 863 char **font_name_list;
+ − 864 int count, i;
+ − 865
+ − 866 if (fontset == NULL)
+ − 867 {
+ − 868 stderr_out ("NULL\n");
+ − 869 return;
+ − 870 }
+ − 871
+ − 872 count = XFontsOfFontSet (fontset, &font_struct_list, &font_name_list);
+ − 873 stderr_out ( "%d font(s) available:\n", count);
+ − 874 for (i=0 ; i < count ; i++)
+ − 875 stderr_out ("Font: %s\n", *(font_name_list+i));
+ − 876 }
+ − 877
+ − 878 void
+ − 879 describe_Status (Status status)
+ − 880 {
+ − 881 #define DESCRIBE_STATUS(value) \
+ − 882 if (status == value) stderr_out ("Status: " #value "\n")
+ − 883
+ − 884 DESCRIBE_STATUS (XBufferOverflow);
+ − 885 DESCRIBE_STATUS (XLookupNone);
+ − 886 DESCRIBE_STATUS (XLookupKeySym);
+ − 887 DESCRIBE_STATUS (XLookupBoth);
+ − 888 DESCRIBE_STATUS (XLookupChars);
+ − 889 #undef DESCRIBE_STATUS
+ − 890 }
+ − 891
+ − 892 void
+ − 893 describe_Window (Window win)
+ − 894 {
+ − 895 char xwincmd[128];
+ − 896 sprintf (xwincmd, "xwininfo -id 0x%x >&2; xwininfo -events -id 0x%x >&2",
+ − 897 (int) win, (int) win);
+ − 898 system (xwincmd);
+ − 899 }
+ − 900
+ − 901 void
+ − 902 describe_XIC (XIC xic)
+ − 903 {
+ − 904 XIMStyle style;
+ − 905 Window client_win=0, focus_win=0;
+ − 906 char *resourceName = NULL;
+ − 907 char *resourceClass = NULL;
+ − 908 char *bad_arg = NULL;
+ − 909 unsigned long filter_mask = NoEventMask;
+ − 910 XVaNestedList p_list, s_list;
+ − 911 XFontSet p_fontset = NULL, s_fontset = NULL;
+ − 912 Pixel p_fg=0, p_bg = 0, s_fg=0, s_bg = 0;
+ − 913 XRectangle *p_area = NULL, *s_area = NULL;
+ − 914 XRectangle *p_needed = NULL, *s_needed = NULL;
+ − 915 XPoint *p_spot = NULL;
+ − 916
+ − 917 /* Check for valid input context and method */
+ − 918 if (!xic)
+ − 919 stderr_out ("Input method is NULL\n");
+ − 920
+ − 921 if (!XIMOfIC(xic))
+ − 922 stderr_out ("XIMOfIC() returns NULL\n");
+ − 923
+ − 924 /* Print out Input Context Attributes */
+ − 925 p_list = XVaCreateNestedList (0,
+ − 926 XNFontSet, &p_fontset,
+ − 927 XNArea, &p_area,
+ − 928 XNAreaNeeded, &p_needed,
+ − 929 XNSpotLocation, &p_spot,
+ − 930 XNForeground, &p_fg,
+ − 931 XNBackground, &p_bg,
+ − 932 NULL);
+ − 933
+ − 934 s_list = XVaCreateNestedList (0,
+ − 935 XNFontSet, &s_fontset,
+ − 936 XNArea, &s_area,
+ − 937 XNAreaNeeded, &s_needed,
+ − 938 XNForeground, &s_fg,
+ − 939 XNBackground, &s_bg,
+ − 940 NULL);
+ − 941
+ − 942 bad_arg = XGetICValues(xic,
+ − 943 XNInputStyle, &style,
+ − 944 XNFilterEvents, &filter_mask,
+ − 945 XNClientWindow, &client_win,
+ − 946 XNFocusWindow, &focus_win,
+ − 947 XNResourceName, &resourceName,
+ − 948 XNResourceClass, &resourceClass,
+ − 949 XNPreeditAttributes, p_list,
+ − 950 XNStatusAttributes, s_list,
+ − 951 NULL);
+ − 952 XFree(p_list);
+ − 953 XFree(s_list);
+ − 954
+ − 955 if (bad_arg != NULL)
+ − 956 stderr_out ("Couldn't get IC value: %s\n", bad_arg);
+ − 957
+ − 958 stderr_out ("\nInput method context attributes:\n");
+ − 959 stderr_out ("Style: "); describe_XIMStyle (style);
+ − 960 stderr_out ("Client window: %lx\n", (unsigned long int)client_win);
+ − 961 stderr_out ("Focus window: %lx\n", (unsigned long int)focus_win);
+ − 962 stderr_out ("Preedit:\n");
+ − 963 describe_XRectangle (" Area", p_area);
+ − 964 describe_XRectangle (" Area needed", p_needed);
+ − 965 stderr_out (" foreground: %lx\n", (unsigned long int)p_fg);
+ − 966 stderr_out (" background: %lx\n", (unsigned long int)p_bg);
+ − 967 stderr_out (" fontset: "); describe_XFontSet (p_fontset);
+ − 968 stderr_out ("Status:\n");
+ − 969 describe_XRectangle (" Area", s_area);
+ − 970 describe_XRectangle (" Area needed", s_needed);
+ − 971 stderr_out (" foreground: %lx\n", (unsigned long int)s_fg);
+ − 972 stderr_out (" background: %lx\n", (unsigned long int)s_bg);
+ − 973 stderr_out (" fontset: \n"); describe_XFontSet (s_fontset);
+ − 974 stderr_out ("XNResourceName: %s\n", resourceName ? resourceName : "NULL");
+ − 975 stderr_out ("XNResourceClass: %s\n", resourceClass ? resourceClass : "NULL");
+ − 976 stderr_out ("XNFilterEvents: "); describe_event_mask (filter_mask);
+ − 977 }
+ − 978
+ − 979 void
+ − 980 describe_XRectangle (char *name, XRectangle *r)
+ − 981 {
+ − 982 if (r == NULL)
+ − 983 stderr_out ("%s: NULL\n", name);
+ − 984 else
+ − 985 stderr_out ("%s: x=%d y=%d w=%d h=%d\n",
+ − 986 name, r->x, r->y, r->width, r->height);
+ − 987 }
+ − 988
+ − 989 /* Print out elements of Event mask */
+ − 990 /* Defines from X11/X.h */
+ − 991 void
+ − 992 describe_event_mask (unsigned long mask)
+ − 993 {
+ − 994 #define DESCRIBE_EVENT_MASK(bit) if ((bit) & mask) stderr_out (#bit " ")
+ − 995 DESCRIBE_EVENT_MASK (NoEventMask);
+ − 996 DESCRIBE_EVENT_MASK (KeyPressMask);
+ − 997 DESCRIBE_EVENT_MASK (KeyReleaseMask);
+ − 998 DESCRIBE_EVENT_MASK (ButtonPressMask);
+ − 999 DESCRIBE_EVENT_MASK (ButtonReleaseMask);
+ − 1000 DESCRIBE_EVENT_MASK (EnterWindowMask);
+ − 1001 DESCRIBE_EVENT_MASK (LeaveWindowMask);
+ − 1002 DESCRIBE_EVENT_MASK (PointerMotionMask);
+ − 1003 DESCRIBE_EVENT_MASK (PointerMotionHintMask);
+ − 1004 DESCRIBE_EVENT_MASK (Button1MotionMask);
+ − 1005 DESCRIBE_EVENT_MASK (Button2MotionMask);
+ − 1006 DESCRIBE_EVENT_MASK (Button3MotionMask);
+ − 1007 DESCRIBE_EVENT_MASK (Button4MotionMask);
+ − 1008 DESCRIBE_EVENT_MASK (Button5MotionMask);
+ − 1009 DESCRIBE_EVENT_MASK (ButtonMotionMask);
+ − 1010 DESCRIBE_EVENT_MASK (KeymapStateMask);
+ − 1011 DESCRIBE_EVENT_MASK (ExposureMask);
+ − 1012 DESCRIBE_EVENT_MASK (VisibilityChangeMask);
+ − 1013 DESCRIBE_EVENT_MASK (StructureNotifyMask);
+ − 1014 DESCRIBE_EVENT_MASK (ResizeRedirectMask);
+ − 1015 DESCRIBE_EVENT_MASK (SubstructureNotifyMask);
+ − 1016 DESCRIBE_EVENT_MASK (SubstructureRedirectMask);
+ − 1017 DESCRIBE_EVENT_MASK (FocusChangeMask);
+ − 1018 DESCRIBE_EVENT_MASK (PropertyChangeMask);
+ − 1019 DESCRIBE_EVENT_MASK (ColormapChangeMask);
+ − 1020 DESCRIBE_EVENT_MASK (OwnerGrabButtonMask);
+ − 1021 #undef DESCRIBE_EVENT_MASK
+ − 1022 stderr_out("\n");
+ − 1023 }
+ − 1024
+ − 1025 void
+ − 1026 describe_XIMStyle (XIMStyle style)
+ − 1027 {
+ − 1028 #define DESCRIBE_STYLE(bit) \
+ − 1029 if (bit & style) \
+ − 1030 stderr_out (#bit " ");
+ − 1031
+ − 1032 DESCRIBE_STYLE (XIMPreeditArea);
+ − 1033 DESCRIBE_STYLE (XIMPreeditCallbacks);
+ − 1034 DESCRIBE_STYLE (XIMPreeditPosition);
+ − 1035 DESCRIBE_STYLE (XIMPreeditNothing);
+ − 1036 DESCRIBE_STYLE (XIMPreeditNone);
+ − 1037 DESCRIBE_STYLE (XIMStatusArea);
+ − 1038 DESCRIBE_STYLE (XIMStatusCallbacks);
+ − 1039 DESCRIBE_STYLE (XIMStatusNothing);
+ − 1040 DESCRIBE_STYLE (XIMStatusNone);
+ − 1041 #undef DESCRIBE_STYLE
+ − 1042 stderr_out("\n");
+ − 1043 }
+ − 1044
+ − 1045 void
+ − 1046 describe_XIMStyles (XIMStyles *p)
+ − 1047 {
+ − 1048 int i;
+ − 1049 stderr_out ("%d Style(s):\n", p->count_styles);
+ − 1050 for (i=0; i<p->count_styles ; i++)
+ − 1051 {
+ − 1052 describe_XIMStyle (p->supported_styles[i]);
+ − 1053 }
+ − 1054 }
+ − 1055
+ − 1056 #endif /* DEBUG_XEMACS */
+ − 1057
+ − 1058 /* Random cruft follows */
+ − 1059
+ − 1060 #if 0
+ − 1061 static void
+ − 1062 Unit_Test (struct frame *f, char * s)
+ − 1063 /* mrb unit testing */
+ − 1064 {
+ − 1065 XrmValue fromVal, toVal;
+ − 1066
+ − 1067 fromVal.addr = s;
+ − 1068 fromVal.size = strlen (s);
+ − 1069 toVal.addr = (XtPointer) &user_preferred_XIMStyles;
+ − 1070 toVal.size = sizeof (XIMStyles);
+ − 1071
+ − 1072 if (XtConvertAndStore (FRAME_X_TEXT_WIDGET (f), XtRString, &fromVal,
+ − 1073 XtRXimStyles, &toVal) != False)
+ − 1074 {
+ − 1075 stderr_out ("Unit_Test: fromVal.addr=0x%x\n",fromVal.addr);
+ − 1076 stderr_out ("Unit_Test: fromVal.size=%d\n", fromVal.size);
+ − 1077 stderr_out ("Unit_Test: toVal.addr=0x%x\n", toVal.addr);
+ − 1078 stderr_out ("Unit_Test: toVal.size=%d\n", toVal.size);
+ − 1079 describe_XIMStyles ((XIMStyles *) toVal.addr);
+ − 1080 }
+ − 1081 }
+ − 1082 #endif
448
+ − 1083 #endif /* XIM_XLIB only */
428
+ − 1084
+ − 1085 #if 0
+ − 1086 /* Get a fontset for IM to use */
+ − 1087 void
+ − 1088 x_init_fontset (struct device *d)
+ − 1089 {
+ − 1090 Display *dpy = DEVICE_X_DISPLAY (d);
+ − 1091 XFontSet fontset;
+ − 1092 char ** missing_charsets;
+ − 1093 int num_missing_charsets;
+ − 1094 char * default_string;
+ − 1095 /* char * font_set_string = "-dt-interface user-medium-r-normal-s*-*-*-*-*-*-*-*-*";*/
+ − 1096 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" ;
+ − 1097
+ − 1098 DEVICE_X_FONTSET (d) = fontset =
+ − 1099 XCreateFontSet (dpy,
+ − 1100 font_set_string,
+ − 1101 &missing_charsets,
+ − 1102 &num_missing_charsets,
+ − 1103 &default_string);
+ − 1104
+ − 1105 if (fontset == NULL)
+ − 1106 {
+ − 1107 stderr_out ("Unable to create fontset from string:\n%s\n", font_set_string);
+ − 1108 return;
+ − 1109 }
+ − 1110 if (num_missing_charsets > 0)
+ − 1111 {
+ − 1112 int i;
+ − 1113 stderr_out ("\nMissing charsets for fontset %s:\n", font_set_string);
+ − 1114 for (i=0; i < num_missing_charsets; i++)
+ − 1115 {
+ − 1116 stderr_out ("%s\n", missing_charsets[i]);
+ − 1117 }
+ − 1118 XFreeStringList (missing_charsets);
+ − 1119 stderr_out ("Default string: %s\n", default_string);
+ − 1120 }
+ − 1121
+ − 1122 #ifdef DEBUG_XIM
+ − 1123 describe_XFontSet (fontset);
+ − 1124 #endif
+ − 1125 }
+ − 1126 #endif /* 0 */