]> andersk Git - moira.git/commitdiff
Initial revision
authormar <mar>
Wed, 29 May 1991 17:16:05 +0000 (17:16 +0000)
committermar <mar>
Wed, 29 May 1991 17:16:05 +0000 (17:16 +0000)
clients/mmoira/formup.c [new file with mode: 0644]

diff --git a/clients/mmoira/formup.c b/clients/mmoira/formup.c
new file mode 100644 (file)
index 0000000..2156eae
--- /dev/null
@@ -0,0 +1,636 @@
+#include       <stdio.h>
+#include       <X11/StringDefs.h>
+#include       <X11/IntrinsicP.h>
+#include       <X11/Shell.h>
+#include       <X11/Core.h>
+#include       <X11/CoreP.h>
+#include       <Xm/Xm.h>
+#include       <Xm/BulletinB.h>
+#include       <Xm/Label.h>
+#include       <Xm/Text.h>
+#include       <Xm/PushB.h>
+#include       <Xm/PushBG.h>
+#include       <Xm/CascadeB.h>
+#include       <Xm/ToggleB.h>
+#include       <Xm/ToggleBG.h>
+#include       <Xm/RowColumn.h>
+#include       <Xm/Separator.h>
+#include       "mmoira.h"
+
+#define        HPADDING                8
+#define        WPADDING                20
+#define        MAX(a,b)        ((a > b) ? a : b)
+
+extern Widget toplevel;
+
+void   map_menu_widget();
+void   manage_widget();
+Widget CreateForm();
+Widget CreateMenu();
+Widget BuildMenuTree();
+int    button_callback();
+int    radio_callback();
+void   menu_callback();
+void   post_menu_handler();
+
+
+/*
+** Read the specification and put up a menu to match...
+**
+** Something in here is making a bad button grab...It either gets the
+** error, 
+**        "BadAccess (attempt to access private resource denied)
+**         Major opcode of failed request:  28 (X_GrabButton)
+**
+** or puts up the menu and permanently grabs the pointer!
+**
+** All Motif pulldown menus are replaced with homebrews until I get an
+** updated widget set to try out.
+*/
+
+Widget
+CreateMenu(parent, spec, orientation)
+Widget         parent;
+MenuItem       **spec;
+int            orientation;
+{
+       Widget          menuparent;
+       MenuItem        *curmenuitem;
+       Widget          childbutton, childmenu;
+       Arg             wargs[10];
+       int             n;
+       XmString        label;          /* !@#$%^ compound string required */
+       Widget          shellparent;
+
+       label = XmStringCreate( "Complete junk", XmSTRING_DEFAULT_CHARSET);
+
+       n = 0;
+
+/* MOTIF menus are broken.
+       XtSetArg(wargs[n], XmNlabelString, label);      n++;
+       menuparent = XmCreatePopupMenu(parent, "randommenu", wargs, n);
+*/
+
+       XtSetArg(wargs[n], XtNmappedWhenManaged, False);        n++;
+       shellparent = XtCreateApplicationShell( "shellparent", 
+                                               transientShellWidgetClass,
+                                               wargs, n);
+
+       n = 0;
+       if (orientation)
+               XtSetArg(wargs[n], XtNorientation, orientation);        n++;
+       menuparent = XtCreateManagedWidget (    "row", 
+                                       xmRowColumnWidgetClass,
+                                       shellparent, wargs, n);
+                                               
+
+/*
+       XtAddEventHandler (     parent, ButtonPressMask, FALSE,
+                               post_menu_handler, menuparent);
+*/
+       for (   curmenuitem = (*spec);
+               curmenuitem;
+               spec++, curmenuitem = (*spec)) {
+
+#ifdef DEBUG
+               printf ("Making entry:  %s\n", curmenuitem->label);
+#endif
+               label = XmStringCreate( curmenuitem->label,
+                                       XmSTRING_DEFAULT_CHARSET);
+               if (curmenuitem->submenu) {
+                       label = XmStringConcat(label,
+                                       XmStringCreate( "...",
+                                       XmSTRING_DEFAULT_CHARSET));
+               }
+               n = 0;
+               XtSetArg(wargs[n], XmNlabelString, label);      n++;
+
+               childbutton = XtCreateManagedWidget(    "child",
+                               xmPushButtonGadgetClass,
+                               menuparent, wargs, n);
+
+               if (curmenuitem->submenu) {
+#ifdef DEBUG
+                       printf ("It has a submenu, which I'm recursing on...\n");
+#endif
+/* MOTIF menus don't work...
+                       childmenu = XmCreatePulldownMenu(menuparent,
+                                       curmenuitem->label,
+                                       NULL, 0);
+
+                       n = 0;
+                       XtSetArg(wargs[n], XmNsubMenuId, childmenu);    n++;
+
+                       childbutton = XtCreateManagedWidget(    "child",
+                                       xmCascadeButtonWidgetClass,
+                                       menuparent, wargs, n);
+*/
+
+                       childmenu = CreateMenu( childbutton, 
+                                               curmenuitem->submenu,
+                                               XmVERTICAL);
+                       XtAddCallback(  childbutton, XmNactivateCallback,
+                                       map_menu_widget, childmenu);
+
+               }
+
+               else {
+                       XtAddCallback(  childbutton, 
+                                       XmNactivateCallback, 
+                                       menu_callback, curmenuitem);
+               }
+       }
+       XtRealizeWidget(shellparent);
+
+       return (shellparent);
+}
+
+/*     We don't need this, since I'm using callbacks rather than
+**     event handlers.
+
+void
+post_menu_handler(w, menu, event)
+Widget w;
+Widget menu;
+XEvent *event;
+{
+       Arg     wargs[10];
+       int     n;
+       Widget  button;
+
+       n = 0;
+       XtSetArg(wargs[n], XmNwhichButton, &button);      n++;
+       XtGetValues(menu, wargs, n);
+
+       if ((Widget) (event->xbutton.button) == button) {
+               XmMenuPosition (menu, event);
+               XtManageChild(menu);
+       }
+
+       else {
+               printf ("Ignoring hit from 'wrong' button\n");
+       }
+}
+*/
+
+
+DisplayForm(spec)
+EntryForm      *spec;
+{
+       Widget  w;
+
+       w = CreateForm(toplevel, spec);
+       XtManageChild(w);
+}
+
+
+/*
+** Read the specification and put up a form to match...
+*/
+
+Widget
+CreateForm(parent, spec)
+Widget         parent;
+EntryForm      *spec;
+{
+       XmBulletinBoardWidget   bb;
+       Arg             wargs[10];
+       int             i, n;
+       XmString        label;          /* compound string required */
+       Dimension       height_so_far = 0, width_so_far = 0;
+       Dimension       height, width;
+       Widget          titleW, instructionW;
+       Position        x, y;
+       Widget          shellparent;
+
+/*
+       n = 0;
+       XtSetArg(wargs[n], XtNmappedWhenManaged, False);        n++;
+       shellparent = XtCreateApplicationShell( "shellparent", 
+                                               topLevelShellWidgetClass,
+                                               wargs, n);
+*/
+
+#define GETSIZE(foo)   n = 0; \
+                       XtSetArg(wargs[n], XtNwidth, &width);   n++; \
+                       XtSetArg(wargs[n], XtNheight, &height); n++; \
+                       XtGetValues (foo, wargs, n); \
+
+#define STORESIZE      if (width > width_so_far) width_so_far = width;\
+                       height_so_far += height + HPADDING;
+
+
+       n = 0;
+       XtSetArg(wargs[n], XmNautoUnmanage, FALSE);             n++;
+       bb = (XmBulletinBoardWidget)
+               XmCreateBulletinBoardDialog(parent, "board", wargs, n);
+
+       label = XmStringCreate(spec->formname, XmSTRING_DEFAULT_CHARSET);
+       n = 0;
+       XtSetArg(wargs[n], XmNlabelString, label);              n++;
+       XtSetArg(wargs[n], XtNx, 0);                            n++;
+       XtSetArg(wargs[n], XtNy, 0);                            n++;
+       titleW = XtCreateManagedWidget( "title",
+                               xmLabelWidgetClass,
+                               bb, wargs, n);
+       GETSIZE(titleW);
+       STORESIZE;
+
+       label = XmStringCreate(spec->instructions, XmSTRING_DEFAULT_CHARSET);
+       n = 0;
+       XtSetArg(wargs[n], XmNlabelString, label);              n++;
+       XtSetArg(wargs[n], XtNx, 0);                            n++;
+       XtSetArg(wargs[n], XtNy, height_so_far);                n++;
+       instructionW = XtCreateManagedWidget(   "title",
+                               xmLabelWidgetClass,
+                               bb, wargs, n);
+       GETSIZE(instructionW);
+       STORESIZE;
+
+       height = height_so_far;
+       width = width_so_far;
+       MakeInputLines((Widget) bb, &height, &width, spec->inputlines);
+       STORESIZE;
+
+       height = height_so_far;
+       width = width_so_far;
+       MakeButtons((Widget) bb, &height, &width, spec->buttons, (char *)spec);
+       STORESIZE;
+
+/*
+** Center the title of the form
+*/
+       n = 0;
+       XtSetArg(wargs[n], XtNwidth, &width);                   n++;
+       XtGetValues (titleW, wargs, n);
+
+       x = (width_so_far - width) / 2;
+
+       n = 0;
+       XtSetArg(wargs[n], XtNx, x);                            n++;
+       XtSetValues (titleW, wargs, n);
+
+       spec->formpointer = (Widget) bb;
+
+       return((Widget) bb);
+}
+
+/*
+** Pheight and pwidth start with the values-to-date of the bboard so far.
+** Return your height and width in them when you're done.
+**
+** Positioning the widgets happens in two phases: 
+**     First, we set their y-positions as we create them.
+**     After they're created, we go back and adjust the x-positions
+**     according to the widest left side noted.
+*/
+
+MakeInputLines(parent, pheight, pwidth, inputlines)
+Widget         parent;
+Dimension      *pheight;
+Dimension      *pwidth;
+UserPrompt      **inputlines;
+{
+       UserPrompt      *current;
+       XmString        label;          /* compound string required */
+       Arg             wargs[10];
+       int             i, n;
+       Widget          child;
+       Dimension       width, height, maxleftwidth = 0, maxrightwidth = 0;
+       Dimension       localy, leftheight = 0, rightheight = 0;
+       UserPrompt      **myinputlines = inputlines;
+       int             foo = 30;
+       Widget          children[20];
+
+       for (   current = (*myinputlines), localy = 0,  i = 0;
+               current; 
+               myinputlines++, current = (*myinputlines), i++) {
+
+
+#ifdef DEBUG
+               printf ("Making entry %d: %s of type %d\n", 
+                               i, current->prompt, current->type);
+#endif
+/*
+** First, make the prompt
+*/
+               label = XmStringCreate( current->prompt, 
+                                       XmSTRING_DEFAULT_CHARSET);
+               n = 0;
+               XtSetArg(wargs[n], XmNlabelString, label);      n++;
+               XtSetArg(wargs[n], XtNy, localy + *pheight);    n++;
+               child = XtCreateManagedWidget(  "prompt",
+                               xmLabelWidgetClass,
+                               parent, wargs, n);
+
+               GETSIZE(child);
+               leftheight = height;
+               if (width > maxleftwidth)
+                       maxleftwidth = width;
+
+/*
+** Second, make the input widget
+*/
+               n = 0;
+               XtSetArg(wargs[n], XtNy, localy + *pheight);    n++;
+               XtSetArg(wargs[n], XtNsensitive, 
+                       !(current->insensitive));               n++;
+               switch (current->type) {
+               case FT_STRING:
+                       children[i] = XtCreateManagedWidget(    "child",
+                                               xmTextWidgetClass,
+                                               parent, wargs, n);
+                       if (current->returnvalue.stringvalue) {
+                               XmTextSetString (children[i], current->returnvalue.stringvalue);
+                       }
+                       GETSIZE (children[i]);
+                       rightheight = height;
+                       if (width > maxrightwidth)
+                               maxrightwidth = width;
+                       break;
+
+               case FT_BOOLEAN:
+                       XtSetArg(wargs[n], XmNset, current->returnvalue.booleanvalue);  n++;
+/*
+** EEEuch!  Not only to I have to use a blank (not NULL!) string to
+** override the ToggleButton's insistance on labelling itself, it has
+** to be a _compound_ blank string!
+*/
+                       label = XmStringCreate( " ", XmSTRING_DEFAULT_CHARSET);
+                       XtSetArg(wargs[n], XmNlabelString, label);      n++;
+
+                       children[i] = XtCreateManagedWidget(    "ignore this",
+                                               xmToggleButtonWidgetClass,
+                                               parent, wargs, n);
+
+                       XtAddCallback(  children[i], XmNvalueChangedCallback,
+                               radio_callback, NULL);
+
+                       GETSIZE (children[i]);
+                       rightheight = height;
+                       if (width > maxrightwidth)
+                               maxrightwidth = width;
+                       break;
+
+               case FT_KEYWORD:
+                       children[i] = XmCreateRadioBox(parent, "radio", wargs, n);
+                       XtManageChild(children[i]);     
+                       AddRadioButtons(        children[i], 
+                                               current,
+                                               &rightheight);
+                       GETSIZE (children[i]);
+                       if (width > maxrightwidth)
+                               maxrightwidth = width;
+                       break;
+
+               default:
+                       printf ("Sorry, don't recognize that type\n");
+                       break;
+               }
+
+               localy += MAX(rightheight, leftheight) + HPADDING;
+       }
+
+/*
+** Now slide the input widgets right as far as the widest prompt.
+*/
+       n = 0;
+       XtSetArg(wargs[n], XtNx, maxleftwidth + WPADDING);      n++;
+       for (; i; i--)
+               XtSetValues (children[i - 1], wargs, n);
+
+       *pheight = localy - HPADDING;
+       *pwidth = maxleftwidth + maxrightwidth + WPADDING;
+}
+
+/*
+** All the junk about keeping track of the sum of the children's heights
+** is because the !#$% RowColumn widget doesn't sum them for us, NOR
+** does it accept SetValues on its XtNHeight!
+*/
+
+AddRadioButtons(parent, prompt, pheight)
+Widget         parent;
+UserPrompt     *prompt;
+Dimension      *pheight;
+{
+       Widget  child;
+       char    *current;
+       Arg     wargs[10];
+       int     i, n;
+       XmString        label;          /* compound string required */
+       Dimension       height, width;
+       Dimension       height_so_far = 0;
+       char    **keywords = prompt->keywords;
+       char    *defvalue = prompt->returnvalue.stringvalue;
+
+       if (!keywords) {
+               fprintf (stderr, "Warning:  No list of keywords for widget\n");
+               return;
+       }
+       for (current=(*keywords); current; keywords++, current=(*keywords)) {
+               n = 0;
+               label = XmStringCreate(current, XmSTRING_DEFAULT_CHARSET);
+               XtSetArg(wargs[n], XmNlabelString, label);      n++;
+               if (!strcmp (current, defvalue)) {
+                       XtSetArg(wargs[n], XmNset, True);       n++;
+               }
+               else {
+                       XtSetArg(wargs[n], XmNset, False);      n++;
+               }
+               child = XtCreateManagedWidget(  current,
+                                               xmToggleButtonGadgetClass,
+                                               parent, wargs, n);
+
+               XtAddCallback(  child, XmNvalueChangedCallback,
+                               radio_callback, prompt);
+
+               GETSIZE (child);
+               height_so_far += height;
+       }
+/*
+       GETSIZE (parent);
+       printf ("height of radio parent was %d\n", height);
+       n = 0;
+       XtSetArg(wargs[n], XtNheight, height_so_far);   n++;
+       XtSetValues (parent, wargs, n);
+       GETSIZE (parent);
+       printf ("height of radio parent is now %d\n", height);
+*/
+       *pheight = height_so_far;
+}
+
+MakeButtons(parent, pheight, pwidth, buttons, data)
+Widget         parent;
+Dimension      *pheight;
+Dimension      *pwidth;
+BottomButton   **buttons;
+caddr_t                data;
+{
+       BottomButton    *current;
+       XmString        label;          /* compound string required */
+       Arg             wargs[10];
+       int             i, n;
+       Dimension       newwidth, width = 25;
+       Widget          newbutton;
+
+       n = 0;
+       XtSetArg(wargs[n], XtNy, *pheight);                     n++;
+       XtSetArg(wargs[n], XtNx, 0);                            n++;
+       XtSetArg(wargs[n], XtNwidth, *pwidth);                  n++;
+       XtCreateManagedWidget(  "separator",
+                               xmSeparatorWidgetClass,
+                               parent, wargs, n);
+       *pheight += HPADDING;
+
+       for (   current=(*buttons); 
+               current; 
+               buttons++, current=(*buttons)) {
+
+#ifdef DEBUG
+               printf ("Making a button labeled %s\n", current->label);
+#endif
+               label = XmStringCreate( current->label, 
+                                       XmSTRING_DEFAULT_CHARSET);
+               n = 0;
+               XtSetArg(wargs[n], XtNy, (*pheight));                   n++;
+               XtSetArg(wargs[n], XtNx, width);                        n++;
+               XtSetArg(wargs[n], XmNlabelString, label);              n++;
+
+               newbutton = XtCreateManagedWidget(      current->label,
+                                               xmPushButtonWidgetClass,
+                                               parent, wargs, n);
+
+               XtAddCallback(  newbutton, XmNactivateCallback,
+                               current->returnfunction, data);
+               n = 0;
+               XtSetArg(wargs[n], XtNwidth, &newwidth);                n++;
+               XtGetValues (newbutton, wargs, n);
+
+               width += (newwidth + WPADDING);
+       }
+
+       (*pheight) += 100;
+}
+
+void
+map_menu_widget(w, widget, call_data)
+Widget w, widget;
+XmAnyCallbackStruct    *call_data;
+{
+       Arg             wargs[10];
+       int             n;
+       Position        x, y;
+       Widget          foo;
+
+       
+       for (   x = 0, y = 0, foo = w->core.parent;
+               foo;
+               foo = foo->core.parent) {
+
+               x += foo->core.x;
+               y += foo->core.y;
+       }
+
+/*
+       if (w->core.parent)
+               x += w->core.parent->core.width;
+*/
+       x += w->core.width;
+       y += w->core.y;
+
+       n = 0;
+       XtSetArg(wargs[n], XtNx, x);            n++;
+       XtSetArg(wargs[n], XtNy, y);            n++;
+       XtSetValues(widget, wargs, n);
+
+       XtMapWidget(widget);    
+}
+
+void
+manage_widget(w, widget, call_data)
+Widget w, widget;
+XmAnyCallbackStruct    *call_data;
+{
+       XtManageChild(widget);  
+}
+
+int
+button_callback(w, client_data, call_data)
+Widget w;
+EntryForm      *client_data;
+XmAnyCallbackStruct    *call_data;
+{
+       XtUnmanageChild(client_data->formpointer);
+}
+
+int
+radio_callback(w, client_data, call_data)
+Widget w;
+XmAnyCallbackStruct    *client_data;
+XmAnyCallbackStruct    *call_data;
+{
+       Arg             wargs[10];
+       int             i, n;
+       XmString        label;          /* !@#$ compound string required! */
+       char            *text_value;
+
+       UserPrompt      *prompt = (UserPrompt *) client_data;
+
+       printf ("radio_callback: button %x, data %x\n", w, client_data);
+
+/*
+** It should be _easy_ to find the value of a label, right?  _WRONG!_
+** Have to disassemble the !@#$ compound text to get a char*, and
+** Motif doesn't provide any functions to do so.  So I stash the label
+** value as the name of the widget.
+
+       n = 0;
+       XtSetArg(wargs[n], XmNlabelString, label);      n++;
+       XtGetValues (w, wargs, n);
+
+       XmStringGetLtoR (label,
+                        XmSTRING_DEFAULT_CHARSET, &text_value);
+*/
+
+
+/*
+** Unfortunately, Xt caches w->core.name into something besides a char*,
+** so I can't use it.  And XtName is, somehow, unavailable.
+
+       if (!prompt) {
+               printf ("Oops!  radio_callback called from '%s' with no data\n",
+                               w->core.name);
+               return(0);
+       }
+
+       printf ("Replacing old value of selection, '%s', with '%s'\n",
+                       prompt->returnvalue.stringvalue,
+                       w->core.name);
+
+       strcpy(prompt->returnvalue.stringvalue, w->core.name);
+*/
+
+}
+
+void
+menu_callback(w, client_data, call_data)
+Widget w;
+XmAnyCallbackStruct    *client_data;
+XmAnyCallbackStruct    *call_data;
+{
+       MenuItem        *itemhit = (MenuItem *) client_data;
+
+#ifdef DEBUG
+       printf  ("menu_callback: item '%s', op %d and string '%s'\n", 
+                       itemhit->label, 
+                       itemhit->operation, 
+                       itemhit->form);
+#endif
+       MoiraMenuRequest(itemhit);
+/*
+** Unmap the shell of this button.  (UGLY HACK until Motif menus work)
+*/
+
+       XtUnmapWidget(XtParent(XtParent(w)));
+}
This page took 0.084396 seconds and 5 git commands to generate.