home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume10 / xprompt2 / part01 / xprompt.c < prev    next >
C/C++ Source or Header  |  1990-10-29  |  10KB  |  345 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.  
  39. Display *dpy;
  40. int scrn;
  41.  
  42. Widget master, form;
  43. XtAppContext app_con;
  44. Pixel origBorderColor;
  45.  
  46. struct promptentry {
  47.    Widget box, label, input;
  48.    char *prompt, *reply;
  49.    struct promptentry *next, *prev;
  50. };
  51.  
  52. struct promptentry *pehead = NULL, *petail = NULL, *active;
  53.  
  54. struct XPromptResources {
  55.    int rlen;
  56.    Boolean grab;
  57.    Pixel hl;
  58. } xpres;
  59.  
  60. #define offset(field) XtOffset (struct XPromptResources*, field)
  61.  
  62. static XrmOptionDescRec Options [] = {
  63.    {"-rlen", "replyLength", XrmoptionSepArg, NULL},
  64.    {"-ibw",  "*input.borderWidth", XrmoptionSepArg, NULL},
  65.    {"-grab", "grabKeyboard", XrmoptionNoArg, "true"},
  66.    {"-nograb", "grabKeyboard", XrmoptionNoArg, "false"},
  67.    {"-pfn",  "*label.font", XrmoptionSepArg, NULL},
  68.    {"-rfn",  "*input*font", XrmoptionSepArg, NULL},
  69.    {"-hl",   "focusHighlightColor", XrmoptionSepArg, NULL},
  70.    {"-p",    "ignoreme", XrmoptionSkipArg, NULL},
  71.    {"-r",    "ignoremetoo", XrmoptionSkipArg, NULL},
  72. };
  73.  
  74. static XtResource Resources [] = {
  75.    {"replyLength", "ReplyLength", XtRInt, sizeof(int), offset (rlen),
  76.       XtRImmediate, (XtPointer)80},
  77.    {"grabKeyboard", "GrabKeyboard", XtRBoolean, sizeof(Boolean), offset (grab),
  78.       XtRImmediate, (XtPointer)True},
  79.    {"focusHighlightColor", XtCBorderColor, XtRPixel, sizeof(Pixel), offset (hl),
  80.           XtRString, XtDefaultBackground},
  81. };
  82.  
  83. void BailApplication ();
  84. void ExitApplicationAndPrint ();
  85. void GrabKeyboardAfterVisible ();
  86. void AdvanceField ();
  87.  
  88. static XtActionsRec Actions [] = {
  89.    {"bail-application", BailApplication},
  90.    {"exit-application-and-print", ExitApplicationAndPrint},
  91.    {"grab-keyboard-after-visible", GrabKeyboardAfterVisible},
  92.    {"advance-field", AdvanceField},
  93. };
  94.  
  95. static char *FallbackResources [] = {
  96.    "XPrompt*AllowShellResize: true",
  97.    "XPrompt*Text.resize: both",
  98.    "XPrompt*Text.resizable: true",
  99.    "XPrompt*Form.borderWidth: 0",
  100.    "XPrompt.xprompt.translations: #override\
  101.         <Visible>: grab-keyboard-after-visible()\n",
  102.    "XPrompt*input.translations: #override\
  103.         <Key>Return: advance-field(1,0)\\n\\\n\
  104.         Ctrl<Key>m:  advance-field(1,0)\\n\\\n\
  105.         Ctrl<Key>n:  advance-field(1,1)\\n\\\n\
  106.                 !<Key>Tab:   advance-field(1,1)\\n\\\n\
  107.         Ctrl<Key>p:  advance-field(-1,1)\\n\\\n\
  108.         !Shift<Key>Tab: advance-field(-1,1)\\n\\\n\
  109.         Ctrl<Key>c:  bail-application()\n",
  110.    NULL
  111. };
  112.  
  113.       
  114. void BailApplication (w, event, argv, argc)
  115. Widget w;
  116. XEvent *event;
  117. String *argv;
  118. Cardinal *argc;
  119. {
  120.    XtDestroyApplicationContext (app_con);
  121.    exit(0);
  122. }
  123.  
  124. void ExitApplicationAndPrint (w, event, argv, argc)
  125. Widget w;
  126. XEvent *event;
  127. String *argv;
  128. Cardinal *argc;
  129. {
  130.    char *reply;
  131.  
  132.    for (active=pehead; active != NULL; active=active->next) {
  133.       XtVaGetValues (active->input, XtNstring, &reply, 0);
  134.       printf ("%s\n", reply);
  135.    }
  136.    exit (0);
  137. }
  138.    
  139. void GrabKeyboardAfterVisible (w, event, argv, argc)
  140. /* Grab the stupid keyboard focus after window is made visible. */
  141. Widget w;
  142. XEvent *event;
  143. String *argv;
  144. Cardinal *argc;
  145. {
  146.    if (event->type == VisibilityNotify && XtIsRealized (master)) {
  147.       if (event->xvisibility.state != VisibilityFullyObscured) {
  148.      XtSetKeyboardFocus (master, active->input);
  149.          if (xpres.grab) {
  150.         XtGrabKeyboard (active->input, True,
  151.                 GrabModeAsync, GrabModeAsync, CurrentTime);
  152.      }
  153.      XtVaGetValues (active->input, XtNborderColor, &origBorderColor, 0);
  154.      XtVaSetValues (active->input, XtNdisplayCaret, (XtPointer)True,
  155.                            XtNborderColor, xpres.hl,
  156.                        0);
  157.       }
  158.    }
  159. }
  160.  
  161. void AdvanceField (w, event, argv, argc)
  162. Widget w;
  163. XEvent *event;
  164. String *argv;
  165. Cardinal *argc;
  166. {
  167.    int deltafield, i;
  168.    Boolean wrap;
  169.  
  170.    if (*argc > 0) {
  171.       deltafield = atoi (argv[0]);
  172.       if (*argc > 1) {
  173.      wrap = atoi (argv[1]) != 0;
  174.       } else {
  175.      wrap = True;
  176.       }
  177.    } else {
  178.       deltafield = 1;
  179.       wrap = True;
  180.    }
  181.  
  182.    XtVaSetValues (active->input, XtNdisplayCaret, (XtPointer)False,
  183.                          XtNborderColor, origBorderColor, 0);
  184.  
  185.    if (deltafield < 0) {
  186.       for (i=deltafield; i<0; i++) {
  187.      active = active->prev;
  188.      if (active == NULL) {
  189.         if (wrap) {
  190.            active = petail;
  191.         } else {
  192.            break;
  193.         }
  194.      }
  195.       }
  196.    } else {
  197.       for (i=deltafield; i>0; i--) {
  198.      active = active->next;
  199.      if (active == NULL) {
  200.         if (wrap) {
  201.            active = pehead;
  202.         } else {
  203.            break;
  204.         }
  205.      }
  206.       }
  207.    }
  208.  
  209.    if (active == NULL)
  210.       ExitApplicationAndPrint (w, event, argv, argc);
  211.    
  212.    event->type = VisibilityNotify;
  213.    event->xvisibility.state = VisibilityUnobscured;
  214.    GrabKeyboardAfterVisible (w, event, NULL, NULL);
  215. }
  216.  
  217. void AddPromptToWidget (pe)
  218. struct promptentry* pe;
  219. {
  220.    XFontStruct *font;
  221.    Dimension width, height;
  222.    Position bmargin, tmargin, lmargin, rmargin;
  223.  
  224.    pe->box = XtVaCreateManagedWidget
  225.      ("form", formWidgetClass, form,
  226.       XtNresizable, (XtPointer)True,
  227.       0);
  228.    if (pe->prev != NULL) {
  229.       XtVaSetValues (pe->box, XtNfromVert, pe->prev->box, 0);
  230.    }
  231.  
  232.    pe->label = XtVaCreateManagedWidget
  233.      ("label", labelWidgetClass, pe->box,
  234.       XtNbottom, XtChainTop,
  235.       XtNtop, XtChainTop,
  236.       XtNright, XtChainLeft,
  237.       XtNleft, XtChainLeft,
  238.       XtNlabel, pe->prompt,
  239.       0);
  240.  
  241.    pe->input = XtVaCreateManagedWidget
  242.      ("input", asciiTextWidgetClass, pe->box,
  243.       XtNbottom, XtChainBottom,
  244.       XtNtop, XtChainTop,
  245.       XtNright, XtChainRight,
  246.       XtNleft, XtChainLeft,
  247.       XtNfromHoriz, pe->label,
  248.       XtNstring, pe->reply, 
  249.       XtNeditType, XawtextEdit,
  250.       XtNresizable, (XtPointer)True,
  251.       XtNdisplayCaret, (XtPointer)False,
  252.       XtNinsertPosition, (pe->reply == NULL)? 0 : strlen (pe->reply),
  253.       0);
  254.  
  255.    XtVaGetValues (pe->input, XtNfont, &font,
  256.           XtNbottomMargin, &bmargin, XtNtopMargin, &tmargin,
  257.           XtNleftMargin, &lmargin, XtNrightMargin, &rmargin, 0);
  258.    width = (font->max_bounds.rbearing - font->min_bounds.lbearing) * xpres.rlen
  259.      + lmargin + rmargin;
  260.    height = font->max_bounds.ascent + font->max_bounds.descent + tmargin + bmargin;
  261.    XtVaSetValues (pe->input, XtNwidth, width, XtNheight, height, 0);
  262. }
  263.  
  264. void usage (progname)
  265. char *progname;
  266. {
  267.    fprintf (stderr,"Usage: %s [flags] {-p prompt [-r reply]} ...\n\n",
  268.         progname);
  269.    fprintf (stderr, "   where flags is one or more of: \n");
  270.    fprintf (stderr, "   -rlen <length>  (Maximum length of user's reply: default 80)\n");
  271.    fprintf (stderr, "   -ibw  <bwidth>  (Border width of inside window: default 1)\n");
  272.    fprintf (stderr, "   -grab           (Grab keyboard)\n");
  273.    fprintf (stderr, "   -nograb         (Don't grab keyboard)\n");
  274.    fprintf (stderr, "   -pfn  <font>    (Prompt font)\n");
  275.    fprintf (stderr, "   -rfn  <font>    (Reply font)\n");
  276.    fprintf (stderr, "   -hl   <color>   (Input highlight color)\n");
  277.    fprintf (stderr, "\n   The default prompt is \"?\"\n");
  278.    exit (1);
  279. }
  280.  
  281.  
  282. main (argc, argv)
  283. int argc;
  284. char **argv;
  285.  
  286. {
  287.    int i, p;
  288.    struct promptentry *temp;
  289.    Widget orig;
  290.    String origGeom;
  291.  
  292.    orig = XtVaAppInitialize (&app_con, "XPrompt", Options, XtNumber(Options),
  293.                    &argc, argv, FallbackResources, 0);
  294.    XtGetApplicationResources (orig, &xpres, Resources, XtNumber(Resources),
  295.                   NULL, 0);
  296.    XtAppAddActions (app_con, Actions, XtNumber(Actions));
  297.  
  298.    master = XtVaCreatePopupShell ("xprompt", applicationShellWidgetClass, orig, 0);
  299.  
  300.    XtVaGetValues (orig, XtNgeometry, &origGeom, 0);
  301.    XtVaSetValues (master, XtNgeometry, origGeom, 0);
  302.  
  303.    form = XtVaCreateManagedWidget ("form", formWidgetClass, master, 0);
  304.  
  305.    if (argc <= 1) {
  306.       /* no args given, use default prompt */
  307.       static struct promptentry defaultprompt = {
  308.      0, 0, 0, "?", NULL, NULL, NULL };
  309.       pehead = petail = &defaultprompt;
  310.       AddPromptToWidget (&defaultprompt);
  311.    }
  312.       
  313.    for (i=1; i<argc; i+=2) {
  314.       if (strcmp ("-p", argv[i]) != 0 || i+1 >= argc) {
  315.      usage (argv[0]);
  316.       }
  317.       temp = (void*) malloc (sizeof (struct promptentry));
  318.       temp->prompt = argv[i+1];
  319.  
  320.       if (i+3 < argc && strcmp ("-r", argv[i+2]) == 0) {
  321.      temp->reply = argv[i+3];
  322.      i += 2;
  323.       } else {
  324.      temp->reply = NULL;
  325.       }
  326.  
  327.       temp->prev = petail;
  328.       temp->next = NULL;
  329.       if (temp->prev != NULL) {
  330.      temp->prev->next = temp;
  331.       } else {
  332.      pehead = temp;
  333.       }
  334.       petail = temp;
  335.       AddPromptToWidget (temp);
  336.    }
  337.    active = pehead;
  338.  
  339.    XtRealizeWidget (master);
  340.    XtPopup (master, XtGrabExclusive);
  341.  
  342.    XtAppMainLoop (app_con);
  343. }
  344.  
  345.