Home | History | Annotate | Line # | Download | only in src
      1 /***********************************************************
      2 
      3 Copyright 1987, 1988, 1994, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included in
     12 all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20 
     21 Except as contained in this notice, the name of The Open Group shall not be
     22 used in advertising or otherwise to promote the sale, use or other dealings
     23 in this Software without prior written authorization from The Open Group.
     24 
     25 
     26 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
     27 
     28                         All Rights Reserved
     29 
     30 Permission to use, copy, modify, and distribute this software and its
     31 documentation for any purpose and without fee is hereby granted,
     32 provided that the above copyright notice appear in all copies and that
     33 both that copyright notice and this permission notice appear in
     34 supporting documentation, and that the name of Digital not be
     35 used in advertising or publicity pertaining to distribution of the
     36 software without specific, written prior permission.
     37 
     38 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
     39 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
     40 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
     41 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
     42 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
     43 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     44 SOFTWARE.
     45 
     46 ******************************************************************/
     47 
     48 #ifdef HAVE_CONFIG_H
     49 #include <config.h>
     50 #endif
     51 #include <X11/IntrinsicP.h>
     52 #include <X11/StringDefs.h>
     53 #include <X11/Xos.h>
     54 #include <X11/Xmu/Misc.h>
     55 #include <X11/Xaw/AsciiText.h>
     56 #include <X11/Xaw/Cardinals.h>
     57 #include <X11/Xaw/Command.h>
     58 #include <X11/Xaw/Label.h>
     59 #include <X11/Xaw/DialogP.h>
     60 #include <X11/Xaw/XawInit.h>
     61 #include "Private.h"
     62 
     63 /*
     64  * After we have set the string in the value widget we set the
     65  * string to a magic value.  So that when a SetValues request is made
     66  * on the dialog value we will notice it, and reset the string
     67  */
     68 #define MAGIC_VALUE	((char *)3)
     69 
     70 #define streq(a,b)	(strcmp((a), (b)) == 0)
     71 
     72 /*
     73  * Class Methods
     74  */
     75 static void XawDialogConstraintInitialize(Widget, Widget,
     76 					  ArgList, Cardinal*);
     77 static void XawDialogGetValuesHook(Widget, ArgList, Cardinal*);
     78 static void XawDialogInitialize(Widget, Widget, ArgList, Cardinal*);
     79 static Boolean XawDialogSetValues(Widget, Widget, Widget,
     80 				  ArgList, Cardinal*);
     81 
     82 /*
     83  * Prototypes
     84  */
     85 static void CreateDialogValueWidget(Widget);
     86 
     87 /*
     88  * Initialization
     89  */
     90 static XtResource resources[] = {
     91   {
     92     XtNlabel,
     93     XtCLabel,
     94     XtRString,
     95     sizeof(String),
     96     XtOffsetOf(DialogRec, dialog.label),
     97     XtRString,
     98     NULL
     99   },
    100   {
    101     XtNvalue,
    102     XtCValue,
    103     XtRString,
    104     sizeof(String),
    105     XtOffsetOf(DialogRec, dialog.value),
    106     XtRString,
    107     NULL
    108   },
    109   {
    110     XtNicon,
    111     XtCIcon,
    112     XtRBitmap,
    113     sizeof(Pixmap),
    114     XtOffsetOf(DialogRec, dialog.icon),
    115     XtRImmediate,
    116     NULL
    117   },
    118 };
    119 
    120 DialogClassRec dialogClassRec = {
    121   /* core */
    122   {
    123     (WidgetClass)&formClassRec,		/* superclass */
    124     "Dialog",				/* class_name */
    125     sizeof(DialogRec),			/* widget_size */
    126     XawInitializeWidgetSet,		/* class_initialize */
    127     NULL,				/* class_part init */
    128     False,				/* class_inited */
    129     XawDialogInitialize,		/* initialize */
    130     NULL,				/* initialize_hook */
    131     XtInheritRealize,			/* realize */
    132     NULL,				/* actions */
    133     0,					/* num_actions */
    134     resources,				/* resources */
    135     XtNumber(resources),		/* num_resources */
    136     NULLQUARK,				/* xrm_class */
    137     True,				/* compress_motion */
    138     True,				/* compress_exposure */
    139     True,				/* compress_enterleave */
    140     False,				/* visible_interest */
    141     NULL,				/* destroy */
    142     XtInheritResize,			/* resize */
    143     XtInheritExpose,			/* expose */
    144     XawDialogSetValues,			/* set_values */
    145     NULL,				/* set_values_hook */
    146     XtInheritSetValuesAlmost,		/* set_values_almost */
    147     XawDialogGetValuesHook,		/* get_values_hook */
    148     NULL,				/* accept_focus */
    149     XtVersion,				/* version */
    150     NULL,				/* callback_private */
    151     NULL,				/* tm_table */
    152     XtInheritQueryGeometry,		/* query_geometry */
    153     XtInheritDisplayAccelerator,	/* display_accelerator */
    154     NULL,				/* extension */
    155   },
    156   /* composite */
    157   {
    158     XtInheritGeometryManager,		/* geometry_manager */
    159     XtInheritChangeManaged,		/* change_managed */
    160     XtInheritInsertChild,		/* insert_child */
    161     XtInheritDeleteChild,		/* delete_child */
    162     NULL,				/* extension */
    163   },
    164   /* constraint */
    165   {
    166     NULL,				/* subresourses */
    167     0,					/* subresource_count */
    168     sizeof(DialogConstraintsRec),	/* constraint_size */
    169     XawDialogConstraintInitialize,	/* initialize */
    170     NULL,				/* destroy */
    171     NULL,				/* set_values */
    172     NULL,				/* extension */
    173   },
    174   /* form */
    175   {
    176     XtInheritLayout,			/* layout */
    177 #ifndef OLDXAW
    178     NULL,
    179 #endif
    180   },
    181   /* dialog */
    182   {
    183     NULL,				/* extension */
    184   }
    185 };
    186 
    187 WidgetClass dialogWidgetClass = (WidgetClass)&dialogClassRec;
    188 
    189 /*
    190  * Implementation
    191  */
    192 /*ARGSUSED*/
    193 static void
    194 XawDialogInitialize(Widget request _X_UNUSED, Widget cnew,
    195 		    ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
    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*/
    233 static void
    234 XawDialogConstraintInitialize(Widget request _X_UNUSED, Widget cnew,
    235 			      ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
    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*/
    270 static Boolean
    271 XawDialogSetValues(Widget current, Widget request _X_UNUSED, 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     unsigned int i;
    278     Bool checks[NUM_CHECKS];
    279 
    280     for (i = 0; i < NUM_CHECKS; i++)
    281 	checks[i] = False;
    282 
    283     for (i = 0; i < *in_num_args; i++) {
    284 	if (streq(XtNicon, in_args[i].name))
    285 	    checks[ICON] = True;
    286 	else if (streq(XtNlabel, in_args[i].name))
    287 	    checks[LABEL] = True;
    288     }
    289 
    290     if (checks[ICON]) {
    291 	if (w->dialog.icon != 0) {
    292 	    XtSetArg(args[0], XtNbitmap, w->dialog.icon);
    293 	    if (old->dialog.iconW != NULL)
    294 		XtSetValues(old->dialog.iconW, args, 1);
    295 	    else {
    296 		XtSetArg(args[1], XtNborderWidth, 0);
    297 		XtSetArg(args[2], XtNleft, XtChainLeft);
    298 		XtSetArg(args[3], XtNright, XtChainLeft);
    299 		w->dialog.iconW = XtCreateWidget("icon", labelWidgetClass,
    300 						 cnew, args, 4);
    301 		((DialogConstraints)w->dialog.labelW->core.constraints)->
    302 		    form.horiz_base = w->dialog.iconW;
    303 		XtManageChild(w->dialog.iconW);
    304 	    }
    305 	}
    306 	else if (old->dialog.icon != 0) {
    307 	    ((DialogConstraints)w->dialog.labelW->core.constraints)->
    308 		form.horiz_base = NULL;
    309 	    XtDestroyWidget(old->dialog.iconW);
    310 	    w->dialog.iconW = NULL;
    311 	}
    312     }
    313 
    314     if (checks[LABEL]) {
    315 	Cardinal num_args = 0;
    316 
    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  */
    359 static void
    360 XawDialogGetValuesHook(Widget w, ArgList args, Cardinal *num_args)
    361 {
    362     Arg a[1];
    363     char * s;
    364     DialogWidget src = (DialogWidget)w;
    365     Cardinal 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 /*
    382  * Function:
    383  *	CreateDialogValueWidget
    384  *
    385  * Parameters:
    386  *	w - dialog widget
    387  *
    388  * Description:
    389  *	Creates the dialog widgets value widget.
    390  *
    391  * Note
    392  *	Must be called only when w->dialog.value is non-nil
    393  */
    394 static void
    395 CreateDialogValueWidget(Widget w)
    396 {
    397     DialogWidget dw = (DialogWidget)w;
    398     Arg arglist[10];
    399     Cardinal num_args = 0;
    400 
    401     XtSetArg(arglist[num_args], XtNstring, dw->dialog.value);     num_args++;
    402     XtSetArg(arglist[num_args], XtNresizable, True);              num_args++;
    403     XtSetArg(arglist[num_args], XtNeditType, XawtextEdit);        num_args++;
    404     XtSetArg(arglist[num_args], XtNfromVert, dw->dialog.labelW);  num_args++;
    405     XtSetArg(arglist[num_args], XtNleft, XtChainLeft);            num_args++;
    406     XtSetArg(arglist[num_args], XtNright, XtChainRight);          num_args++;
    407 
    408     dw->dialog.valueW = XtCreateWidget("value", asciiTextWidgetClass,
    409 				       w, arglist, num_args);
    410 
    411     /* if the value widget is being added after buttons,
    412      * then the buttons need new layout constraints
    413      */
    414     if (dw->composite.num_children > 1) {
    415 	WidgetList children = dw->composite.children;
    416 	Widget *childP;
    417 
    418         for (childP = children + dw->composite.num_children - 1;
    419 	     childP >= children; childP-- ) {
    420 	    if (*childP == dw->dialog.labelW || *childP == dw->dialog.valueW)
    421 		continue;
    422 
    423 	    if (XtIsManaged(*childP) &&
    424 	        XtIsSubclass(*childP, commandWidgetClass)) {
    425 		((DialogConstraints)(*childP)->core.constraints)->
    426 		    form.vert_base = dw->dialog.valueW;
    427 	    }
    428 	}
    429     }
    430     XtManageChild(dw->dialog.valueW);
    431 
    432     /*
    433      * Value widget gets the keyboard focus
    434      */
    435     XtSetKeyboardFocus(w, dw->dialog.valueW);
    436     dw->dialog.value = MAGIC_VALUE;
    437 }
    438 
    439 void
    440 XawDialogAddButton(Widget dialog, _Xconst char* name, XtCallbackProc function,
    441 		   XtPointer param)
    442 {
    443     /*
    444      * Correct Constraints are all set in ConstraintInitialize()
    445      */
    446     Widget button;
    447 
    448     button = XtCreateManagedWidget(name, commandWidgetClass, dialog, NULL, 0);
    449 
    450     if (function != NULL)	/* don't add NULL callback func */
    451 	XtAddCallback(button, XtNcallback, function, param);
    452 }
    453 
    454 char *
    455 XawDialogGetValueString(Widget w)
    456 {
    457     Arg args[1];
    458     char *value;
    459 
    460     XtSetArg(args[0], XtNstring, &value);
    461     XtGetValues(((DialogWidget)w)->dialog.valueW, args, 1);
    462 
    463     return(value);
    464 }
    465