XawIm.c revision 7a84e134
1/* $Xorg: XawIm.c,v 1.6 2001/02/09 02:03:47 xorgcvs Exp $ */ 2 3/* 4 * Copyright 1991 by OMRON Corporation 5 * 6 * Permission to use, copy, modify, distribute, and sell this software and its 7 * documentation for any purpose is hereby granted without fee, provided that 8 * the above copyright notice appear in all copies and that both that 9 * copyright notice and this permission notice appear in supporting 10 * documentation, and that the name of OMRON not be used in advertising or 11 * publicity pertaining to distribution of the software without specific, 12 * written prior permission. OMRON makes no representations about the 13 * suitability of this software for any purpose. It is provided "as is" 14 * without express or implied warranty. 15 * 16 * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 17 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 18 * OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 19 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 20 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, 21 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 22 * SOFTWARE. 23 * 24 * Author: Seiji Kuwari OMRON Corporation 25 * kuwa@omron.co.jp 26 * kuwa%omron.co.jp@uunet.uu.net 27 */ 28 29 30/* 31 32Copyright 1994, 1998 The Open Group 33 34Permission to use, copy, modify, distribute, and sell this software and its 35documentation for any purpose is hereby granted without fee, provided that 36the above copyright notice appear in all copies and that both that 37copyright notice and this permission notice appear in supporting 38documentation. 39 40The above copyright notice and this permission notice shall be included in 41all copies or substantial portions of the Software. 42 43THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 44IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 45FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 46OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 47AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 48CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 49 50Except as contained in this notice, the name of The Open Group shall not be 51used in advertising or otherwise to promote the sale, use or other dealings 52in this Software without prior written authorization from The Open Group. 53 54*/ 55/* $XFree86: xc/lib/Xaw/XawIm.c,v 1.14tsi Exp $ */ 56 57#ifdef HAVE_CONFIG_H 58#include <config.h> 59#endif 60#include <X11/IntrinsicP.h> 61#include <X11/StringDefs.h> 62#include <X11/Xos.h> 63#include <X11/Xfuncs.h> 64#include <X11/ShellP.h> 65#include <X11/Xaw/TextP.h> 66#include <X11/Xaw/MultiSrc.h> 67#include <X11/Xaw/MultiSinkP.h> 68#include <X11/Xaw/XawImP.h> 69#include <X11/Xaw/VendorEP.h> 70#include "XawI18n.h" 71#include <ctype.h> 72 73#include <stdarg.h> 74 75#define maxAscentOfFontSet(fontset) \ 76 ( - (XExtentsOfFontSet((fontset)))->max_logical_extent.y) 77 78#define maxHeightOfFontSet(fontset) \ 79 ((XExtentsOfFontSet((fontset)))->max_logical_extent.height) 80 81#define maxDescentOfFontSet(fontset) \ 82 (maxHeightOfFontSet(fontset) - maxAscentOfFontSet(fontset)) 83 84#define Offset(field) (XtOffsetOf(XawIcTablePart, field)) 85 86/***************************************************** 87 * 88 * Forward reference prototypes 89 * 90 *****************************************************/ 91 92/* 93 * Prototypes 94 */ 95static void AllCreateIC(XawVendorShellExtPart*); 96static void CloseIM(XawVendorShellExtPart*); 97static void CompileResourceList(XtResourceList, unsigned int); 98static void ConfigureCB(Widget, XtPointer, XEvent*, Boolean*); 99static void CreateIC(Widget, XawVendorShellExtPart*); 100static XawIcTableList CreateIcTable(Widget, XawVendorShellExtPart*); 101static XawIcTableList CurrentSharedIcTable(XawVendorShellExtPart*); 102static void Destroy(Widget, XawVendorShellExtPart*); 103static void DestroyAllIM(XawVendorShellExtPart*); 104static void DestroyIC(Widget, XawVendorShellExtPart*); 105static void FreeAllDataOfVendorShell(XawVendorShellExtPart*, 106 VendorShellWidget); 107static XawVendorShellExtPart *GetExtPart(VendorShellWidget); 108static XawIcTableList GetIcTable(Widget, XawVendorShellExtPart*); 109static XawIcTableList GetIcTableShared(Widget, XawVendorShellExtPart*); 110static XIMStyle GetInputStyleOfIC(XawVendorShellExtPart*); 111static Bool Initialize(VendorShellWidget, XawVendorShellExtPart*); 112static Bool IsCreatedIC(Widget, XawVendorShellExtPart*); 113static Bool IsRegistered(Widget, XawVendorShellExtPart*); 114static Bool IsSharedIC(XawVendorShellExtPart*); 115static Bool NoRegistered(XawVendorShellExtPart*); 116static void OpenIM(XawVendorShellExtPart*); 117static void Reconnect(XawVendorShellExtPart*); 118static void Register(Widget, XawVendorShellExtPart*); 119static Bool RegisterToVendorShell(Widget, XawVendorShellExtPart*); 120static void ResizeVendorShell(VendorShellWidget, XawVendorShellExtPart*); 121static Bool ResizeVendorShell_Core(VendorShellWidget, XawVendorShellExtPart*, 122 XawIcTableList); 123static VendorShellWidget SearchVendorShell(Widget); 124static Widget SetErrCnxt(Widget, XIM); 125static XawVendorShellExtPart *SetExtPart(VendorShellWidget, 126 XawVendorShellExtWidget); 127static void SetFocus(Widget, XawVendorShellExtPart*); 128static void SetFocusValues(Widget, ArgList, Cardinal, Bool); 129static void SetICFocus(Widget, XawVendorShellExtPart*); 130static void SetICValues(Widget, XawVendorShellExtPart*, Bool); 131static void SetICValuesShared(Widget, XawVendorShellExtPart*, XawIcTableList, 132 Bool); 133static void SetValues(Widget, XawVendorShellExtPart*, ArgList, Cardinal); 134static unsigned int SetVendorShellHeight(XawVendorShellExtPart*, 135 unsigned int); 136static void SharedICChangeFocusWindow(Widget, XawVendorShellExtPart*, 137 XawIcTableList); 138static void SizeNegotiation(XawIcTableList, unsigned int, unsigned int); 139static void Unregister(Widget, XawVendorShellExtPart*); 140static void UnregisterFromVendorShell(Widget, XawVendorShellExtPart*); 141static void UnsetFocus(Widget); 142static void UnsetICFocus(Widget, XawVendorShellExtPart*); 143static void VendorShellDestroyed(Widget, XtPointer, XtPointer); 144 145/* 146 * From Vendor.c 147 */ 148void XawVendorShellExtResize(Widget); 149void XawVendorStructureNotifyHandler(Widget, XtPointer, XEvent*, Boolean*); 150 151 152/* 153 * From Xt/Resources.c 154 */ 155void _XtCopyFromArg(XtArgVal src, char*, unsigned int); 156 157static XtResource resources[] = 158{ 159 { 160 XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet), 161 Offset (font_set), XtRString, XtDefaultFontSet 162 }, 163 { 164 XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), 165 Offset (foreground), XtRString, (XtPointer)"XtDefaultForeground" 166 }, 167 { 168 XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel), 169 Offset (background), XtRString, (XtPointer)"XtDefaultBackground" 170 }, 171 { 172 XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap), 173 Offset (bg_pixmap), XtRImmediate, (XtPointer) XtUnspecifiedPixmap 174 }, 175 { 176 XtNinsertPosition, XtCTextPosition, XtRInt, sizeof (XawTextPosition), 177 Offset (cursor_position), XtRImmediate, (XtPointer) 0 178 } 179}; 180#undef Offset 181 182 183static VendorShellWidget SearchVendorShell( w ) 184 Widget w; 185{ 186 while(w && !XtIsShell(w)) w = XtParent(w); 187 if (w && XtIsVendorShell(w)) return((VendorShellWidget)w); 188 return(NULL); 189} 190 191static XContext extContext = (XContext)NULL; 192 193static XawVendorShellExtPart * 194SetExtPart(VendorShellWidget w, XawVendorShellExtWidget vew) 195{ 196 contextDataRec *contextData; 197 198 if (extContext == (XContext)NULL) extContext = XUniqueContext(); 199 200 contextData = XtNew(contextDataRec); 201 contextData->parent = (Widget)w; 202 contextData->ve = (Widget)vew; 203 if (XSaveContext(XtDisplay(w), (Window)w, extContext, (char *)contextData)) { 204 return(NULL); 205 } 206 return(&(vew->vendor_ext)); 207} 208 209static XawVendorShellExtPart * 210GetExtPart(VendorShellWidget w) 211{ 212 contextDataRec *contextData; 213 XawVendorShellExtWidget vew; 214 215 if (XFindContext(XtDisplay(w), (Window)w, extContext, 216 (XPointer*)&contextData)) { 217 return(NULL); 218 } 219 vew = (XawVendorShellExtWidget)contextData->ve; 220 return(&(vew->vendor_ext)); 221} 222 223static Bool 224IsSharedIC(XawVendorShellExtPart * ve) 225{ 226 return( ve->ic.shared_ic ); 227} 228 229static XawIcTableList 230GetIcTableShared(Widget w, XawVendorShellExtPart *ve) 231{ 232 XawIcTableList p; 233 234 for (p = ve->ic.ic_table; p; p = p->next) { 235 if (p->widget == w) { 236 if (IsSharedIC(ve)) { 237 return(ve->ic.shared_ic_table); 238 } else { 239 return(p); 240 } 241 } 242 } 243 return(NULL); 244} 245 246static XawIcTableList 247GetIcTable(Widget w, XawVendorShellExtPart *ve) 248{ 249 XawIcTableList p; 250 251 for (p = ve->ic.ic_table; p; p = p->next) { 252 if (p->widget == w) { 253 return(p); 254 } 255 } 256 return(NULL); 257} 258 259static XIMStyle 260GetInputStyleOfIC(XawVendorShellExtPart *ve) 261{ 262 263 if (!ve) return((XIMStyle)0); 264 return(ve->ic.input_style); 265} 266 267/*ARGSUSED*/ 268static void 269ConfigureCB(Widget w, XtPointer closure, XEvent *event, Boolean *unused) 270{ 271 XawIcTableList p; 272 XawVendorShellExtPart *ve; 273 VendorShellWidget vw; 274 XVaNestedList pe_attr; 275 XRectangle pe_area; 276 XawTextMargin *margin; 277 278 if (event->type != ConfigureNotify) return; 279 280 if ((vw = SearchVendorShell(w)) == NULL) return; 281 282 if ((ve = GetExtPart(vw)) != NULL) { 283 if (IsSharedIC(ve)) return; 284 if ((ve->im.xim == NULL) || 285 ((p = GetIcTableShared(w, ve)) == NULL) || 286 (p->xic == NULL) || !(p->input_style & XIMPreeditPosition)) return; 287 pe_area.x = 0; 288 pe_area.y = 0; 289 pe_area.width = w->core.width; 290 pe_area.height = w->core.height; 291 margin = &(((TextWidget)w)->text.margin); 292 pe_area.x += margin->left; 293 pe_area.y += margin->top; 294 pe_area.width -= (margin->left + margin->right - 1); 295 pe_area.height -= (margin->top + margin->bottom - 1); 296 297 pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL); 298 XSetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL); 299 XtFree(pe_attr); 300 } 301} 302 303static XContext errContext = (XContext)NULL; 304 305static Widget SetErrCnxt(Widget w, XIM xim) 306{ 307 contextErrDataRec *contextErrData; 308 309 if (errContext == (XContext)NULL) errContext = XUniqueContext(); 310 311 contextErrData = XtNew(contextErrDataRec); 312 contextErrData->widget = w; 313 contextErrData->xim = xim; 314 if (XSaveContext(XtDisplay(w), (Window)xim, errContext, 315 (char *)contextErrData)) { 316 return(NULL); 317 } 318 return(contextErrData->widget); 319} 320 321#if 0 322static Widget 323GetErrCnxt(XIM error_im) 324{ 325 contextErrDataRec *contextErrData; 326 327 if (XFindContext(XDisplayOfIM(error_im), (Window)error_im, errContext, 328 (XPointer*)&contextErrData)) { 329 return(NULL); 330 } 331 return(contextErrData->widget); 332} 333#endif 334 335static void 336CloseIM(XawVendorShellExtPart *ve) 337{ 338 if (ve->im.xim) 339 XCloseIM(ve->im.xim); 340} 341 342static unsigned int 343SetVendorShellHeight(XawVendorShellExtPart* ve, unsigned int height) 344{ 345 Arg args[2]; 346 Cardinal i = 0; 347 348 if (ve->im.area_height < height || height == 0) { 349 XtSetArg(args[i], XtNheight, 350 (ve->parent->core.height + height - ve->im.area_height)); 351 ve->im.area_height = height; 352 XtSetValues(ve->parent, args, 1); 353 } 354 return(ve->im.area_height); 355} 356 357static void 358DestroyAllIM(XawVendorShellExtPart *ve) 359{ 360 XawIcTableList p; 361 contextErrDataRec *contextErrData; 362 363 /* 364 * Destory all ICs 365 */ 366 if (IsSharedIC(ve)) { 367 if ((p = ve->ic.shared_ic_table) && p->xic) { 368 DestroyIC(p->widget, ve); 369 p->xic = NULL; 370 p->ic_focused = FALSE; 371 } 372 } else { 373 for (p = ve->ic.ic_table; p; p = p->next) { 374 if (p->xic == NULL) continue; 375 DestroyIC(p->widget, ve); 376 p->xic = NULL; 377 p->ic_focused = FALSE; 378 } 379 } 380 if (!ve->im.xim) return; 381 /* 382 * Close Input Method 383 */ 384 if (!XFindContext(XDisplayOfIM(ve->im.xim), (Window)ve->im.xim, errContext, 385 (XPointer*)&contextErrData)) { 386 if (contextErrData) XtFree((char *)contextErrData); 387 } 388 XDeleteContext(XDisplayOfIM(ve->im.xim), (Window)ve->im.xim, errContext); 389 CloseIM(ve); 390 ve->im.xim = NULL; 391 392 /* 393 * resize vendor shell to core size 394 */ 395 (void) SetVendorShellHeight(ve, 0); 396 /* 397 XawVendorShellExtResize(vw); 398 */ 399 return; 400} 401 402static void 403FreeAllDataOfVendorShell(XawVendorShellExtPart *ve, VendorShellWidget vw) 404{ 405 XawIcTableList p, next; 406 contextErrDataRec *contextErrData; 407 408 if (!XFindContext(XtDisplay(vw), (Window)vw, extContext, 409 (XPointer*)&contextErrData)) { 410 if (contextErrData) XtFree((char *)contextErrData); 411 } 412 XDeleteContext(XtDisplay(vw), (Window)vw, extContext); 413 if (ve->ic.shared_ic_table) 414 XtFree((char *)ve->ic.shared_ic_table); 415 if (ve->im.resources) XtFree((char *)ve->im.resources); 416 for (p = ve->ic.ic_table; p; p = next) { 417 next = p->next; 418 XtFree((char *)p); 419 } 420} 421 422static void 423VendorShellDestroyed(Widget w, XtPointer cl_data, XtPointer ca_data) 424{ 425 XawVendorShellExtPart *ve; 426 427 if ( ( ve = GetExtPart( (VendorShellWidget) w ) ) == NULL ) return; 428 DestroyAllIM( ve ); 429 FreeAllDataOfVendorShell( ve, (VendorShellWidget) w ); 430 return; 431} 432 433#if 0 434static int 435IOErrorHandler(XIM error_im) 436{ 437 VendorShellWidget vw; 438 XawVendorShellExtPart * ve; 439 440 if ((vw = (VendorShellWidget)GetErrCnxt(error_im)) == NULL 441 || (ve = GetExtPart(vw)) == NULL) return(0); 442 443 DestroyAllIM(ve); 444 return(0); 445} 446#endif 447 448/* 449 * Attempt to open an input method 450 */ 451 452static void 453OpenIM(XawVendorShellExtPart *ve) 454{ 455 int i; 456 char *p, *s, *ns, *end, *pbuf, buf[32]; 457 XIM xim = NULL; 458 XIMStyles *xim_styles; 459 XIMStyle input_style = 0; 460 Boolean found; 461 462 if (ve->im.open_im == False) return; 463 ve->im.xim = NULL; 464 if (ve->im.input_method == NULL) { 465 if ((p = XSetLocaleModifiers("@im=none")) != NULL && *p) 466 xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL); 467 } else { 468 /* no fragment can be longer than the whole string */ 469 Cardinal len = strlen (ve->im.input_method) + 5; 470 471 if (len < sizeof buf) pbuf = buf; 472 else pbuf = XtMalloc (len); 473 474 if (pbuf == NULL) return; 475 476 for(ns=s=ve->im.input_method; ns && *s;) { 477 /* skip any leading blanks */ 478 while (*s && isspace(*s)) s++; 479 if (!*s) break; 480 if ((ns = end = strchr(s, ',')) == NULL) 481 end = s + strlen(s); 482 /* If there is a spurious comma end can be the same as s */ 483 if (end > s) { 484 /* strip any trailing blanks */ 485 while (isspace(*(end - 1))) end--; 486 487 strcpy (pbuf, "@im="); 488 strncat (pbuf, s, end - s); 489 pbuf[end - s + 4] = '\0'; 490 } 491 492 if ((p = XSetLocaleModifiers(pbuf)) != NULL && *p 493 && (xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL)) != NULL) 494 break; 495 496 s = ns + 1; 497 } 498 499 if (pbuf != buf) XtFree (pbuf); 500 } 501 if (xim == NULL) { 502 if ((p = XSetLocaleModifiers("")) != NULL) { 503 xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL); 504 } 505 } 506 if (xim == NULL) { 507 XtAppWarning(XtWidgetToApplicationContext(ve->parent), 508 "Input Method Open Failed"); 509 return; 510 } 511 if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) 512 || !xim_styles) { 513 XtAppWarning(XtWidgetToApplicationContext(ve->parent), 514 "input method doesn't support any style"); 515 XCloseIM(xim); 516 return; 517 } 518 found = False; 519 for(ns = s = ve->im.preedit_type; s && !found;) { 520 while (*s && isspace(*s)) s++; 521 if (!*s) break; 522 if ((ns = end = strchr(s, ',')) == NULL) 523 end = s + strlen(s); 524 else 525 ns++; 526 if (end > s) 527 while (isspace(*(end - 1))) end--; 528 529 if (!strncmp(s, "OverTheSpot", end - s)) { 530 input_style = (XIMPreeditPosition | XIMStatusArea); 531 } else if (!strncmp(s, "OffTheSpot", end - s)) { 532 input_style = (XIMPreeditArea | XIMStatusArea); 533 } else if (!strncmp(s, "Root", end - s)) { 534 input_style = (XIMPreeditNothing | XIMStatusNothing); 535 } 536 for (i = 0; (unsigned short)i < xim_styles->count_styles; i++) 537 if (input_style == xim_styles->supported_styles[i]) { 538 ve->ic.input_style = input_style; 539 SetErrCnxt(ve->parent, xim); 540 ve->im.xim = xim; 541 found = True; 542 break; 543 } 544 545 s = ns; 546 } 547 XFree(xim_styles); 548 549 if (!found) { 550 XCloseIM(xim); 551 XtAppWarning(XtWidgetToApplicationContext(ve->parent), 552 "input method doesn't support my input style"); 553 } 554} 555 556static Bool 557ResizeVendorShell_Core(VendorShellWidget vw, XawVendorShellExtPart *ve, 558 XawIcTableList p) 559{ 560 XVaNestedList pe_attr, st_attr; 561 XRectangle pe_area, st_area; 562 XRectangle *get_pe_area = NULL, *get_st_area = NULL; 563 564 st_area.width = 0; 565 if (p->input_style & XIMStatusArea) { 566 st_attr = XVaCreateNestedList(0, XNArea, &get_st_area, NULL); 567 XGetICValues(p->xic, XNStatusAttributes, st_attr, NULL); 568 XFree(st_attr); 569 if (p->xic == NULL) { 570 return(FALSE); 571 } 572 st_area.x = 0; 573 st_area.y = vw->core.height - ve->im.area_height; 574 st_area.width = get_st_area->width; 575 st_area.height = get_st_area->height; 576 XFree(get_st_area); 577 st_attr = XVaCreateNestedList(0, XNArea, &st_area, NULL); 578 XSetICValues(p->xic, XNStatusAttributes, st_attr, NULL); 579 XFree(st_attr); 580 if (p->xic == NULL) { 581 return(FALSE); 582 } 583 } 584 if (p->input_style & XIMPreeditArea) { 585 pe_attr = XVaCreateNestedList(0, XNArea, &get_pe_area, NULL); 586 XGetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL); 587 XFree(pe_attr); 588 if (p->xic == NULL) { 589 return(FALSE); 590 } 591 pe_area.x = st_area.width; 592 pe_area.y = vw->core.height - ve->im.area_height; 593 pe_area.width = vw->core.width; 594 pe_area.height = get_pe_area->height; 595 if (p->input_style & XIMStatusArea) { 596 pe_area.width -= st_area.width; 597 } 598 XFree(get_pe_area); 599 pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL); 600 XSetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL); 601 XFree(pe_attr); 602 } 603 return(TRUE); 604} 605 606static void 607ResizeVendorShell(VendorShellWidget vw, XawVendorShellExtPart *ve) 608{ 609 XawIcTableList p; 610 611 if (IsSharedIC(ve)) { 612 p = ve->ic.shared_ic_table; 613 if (p->xic == NULL) return; 614 ResizeVendorShell_Core(vw, ve, p); 615 return; 616 } 617 for (p = ve->ic.ic_table; p; p = p->next) { 618 if (p->xic == NULL) continue; 619 if (ResizeVendorShell_Core(vw, ve, p) == FALSE) return; 620 } 621} 622 623static XawIcTableList 624CreateIcTable(Widget w, XawVendorShellExtPart *ve) 625{ 626 XawIcTableList table; 627 628 table = (XawIcTableList) XtMalloc(sizeof(XawIcTablePart)); 629 if (table == NULL) return(NULL); 630 table->widget = w; 631 table->xic = NULL; 632 table->flg = table->prev_flg = 0; 633 table->font_set = NULL; 634 table->foreground = table->background = 0xffffffff; 635 table->bg_pixmap = 0; 636 table->cursor_position = 0xffff; 637 table->line_spacing = 0; 638 table->ic_focused = FALSE; 639 table->openic_error = FALSE; 640 return(table); 641} 642 643static Bool 644RegisterToVendorShell(Widget w, XawVendorShellExtPart *ve) 645{ 646 XawIcTableList table; 647 648 if ((table = CreateIcTable(w, ve)) == NULL) return(FALSE); 649 table->next = ve->ic.ic_table; 650 ve->ic.ic_table = table; 651 return(TRUE); 652} 653 654static void 655UnregisterFromVendorShell(Widget w, XawVendorShellExtPart *ve) 656{ 657 XawIcTableList *prev, p; 658 659 for (prev = &ve->ic.ic_table; (p = *prev) != NULL; prev = &p->next) { 660 if (p->widget == w) { 661 *prev = p->next; 662 XtFree((char *)p); 663 break; 664 } 665 } 666 return; 667} 668 669static void 670SetICValuesShared(Widget w, XawVendorShellExtPart *ve, 671 XawIcTableList p, Bool check) 672{ 673 XawIcTableList pp; 674 675 if ((pp = GetIcTable(w, ve)) == NULL) return; 676 if (check == TRUE && CurrentSharedIcTable(ve) != pp) return; 677 678 if (pp->prev_flg & CICursorP && p->cursor_position != pp->cursor_position) { 679 p->cursor_position = pp->cursor_position; 680 p->flg |= CICursorP; 681 } 682 if (pp->prev_flg & CIFontSet && p->font_set != pp->font_set) { 683 p->font_set = pp->font_set; 684 p->flg |= (CIFontSet|CICursorP); 685 } 686 if (pp->prev_flg & CIFg && p->foreground != pp->foreground) { 687 p->foreground = pp->foreground; 688 p->flg |= CIFg; 689 } 690 if (pp->prev_flg & CIBg && p->background != pp->background) { 691 p->background = pp->background; 692 p->flg |= CIBg; 693 } 694 if (pp->prev_flg & CIBgPixmap && p->bg_pixmap != pp->bg_pixmap) { 695 p->bg_pixmap = pp->bg_pixmap; 696 p->flg |= CIBgPixmap; 697 } 698 if (pp->prev_flg & CILineS && p->line_spacing != pp->line_spacing) { 699 p->line_spacing = pp->line_spacing; 700 p->flg |= CILineS; 701 } 702} 703 704static Bool 705IsCreatedIC(Widget w, XawVendorShellExtPart *ve) 706{ 707 XawIcTableList p; 708 709 if (ve->im.xim == NULL) return(FALSE); 710 if ((p = GetIcTableShared(w, ve)) == NULL) return(FALSE); 711 if (p->xic == NULL) return(FALSE); 712 return(TRUE); 713} 714 715static void 716SizeNegotiation(XawIcTableList p, unsigned int width, unsigned int height) 717{ 718 XRectangle pe_area, st_area; 719 XVaNestedList pe_attr = NULL, st_attr = NULL; 720 int ic_cnt = 0; 721 XRectangle *pe_area_needed = NULL, *st_area_needed = NULL; 722 XPointer ic_a[5]; 723 724 if (p->input_style & XIMPreeditArea) { 725 pe_attr = XVaCreateNestedList(0, XNAreaNeeded, &pe_area_needed, NULL); 726 ic_a[ic_cnt] = (XPointer) XNPreeditAttributes; ic_cnt++; 727 ic_a[ic_cnt] = (XPointer) pe_attr; ic_cnt++; 728 } 729 if (p->input_style & XIMStatusArea) { 730 st_attr = XVaCreateNestedList(0, XNAreaNeeded, &st_area_needed, NULL); 731 ic_a[ic_cnt] = (XPointer) XNStatusAttributes; ic_cnt++; 732 ic_a[ic_cnt] = (XPointer) st_attr; ic_cnt++; 733 } 734 ic_a[ic_cnt] = (XPointer) NULL; 735 736 if (ic_cnt > 0) { 737 XGetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], NULL); 738 if (pe_attr) XFree(pe_attr); 739 if (st_attr) XFree(st_attr); 740 if (p->xic == NULL) { 741 p->openic_error = True; 742 return; 743 } 744 pe_attr = st_attr = NULL; 745 ic_cnt = 0; 746 if (p->input_style & XIMStatusArea) { 747 st_area.height = st_area_needed->height; 748 st_area.x = 0; 749 st_area.y = height - st_area.height; 750 if (p->input_style & XIMPreeditArea) { 751 st_area.width = st_area_needed->width; 752 } else { 753 st_area.width = width; 754 } 755 756 XFree(st_area_needed); 757 st_attr = XVaCreateNestedList(0, XNArea, &st_area, NULL); 758 ic_a[ic_cnt] = (XPointer) XNStatusAttributes; ic_cnt++; 759 ic_a[ic_cnt] = (XPointer) st_attr; ic_cnt++; 760 } 761 if (p->input_style & XIMPreeditArea) { 762 if (p->input_style & XIMStatusArea) { 763 pe_area.x = st_area.width; 764 pe_area.width = width - st_area.width; 765 } else { 766 pe_area.x = 0; 767 pe_area.width = width; 768 } 769 pe_area.height = pe_area_needed->height; 770 XFree(pe_area_needed); 771 pe_area.y = height - pe_area.height; 772 pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL); 773 ic_a[ic_cnt] = (XPointer) XNPreeditAttributes; ic_cnt++; 774 ic_a[ic_cnt] = (XPointer) pe_attr; ic_cnt++; 775 } 776 ic_a[ic_cnt] = (XPointer) NULL; 777 XSetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], NULL); 778 if (pe_attr) XFree(pe_attr); 779 if (st_attr) XFree(st_attr); 780 if (p->xic == NULL) { 781 p->openic_error = True; 782 return; 783 } 784 } 785} 786 787static void 788CreateIC(Widget w, XawVendorShellExtPart *ve) 789{ 790 XawIcTableList p; 791 XPoint position; 792 XRectangle pe_area, st_area; 793 XVaNestedList pe_attr = NULL, st_attr = NULL; 794 XPointer ic_a[20], pe_a[20], st_a[20]; 795 Dimension height = 0; 796 int ic_cnt = 0, pe_cnt = 0, st_cnt = 0; 797 XawTextMargin *margin; 798 799 if (!XtIsRealized(w)) return; 800 if (((ve->im.xim == NULL) || (p = GetIcTableShared(w, ve)) == NULL) || 801 p->xic || (p->openic_error != FALSE)) return; 802 803 p->input_style = GetInputStyleOfIC(ve); 804 805 if (IsSharedIC(ve)) SetICValuesShared(w, ve, p, FALSE); 806 XFlush(XtDisplay(w)); 807 808 if (p->input_style & (XIMPreeditArea|XIMPreeditPosition|XIMStatusArea)) { 809 if (p->flg & CIFontSet) { 810 pe_a[pe_cnt] = (XPointer) XNFontSet; pe_cnt++; 811 pe_a[pe_cnt] = (XPointer) p->font_set; pe_cnt++; 812 st_a[st_cnt] = (XPointer) XNFontSet; st_cnt++; 813 st_a[st_cnt] = (XPointer) p->font_set; st_cnt++; 814 if (p->font_set) { 815 height = maxAscentOfFontSet(p->font_set) 816 + maxDescentOfFontSet(p->font_set); 817 } 818 height = SetVendorShellHeight(ve, height); 819 } 820 if (p->flg & CIFg) { 821 pe_a[pe_cnt] = (XPointer) XNForeground; pe_cnt++; 822 pe_a[pe_cnt] = (XPointer) p->foreground; pe_cnt++; 823 st_a[st_cnt] = (XPointer) XNForeground; st_cnt++; 824 st_a[st_cnt] = (XPointer) p->foreground; st_cnt++; 825 } 826 if (p->flg & CIBg) { 827 pe_a[pe_cnt] = (XPointer) XNBackground; pe_cnt++; 828 pe_a[pe_cnt] = (XPointer) p->background; pe_cnt++; 829 st_a[st_cnt] = (XPointer) XNBackground; st_cnt++; 830 st_a[st_cnt] = (XPointer) p->background; st_cnt++; 831 } 832 if (p->flg & CIBgPixmap) { 833 pe_a[pe_cnt] = (XPointer) XNBackgroundPixmap; pe_cnt++; 834 pe_a[pe_cnt] = (XPointer) p->bg_pixmap; pe_cnt++; 835 st_a[st_cnt] = (XPointer) XNBackgroundPixmap; st_cnt++; 836 st_a[st_cnt] = (XPointer) p->bg_pixmap; st_cnt++; 837 } 838 if (p->flg & CILineS) { 839 pe_a[pe_cnt] = (XPointer) XNLineSpace; pe_cnt++; 840 pe_a[pe_cnt] = (XPointer) p->line_spacing; pe_cnt++; 841 st_a[st_cnt] = (XPointer) XNLineSpace; st_cnt++; 842 st_a[st_cnt] = (XPointer) p->line_spacing; st_cnt++; 843 } 844 } 845 if (p->input_style & XIMPreeditArea) { 846 pe_area.x = 0; 847 pe_area.y = ve->parent->core.height - height; 848 pe_area.width = ve->parent->core.width; 849 pe_area.height = height; 850 pe_a[pe_cnt] = (XPointer) XNArea; pe_cnt++; 851 pe_a[pe_cnt] = (XPointer) &pe_area; pe_cnt++; 852 } 853 if (p->input_style & XIMPreeditPosition) { 854 pe_area.x = 0; 855 pe_area.y = 0; 856 pe_area.width = w->core.width; 857 pe_area.height = w->core.height; 858 margin = &(((TextWidget)w)->text.margin); 859 pe_area.x += margin->left; 860 pe_area.y += margin->top; 861 pe_area.width -= (margin->left + margin->right - 1); 862 pe_area.height -= (margin->top + margin->bottom - 1); 863 pe_a[pe_cnt] = (XPointer) XNArea; pe_cnt++; 864 pe_a[pe_cnt] = (XPointer) &pe_area; pe_cnt++; 865 if (p->flg & CICursorP) { 866 _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y); 867 } else { 868 position.x = position.y = 0; 869 } 870 pe_a[pe_cnt] = (XPointer) XNSpotLocation; pe_cnt++; 871 pe_a[pe_cnt] = (XPointer) &position; pe_cnt++; 872 } 873 if (p->input_style & XIMStatusArea) { 874 st_area.x = 0; 875 st_area.y = ve->parent->core.height - height; 876 st_area.width = ve->parent->core.width; 877 st_area.height = height; 878 st_a[st_cnt] = (XPointer) XNArea; st_cnt++; 879 st_a[st_cnt] = (XPointer) &st_area; st_cnt++; 880 } 881 882 ic_a[ic_cnt] = (XPointer) XNInputStyle; ic_cnt++; 883 ic_a[ic_cnt] = (XPointer) p->input_style; ic_cnt++; 884 ic_a[ic_cnt] = (XPointer) XNClientWindow; ic_cnt++; 885 ic_a[ic_cnt] = (XPointer) XtWindow(ve->parent); ic_cnt++; 886 ic_a[ic_cnt] = (XPointer) XNFocusWindow; ic_cnt++; 887 ic_a[ic_cnt] = (XPointer) XtWindow(w); ic_cnt++; 888 889 if (pe_cnt > 0) { 890 pe_a[pe_cnt] = (XPointer) NULL; 891 pe_attr = XVaCreateNestedList(0, pe_a[0], pe_a[1], pe_a[2], pe_a[3], 892 pe_a[4], pe_a[5], pe_a[6], pe_a[7], pe_a[8], 893 pe_a[9], pe_a[10], pe_a[11], pe_a[12], 894 pe_a[13], pe_a[14], pe_a[15], pe_a[16], 895 pe_a[17], pe_a[18], NULL); 896 ic_a[ic_cnt] = (XPointer) XNPreeditAttributes; ic_cnt++; 897 ic_a[ic_cnt] = (XPointer) pe_attr; ic_cnt++; 898 } 899 900 if (st_cnt > 0) { 901 st_a[st_cnt] = (XPointer) NULL; 902 st_attr = XVaCreateNestedList(0, st_a[0], st_a[1], st_a[2], st_a[3], 903 st_a[4], st_a[5], st_a[6], st_a[7], st_a[8], 904 st_a[9], st_a[10], st_a[11], st_a[12], 905 st_a[13], st_a[14], st_a[15], st_a[16], 906 st_a[17], st_a[18], NULL); 907 ic_a[ic_cnt] = (XPointer) XNStatusAttributes; ic_cnt++; 908 ic_a[ic_cnt] = (XPointer) st_attr; ic_cnt++; 909 } 910 ic_a[ic_cnt] = (XPointer) NULL; 911 912 p->xic = XCreateIC(ve->im.xim, ic_a[0], ic_a[1], ic_a[2], ic_a[3], 913 ic_a[4], ic_a[5], ic_a[6], ic_a[7], ic_a[8], ic_a[9], 914 ic_a[10], ic_a[11], ic_a[12], ic_a[13], ic_a[14], 915 ic_a[15], ic_a[16], ic_a[17], ic_a[18], NULL); 916 if (pe_attr) XtFree(pe_attr); 917 if (st_attr) XtFree(st_attr); 918 919 if (p->xic == NULL) { 920 p->openic_error = True; 921 return; 922 } 923 924 SizeNegotiation(p, ve->parent->core.width, ve->parent->core.height); 925 926 p->flg &= ~(CIFontSet | CIFg | CIBg | CIBgPixmap | CICursorP | CILineS); 927 928 if (!IsSharedIC(ve)) { 929 if (p->input_style & XIMPreeditPosition) { 930 XtAddEventHandler(w, (EventMask)StructureNotifyMask, FALSE, 931 (XtEventHandler)ConfigureCB, (Opaque)NULL); 932 } 933 } 934} 935 936static void 937SetICValues(Widget w, XawVendorShellExtPart *ve, Bool focus) 938{ 939 XawIcTableList p; 940 XPoint position; 941 XRectangle pe_area; 942 XVaNestedList pe_attr = NULL, st_attr = NULL; 943 XPointer ic_a[20], pe_a[20], st_a[20]; 944 int ic_cnt = 0, pe_cnt = 0, st_cnt = 0; 945 XawTextMargin *margin; 946 int height = 0; 947 948 if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || 949 (p->xic == NULL)) return; 950 951 if (IsSharedIC(ve)) SetICValuesShared(w, ve, p, TRUE); 952 XFlush(XtDisplay(w)); 953 if (focus == FALSE && 954 !(p->flg & (CIFontSet | CIFg | CIBg | 955 CIBgPixmap | CICursorP | CILineS))) return; 956#ifdef SPOT 957 if ((p->input_style & XIMPreeditPosition) 958 && ((!IsSharedIC(ve) && ((p->flg & ~CIICFocus) == CICursorP)) 959 || (IsSharedIC(ve) && p->flg == CICursorP))) { 960 _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y); 961 _XipChangeSpot(p->xic, position.x, position.y); 962 p->flg &= ~CICursorP; 963 return; 964 } 965#endif 966 967 if (p->input_style & (XIMPreeditArea|XIMPreeditPosition|XIMStatusArea)) { 968 if (p->flg & CIFontSet) { 969 pe_a[pe_cnt] = (XPointer) XNFontSet; pe_cnt++; 970 pe_a[pe_cnt] = (XPointer) p->font_set; pe_cnt++; 971 st_a[st_cnt] = (XPointer) XNFontSet; st_cnt++; 972 st_a[st_cnt] = (XPointer) p->font_set; st_cnt++; 973 if (p->font_set) { 974 height = maxAscentOfFontSet(p->font_set) 975 + maxDescentOfFontSet(p->font_set); 976 } 977 height = SetVendorShellHeight(ve, height); 978 } 979 if (p->flg & CIFg) { 980 pe_a[pe_cnt] = (XPointer) XNForeground; pe_cnt++; 981 pe_a[pe_cnt] = (XPointer) p->foreground; pe_cnt++; 982 st_a[st_cnt] = (XPointer) XNForeground; st_cnt++; 983 st_a[st_cnt] = (XPointer) p->foreground; st_cnt++; 984 } 985 if (p->flg & CIBg) { 986 pe_a[pe_cnt] = (XPointer) XNBackground; pe_cnt++; 987 pe_a[pe_cnt] = (XPointer) p->background; pe_cnt++; 988 st_a[st_cnt] = (XPointer) XNBackground; st_cnt++; 989 st_a[st_cnt] = (XPointer) p->background; st_cnt++; 990 } 991 if (p->flg & CIBgPixmap) { 992 pe_a[pe_cnt] = (XPointer) XNBackgroundPixmap; pe_cnt++; 993 pe_a[pe_cnt] = (XPointer) p->bg_pixmap; pe_cnt++; 994 st_a[st_cnt] = (XPointer) XNBackgroundPixmap; st_cnt++; 995 st_a[st_cnt] = (XPointer) p->bg_pixmap; st_cnt++; 996 } 997 if (p->flg & CILineS) { 998 pe_a[pe_cnt] = (XPointer) XNLineSpace; pe_cnt++; 999 pe_a[pe_cnt] = (XPointer) p->line_spacing; pe_cnt++; 1000 st_a[st_cnt] = (XPointer) XNLineSpace; st_cnt++; 1001 st_a[st_cnt] = (XPointer) p->line_spacing; st_cnt++; 1002 } 1003 } 1004 if (p->input_style & XIMPreeditPosition) { 1005 if (p->flg & CICursorP) { 1006 _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y); 1007 pe_a[pe_cnt] = (XPointer) XNSpotLocation; pe_cnt++; 1008 pe_a[pe_cnt] = (XPointer) &position; pe_cnt++; 1009 } 1010 } 1011 if (IsSharedIC(ve)) { 1012 if (p->input_style & XIMPreeditPosition) { 1013 pe_area.x = 0; 1014 pe_area.y = 0; 1015 pe_area.width = w->core.width; 1016 pe_area.height = w->core.height; 1017 margin = &(((TextWidget)w)->text.margin); 1018 pe_area.x += margin->left; 1019 pe_area.y += margin->top; 1020 pe_area.width -= (margin->left + margin->right - 1); 1021 pe_area.height -= (margin->top + margin->bottom - 1); 1022 pe_a[pe_cnt] = (XPointer) XNArea; pe_cnt++; 1023 pe_a[pe_cnt] = (XPointer) &pe_area; pe_cnt++; 1024 } 1025 } 1026 1027 if (pe_cnt > 0) { 1028 pe_a[pe_cnt] = (XPointer) NULL; 1029 pe_attr = XVaCreateNestedList(0, pe_a[0], pe_a[1], pe_a[2], pe_a[3], 1030 pe_a[4], pe_a[5], pe_a[6], pe_a[7], 1031 pe_a[8], pe_a[9], pe_a[10], pe_a[11], 1032 pe_a[12], pe_a[13], pe_a[14], pe_a[15], 1033 pe_a[16], pe_a[17], pe_a[18], NULL); 1034 ic_a[ic_cnt] = (XPointer) XNPreeditAttributes; ic_cnt++; 1035 ic_a[ic_cnt] = (XPointer) pe_attr; ic_cnt++; 1036 } 1037 if (st_cnt > 0) { 1038 st_a[st_cnt] = (XPointer) NULL; 1039 st_attr = XVaCreateNestedList(0, st_a[0], st_a[1], st_a[2], st_a[3], 1040 st_a[4], st_a[5], st_a[6], st_a[7], 1041 st_a[8], st_a[9], st_a[10], st_a[11], 1042 st_a[12], st_a[13], st_a[14], st_a[15], 1043 st_a[16], st_a[17], st_a[18], NULL); 1044 ic_a[ic_cnt] = (XPointer) XNStatusAttributes; ic_cnt++; 1045 ic_a[ic_cnt] = (XPointer) st_attr; ic_cnt++; 1046 } 1047 if (focus == TRUE) { 1048 ic_a[ic_cnt] = (XPointer) XNFocusWindow; ic_cnt++; 1049 ic_a[ic_cnt] = (XPointer) XtWindow(w); ic_cnt++; 1050 } 1051 if (ic_cnt > 0) { 1052 ic_a[ic_cnt] = (XPointer) NULL; 1053 XSetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], ic_a[4], 1054 ic_a[5], ic_a[6], ic_a[7], ic_a[8], ic_a[9], ic_a[10], 1055 ic_a[11], ic_a[12], ic_a[13], ic_a[14], ic_a[15], 1056 ic_a[16], ic_a[17], ic_a[18], NULL); 1057 if (pe_attr) XtFree(pe_attr); 1058 if (st_attr) XtFree(st_attr); 1059 } 1060 1061 if (IsSharedIC(ve) && p->flg & CIFontSet) 1062 SizeNegotiation(p, ve->parent->core.width, ve->parent->core.height); 1063 1064 p->flg &= ~(CIFontSet | CIFg | CIBg | CIBgPixmap | CICursorP | CILineS); 1065} 1066 1067static void 1068SharedICChangeFocusWindow(Widget w, XawVendorShellExtPart *ve, 1069 XawIcTableList p) 1070{ 1071 XawIcTableList pp; 1072 1073 if (w == NULL) { 1074 ve->ic.current_ic_table = NULL; 1075 return; 1076 } 1077 if ((pp = GetIcTable(w, ve)) == NULL) return; 1078 ve->ic.current_ic_table = pp; 1079 SetICValues(w, ve, TRUE); 1080} 1081 1082static XawIcTableList 1083CurrentSharedIcTable(XawVendorShellExtPart *ve) 1084{ 1085 return(ve->ic.current_ic_table); 1086} 1087 1088static void 1089SetICFocus(Widget w, XawVendorShellExtPart *ve) 1090{ 1091 XawIcTableList p, pp; 1092 1093 if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || 1094 (p->xic == NULL)) return; 1095 1096 if (IsSharedIC(ve)) { 1097 pp = CurrentSharedIcTable(ve); 1098 if (pp == NULL || pp->widget != w) { 1099 SharedICChangeFocusWindow(w, ve, p); 1100 } 1101 } 1102 if (p->flg & CIICFocus && p->ic_focused == FALSE) { 1103 p->ic_focused = TRUE; 1104 XSetICFocus(p->xic); 1105 } 1106 p->flg &= ~CIICFocus; 1107} 1108 1109static void 1110UnsetICFocus(Widget w, XawVendorShellExtPart *ve) 1111{ 1112 XawIcTableList p, pp; 1113 1114 if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || 1115 (p->xic == NULL)) return; 1116 1117 if (IsSharedIC(ve) && (pp = CurrentSharedIcTable(ve))) { 1118 if (pp->widget != w) { 1119 return; 1120 } 1121 SharedICChangeFocusWindow(NULL, ve, p); 1122 } 1123 if (p->ic_focused == TRUE) { 1124 XUnsetICFocus(p->xic); 1125 p->ic_focused = FALSE; 1126 } 1127} 1128 1129static void 1130SetValues(Widget w, XawVendorShellExtPart *ve, 1131 ArgList args, Cardinal num_args) 1132{ 1133 ArgList arg; 1134 1135 XrmName argName; 1136 XrmResourceList xrmres; 1137 Cardinal i; 1138 XawIcTablePart *p, save_tbl; 1139 1140 if ((p = GetIcTable(w, ve)) == NULL) return; 1141 1142 memcpy(&save_tbl, p, sizeof(XawIcTablePart)); 1143 1144 for (arg = args ; num_args != 0; num_args--, arg++) { 1145 argName = XrmStringToName(arg->name); 1146 for (xrmres = (XrmResourceList)ve->im.resources, i = 0; 1147 i < ve->im.num_resources; i++, xrmres++) { 1148 if (argName == xrmres->xrm_name) { 1149 _XtCopyFromArg(arg->value, 1150 (char *)p - xrmres->xrm_offset - 1, 1151 xrmres->xrm_size); 1152 break; 1153 } 1154 } 1155 } 1156 if (p->font_set != save_tbl.font_set) { 1157 p->flg |= CIFontSet; 1158 } 1159 if (p->foreground != save_tbl.foreground) { 1160 p->flg |= CIFg; 1161 } 1162 if (p->background !=save_tbl.background) { 1163 p->flg |= CIBg; 1164 } 1165 if (p->bg_pixmap != save_tbl.bg_pixmap) { 1166 p->flg |= CIBgPixmap; 1167 } 1168 if (p->cursor_position != save_tbl.cursor_position) { 1169 p->flg |= CICursorP; 1170 } 1171 if (p->line_spacing != save_tbl.line_spacing) { 1172 p->flg |= CILineS; 1173 } 1174 p->prev_flg |= p->flg; 1175} 1176 1177static void 1178SetFocus(Widget w, XawVendorShellExtPart *ve) 1179{ 1180 XawIcTableList p; 1181 if ((p = GetIcTableShared(w, ve)) == NULL) return; 1182 1183 if ( p->ic_focused == FALSE || IsSharedIC(ve)) { 1184 p->flg |= CIICFocus; 1185 } 1186 p->prev_flg |= p->flg; 1187} 1188 1189static void 1190DestroyIC(Widget w, XawVendorShellExtPart *ve) 1191{ 1192 XawIcTableList p; 1193 1194 if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || 1195 (p->xic == NULL)) return; 1196 if (IsSharedIC(ve)) { 1197 if (GetIcTable(w, ve) == ve->ic.current_ic_table) { 1198 UnsetICFocus(w, ve); 1199 } 1200 return; 1201 } 1202 XDestroyIC(p->xic); 1203 if (!IsSharedIC(ve)) { 1204 if (p->input_style & XIMPreeditPosition) { 1205 XtRemoveEventHandler(w, (EventMask)StructureNotifyMask, FALSE, 1206 (XtEventHandler)ConfigureCB, (Opaque)NULL); 1207 } 1208 } 1209} 1210 1211static void 1212SetFocusValues(Widget inwidg, ArgList args, Cardinal num_args, Bool focus) 1213{ 1214 XawVendorShellExtPart *ve; 1215 VendorShellWidget vw; 1216 1217 if ((vw = SearchVendorShell(inwidg)) == NULL) return; 1218 if ((ve = GetExtPart(vw)) != NULL) { 1219 if (num_args > 0) SetValues(inwidg, ve, args, num_args); 1220 if (focus) SetFocus(inwidg, ve); 1221 if (XtIsRealized((Widget)vw) && ve->im.xim) { 1222 if (IsCreatedIC(inwidg, ve)) { 1223 SetICValues(inwidg, ve, FALSE); 1224 if (focus) SetICFocus(inwidg, ve); 1225 } else { 1226 CreateIC(inwidg, ve); 1227 SetICFocus(inwidg, ve); 1228 } 1229 } 1230 } 1231} 1232 1233static void 1234UnsetFocus(Widget inwidg) 1235{ 1236 XawVendorShellExtPart *ve; 1237 VendorShellWidget vw; 1238 XawIcTableList p; 1239 1240 if ((vw = SearchVendorShell(inwidg)) == NULL) return; 1241 if ((ve = GetExtPart(vw)) != NULL) { 1242 if ((p = GetIcTableShared(inwidg, ve)) == NULL) return; 1243 if (p->flg & CIICFocus) { 1244 p->flg &= ~CIICFocus; 1245 } 1246 p->prev_flg &= ~CIICFocus; 1247 if (ve->im.xim && XtIsRealized((Widget)vw) && p->xic) { 1248 UnsetICFocus(inwidg, ve); 1249 } 1250 } 1251} 1252 1253static Bool 1254IsRegistered(Widget w, XawVendorShellExtPart* ve) 1255{ 1256 XawIcTableList p; 1257 1258 for (p = ve->ic.ic_table; p; p = p->next) 1259 { 1260 if (p->widget == w) return(TRUE); 1261 } 1262 return(FALSE); 1263} 1264 1265static void 1266Register(Widget inwidg, XawVendorShellExtPart* ve) 1267{ 1268 if (ve->im.xim == NULL) 1269 { 1270 OpenIM(ve); 1271 } 1272 1273 if (IsRegistered(inwidg, ve)) return; 1274 1275 if (RegisterToVendorShell(inwidg, ve) == FALSE) return; 1276 1277 if (ve->im.xim == NULL) return; 1278 1279 if (XtIsRealized(ve->parent)) 1280 { 1281 CreateIC(inwidg, ve); 1282 SetICFocus(inwidg, ve); 1283 } 1284} 1285 1286static Bool 1287NoRegistered(XawVendorShellExtPart* ve) 1288{ 1289 if (ve->ic.ic_table == NULL) return(TRUE); 1290 return(FALSE); 1291} 1292 1293static void 1294Unregister(Widget inwidg, XawVendorShellExtPart *ve) 1295{ 1296 if (!IsRegistered(inwidg, ve)) return; 1297 1298 DestroyIC(inwidg, ve); 1299 1300 UnregisterFromVendorShell(inwidg, ve); 1301 1302 if (NoRegistered(ve)) 1303 { 1304 CloseIM(ve); 1305 ve->im.xim = NULL; 1306 /* 1307 * resize vendor shell to core size 1308 */ 1309 (void) SetVendorShellHeight(ve, 0); 1310 } 1311} 1312 1313static void 1314AllCreateIC(XawVendorShellExtPart *ve) 1315{ 1316 XawIcTableList p; 1317 1318 if (ve->im.xim == NULL) return; 1319 if (IsSharedIC(ve) && ve->ic.ic_table[0].widget) { 1320 p = ve->ic.shared_ic_table; 1321 if (p->xic == NULL) 1322 CreateIC(ve->ic.ic_table[0].widget, ve); 1323 SetICFocus(ve->ic.ic_table[0].widget, ve); 1324 return; 1325 } 1326 for (p = ve->ic.ic_table; p; p = p->next) { 1327 if (p->xic == NULL) 1328 CreateIC(p->widget, ve); 1329 } 1330 for (p = ve->ic.ic_table; p; p = p->next) { 1331 SetICFocus(p->widget, ve); 1332 } 1333} 1334 1335 1336static void 1337Reconnect(XawVendorShellExtPart *ve) 1338{ 1339 XawIcTableList p; 1340 1341 ve->im.open_im = True; 1342 if (ve->im.xim == NULL) { 1343 OpenIM(ve); 1344 } 1345 if (ve->im.xim == NULL) return; 1346 1347 if (IsSharedIC(ve)) { 1348 p = ve->ic.shared_ic_table; 1349 p->flg = p->prev_flg; 1350 p->openic_error = FALSE; 1351 } else { 1352 for (p = ve->ic.ic_table; p; p = p->next) { 1353 p->flg = p->prev_flg; 1354 p->openic_error = FALSE; 1355 } 1356 } 1357 AllCreateIC(ve); 1358} 1359 1360 1361static void 1362CompileResourceList(XtResourceList res, unsigned int num_res) 1363{ 1364 unsigned int count; 1365 1366#define xrmres ((XrmResourceList) res) 1367 for (count = 0; count < num_res; res++, count++) { 1368 xrmres->xrm_name = XrmPermStringToQuark(res->resource_name); 1369 xrmres->xrm_class = XrmPermStringToQuark(res->resource_class); 1370 xrmres->xrm_type = XrmPermStringToQuark(res->resource_type); 1371 xrmres->xrm_offset = -res->resource_offset - 1; 1372 xrmres->xrm_default_type = XrmPermStringToQuark(res->default_type); 1373 } 1374#undef xrmres 1375} 1376 1377static Bool 1378Initialize(VendorShellWidget vw, XawVendorShellExtPart *ve) 1379{ 1380 if (!XtIsVendorShell((Widget)vw)) return(FALSE); 1381 ve->parent = (Widget)vw; 1382 ve->im.xim = NULL; 1383 ve->im.area_height = 0; 1384 ve->im.resources = (XrmResourceList)XtMalloc(sizeof(resources)); 1385 if (ve->im.resources == NULL) return(FALSE); 1386 memcpy((char *)ve->im.resources, (char *)resources, sizeof(resources)); 1387 ve->im.num_resources = XtNumber(resources); 1388 CompileResourceList( (XtResourceList) ve->im.resources, 1389 ve->im.num_resources ); 1390 if ((ve->ic.shared_ic_table = CreateIcTable( (Widget)vw, ve)) == NULL) 1391 return(FALSE); 1392 ve->ic.current_ic_table = NULL; 1393 ve->ic.ic_table = NULL; 1394 return(TRUE); 1395} 1396 1397 1398/* Destroy() 1399 * 1400 * This frees all (most?) of the resources malloced by XawIm. 1401 * It is called by _XawImDestroy, which is called by Vendor.c's 1402 * VendorExt's Destroy method. Sheeran, Omron KK, 93/08/05 */ 1403 1404static void 1405Destroy(Widget w, XawVendorShellExtPart *ve) 1406{ 1407 contextDataRec *contextData; 1408 contextErrDataRec *contextErrData; 1409 1410 if (!XtIsVendorShell( w ) ) 1411 return; 1412 XtFree( (char*) ve->im.resources ); 1413 1414 if (extContext != (XContext)NULL && 1415 !XFindContext (XtDisplay (w), (Window)w, 1416 extContext, (XPointer*)&contextData)) 1417 XtFree( (char*) contextData ); 1418 1419 if (errContext != (XContext)NULL && 1420 !XFindContext (XDisplayOfIM( ve->im.xim ), (Window) ve->im.xim, 1421 errContext, (XPointer*) &contextErrData)) 1422 XtFree( (char*) contextErrData ); 1423} 1424 1425/********************************************* 1426 * 1427 * SEMI-PRIVATE FUNCTIONS 1428 * For use by other Xaw modules 1429 * 1430 ********************************************/ 1431 1432void 1433_XawImResizeVendorShell(Widget w) 1434{ 1435 XawVendorShellExtPart *ve; 1436 1437 if ( ( ve = GetExtPart( (VendorShellWidget) w ) ) && ve->im.xim ) { 1438 ResizeVendorShell( (VendorShellWidget) w, ve ); 1439 } 1440} 1441 1442 1443Dimension 1444_XawImGetShellHeight(Widget w) 1445{ 1446 XawVendorShellExtPart *ve; 1447 1448 if (!XtIsVendorShell( w ) ) return( w->core.height ); 1449 if ( (ve = GetExtPart( (VendorShellWidget) w )) != NULL ) { 1450 return( w->core.height - ve->im.area_height ); 1451 } 1452 return( w->core.height ); 1453} 1454 1455void 1456_XawImRealize(Widget w) 1457{ 1458 XawVendorShellExtPart *ve; 1459 1460 if ( !XtIsRealized( w ) || !XtIsVendorShell( w ) ) return; 1461 if ( (ve = GetExtPart( (VendorShellWidget) w )) != NULL ) { 1462 XtAddEventHandler( w, (EventMask)StructureNotifyMask, FALSE, 1463 XawVendorStructureNotifyHandler, (XtPointer)NULL ); 1464 AllCreateIC(ve); 1465 } 1466} 1467 1468void 1469_XawImInitialize(Widget w, Widget ext) 1470{ 1471 XawVendorShellExtPart *ve; 1472 1473 if ( !XtIsVendorShell( w ) ) return; 1474 if ( (ve = SetExtPart( (VendorShellWidget) w, (XawVendorShellExtWidget)ext )) != NULL ) { 1475 if ( Initialize( (VendorShellWidget) w, ve ) == FALSE ) return; 1476 XtAddCallback( w, XtNdestroyCallback, VendorShellDestroyed, 1477 (XtPointer) NULL ); 1478 } 1479} 1480 1481void 1482_XawImReconnect(Widget inwidg) 1483{ 1484 XawVendorShellExtPart *ve; 1485 VendorShellWidget vw; 1486 1487 if ((vw = SearchVendorShell(inwidg)) == NULL) return; 1488 if ((ve = GetExtPart(vw)) != NULL) { 1489 Reconnect(ve); 1490 } 1491} 1492 1493void 1494_XawImRegister(Widget inwidg) 1495{ 1496 XawVendorShellExtPart *ve; 1497 VendorShellWidget vw; 1498 1499 if ((vw = SearchVendorShell(inwidg)) == NULL) return; 1500 if ((ve = GetExtPart(vw)) != NULL) { 1501 Register(inwidg, ve); 1502 } 1503} 1504 1505void 1506_XawImUnregister(Widget inwidg) 1507{ 1508 XawVendorShellExtPart *ve; 1509 VendorShellWidget vw; 1510 1511 if ((vw = SearchVendorShell(inwidg)) == NULL) return; 1512 if ((ve = GetExtPart(vw)) != NULL) { 1513 Unregister(inwidg, ve); 1514 } 1515} 1516 1517void 1518_XawImSetValues(Widget inwidg, ArgList args, Cardinal num_args) 1519{ 1520 SetFocusValues( inwidg, args, num_args, FALSE ); 1521} 1522 1523void 1524_XawImSetFocusValues(Widget inwidg, ArgList args, Cardinal num_args) 1525{ 1526 SetFocusValues(inwidg, args, num_args, TRUE); 1527} 1528 1529void 1530_XawImUnsetFocus(Widget inwidg) 1531{ 1532 UnsetFocus(inwidg); 1533} 1534 1535int 1536_XawImWcLookupString(Widget inwidg, XKeyPressedEvent *event, 1537 wchar_t* buffer_return, int bytes_buffer, 1538 KeySym *keysym_return) 1539{ 1540 XawVendorShellExtPart* ve; 1541 VendorShellWidget vw; 1542 XawIcTableList p; 1543 int i, ret; 1544 char tmp_buf[64], *tmp_p; 1545 wchar_t* buf_p; 1546 1547 if ((vw = SearchVendorShell(inwidg)) && (ve = GetExtPart(vw)) && 1548 ve->im.xim && (p = GetIcTableShared(inwidg, ve)) && p->xic) { 1549 return(XwcLookupString(p->xic, event, buffer_return, bytes_buffer/sizeof(wchar_t), 1550 keysym_return, NULL)); 1551 } 1552 ret = XLookupString( event, tmp_buf, sizeof(tmp_buf), keysym_return, 1553 NULL ); 1554 for ( i = 0, tmp_p = tmp_buf, buf_p = buffer_return; i < ret; i++ ) { 1555 *buf_p++ = _Xaw_atowc(*tmp_p++); 1556 } 1557 return( ret ); 1558} 1559 1560int 1561_XawLookupString(Widget w, XKeyEvent *event, char *buffer_return, int buffer_size, 1562 KeySym *keysym_return) 1563{ 1564 XawVendorShellExtPart *ve; 1565 VendorShellWidget vw; 1566 XawIcTableList p; 1567 1568 if ((vw = SearchVendorShell(w)) && (ve = GetExtPart(vw)) 1569 && ve->im.xim && (p = GetIcTableShared(w, ve)) && p->xic) 1570 return (XmbLookupString(p->xic, event, buffer_return, buffer_size, 1571 keysym_return, NULL)); 1572 1573 return (XLookupString(event, buffer_return, buffer_size, 1574 keysym_return, NULL)); 1575} 1576 1577int 1578_XawImGetImAreaHeight(Widget w) 1579{ 1580 XawVendorShellExtPart *ve; 1581 VendorShellWidget vw; 1582 1583 if ((vw = SearchVendorShell(w)) && (ve = GetExtPart(vw))) { 1584 return(ve->im.area_height); 1585 } 1586 return(0); 1587} 1588 1589void 1590_XawImCallVendorShellExtResize(Widget w) 1591{ 1592 VendorShellWidget vw; 1593 1594 if ((vw = SearchVendorShell(w)) && GetExtPart(vw)) { 1595 XawVendorShellExtResize((Widget)vw); 1596 } 1597} 1598 1599 1600/* _XawImDestroy() 1601 * 1602 * This should be called by the VendorExt from its 1603 * core Destroy method. Sheeran, Omron KK 93/08/05 */ 1604 1605void 1606_XawImDestroy(Widget w, Widget ext) 1607{ 1608 XawVendorShellExtPart *ve; 1609 1610 if ( !XtIsVendorShell( w ) ) return; 1611 if ( (ve = GetExtPart( (VendorShellWidget) w )) != NULL ) 1612 Destroy( w, ve ); 1613} 1614