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