home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / xdbx / part02 / dialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-28  |  9.3 KB  |  307 lines

  1. /*****************************************************************************
  2.  *
  3.  *  xdbx - X Window System interface to the dbx debugger
  4.  *
  5.  *  Copyright 1989 The University of Texas at Austin
  6.  *  Copyright 1990 Microelectronics and Computer Technology Corporation
  7.  *
  8.  *  Permission to use, copy, modify, and distribute this software and its
  9.  *  documentation for any purpose and without fee is hereby granted,
  10.  *  provided that the above copyright notice appear in all copies and that
  11.  *  both that copyright notice and this permission notice appear in
  12.  *  supporting documentation, and that the name of The University of Texas
  13.  *  and Microelectronics and Computer Technology Corporation (MCC) not be 
  14.  *  used in advertising or publicity pertaining to distribution of
  15.  *  the software without specific, written prior permission.  The
  16.  *  University of Texas and MCC makes no representations about the 
  17.  *  suitability of this software for any purpose.  It is provided "as is" 
  18.  *  without express or implied warranty.
  19.  *
  20.  *  THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO
  21.  *  THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  22.  *  FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR
  23.  *  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  24.  *  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
  25.  *  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  26.  *  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  *
  28.  *  Author:      Po Cheung
  29.  *  Created:       March 10, 1989
  30.  *
  31.  *****************************************************************************/
  32.  
  33. /*  dialog.c
  34.  *
  35.  *    Create the dialogue window where the user enter dbx commands, and
  36.  *    provide action procs to make a text widget behave like a terminal.
  37.  *
  38.  *    InsertSpace():    Prevent user from deleting past the prompt (action proc
  39.  *            for DELETE or BACKSPACE).
  40.  *    DeleteWord():    Word delete in dialog window. (action proc for Ctrl-w).
  41.  *    DeleteLine():    Line delete in dialog window. (action proc for Ctrl-u).
  42.  *    Dispatch():    Send an input command line to dbx. (action proc for CR).
  43.  *    SigInt():        Send SIGINT to dbx (action proc for Ctrl-C).
  44.  *    SigEof():        Send an EOF signal to dbx (action proc for Ctrl-D).
  45.  *    SigQuit():    Send SIGQUIT to dbx (action proc for Ctrl-\).
  46.  *    CreateDialogWindow(): Create dialog window and install action table.
  47.  *    AppendDialogText():       Append string to dialog window.
  48.  */
  49.  
  50. #include <signal.h>
  51. #include "global.h"
  52.  
  53. #define    DIALOGSIZE    100000        /* max size of dialogue window buffer */
  54.  
  55. Widget    dialogWindow;            /* text window as a dbx terminal */
  56. Boolean FalseSignal = FALSE;        /* set to TRUE before self-generated
  57.                        interrupt/quit signals */
  58. static char DialogText[DIALOGSIZE];    /* text buffer for widget */
  59. static XawTextPosition  StartPos;          /* starting position of input text */
  60.  
  61.  
  62. /*  This procedure prevents the user from deleting past the prompt, or
  63.  *  any text appended by AppendDialogText() to the dialog window.
  64.  *  It checks the last position of text, if it matches StartPos, set
  65.  *  by AppendDialogText(), it inserts a space so that delete-previous-
  66.  *  character() can only delete the space character.
  67.  */
  68. /* ARGSUSED */
  69. static void InsertSpace(w, event, params, num_params)
  70.     Widget w;
  71.     XEvent *event;
  72.     String *params;
  73.     Cardinal *num_params;
  74. {
  75.     XawTextBlock    textblock;
  76.     XawTextPosition lastPos;
  77.  
  78.     if (XawTextGetInsertionPoint(w) <= StartPos) {
  79.         lastPos = TextGetLastPos(w);
  80.     if (lastPos == StartPos) {
  81.         textblock.firstPos = 0;
  82.         textblock.length   = 1;
  83.         textblock.ptr      = " ";
  84.         XawTextReplace(w, lastPos, lastPos, &textblock);
  85.         XawTextSetInsertionPoint(w, lastPos+1);
  86.     }
  87.     }
  88. }
  89.  
  90. /*  Erases the preceding word.
  91.  *  Simulates the action of the WERASE character (ctrl-W).
  92.  */
  93. /* ARGSUSED */
  94. void DeleteWord(w, event, params, num_params)
  95.     Widget w;
  96.     XEvent *event;
  97.     String *params;
  98.     Cardinal *num_params;
  99. {
  100.     XawTextBlock        textblock;
  101.     XawTextPosition    pos;
  102.     Cardinal         i;
  103.  
  104.     textblock.firstPos = 0;
  105.     textblock.length   = 0;
  106.     textblock.ptr      = "";
  107.  
  108.     pos = XawTextGetInsertionPoint(w); 
  109.     if (pos <= StartPos)
  110.         pos = TextGetLastPos(w); 
  111.     for (i=pos; i > StartPos && DialogText[i-1] == ' '; i--);
  112.     for (; i > StartPos && DialogText[i-1] != ' '; i--);
  113.     XawTextReplace(w, i, pos, &textblock);
  114.     XawTextSetInsertionPoint(w, i);
  115. }
  116.  
  117.  
  118. /*  Deletes the entire current input line.
  119.  *  simulates the action of the KILL character (ctrl-U).
  120.  */
  121. /* ARGSUSED */
  122. void DeleteLine(w, event, params, num_params)
  123.     Widget w;
  124.     XEvent *event;
  125.     String *params;
  126.     Cardinal *num_params;
  127. {
  128.     XawTextBlock        textblock;
  129.     XawTextPosition     pos, beginPos;
  130.     Cardinal         i;
  131.     char        *s;
  132.  
  133.     textblock.firstPos = 0;
  134.     textblock.length   = 0;
  135.     textblock.ptr      = "";
  136.  
  137.     pos = XawTextGetInsertionPoint(w); 
  138.     if (w == dialogWindow) {
  139.     s = DialogText;
  140.     beginPos = StartPos;
  141.     if (pos <= beginPos)
  142.             pos = TextGetLastPos(w);
  143.     }
  144.     for (i=pos; i > beginPos && s[i-1] != '\n'; i--);
  145.     XawTextReplace(w, i, pos, &textblock);
  146.     XawTextSetInsertionPoint(w, i);
  147. }
  148.  
  149.  
  150. /*  Dispatch() is invoked on every <CR>.
  151.  *  It collects text from the dialog window and sends it to dbx.
  152.  *  If the string is a command to dbx (Prompt would be TRUE),
  153.  *  it is stored in the global variable, Command.
  154.  */
  155. /* ARGSUSED */
  156. static void Dispatch(w, event, params, num_params)
  157.     Widget w;
  158.     XEvent *event;
  159.     String *params;
  160.     Cardinal *num_params; 
  161. {
  162.     char s[LINESIZ];
  163.  
  164.     strcpy(s, DialogText + StartPos);
  165.     if (Prompt) {
  166.     send_command(s);
  167.     }
  168.     else {
  169.         write_dbx(s);
  170.     }
  171. }
  172.  
  173.  
  174. /*  Sends an interrupt signal, SIGINT, to dbx.
  175.  *  Simulates the action of the INTR character (ctrl-C).
  176.  */
  177. /* ARGSUSED */
  178. static void SigInt(w, event, params, num_params)
  179.     Widget w;
  180.     XEvent *event;
  181.     String *params;
  182.     Cardinal *num_params;
  183. {
  184.     FalseSignal = TRUE;
  185.     killpg(dbxpid, SIGINT);
  186. }
  187.  
  188.  
  189. /*  Sends an EOF signal to dbx. (ctrl-D) */
  190. /* ARGSUSED */
  191. static void SigEof(w, event, params, num_params)
  192.     Widget w;
  193.     XEvent *event;
  194.     String *params;
  195.     Cardinal *num_params;
  196. {
  197.     write_dbx("\04");
  198. }
  199.  
  200.  
  201. /*  Sends a QUIT signal, SIGQUIT, to dbx. 
  202.  *  Simulates the action of the QUIT character (ctrl-\) 
  203.  */
  204. /* ARGSUSED */
  205. static void SigQuit(w, event, params, num_params)
  206.     Widget w;
  207.     XEvent *event;
  208.     String *params;
  209.     Cardinal *num_params;
  210. {
  211.     FalseSignal = TRUE;
  212.     killpg(dbxpid, SIGQUIT);
  213. }
  214.  
  215.  
  216. /* 
  217.  *  Dialog window has its own set of translations for editing.
  218.  *  Special action procedures for keys Delete/Backspace, Carriage Return,
  219.  *  Ctrl-U, Ctrl-C, Ctrl-D, Ctrl-\, and word selection.
  220.  */
  221. void CreateDialogWindow(parent)
  222. Widget parent;
  223. {
  224.     Arg     args[MAXARGS];
  225.     Cardinal     n;
  226.  
  227.     static XtActionsRec dialog_actions[] = {
  228.     {"SigInt",     (XtActionProc) SigInt},
  229.     {"SigEof",     (XtActionProc) SigEof},
  230.     {"SigQuit",     (XtActionProc) SigQuit},
  231.     {"InsertSpace", (XtActionProc) InsertSpace},
  232.     {"Dispatch",     (XtActionProc) Dispatch},
  233.         {NULL, NULL}
  234.     };
  235.  
  236.     static String translations = "#override\n\
  237.      Ctrl<Key>C:    SigInt()\n\
  238.      Ctrl<Key>D:    SigEof()\n\
  239.      Ctrl<Key>|:    SigQuit()\n\
  240.      Ctrl<Key>W:    DeleteWord()\n\
  241.      Ctrl<Key>U:    DeleteLine()\n\
  242.      Ctrl<Key>H:    InsertSpace() delete-previous-character()\n\
  243.      <Key>Delete:    InsertSpace() delete-previous-character()\n\
  244.      <Key>BackSpace:    InsertSpace() delete-previous-character()\n\
  245.      <Key>Return:    newline() Dispatch()\n\
  246.     ";
  247.  
  248.     n = 0;
  249.     XtSetArg(args[n], XtNuseStringInPlace, True);                       n++;
  250.     XtSetArg(args[n], XtNstring, (XtArgVal) DialogText);        n++;
  251.     XtSetArg(args[n], XtNlength, (XtArgVal) DIALOGSIZE);        n++;
  252.     XtSetArg(args[n], XtNeditType, (XtArgVal) XawtextAppend);        n++;
  253.     XtSetArg(args[n], XtNscrollVertical, XawtextScrollAlways);        n++;
  254.     XtSetArg(args[n], XtNwrap, XawtextWrapWord);            n++;
  255.     dialogWindow = XtCreateManagedWidget("dialogWindow", asciiTextWidgetClass,
  256.                      parent, args, n );
  257.     XtOverrideTranslations(dialogWindow, XtParseTranslationTable(translations));
  258.     XtAppAddActions(app_context, dialog_actions, XtNumber(dialog_actions));
  259. }
  260.  
  261. static void TextSetLastPos(w, lastPos)
  262. Widget w;
  263. XawTextPosition lastPos;
  264. {
  265.     TextWidget ctx = (TextWidget) w;
  266.     ctx->text.lastPos = lastPos;
  267. }
  268.  
  269. void AppendDialogText(s)
  270.     char   *s;
  271. {
  272.     XawTextPosition     i, lastPos;
  273.     XawTextBlock        textblock, nullblock;
  274.     Arg         args[MAXARGS];
  275.     Cardinal         n;
  276.  
  277.     if (!s || !strcmp(s, "")) return;
  278.  
  279.     textblock.firstPos = 0;
  280.     textblock.length   = strlen(s);
  281.     textblock.ptr      = s;
  282.  
  283.     lastPos = TextGetLastPos(dialogWindow);
  284.     if (textblock.length > DIALOGSIZE) {
  285.     bell(0);
  286.     fprintf(stderr, "xdbx error: cannot display string in dialogue window\n\
  287.             string has %d bytes; dialogue window size limit is %d bytes\n",
  288.         textblock.length, DIALOGSIZE);
  289.         return;
  290.     }
  291.     if (lastPos + textblock.length > DIALOGSIZE) {
  292.     nullblock.firstPos = 0;
  293.     nullblock.length = 0;
  294.     nullblock.ptr = "";
  295.  
  296.     i = textblock.length - (DIALOGSIZE - lastPos);
  297.     if (i < 0.9*DIALOGSIZE)
  298.         i += 0.1*DIALOGSIZE;
  299.         while (DialogText[i] != '\n') i++;
  300.         XawTextReplace(dialogWindow, 0, i+1, &nullblock);
  301.         lastPos = TextGetLastPos(dialogWindow);
  302.     }
  303.     XawTextReplace(dialogWindow, lastPos, lastPos, &textblock);
  304.     StartPos = TextGetLastPos(dialogWindow);
  305.     XawTextSetInsertionPoint(dialogWindow, StartPos);
  306. }
  307.