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