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