upload tizen1.0 source
[framework/uifw/xorg/lib/libxaw.git] / src / Dialog.c
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   },
178   /* dialog */
179   {
180     NULL,                               /* extension */
181   }
182 };
183
184 WidgetClass dialogWidgetClass = (WidgetClass)&dialogClassRec;
185
186 /*
187  * Implementation
188  */
189 /*ARGSUSED*/
190 static void
191 XawDialogInitialize(Widget request, Widget cnew,
192                     ArgList args, Cardinal *num_args)
193 {
194     DialogWidget dw = (DialogWidget)cnew;
195     Arg arglist[9];
196     Cardinal arg_cnt = 0;
197
198     XtSetArg(arglist[arg_cnt], XtNborderWidth, 0);                  arg_cnt++;
199     XtSetArg(arglist[arg_cnt], XtNleft, XtChainLeft);               arg_cnt++;
200
201     if (dw->dialog.icon != (Pixmap)0) {
202         XtSetArg(arglist[arg_cnt], XtNbitmap, dw->dialog.icon);     arg_cnt++;
203         XtSetArg(arglist[arg_cnt], XtNright, XtChainLeft);          arg_cnt++;
204         dw->dialog.iconW = XtCreateManagedWidget("icon", labelWidgetClass,
205                                                  cnew, arglist, arg_cnt);
206         arg_cnt = 2;
207         XtSetArg(arglist[arg_cnt], XtNfromHoriz, dw->dialog.iconW); arg_cnt++;
208     }
209     else
210         dw->dialog.iconW = NULL;
211
212     XtSetArg(arglist[arg_cnt], XtNlabel, dw->dialog.label);         arg_cnt++;
213     XtSetArg(arglist[arg_cnt], XtNright, XtChainRight);             arg_cnt++;
214
215     dw->dialog.labelW = XtCreateManagedWidget("label", labelWidgetClass,
216                                               cnew, arglist, arg_cnt);
217
218     if (dw->dialog.iconW != NULL &&
219         XtHeight(dw->dialog.labelW) < XtHeight(dw->dialog.iconW)) {
220         XtSetArg(arglist[0], XtNheight, XtHeight(dw->dialog.iconW));
221         XtSetValues(dw->dialog.labelW, arglist, 1);
222     }
223     if (dw->dialog.value != NULL) 
224         CreateDialogValueWidget((Widget)dw);
225     else
226         dw->dialog.valueW = NULL;
227 }
228
229 /*ARGSUSED*/
230 static void
231 XawDialogConstraintInitialize(Widget request, Widget cnew,
232                               ArgList args, Cardinal *num_args)
233 {
234     DialogWidget dw = (DialogWidget)cnew->core.parent;
235     DialogConstraints constraint = (DialogConstraints)cnew->core.constraints;
236
237     if (!XtIsSubclass(cnew, commandWidgetClass)) /* if not a button */
238         return;                                  /* then just use defaults */
239
240     constraint->form.left = constraint->form.right = XtChainLeft;
241     if (dw->dialog.valueW == NULL) 
242         constraint->form.vert_base = dw->dialog.labelW;
243     else
244         constraint->form.vert_base = dw->dialog.valueW;
245
246     if (dw->composite.num_children > 1) {
247         WidgetList children = dw->composite.children;
248         Widget *childP;
249
250         for (childP = children + dw->composite.num_children - 1;
251            childP >= children; childP-- ) {
252             if (*childP == dw->dialog.labelW || *childP == dw->dialog.valueW)
253                 break;
254             if (XtIsManaged(*childP) &&
255                 XtIsSubclass(*childP, commandWidgetClass)) {
256                 constraint->form.horiz_base = *childP;
257                 break;
258             }
259         }
260     }
261 }
262
263 #define ICON 0
264 #define LABEL 1
265 #define NUM_CHECKS 2
266 /*ARGSUSED*/
267 static Boolean
268 XawDialogSetValues(Widget current, Widget request, Widget cnew,
269                    ArgList in_args, Cardinal *in_num_args)
270 {
271     DialogWidget w = (DialogWidget)cnew;
272     DialogWidget old = (DialogWidget)current;
273     Arg args[5];
274     Cardinal num_args;
275     unsigned int i;
276     Bool checks[NUM_CHECKS];
277
278     for (i = 0; i < NUM_CHECKS; i++)
279         checks[i] = False;
280
281     for (i = 0; i < *in_num_args; i++) {
282         if (streq(XtNicon, in_args[i].name))
283             checks[ICON] = True;
284         else if (streq(XtNlabel, in_args[i].name))
285             checks[LABEL] = True;
286     }
287
288     if (checks[ICON]) {
289         if (w->dialog.icon != 0) {
290             XtSetArg(args[0], XtNbitmap, w->dialog.icon);
291             if (old->dialog.iconW != NULL)
292                 XtSetValues(old->dialog.iconW, args, 1);
293             else {
294                 XtSetArg(args[1], XtNborderWidth, 0);
295                 XtSetArg(args[2], XtNleft, XtChainLeft);
296                 XtSetArg(args[3], XtNright, XtChainLeft);
297                 w->dialog.iconW = XtCreateWidget("icon", labelWidgetClass,
298                                                  cnew, args, 4);
299                 ((DialogConstraints)w->dialog.labelW->core.constraints)->
300                     form.horiz_base = w->dialog.iconW;
301                 XtManageChild(w->dialog.iconW);
302             }
303         }
304         else if (old->dialog.icon != 0) {
305             ((DialogConstraints)w->dialog.labelW->core.constraints)->
306                 form.horiz_base = NULL;
307             XtDestroyWidget(old->dialog.iconW);
308             w->dialog.iconW = NULL;
309         }
310     }
311
312     if (checks[LABEL]) {
313         num_args = 0;
314         XtSetArg(args[num_args], XtNlabel, w->dialog.label);    num_args++;
315         if (w->dialog.iconW != NULL &&
316             XtHeight(w->dialog.labelW) <= XtHeight(w->dialog.iconW)) {
317             XtSetArg(args[num_args], XtNheight, XtHeight(w->dialog.iconW));
318             num_args++;
319         }
320         XtSetValues(w->dialog.labelW, args, num_args);
321     }
322
323     if (w->dialog.value != old->dialog.value) {
324         if (w->dialog.value == NULL)    /* only get here if it
325                                            wasn't NULL before */
326             XtDestroyWidget(old->dialog.valueW);
327         else if (old->dialog.value == NULL) {   /* create a new value widget */
328             XtWidth(w) = XtWidth(old);
329             XtHeight(w) = XtHeight(old);
330             CreateDialogValueWidget(cnew);
331         }
332         else {                          /* Widget ok, just change string */
333             Arg nargs[1];
334
335             XtSetArg(nargs[0], XtNstring, w->dialog.value);
336             XtSetValues(w->dialog.valueW, nargs, 1);
337             w->dialog.value = MAGIC_VALUE;
338         }
339     }
340
341     return (False);
342 }
343
344 /*
345  * Function:
346  *      XawDialogGetValuesHook
347  *
348  * Parameters:
349  *      w        - Dialog Widget
350  *      args     - argument list
351  *      num_args - number of args
352  *
353  * Description:
354  *      This is a get values hook routine that gets the values in the dialog.
355  */
356 static void
357 XawDialogGetValuesHook(Widget w, ArgList args, Cardinal *num_args)
358 {
359     Arg a[1];
360     String s;
361     DialogWidget src = (DialogWidget)w;
362     unsigned int i;
363   
364     for (i = 0; i < *num_args; i++)
365         if (streq(args[i].name, XtNvalue)) {
366             XtSetArg(a[0], XtNstring, &s);
367             XtGetValues(src->dialog.valueW, a, 1);
368             *((char **)args[i].value) = s;
369         }
370         else if (streq(args[i].name, XtNlabel)) {
371             XtSetArg(a[0], XtNlabel, &s);
372             XtGetValues(src->dialog.labelW, a, 1);
373             *((char **)args[i].value) = s;
374         }
375 }
376
377 /*
378  * Function:
379  *      CreateDialogValueWidget
380  *
381  * Parameters:
382  *      w - dialog widget
383  *
384  * Description:
385  *      Creates the dialog widgets value widget.
386  *
387  * Note
388  *      Must be called only when w->dialog.value is non-nil
389  */
390 static void
391 CreateDialogValueWidget(Widget w)
392 {
393     DialogWidget dw = (DialogWidget)w;
394     Arg arglist[10];
395     Cardinal num_args = 0;
396
397     XtSetArg(arglist[num_args], XtNstring, dw->dialog.value);     num_args++;
398     XtSetArg(arglist[num_args], XtNresizable, True);              num_args++;
399     XtSetArg(arglist[num_args], XtNeditType, XawtextEdit);        num_args++;
400     XtSetArg(arglist[num_args], XtNfromVert, dw->dialog.labelW);  num_args++;
401     XtSetArg(arglist[num_args], XtNleft, XtChainLeft);            num_args++;
402     XtSetArg(arglist[num_args], XtNright, XtChainRight);          num_args++;
403
404     dw->dialog.valueW = XtCreateWidget("value", asciiTextWidgetClass,
405                                        w, arglist, num_args);
406
407     /* if the value widget is being added after buttons,
408      * then the buttons need new layout constraints
409      */
410     if (dw->composite.num_children > 1) {
411         WidgetList children = dw->composite.children;
412         Widget *childP;
413
414         for (childP = children + dw->composite.num_children - 1;
415              childP >= children; childP-- ) {
416             if (*childP == dw->dialog.labelW || *childP == dw->dialog.valueW)
417                 continue;
418
419             if (XtIsManaged(*childP) &&
420                 XtIsSubclass(*childP, commandWidgetClass)) {
421                 ((DialogConstraints)(*childP)->core.constraints)->
422                     form.vert_base = dw->dialog.valueW;
423             }
424         }
425     }
426     XtManageChild(dw->dialog.valueW);
427
428     /*
429      * Value widget gets the keyboard focus
430      */
431     XtSetKeyboardFocus(w, dw->dialog.valueW);
432     dw->dialog.value = MAGIC_VALUE;
433 }
434
435 void
436 XawDialogAddButton(Widget dialog, _Xconst char* name, XtCallbackProc function,
437                    XtPointer param)
438 {
439     /*
440      * Correct Constraints are all set in ConstraintInitialize()
441      */
442     Widget button;
443
444     button = XtCreateManagedWidget(name, commandWidgetClass, dialog, NULL, 0);
445
446     if (function != NULL)       /* don't add NULL callback func */
447         XtAddCallback(button, XtNcallback, function, param);
448 }
449
450 char *
451 XawDialogGetValueString(Widget w)
452 {
453     Arg args[1];
454     char *value;
455
456     XtSetArg(args[0], XtNstring, &value);
457     XtGetValues(((DialogWidget)w)->dialog.valueW, args, 1);
458
459     return(value);
460 }