Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2 
      3 Copyright 1989, 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
     12 in all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 OTHER DEALINGS IN THE SOFTWARE.
     21 
     22 Except as contained in this notice, the name of The Open Group shall
     23 not be used in advertising or otherwise to promote the sale, use or
     24 other dealings in this Software without prior written authorization
     25 from The Open Group.
     26 
     27 */
     28 
     29 /*
     30  * Author:  Davor Matic, MIT X Consortium
     31  */
     32 
     33 #ifdef HAVE_CONFIG_H
     34 # include "config.h"
     35 #endif
     36 
     37 #include <X11/Intrinsic.h>
     38 #include <X11/StringDefs.h>
     39 #include <X11/Shell.h>
     40 #include <X11/Xaw/Dialog.h>
     41 #include <X11/Xaw/Command.h>
     42 #include <X11/Xmu/CharSet.h>
     43 
     44 #include "Dialog.h"
     45 
     46 #define min(x, y)                     (((x) < (y)) ? (x) : (y))
     47 #define max(x, y)                     (((x) > (y)) ? (x) : (y))
     48 
     49 
     50 static void SetDialogButton(Widget w, XEvent *event,
     51 			    String *argv, Cardinal *argc);
     52 
     53 static XtActionsRec actions_table[] = {
     54   {"set-dialog-button", SetDialogButton},
     55 };
     56 
     57 static DialogButton dialog_buttons[] = {
     58     {"yes", Yes},
     59     {"no", No},
     60     {"maybe", Maybe},
     61     {"okay", Okay},
     62     {"abort", Abort},
     63     {"cancel", Cancel},
     64     {"retry", Retry},
     65 };
     66 
     67 static unsigned long selected;
     68 
     69 /* ARGSUSED */
     70 static void
     71 SetSelected(Widget w, XtPointer clientData, XtPointer callData) /* ARGSUSED */
     72 {
     73     String name = (String)clientData;
     74 
     75     for (Cardinal i = 0; i < XtNumber(dialog_buttons); i++)
     76 	if (!strcmp(dialog_buttons[i].name, name))
     77 	    selected |= dialog_buttons[i].flag;
     78 }
     79 
     80 /* ARGSUSED */
     81 static void
     82 SetDialogButton(Widget w,	/* not used */
     83 		XEvent *event,	/* not used */
     84 		String *argv,
     85 		Cardinal *argc)
     86 {
     87   char button_name[80];
     88   XtPointer dummy = NULL;
     89 
     90   for (Cardinal i = 0; i < *argc; i++) {
     91     XmuCopyISOLatin1Lowered (button_name, argv[i]);
     92     SetSelected(w, button_name, dummy);
     93   }
     94 }
     95 
     96 static Boolean firstTime = True;
     97 
     98 Dialog
     99 CreateDialog(Widget top_widget, String name, unsigned long options)
    100 {
    101     Dialog popup;
    102 
    103     popup = (Dialog) XtMalloc(sizeof(_Dialog));
    104 
    105     if (! popup)
    106       return NULL;
    107 
    108      if (firstTime) {
    109 	  XtAddActions(actions_table, XtNumber(actions_table));
    110 	  firstTime = False;
    111 	}
    112 	popup->top_widget = top_widget;
    113 	popup->shell_widget = XtCreatePopupShell(name,
    114 						 transientShellWidgetClass,
    115 						 top_widget, NULL, 0);
    116 	popup->dialog_widget = XtCreateManagedWidget("dialog",
    117 						     dialogWidgetClass,
    118 						     popup->shell_widget,
    119 						     NULL, 0);
    120 	for (Cardinal i = 0; i < XtNumber(dialog_buttons); i++)
    121 	    if (options & dialog_buttons[i].flag)
    122 		XawDialogAddButton(popup->dialog_widget,
    123 				   dialog_buttons[i].name,
    124 				   SetSelected, (XtPointer)dialog_buttons[i].name);
    125 	popup->options = options;
    126 	return popup;
    127 }
    128 
    129 void
    130 PopdownDialog(Dialog popup, _XtString *answer)
    131 {
    132     if (answer)
    133 	*answer = XawDialogGetValueString(popup->dialog_widget);
    134 
    135     XtPopdown(popup->shell_widget);
    136 }
    137 
    138 unsigned long
    139 PopupDialog(Dialog popup, String message, String suggestion,
    140 	    _XtString *answer, XtGrabKind grab)
    141 {
    142   Position popup_x, popup_y, top_x, top_y;
    143   Dimension popup_width, popup_height, top_width, top_height, border_width;
    144   int n;
    145   Arg wargs[4];
    146 
    147   n = 0;
    148   XtSetArg(wargs[n], XtNlabel, message); n++;
    149   XtSetArg(wargs[n], XtNvalue, suggestion); n++;
    150   XtSetValues(popup->dialog_widget, wargs, n);
    151 
    152   XtRealizeWidget(popup->shell_widget);
    153 
    154   n = 0;
    155   XtSetArg(wargs[n], XtNx, &top_x); n++;
    156   XtSetArg(wargs[n], XtNy, &top_y); n++;
    157   XtSetArg(wargs[n], XtNwidth, &top_width); n++;
    158   XtSetArg(wargs[n], XtNheight, &top_height); n++;
    159   XtGetValues(popup->top_widget, wargs, n);
    160 
    161   n = 0;
    162   XtSetArg(wargs[n], XtNwidth, &popup_width); n++;
    163   XtSetArg(wargs[n], XtNheight, &popup_height); n++;
    164   XtSetArg(wargs[n], XtNborderWidth, &border_width); n++;
    165   XtGetValues(popup->shell_widget, wargs, n);
    166 
    167   popup_x = max(0,
    168 	min(top_x + ((Position)top_width - (Position)popup_width) / 2,
    169 	    (Position)DisplayWidth(XtDisplay(popup->shell_widget),
    170 		   DefaultScreen(XtDisplay(popup->shell_widget))) -
    171 	    (Position)popup_width - 2 * (Position)border_width));
    172   popup_y = max(0,
    173 	min(top_y + ((Position)top_height - (Position)popup_height) / 2,
    174 	    (Position)DisplayHeight(XtDisplay(popup->shell_widget),
    175 		    DefaultScreen(XtDisplay(popup->shell_widget))) -
    176 	    (Position)popup_height - 2 * (Position)border_width));
    177   n = 0;
    178   XtSetArg(wargs[n], XtNx, popup_x); n++;
    179   XtSetArg(wargs[n], XtNy, popup_y); n++;
    180   XtSetValues(popup->shell_widget, wargs, n);
    181 
    182   selected = None;
    183 
    184   XtPopup(popup->shell_widget, grab);
    185   XWarpPointer(XtDisplay(popup->shell_widget),
    186 	       XtWindow(popup->top_widget),
    187 	       XtWindow(popup->shell_widget),
    188 	       0, 0, top_width, top_height,
    189 	       popup_width / 2, popup_height / 2);
    190 
    191   while ((selected & popup->options) == None) {
    192       XEvent event;
    193       XtNextEvent(&event);
    194       XtDispatchEvent(&event);
    195   }
    196 
    197   PopdownDialog(popup, answer);
    198 
    199   return (selected & popup->options);
    200 }
    201