home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xprompt / xprompt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-19  |  9.3 KB  |  344 lines

  1. /*
  2.    xprompt.c
  3.    
  4.    Better version of xprompt.
  5.    by Mike & Bob
  6.    Last edited: Wed Jun 27 17:40:54 1990 by mjm (Michael Murphy) on lightning
  7.  
  8.    Copyright (C) 1990 Michael Murphy and Robert Forsman
  9.  
  10.     This program is free software; you can redistribute it and/or modify
  11.     it under the terms of the GNU General Public License as published by
  12.     the Free Software Foundation; either version 1, or (at your option)
  13.     any later version.
  14.  
  15.     This program is distributed in the hope that it will be useful,
  16.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.     GNU General Public License for more details.
  19.  
  20.     You should have received a copy of the GNU General Public License
  21.     along with this program; if not, write to the Free Software
  22.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  
  24. */
  25.  
  26. char ego[] = "Copyright (C) 1990 Michael Murphy and Robert Forsman\n";
  27. #include "patchlevel.h"
  28.  
  29. #include <stdio.h>
  30. #include <X11/Intrinsic.h>
  31. #include <X11/StringDefs.h>
  32. #include <X11/Shell.h>
  33. #include <X11/Xaw/Box.h>
  34. #include <X11/Xaw/Form.h>
  35. #include <X11/Xaw/AsciiText.h>
  36. #include <X11/Xaw/Label.h>
  37.  
  38. Display *dpy;
  39. int scrn;
  40.  
  41. Widget master, form;
  42. XtAppContext app_con;
  43. Pixel origBorderColor;
  44.  
  45. struct promptentry {
  46.    Widget box, label, input;
  47.    char *prompt, *reply;
  48.    struct promptentry *next, *prev;
  49. };
  50.  
  51. struct promptentry *pehead = NULL, *petail = NULL, *active;
  52.  
  53. struct XPromptResources {
  54.    int rlen;
  55.    Boolean grab;
  56.    Pixel hl;
  57. } xpres;
  58.  
  59. #define offset(field) XtOffset (struct XPromptResources*, field)
  60.  
  61. static XrmOptionDescRec Options [] = {
  62.    {"-rlen", "replyLength", XrmoptionSepArg, NULL},
  63.    {"-ibw",  "*input.borderWidth", XrmoptionSepArg, NULL},
  64.    {"-grab", "grabKeyboard", XrmoptionNoArg, "true"},
  65.    {"-nograb", "grabKeyboard", XrmoptionNoArg, "false"},
  66.    {"-pfn",  "*label.font", XrmoptionSepArg, NULL},
  67.    {"-rfn",  "*input*font", XrmoptionSepArg, NULL},
  68.    {"-hl",   "focusHighlightColor", XrmoptionSepArg, NULL},
  69.    {"-p",    "ignoreme", XrmoptionSkipArg, NULL},
  70.    {"-r",    "ignoremetoo", XrmoptionSkipArg, NULL},
  71. };
  72.  
  73. static XtResource Resources [] = {
  74.    {"replyLength", "ReplyLength", XtRInt, sizeof(int), offset (rlen),
  75.       XtRImmediate, (XtPointer)80},
  76.    {"grabKeyboard", "GrabKeyboard", XtRBoolean, sizeof(Boolean), offset (grab),
  77.       XtRImmediate, (XtPointer)True},
  78.    {"focusHighlightColor", XtCBorderColor, XtRPixel, sizeof(Pixel), offset (hl),
  79.           XtRString, XtDefaultBackground},
  80. };
  81.  
  82. void BailApplication ();
  83. void ExitApplicationAndPrint ();
  84. void GrabKeyboardAfterVisible ();
  85. void AdvanceField ();
  86.  
  87. static XtActionsRec Actions [] = {
  88.    {"bail-application", BailApplication},
  89.    {"exit-application-and-print", ExitApplicationAndPrint},
  90.    {"grab-keyboard-after-visible", GrabKeyboardAfterVisible},
  91.    {"advance-field", AdvanceField},
  92. };
  93.  
  94. static char *FallbackResources [] = {
  95.    "XPrompt*AllowShellResize: true",
  96.    "XPrompt*Text.resize: both",
  97.    "XPrompt*Text.resizable: true",
  98.    "XPrompt*Form.borderWidth: 0",
  99.    "XPrompt.xprompt.translations: #override\
  100.         <Visible>: grab-keyboard-after-visible()\n",
  101.    "XPrompt*input.translations: #override\
  102.         <Key>Return: advance-field(1,0)\\n\\\n\
  103.         Ctrl<Key>m:  advance-field(1,0)\\n\\\n\
  104.         Ctrl<Key>n:  advance-field(1,1)\\n\\\n\
  105.                 !<Key>Tab:   advance-field(1,1)\\n\\\n\
  106.         Ctrl<Key>p:  advance-field(-1,1)\\n\\\n\
  107.         !Shift<Key>Tab: advance-field(-1,1)\\n\\\n\
  108.         Ctrl<Key>c:  bail-application()\n",
  109.    NULL
  110. };
  111.  
  112.       
  113. void BailApplication (w, event, argv, argc)
  114. Widget w;
  115. XEvent *event;
  116. String *argv;
  117. Cardinal *argc;
  118. {
  119.    XtDestroyApplicationContext (app_con);
  120.    exit(0);
  121. }
  122.  
  123. void ExitApplicationAndPrint (w, event, argv, argc)
  124. Widget w;
  125. XEvent *event;
  126. String *argv;
  127. Cardinal *argc;
  128. {
  129.    char *reply;
  130.  
  131.    for (active=pehead; active != NULL; active=active->next) {
  132.       XtVaGetValues (active->input, XtNstring, &reply, 0);
  133.       printf ("%s\n", reply);
  134.    }
  135.    exit (0);
  136. }
  137.    
  138. void GrabKeyboardAfterVisible (w, event, argv, argc)
  139. /* Grab the stupid keyboard focus after window is made visible. */
  140. Widget w;
  141. XEvent *event;
  142. String *argv;
  143. Cardinal *argc;
  144. {
  145.    if (event->type == VisibilityNotify && XtIsRealized (master)) {
  146.       if (event->xvisibility.state != VisibilityFullyObscured) {
  147.      XtSetKeyboardFocus (master, active->input);
  148.          if (xpres.grab) {
  149.         XtGrabKeyboard (active->input, True,
  150.                 GrabModeAsync, GrabModeAsync, CurrentTime);
  151.      }
  152.      XtVaGetValues (active->input, XtNborderColor, &origBorderColor, 0);
  153.      XtVaSetValues (active->input, XtNdisplayCaret, (XtPointer)True,
  154.                            XtNborderColor, xpres.hl,
  155.                        0);
  156.       }
  157.    }
  158. }
  159.  
  160. void AdvanceField (w, event, argv, argc)
  161. Widget w;
  162. XEvent *event;
  163. String *argv;
  164. Cardinal *argc;
  165. {
  166.    int deltafield, i;
  167.    Boolean wrap;
  168.  
  169.    if (*argc > 0) {
  170.       deltafield = atoi (argv[0]);
  171.       if (*argc > 1) {
  172.      wrap = atoi (argv[1]) != 0;
  173.       } else {
  174.      wrap = True;
  175.       }
  176.    } else {
  177.       deltafield = 1;
  178.       wrap = True;
  179.    }
  180.  
  181.    XtVaSetValues (active->input, XtNdisplayCaret, (XtPointer)False,
  182.                          XtNborderColor, origBorderColor, 0);
  183.  
  184.    if (deltafield < 0) {
  185.       for (i=deltafield; i<0; i++) {
  186.      active = active->prev;
  187.      if (active == NULL) {
  188.         if (wrap) {
  189.            active = petail;
  190.         } else {
  191.            break;
  192.         }
  193.      }
  194.       }
  195.    } else {
  196.       for (i=deltafield; i>0; i--) {
  197.      active = active->next;
  198.      if (active == NULL) {
  199.         if (wrap) {
  200.            active = pehead;
  201.         } else {
  202.            break;
  203.         }
  204.      }
  205.       }
  206.    }
  207.  
  208.    if (active == NULL)
  209.       ExitApplicationAndPrint (w, event, argv, argc);
  210.    
  211.    event->type = VisibilityNotify;
  212.    event->xvisibility.state = VisibilityUnobscured;
  213.    GrabKeyboardAfterVisible (w, event, NULL, NULL);
  214. }
  215.  
  216. void AddPromptToWidget (pe)
  217. struct promptentry* pe;
  218. {
  219.    XFontStruct *font;
  220.    Dimension width, height;
  221.    Position bmargin, tmargin, lmargin, rmargin;
  222.  
  223.    pe->box = XtVaCreateManagedWidget
  224.      ("form", formWidgetClass, form,
  225.       XtNresizable, (XtPointer)True,
  226.       0);
  227.    if (pe->prev != NULL) {
  228.       XtVaSetValues (pe->box, XtNfromVert, pe->prev->box, 0);
  229.    }
  230.  
  231.    pe->label = XtVaCreateManagedWidget
  232.      ("label", labelWidgetClass, pe->box,
  233.       XtNbottom, XtChainTop,
  234.       XtNtop, XtChainTop,
  235.       XtNright, XtChainLeft,
  236.       XtNleft, XtChainLeft,
  237.       XtNlabel, pe->prompt,
  238.       0);
  239.  
  240.    pe->input = XtVaCreateManagedWidget
  241.      ("input", asciiTextWidgetClass, pe->box,
  242.       XtNbottom, XtChainBottom,
  243.       XtNtop, XtChainTop,
  244.       XtNright, XtChainRight,
  245.       XtNleft, XtChainLeft,
  246.       XtNfromHoriz, pe->label,
  247.       XtNstring, pe->reply, 
  248.       XtNeditType, XawtextEdit,
  249.       XtNresizable, (XtPointer)True,
  250.       XtNdisplayCaret, (XtPointer)False,
  251.       XtNinsertPosition, (pe->reply == NULL)? 0 : strlen (pe->reply),
  252.       0);
  253.  
  254.    XtVaGetValues (pe->input, XtNfont, &font,
  255.           XtNbottomMargin, &bmargin, XtNtopMargin, &tmargin,
  256.           XtNleftMargin, &lmargin, XtNrightMargin, &rmargin, 0);
  257.    width = (font->max_bounds.rbearing - font->min_bounds.lbearing) * xpres.rlen
  258.      + lmargin + rmargin;
  259.    height = font->max_bounds.ascent + font->max_bounds.descent + tmargin + bmargin;
  260.    XtVaSetValues (pe->input, XtNwidth, width, XtNheight, height, 0);
  261. }
  262.  
  263. void usage (progname)
  264. char *progname;
  265. {
  266.    fprintf (stderr,"Usage: %s [flags] {-p prompt [-r reply]} ...\n\n",
  267.         progname);
  268.    fprintf (stderr, "   where flags is one or more of: \n");
  269.    fprintf (stderr, "   -rlen <length>  (Maximum length of user's reply: default 80)\n");
  270.    fprintf (stderr, "   -ibw  <bwidth>  (Border width of inside window: default 1)\n");
  271.    fprintf (stderr, "   -grab           (Grab keyboard)\n");
  272.    fprintf (stderr, "   -nograb         (Don't grab keyboard)\n");
  273.    fprintf (stderr, "   -pfn  <font>    (Prompt font)\n");
  274.    fprintf (stderr, "   -rfn  <font>    (Reply font)\n");
  275.    fprintf (stderr, "   -hl   <color>   (Input highlight color)\n");
  276.    fprintf (stderr, "\n   The default prompt is \"?\"\n");
  277.    exit (1);
  278. }
  279.  
  280.  
  281. main (argc, argv)
  282. int argc;
  283. char **argv;
  284.  
  285. {
  286.    int i, p;
  287.    struct promptentry *temp;
  288.    Widget orig;
  289.    String origGeom;
  290.  
  291.    orig = XtVaAppInitialize (&app_con, "XPrompt", Options, XtNumber(Options),
  292.                    &argc, argv, FallbackResources, 0);
  293.    XtGetApplicationResources (orig, &xpres, Resources, XtNumber(Resources),
  294.                   NULL, 0);
  295.    XtAppAddActions (app_con, Actions, XtNumber(Actions));
  296.  
  297.    master = XtVaCreatePopupShell ("xprompt", applicationShellWidgetClass, orig, 0);
  298.  
  299.    XtVaGetValues (orig, XtNgeometry, &origGeom, 0);
  300.    XtVaSetValues (master, XtNgeometry, origGeom, 0);
  301.  
  302.    form = XtVaCreateManagedWidget ("form", formWidgetClass, master, 0);
  303.  
  304.    if (argc <= 1) {
  305.       /* no args given, use default prompt */
  306.       static struct promptentry defaultprompt = {
  307.      0, 0, 0, "?", NULL, NULL, NULL };
  308.       pehead = petail = &defaultprompt;
  309.       AddPromptToWidget (&defaultprompt);
  310.    }
  311.       
  312.    for (i=1; i<argc; i+=2) {
  313.       if (strcmp ("-p", argv[i]) != 0 || i+1 >= argc) {
  314.      usage (argv[0]);
  315.       }
  316.       temp = (void*) malloc (sizeof (struct promptentry));
  317.       temp->prompt = argv[i+1];
  318.  
  319.       if (i+3 < argc && strcmp ("-r", argv[i+2]) == 0) {
  320.      temp->reply = argv[i+3];
  321.      i += 2;
  322.       } else {
  323.      temp->reply = NULL;
  324.       }
  325.  
  326.       temp->prev = petail;
  327.       temp->next = NULL;
  328.       if (temp->prev != NULL) {
  329.      temp->prev->next = temp;
  330.       } else {
  331.      pehead = temp;
  332.       }
  333.       petail = temp;
  334.       AddPromptToWidget (temp);
  335.    }
  336.    active = pehead;
  337.  
  338.    XtRealizeWidget (master);
  339.    XtPopup (master, XtGrabExclusive);
  340.  
  341.    XtAppMainLoop (app_con);
  342. }
  343.  
  344.