Simple.c revision 994689c1
1/*********************************************************** 2 3Copyright 1987, 1988, 1994, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25 26Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 27 28 All Rights Reserved 29 30Permission to use, copy, modify, and distribute this software and its 31documentation for any purpose and without fee is hereby granted, 32provided that the above copyright notice appear in all copies and that 33both that copyright notice and this permission notice appear in 34supporting documentation, and that the name of Digital not be 35used in advertising or publicity pertaining to distribution of the 36software without specific, written prior permission. 37 38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 44SOFTWARE. 45 46******************************************************************/ 47 48#ifdef HAVE_CONFIG_H 49#include <config.h> 50#endif 51#include <stdio.h> 52#include <X11/IntrinsicP.h> 53#include <X11/StringDefs.h> 54#include <X11/Xmu/Drawing.h> 55#include <X11/Xmu/SysUtil.h> 56#include <X11/Xaw/SimpleP.h> 57#include <X11/Xaw/XawInit.h> 58#include "Private.h" 59#ifndef OLDXAW 60#include <X11/Xaw/Tip.h> 61#endif 62 63/* 64 * Class Methods 65 */ 66static Bool ChangeSensitive(Widget); 67static void XawSimpleClassInitialize(void); 68static void XawSimpleClassPartInitialize(WidgetClass); 69#ifndef OLDXAW 70static void XawSimpleInitialize(Widget, Widget, ArgList, Cardinal*); 71static void XawSimpleDestroy(Widget); 72static void XawSimpleExpose(Widget, XEvent*, Region); 73#endif 74static void XawSimpleRealize(Widget, Mask*, XSetWindowAttributes*); 75static Boolean XawSimpleSetValues(Widget, Widget, Widget, ArgList, Cardinal*); 76 77/* 78 * Prototypes 79 */ 80static void ConvertCursor(Widget); 81 82/* 83 * Initialization 84 */ 85#ifndef OLDXAW 86static XtActionsRec actions[] = { 87 {"set-values", XawSetValuesAction}, 88 {"get-values", XawGetValuesAction}, 89 {"declare", XawDeclareAction}, 90 {"call-proc", XawCallProcAction}, 91}; 92#endif 93 94#define offset(field) XtOffsetOf(SimpleRec, simple.field) 95static XtResource resources[] = { 96 { 97 XtNcursor, 98 XtCCursor, 99 XtRCursor, 100 sizeof(Cursor), 101 offset(cursor), 102 XtRImmediate, 103 (XtPointer)None 104 }, 105 { 106 XtNinsensitiveBorder, 107 XtCInsensitive, 108 XtRPixmap, 109 sizeof(Pixmap), 110 offset(insensitive_border), 111 XtRImmediate, 112 NULL 113 }, 114 { 115 XtNpointerColor, 116 XtCForeground, 117 XtRPixel, 118 sizeof(Pixel), 119 offset(pointer_fg), 120 XtRString, 121 XtDefaultForeground 122 }, 123 { 124 XtNpointerColorBackground, 125 XtCBackground, 126 XtRPixel, 127 sizeof(Pixel), 128 offset(pointer_bg), 129 XtRString, 130 XtDefaultBackground 131 }, 132 { 133 XtNcursorName, 134 XtCCursor, 135 XtRString, 136 sizeof(String), 137 offset(cursor_name), 138 XtRString, 139 NULL 140 }, 141 { 142 XtNinternational, 143 XtCInternational, 144 XtRBoolean, 145 sizeof(Boolean), 146 offset(international), 147 XtRImmediate, 148 (XtPointer)False 149 }, 150#ifndef OLDXAW 151 { 152 XawNdisplayList, 153 XawCDisplayList, 154 XawRDisplayList, 155 sizeof(XawDisplayList*), 156 offset(display_list), 157 XtRImmediate, 158 NULL 159 }, 160 { 161 XtNtip, 162 XtCTip, 163 XtRString, 164 sizeof(String), 165 offset(tip), 166 XtRImmediate, 167 NULL 168 }, 169#endif 170#undef offset 171}; 172 173SimpleClassRec simpleClassRec = { 174 /* core */ 175 { 176 (WidgetClass)&widgetClassRec, /* superclass */ 177 "Simple", /* class_name */ 178 sizeof(SimpleRec), /* widget_size */ 179 XawSimpleClassInitialize, /* class_initialize */ 180 XawSimpleClassPartInitialize, /* class_part_initialize */ 181 False, /* class_inited */ 182#ifndef OLDXAW 183 XawSimpleInitialize, /* initialize */ 184#else 185 NULL, /* initialize */ 186#endif 187 NULL, /* initialize_hook */ 188 XawSimpleRealize, /* realize */ 189#ifndef OLDXAW 190 actions, /* actions */ 191 XtNumber(actions), /* num_actions */ 192#else 193 NULL, /* actions */ 194 0, /* num_actions */ 195#endif 196 resources, /* resources */ 197 XtNumber(resources), /* num_resources */ 198 NULLQUARK, /* xrm_class */ 199 True, /* compress_motion */ 200 True, /* compress_exposure */ 201 True, /* compress_enterleave */ 202 False, /* visible_interest */ 203#ifndef OLDXAW 204 XawSimpleDestroy, /* destroy */ 205#else 206 NULL, /* destroy */ 207#endif 208 NULL, /* resize */ 209#ifndef OLDXAW 210 XawSimpleExpose, /* expose */ 211#else 212 NULL, /* expose */ 213#endif 214 XawSimpleSetValues, /* set_values */ 215 NULL, /* set_values_hook */ 216 XtInheritSetValuesAlmost, /* set_values_almost */ 217 NULL, /* get_values_hook */ 218 NULL, /* accept_focus */ 219 XtVersion, /* version */ 220 NULL, /* callback_private */ 221 NULL, /* tm_table */ 222 XtInheritQueryGeometry, /* query_geometry */ 223 XtInheritDisplayAccelerator, /* display_accelerator */ 224 NULL, /* extension */ 225 }, 226 /* simple */ 227 { 228 ChangeSensitive, /* change_sensitive */ 229 }, 230}; 231 232WidgetClass simpleWidgetClass = (WidgetClass)&simpleClassRec; 233 234static void 235XawSimpleClassInitialize(void) 236{ 237 static XtConvertArgRec convertArg[] = { 238 { 239 XtWidgetBaseOffset, 240 (XtPointer)XtOffsetOf(WidgetRec, core.screen), 241 sizeof(Screen *) 242 }, 243 { 244 XtResourceString, 245 (XtPointer)XtNpointerColor, 246 sizeof(Pixel) 247 }, 248 { 249 XtResourceString, 250 (XtPointer)XtNpointerColorBackground, 251 sizeof(Pixel) 252 }, 253 { 254 XtWidgetBaseOffset, 255 (XtPointer)XtOffsetOf(WidgetRec, core.colormap), 256 sizeof(Colormap) 257 }, 258 }; 259 260 XawInitializeWidgetSet(); 261 XtSetTypeConverter(XtRString, XtRColorCursor, XmuCvtStringToColorCursor, 262 convertArg, XtNumber(convertArg), XtCacheByDisplay, NULL); 263} 264 265static void 266XawSimpleClassPartInitialize(WidgetClass cclass) 267{ 268 SimpleWidgetClass c = (SimpleWidgetClass)cclass; 269 SimpleWidgetClass super = (SimpleWidgetClass)c->core_class.superclass; 270 271 if (c->simple_class.change_sensitive == NULL) { 272 char buf[BUFSIZ]; 273 274 (void)XmuSnprintf(buf, sizeof(buf), 275 "%s Widget: The Simple Widget class method " 276 "'change_sensitive' is undefined.\nA function " 277 "must be defined or inherited.", 278 c->core_class.class_name); 279 XtWarning(buf); 280 c->simple_class.change_sensitive = ChangeSensitive; 281 } 282 283 if (c->simple_class.change_sensitive == XtInheritChangeSensitive) 284 c->simple_class.change_sensitive = super->simple_class.change_sensitive; 285} 286 287#ifndef OLDXAW 288/*ARGSUSED*/ 289static void 290XawSimpleInitialize(Widget request, Widget cnew, 291 ArgList args, Cardinal *num_args) 292{ 293 SimpleWidget simple = (SimpleWidget)cnew; 294 295 if (simple->simple.tip) 296 simple->simple.tip = XtNewString(simple->simple.tip); 297} 298 299static void 300XawSimpleDestroy(Widget w) 301{ 302 SimpleWidget simple = (SimpleWidget)w; 303 304 if (simple->simple.tip) 305 XtFree((XtPointer)simple->simple.tip); 306} 307#endif 308 309static void 310XawSimpleRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes) 311{ 312#ifndef OLDXAW 313 XawPixmap *pixmap; 314#endif 315 Pixmap border_pixmap = CopyFromParent; 316 317 if (!XtIsSensitive(w)) 318 { 319 /* change border to gray; have to remember the old one, 320 * so XtDestroyWidget deletes the proper one */ 321 if (((SimpleWidget)w)->simple.insensitive_border == None) 322 ((SimpleWidget)w)->simple.insensitive_border = 323 XmuCreateStippledPixmap(XtScreen(w), 324 w->core.border_pixel, 325 w->core.background_pixel, 326 w->core.depth); 327 border_pixmap = w->core.border_pixmap; 328 attributes->border_pixmap = 329 w->core.border_pixmap = ((SimpleWidget)w)->simple.insensitive_border; 330 331 *valueMask |= CWBorderPixmap; 332 *valueMask &= ~CWBorderPixel; 333 } 334 335 ConvertCursor(w); 336 337 if ((attributes->cursor = ((SimpleWidget)w)->simple.cursor) != None) 338 *valueMask |= CWCursor; 339 340 XtCreateWindow(w, InputOutput, (Visual *)CopyFromParent, 341 *valueMask, attributes); 342 343 if (!XtIsSensitive(w)) 344 w->core.border_pixmap = border_pixmap; 345 346#ifndef OLDXAW 347 if (w->core.background_pixmap > XtUnspecifiedPixmap) { 348 pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w), 349 w->core.colormap, w->core.depth); 350 if (pixmap && pixmap->mask) 351 XawReshapeWidget(w, pixmap); 352 } 353 354 if (((SimpleWidget)w)->simple.tip) 355 XawTipEnable(w); 356#endif 357} 358 359/* 360 * Function: 361 * ConvertCursor 362 * 363 * Parameters: 364 * w - simple widget 365 * 366 * Description: 367 * Converts a name to a new cursor. 368 */ 369static void 370ConvertCursor(Widget w) 371{ 372 SimpleWidget simple = (SimpleWidget) w; 373 XrmValue from, to; 374 Cursor cursor = None; 375 376 if (simple->simple.cursor_name == NULL) 377 return; 378 379 from.addr = (XPointer)simple->simple.cursor_name; 380 from.size = strlen((char *)from.addr) + 1; 381 382 to.size = sizeof(Cursor); 383 to.addr = (XPointer)&cursor; 384 385 if (XtConvertAndStore(w, XtRString, &from, XtRColorCursor, &to)) 386 simple->simple.cursor = cursor; 387 else 388 XtAppErrorMsg(XtWidgetToApplicationContext(w), 389 "convertFailed","ConvertCursor","XawError", 390 "Simple: ConvertCursor failed.", 391 NULL, NULL); 392} 393 394 395/*ARGSUSED*/ 396static Boolean 397XawSimpleSetValues(Widget current, Widget request, Widget cnew, 398 ArgList args, Cardinal *num_args) 399{ 400 SimpleWidget s_old = (SimpleWidget)current; 401 SimpleWidget s_new = (SimpleWidget)cnew; 402 Bool new_cursor = False; 403 404 /* this disables user changes after creation */ 405 s_new->simple.international = s_old->simple.international; 406 407 if (XtIsSensitive(current) != XtIsSensitive(cnew)) 408 (*((SimpleWidgetClass)XtClass(cnew))->simple_class.change_sensitive) 409 (cnew); 410 411 if (s_old->simple.cursor != s_new->simple.cursor) 412 new_cursor = True; 413 414 /* 415 * We are not handling the string cursor_name correctly here 416 */ 417 418 if (s_old->simple.pointer_fg != s_new->simple.pointer_fg || 419 s_old->simple.pointer_bg != s_new->simple.pointer_bg || 420 s_old->simple.cursor_name != s_new->simple.cursor_name) { 421 ConvertCursor(cnew); 422 new_cursor = True; 423 } 424 425 if (new_cursor && XtIsRealized(cnew)) { 426 if (s_new->simple.cursor != None) 427 XDefineCursor(XtDisplay(cnew), XtWindow(cnew), s_new->simple.cursor); 428 else 429 XUndefineCursor(XtDisplay(cnew), XtWindow(cnew)); 430 } 431 432#ifndef OLDXAW 433 if (s_old->core.background_pixmap != s_new->core.background_pixmap) { 434 XawPixmap *opix, *npix; 435 436 opix = XawPixmapFromXPixmap(s_old->core.background_pixmap, 437 XtScreen(s_old), s_old->core.colormap, 438 s_old->core.depth); 439 npix = XawPixmapFromXPixmap(s_new->core.background_pixmap, 440 XtScreen(s_new), s_new->core.colormap, 441 s_new->core.depth); 442 if ((npix && npix->mask) || (opix && opix->mask)) 443 XawReshapeWidget(cnew, npix); 444 } 445 446 if (s_old->simple.tip != s_new->simple.tip) { 447 if (s_old->simple.tip) 448 XtFree((XtPointer)s_old->simple.tip); 449 if (s_new->simple.tip) 450 s_new->simple.tip = XtNewString(s_new->simple.tip); 451 } 452 453 if (s_old->simple.tip && !s_new->simple.tip) 454 XawTipDisable(cnew); 455 else if (!s_old->simple.tip && s_new->simple.tip) 456 XawTipEnable(cnew); 457 458 if (s_old->simple.display_list != s_new->simple.display_list) 459 return (True); 460#endif /* OLDXAW */ 461 462 return (False); 463} 464 465#ifndef OLDXAW 466static void 467XawSimpleExpose(Widget w, XEvent *event, Region region) 468{ 469 SimpleWidget xaw = (SimpleWidget)w; 470 471 if (xaw->simple.display_list) 472 XawRunDisplayList(w, xaw->simple.display_list, event, region); 473} 474#endif 475 476static Bool 477ChangeSensitive(Widget w) 478{ 479 if (XtIsRealized(w)) { 480 if (XtIsSensitive(w)) 481 if (w->core.border_pixmap != XtUnspecifiedPixmap) 482 XSetWindowBorderPixmap(XtDisplay(w), XtWindow(w), 483 w->core.border_pixmap); 484 else 485 XSetWindowBorder(XtDisplay(w), XtWindow(w), 486 w->core.border_pixel); 487 else { 488 if (((SimpleWidget)w)->simple.insensitive_border == None) 489 ((SimpleWidget)w)->simple.insensitive_border = 490 XmuCreateStippledPixmap(XtScreen(w), 491 w->core.border_pixel, 492 w->core.background_pixel, 493 w->core.depth); 494 XSetWindowBorderPixmap(XtDisplay(w), XtWindow(w), 495 ((SimpleWidget)w)->simple.insensitive_border); 496 } 497 } 498 499 return (False); 500} 501