Dialog.c revision 775e7de9
1/* $Xorg: Dialog.c,v 1.4 2001/02/09 02:03:43 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/* $XFree86: xc/lib/Xaw/Dialog.c,v 1.7 2001/01/17 19:42:26 dawes Exp $ */ 50 51#ifdef HAVE_CONFIG_H 52#include <config.h> 53#endif 54#include <X11/IntrinsicP.h> 55#include <X11/StringDefs.h> 56#include <X11/Xos.h> 57#include <X11/Xmu/Misc.h> 58#include <X11/Xaw/AsciiText.h> 59#include <X11/Xaw/Cardinals.h> 60#include <X11/Xaw/Command.h> 61#include <X11/Xaw/Label.h> 62#include <X11/Xaw/DialogP.h> 63#include <X11/Xaw/XawInit.h> 64#include "Private.h" 65 66/* 67 * After we have set the string in the value widget we set the 68 * string to a magic value. So that when a SetValues request is made 69 * on the dialog value we will notice it, and reset the string 70 */ 71#define MAGIC_VALUE ((char *)3) 72 73#define streq(a,b) (strcmp((a), (b)) == 0) 74 75/* 76 * Class Methods 77 */ 78static void XawDialogConstraintInitialize(Widget, Widget, 79 ArgList, Cardinal*); 80static void XawDialogGetValuesHook(Widget, ArgList, Cardinal*); 81static void XawDialogInitialize(Widget, Widget, ArgList, Cardinal*); 82static Boolean XawDialogSetValues(Widget, Widget, Widget, 83 ArgList, Cardinal*); 84 85/* 86 * Prototypes 87 */ 88static void CreateDialogValueWidget(Widget); 89 90/* 91 * Initialization 92 */ 93static XtResource resources[] = { 94 { 95 XtNlabel, 96 XtCLabel, 97 XtRString, 98 sizeof(String), 99 XtOffsetOf(DialogRec, dialog.label), 100 XtRString, 101 NULL 102 }, 103 { 104 XtNvalue, 105 XtCValue, 106 XtRString, 107 sizeof(String), 108 XtOffsetOf(DialogRec, dialog.value), 109 XtRString, 110 NULL 111 }, 112 { 113 XtNicon, 114 XtCIcon, 115 XtRBitmap, 116 sizeof(Pixmap), 117 XtOffsetOf(DialogRec, dialog.icon), 118 XtRImmediate, 119 NULL 120 }, 121}; 122 123DialogClassRec dialogClassRec = { 124 /* core */ 125 { 126 (WidgetClass)&formClassRec, /* superclass */ 127 "Dialog", /* class_name */ 128 sizeof(DialogRec), /* widget_size */ 129 XawInitializeWidgetSet, /* class_initialize */ 130 NULL, /* class_part init */ 131 False, /* class_inited */ 132 XawDialogInitialize, /* initialize */ 133 NULL, /* initialize_hook */ 134 XtInheritRealize, /* realize */ 135 NULL, /* actions */ 136 0, /* num_actions */ 137 resources, /* resources */ 138 XtNumber(resources), /* num_resources */ 139 NULLQUARK, /* xrm_class */ 140 True, /* compress_motion */ 141 True, /* compress_exposure */ 142 True, /* compress_enterleave */ 143 False, /* visible_interest */ 144 NULL, /* destroy */ 145 XtInheritResize, /* resize */ 146 XtInheritExpose, /* expose */ 147 XawDialogSetValues, /* set_values */ 148 NULL, /* set_values_hook */ 149 XtInheritSetValuesAlmost, /* set_values_almost */ 150 XawDialogGetValuesHook, /* get_values_hook */ 151 NULL, /* accept_focus */ 152 XtVersion, /* version */ 153 NULL, /* callback_private */ 154 NULL, /* tm_table */ 155 XtInheritQueryGeometry, /* query_geometry */ 156 XtInheritDisplayAccelerator, /* display_accelerator */ 157 NULL, /* extension */ 158 }, 159 /* composite */ 160 { 161 XtInheritGeometryManager, /* geometry_manager */ 162 XtInheritChangeManaged, /* change_managed */ 163 XtInheritInsertChild, /* insert_child */ 164 XtInheritDeleteChild, /* delete_child */ 165 NULL, /* extension */ 166 }, 167 /* constraint */ 168 { 169 NULL, /* subresourses */ 170 0, /* subresource_count */ 171 sizeof(DialogConstraintsRec), /* constraint_size */ 172 XawDialogConstraintInitialize, /* initialize */ 173 NULL, /* destroy */ 174 NULL, /* set_values */ 175 NULL, /* extension */ 176 }, 177 /* form */ 178 { 179 XtInheritLayout, /* layout */ 180 }, 181 /* dialog */ 182 { 183 NULL, /* extension */ 184 } 185}; 186 187WidgetClass dialogWidgetClass = (WidgetClass)&dialogClassRec; 188 189/* 190 * Implementation 191 */ 192/*ARGSUSED*/ 193static void 194XawDialogInitialize(Widget request, Widget cnew, 195 ArgList args, Cardinal *num_args) 196{ 197 DialogWidget dw = (DialogWidget)cnew; 198 Arg arglist[9]; 199 Cardinal arg_cnt = 0; 200 201 XtSetArg(arglist[arg_cnt], XtNborderWidth, 0); arg_cnt++; 202 XtSetArg(arglist[arg_cnt], XtNleft, XtChainLeft); arg_cnt++; 203 204 if (dw->dialog.icon != (Pixmap)0) { 205 XtSetArg(arglist[arg_cnt], XtNbitmap, dw->dialog.icon); arg_cnt++; 206 XtSetArg(arglist[arg_cnt], XtNright, XtChainLeft); arg_cnt++; 207 dw->dialog.iconW = XtCreateManagedWidget("icon", labelWidgetClass, 208 cnew, arglist, arg_cnt); 209 arg_cnt = 2; 210 XtSetArg(arglist[arg_cnt], XtNfromHoriz, dw->dialog.iconW); arg_cnt++; 211 } 212 else 213 dw->dialog.iconW = NULL; 214 215 XtSetArg(arglist[arg_cnt], XtNlabel, dw->dialog.label); arg_cnt++; 216 XtSetArg(arglist[arg_cnt], XtNright, XtChainRight); arg_cnt++; 217 218 dw->dialog.labelW = XtCreateManagedWidget("label", labelWidgetClass, 219 cnew, arglist, arg_cnt); 220 221 if (dw->dialog.iconW != NULL && 222 XtHeight(dw->dialog.labelW) < XtHeight(dw->dialog.iconW)) { 223 XtSetArg(arglist[0], XtNheight, XtHeight(dw->dialog.iconW)); 224 XtSetValues(dw->dialog.labelW, arglist, 1); 225 } 226 if (dw->dialog.value != NULL) 227 CreateDialogValueWidget((Widget)dw); 228 else 229 dw->dialog.valueW = NULL; 230} 231 232/*ARGSUSED*/ 233static void 234XawDialogConstraintInitialize(Widget request, Widget cnew, 235 ArgList args, Cardinal *num_args) 236{ 237 DialogWidget dw = (DialogWidget)cnew->core.parent; 238 DialogConstraints constraint = (DialogConstraints)cnew->core.constraints; 239 240 if (!XtIsSubclass(cnew, commandWidgetClass)) /* if not a button */ 241 return; /* then just use defaults */ 242 243 constraint->form.left = constraint->form.right = XtChainLeft; 244 if (dw->dialog.valueW == NULL) 245 constraint->form.vert_base = dw->dialog.labelW; 246 else 247 constraint->form.vert_base = dw->dialog.valueW; 248 249 if (dw->composite.num_children > 1) { 250 WidgetList children = dw->composite.children; 251 Widget *childP; 252 253 for (childP = children + dw->composite.num_children - 1; 254 childP >= children; childP-- ) { 255 if (*childP == dw->dialog.labelW || *childP == dw->dialog.valueW) 256 break; 257 if (XtIsManaged(*childP) && 258 XtIsSubclass(*childP, commandWidgetClass)) { 259 constraint->form.horiz_base = *childP; 260 break; 261 } 262 } 263 } 264} 265 266#define ICON 0 267#define LABEL 1 268#define NUM_CHECKS 2 269/*ARGSUSED*/ 270static Boolean 271XawDialogSetValues(Widget current, Widget request, Widget cnew, 272 ArgList in_args, Cardinal *in_num_args) 273{ 274 DialogWidget w = (DialogWidget)cnew; 275 DialogWidget old = (DialogWidget)current; 276 Arg args[5]; 277 Cardinal num_args; 278 unsigned int i; 279 Bool checks[NUM_CHECKS]; 280 281 for (i = 0; i < NUM_CHECKS; i++) 282 checks[i] = False; 283 284 for (i = 0; i < *in_num_args; i++) { 285 if (streq(XtNicon, in_args[i].name)) 286 checks[ICON] = True; 287 else if (streq(XtNlabel, in_args[i].name)) 288 checks[LABEL] = True; 289 } 290 291 if (checks[ICON]) { 292 if (w->dialog.icon != 0) { 293 XtSetArg(args[0], XtNbitmap, w->dialog.icon); 294 if (old->dialog.iconW != NULL) 295 XtSetValues(old->dialog.iconW, args, 1); 296 else { 297 XtSetArg(args[1], XtNborderWidth, 0); 298 XtSetArg(args[2], XtNleft, XtChainLeft); 299 XtSetArg(args[3], XtNright, XtChainLeft); 300 w->dialog.iconW = XtCreateWidget("icon", labelWidgetClass, 301 cnew, args, 4); 302 ((DialogConstraints)w->dialog.labelW->core.constraints)-> 303 form.horiz_base = w->dialog.iconW; 304 XtManageChild(w->dialog.iconW); 305 } 306 } 307 else if (old->dialog.icon != 0) { 308 ((DialogConstraints)w->dialog.labelW->core.constraints)-> 309 form.horiz_base = NULL; 310 XtDestroyWidget(old->dialog.iconW); 311 w->dialog.iconW = NULL; 312 } 313 } 314 315 if (checks[LABEL]) { 316 num_args = 0; 317 XtSetArg(args[num_args], XtNlabel, w->dialog.label); num_args++; 318 if (w->dialog.iconW != NULL && 319 XtHeight(w->dialog.labelW) <= XtHeight(w->dialog.iconW)) { 320 XtSetArg(args[num_args], XtNheight, XtHeight(w->dialog.iconW)); 321 num_args++; 322 } 323 XtSetValues(w->dialog.labelW, args, num_args); 324 } 325 326 if (w->dialog.value != old->dialog.value) { 327 if (w->dialog.value == NULL) /* only get here if it 328 wasn't NULL before */ 329 XtDestroyWidget(old->dialog.valueW); 330 else if (old->dialog.value == NULL) { /* create a new value widget */ 331 XtWidth(w) = XtWidth(old); 332 XtHeight(w) = XtHeight(old); 333 CreateDialogValueWidget(cnew); 334 } 335 else { /* Widget ok, just change string */ 336 Arg nargs[1]; 337 338 XtSetArg(nargs[0], XtNstring, w->dialog.value); 339 XtSetValues(w->dialog.valueW, nargs, 1); 340 w->dialog.value = MAGIC_VALUE; 341 } 342 } 343 344 return (False); 345} 346 347/* 348 * Function: 349 * XawDialogGetValuesHook 350 * 351 * Parameters: 352 * w - Dialog Widget 353 * args - argument list 354 * num_args - number of args 355 * 356 * Description: 357 * This is a get values hook routine that gets the values in the dialog. 358 */ 359static void 360XawDialogGetValuesHook(Widget w, ArgList args, Cardinal *num_args) 361{ 362 Arg a[1]; 363 String s; 364 DialogWidget src = (DialogWidget)w; 365 unsigned int i; 366 367 for (i = 0; i < *num_args; i++) 368 if (streq(args[i].name, XtNvalue)) { 369 XtSetArg(a[0], XtNstring, &s); 370 XtGetValues(src->dialog.valueW, a, 1); 371 *((char **)args[i].value) = s; 372 } 373 else if (streq(args[i].name, XtNlabel)) { 374 XtSetArg(a[0], XtNlabel, &s); 375 XtGetValues(src->dialog.labelW, a, 1); 376 *((char **)args[i].value) = s; 377 } 378} 379 380/* 381 * Function: 382 * CreateDialogValueWidget 383 * 384 * Parameters: 385 * w - dialog widget 386 * 387 * Description: 388 * Creates the dialog widgets value widget. 389 * 390 * Note 391 * Must be called only when w->dialog.value is non-nil 392 */ 393static void 394CreateDialogValueWidget(Widget w) 395{ 396 DialogWidget dw = (DialogWidget)w; 397 Arg arglist[10]; 398 Cardinal num_args = 0; 399 400 XtSetArg(arglist[num_args], XtNstring, dw->dialog.value); num_args++; 401 XtSetArg(arglist[num_args], XtNresizable, True); num_args++; 402 XtSetArg(arglist[num_args], XtNeditType, XawtextEdit); num_args++; 403 XtSetArg(arglist[num_args], XtNfromVert, dw->dialog.labelW); num_args++; 404 XtSetArg(arglist[num_args], XtNleft, XtChainLeft); num_args++; 405 XtSetArg(arglist[num_args], XtNright, XtChainRight); num_args++; 406 407 dw->dialog.valueW = XtCreateWidget("value", asciiTextWidgetClass, 408 w, arglist, num_args); 409 410 /* if the value widget is being added after buttons, 411 * then the buttons need new layout constraints 412 */ 413 if (dw->composite.num_children > 1) { 414 WidgetList children = dw->composite.children; 415 Widget *childP; 416 417 for (childP = children + dw->composite.num_children - 1; 418 childP >= children; childP-- ) { 419 if (*childP == dw->dialog.labelW || *childP == dw->dialog.valueW) 420 continue; 421 422 if (XtIsManaged(*childP) && 423 XtIsSubclass(*childP, commandWidgetClass)) { 424 ((DialogConstraints)(*childP)->core.constraints)-> 425 form.vert_base = dw->dialog.valueW; 426 } 427 } 428 } 429 XtManageChild(dw->dialog.valueW); 430 431 /* 432 * Value widget gets the keyboard focus 433 */ 434 XtSetKeyboardFocus(w, dw->dialog.valueW); 435 dw->dialog.value = MAGIC_VALUE; 436} 437 438void 439XawDialogAddButton(Widget dialog, _Xconst char* name, XtCallbackProc function, 440 XtPointer param) 441{ 442 /* 443 * Correct Constraints are all set in ConstraintInitialize() 444 */ 445 Widget button; 446 447 button = XtCreateManagedWidget(name, commandWidgetClass, dialog, NULL, 0); 448 449 if (function != NULL) /* don't add NULL callback func */ 450 XtAddCallback(button, XtNcallback, function, param); 451} 452 453char * 454XawDialogGetValueString(Widget w) 455{ 456 Arg args[1]; 457 char *value; 458 459 XtSetArg(args[0], XtNstring, &value); 460 XtGetValues(((DialogWidget)w)->dialog.valueW, args, 1); 461 462 return(value); 463} 464