home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / sys / hp / 15255 < prev    next >
Encoding:
Text File  |  1993-01-24  |  159.1 KB  |  5,777 lines

  1. Newsgroups: comp.sys.hp
  2. Path: sparky!uunet!cs.utexas.edu!torn!watserv2.uwaterloo.ca!maxwell.uwaterloo.ca!gordon
  3. From: gordon@maxwell.uwaterloo.ca (Gordon R. Strachan)
  4. Subject: XControl program and terminal emulator 3/4
  5. Message-ID: <C1CAMv.FLp@watserv2.uwaterloo.ca>
  6. Sender: news@watserv2.uwaterloo.ca
  7. Reply-To: gordon@maxwell.uwaterloo.ca (Gordon R. Strachan)
  8. Organization: University of Waterloo
  9. Date: Sun, 24 Jan 1993 03:49:42 GMT
  10. Lines: 5765
  11.  
  12.  
  13. # This is a shell archive.  Remove anything before this line,
  14. # then unpack it by saving it in a file and typing "sh file".
  15. #
  16. # Wrapped by Gordon R. Strachan <gordon@maxwell> on Sat Jan 23 22:18:43 1993
  17. #
  18. # This archive contains:
  19. #    GenTerm/Parse.c        GenTerm/Pty.c        
  20. #    GenTerm/Pty.man        GenTerm/TAGS        
  21. #    GenTerm/ctest.c        GenTerm/hpterm.par    
  22. #    GenTerm/test.c        xcontrol/ParseString.c    
  23. #    xcontrol/TAGS        xcontrol/XControl.ad    
  24. #
  25. # Error checking via wc(1) will be performed.
  26.  
  27. LANG=""; export LANG
  28. PATH=/bin:/usr/bin:$PATH; export PATH
  29.  
  30. echo x - GenTerm/Parse.c
  31. cat >GenTerm/Parse.c <<'@EOF'
  32. /* Parse.c : This file contains the terminal emulator parser */
  33. /* History:                                 */
  34. /*         Written by G. R. Strachan 1992 */
  35.  
  36. /*  Copyright Gordon R. Strachan 1992 */
  37. /*  This code is provided as is, neither the University of Waterloo nor */
  38. /*  the author is liable for any damage caused by the use or misuse of this */
  39. /*  code.  */
  40.  
  41. /* Permission is granted to copy, use and modify this code provided it is */
  42. /* not sold for profit and the above copyright remains intact. */
  43.  
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <termios.h>
  47. #include <X11/StringDefs.h>
  48. #include <X11/IntrinsicP.h>
  49. #include <X11/Shell.h>
  50. #include <X11/keysym.h>
  51. #include <X11/keysymdef.h>
  52. #include "GenTermEmP.h"
  53. #include "Parser.h"
  54.  
  55. static char *GtEIntToStringConvert();
  56. struct InputArgument *GtEPushArgs();
  57. void GtEPopArgs();
  58.  
  59. static int GtENewLine();
  60. static int GtEDownLine();
  61. static int GtEUpLine();
  62. static int GtECarriageReturn();
  63. static int GtENextTab();
  64. static int GtEMoveLeft();
  65. static int GtEMoveRight();
  66. static int GtESoundBell();
  67. static int GtEMoveCursor();
  68. static int GtEGetBottomText();
  69. static int GtEGetPosition();
  70. static int GtESetFont();
  71. static int GtEIgnore();
  72. static int GtESetField();
  73. static int GtEClearLine();
  74. static int GtEClearDisplay();
  75. static int GtEMath();
  76. static int GtELoadAttribute();
  77. static int GtEClearMemory();
  78. static int GtEInsertLines();
  79. static int GtEDeleteLines();
  80. static int GtESetTop();
  81. static int GtEDeleteCharacters();
  82. static int GtEGetTop();
  83. static int GtEGetScreenSize();
  84. static int GtESetInsertMode();
  85. static int GtESetTab();
  86. static int GtEUnSetTab();
  87. static int GtESetParseTable();
  88. static int GtESetKeyTable();
  89. static int GtESetResource();
  90. static int GtEGetResource();
  91. static int GtEEmit();
  92. static int GtEGetLine();
  93. static int GtEPreviousTab();
  94. static int GtESetScrollRegion();
  95. static int GtEIf();
  96. static int GtEReject();
  97. static int GtEGetTopOfScrollRegion();
  98. static int GtEQuit();
  99. static int GtEGetFont();
  100. static int GtESetInverseVideo();
  101. static int GtESetUnderLineMode();
  102. static int GtESetHalfBrightMode();
  103. static int GtESetBlinkMode();
  104. static int GtEProgramKey();
  105. static int GtESetPen();
  106. static int GtEGetPen();
  107. static int GtEDefinePen();
  108. static int GtEExecuteFunctionKey();
  109. static int GtEEscapeCallback();
  110. static int GtELoadMapTable();
  111. static int GtEProgramMapTable();
  112. static int GtEStore();
  113. static int GtEFetch();
  114. static int GtEOutputString();
  115. static int GtEGetArg();
  116. static int GtEGetLastButtonEvent();
  117. static int GtEToAscii();
  118. static int GtEConvertPosition();
  119. static int GtECheckModifiers();
  120. static int GtEGetStringLength();
  121. static int GtEGetSubString();
  122. static int GtEIntToString();
  123. static int GtESetFlow();
  124.  
  125. static int GtEMatchInt();
  126. static int GtEMatchDigits();
  127. static int GtEMatchSelect();
  128. static int GtEMatchString();
  129. static int GtEMatchFloat();
  130. static int GtEMatchUpto();
  131.  
  132. static int ArgToInt();
  133. static char *ArgToString();
  134. static float ArgToFloat();
  135.  
  136. struct FuncDefs Translators[]=
  137. {{"DownLine",GtEDownLine},
  138.   {"NewLine",GtENewLine},
  139.   {"CarriageReturn",GtECarriageReturn},
  140.   {"NextTab",GtENextTab},
  141.   {"MoveLeft",GtEMoveLeft},
  142.   {"MoveRight",GtEMoveRight},
  143.   {"MoveCursor",GtEMoveCursor},
  144.   {"GetBottomText",GtEGetBottomText},
  145.   {"GetPosition",GtEGetPosition},
  146.   {"SetFont",GtESetFont},
  147.   {"Ignore",GtEIgnore},
  148.   {"SoundBell",GtESoundBell},
  149.   {"UpLine",GtEUpLine},
  150.   {"SetField",GtESetField},
  151.   {"ClearLine",GtEClearLine},
  152.   {"ClearDisplay",GtEClearDisplay},
  153.   {"Math",GtEMath},
  154.   {"LoadAttribute",GtELoadAttribute},
  155.   {"ClearMemory",GtEClearMemory},
  156.   {"InsertLines",GtEInsertLines},
  157.   {"DeleteLines",GtEDeleteLines},
  158.   {"SetTop",GtESetTop},
  159.   {"DeleteCharacters",GtEDeleteCharacters},
  160.   {"GetTop",GtEGetTop},
  161.   {"GetScreenSize",GtEGetScreenSize},
  162.   {"SetInsertMode",GtESetInsertMode},
  163.   {"SetTab",GtESetTab},
  164.   {"UnSetTab",GtEUnSetTab},
  165.   {"SetParseTable",GtESetParseTable},
  166.   {"SetKeyTable",GtESetKeyTable},
  167.   {"SetResource",GtESetResource},
  168.   {"Emit",GtEEmit},
  169.   {"GetLine",GtEGetLine},
  170.   {"PreviousTab",GtEPreviousTab},
  171.   {"SetScrollRegion",GtESetScrollRegion},
  172.   {"If",GtEIf},
  173.   {"Reject",GtEReject},
  174.   {"GetTopOfScrollRegion",GtEGetTopOfScrollRegion},
  175.   {"Quit",GtEQuit},
  176.   {"GetFont",GtEGetFont},
  177.   {"SetInverseVideo",GtESetInverseVideo},
  178.   {"SetUnderLineMode",GtESetUnderLineMode},
  179.   {"SetHalfBrightMode",GtESetHalfBrightMode},
  180.   {"SetBlinkMode",GtESetBlinkMode},
  181.   {"ProgramKey",GtEProgramKey},
  182.   {"SetPen",GtESetPen},
  183.   {"GetPen",GtEGetPen},
  184.   {"DefinePen",GtEDefinePen},
  185.   {"ExecuteFunctionKey",GtEExecuteFunctionKey},
  186.   {"EscapeCallback",GtEEscapeCallback},
  187.   {"LoadMapTable",GtELoadMapTable},
  188.   {"ProgramMapTable",GtEProgramMapTable},
  189.   {"Store",GtEStore},
  190.   {"Fetch",GtEFetch},
  191.   {"OutputString",GtEOutputString},
  192.   {"GetResource",GtEGetResource},
  193.   {"GetArg",GtEGetArg},
  194.   {"GetLastButtonEvent",GtEGetLastButtonEvent},
  195.   {"ToAscii",GtEToAscii},
  196.   {"ConvertPosition",GtEConvertPosition},
  197.   {"CheckModifiers",GtECheckModifiers},
  198.   {"GetStringLength",GtEGetStringLength},
  199.   {"GetSubString",GtEGetSubString},
  200.   {"IntToString",GtEIntToString},
  201.   {"SetFlow",GtESetFlow},
  202.   {NULL,NULL}
  203. };
  204.  
  205. struct FuncDefs Specials[]=
  206. {{"Int",GtEMatchInt},
  207.   {"Select",GtEMatchSelect},
  208.   {"String",GtEMatchString},
  209.   {"Float",GtEMatchFloat},
  210.   {"Digits",GtEMatchDigits},
  211.   {"Upto",GtEMatchUpto},
  212.   {NULL,NULL}
  213. };
  214.  
  215. /* GtEParse:  This function is the main entry point to the GenTermEm Widget. */
  216. /*  It takes as input a string that is to be displayed.  It passes the */
  217. /*  string through the current parse table.  If it matches an entry in the */
  218. /*  table then the translators defined for that sequence are executed.  If */
  219. /*  no match is found then the string is simply displayed. */
  220.  
  221. GtEParse(w,string,len)
  222.  
  223. GenTermEmWidget w;
  224. char *string;
  225. int len;
  226.  
  227. {
  228.  int i,j,k;
  229.  char Storage[1024];
  230.  int StorePoint = 0;
  231.  struct ParseItem *temp;
  232.  struct Translator *StartTrans,*trans;
  233.  int Matched;
  234.  int Result;
  235.  int num;
  236.  int ReturnVal;
  237.  
  238.  for(i = 0; i < len; i++)
  239.   {
  240.    temp  = w->genTermEm.CurrentPoint;
  241.    Matched = 0;
  242.    while(temp != NULL)   /* first search for the character in parse table */
  243.     {
  244.      if(temp->c == string[i])    /* found and entry in our parse table */
  245.       {
  246.        w->genTermEm.InputStack[w->genTermEm.TopStack++] = string[i];
  247.        w->genTermEm.CurrentPoint = temp = temp->child;
  248.        Matched = 1;
  249.        break;
  250.       }
  251.      else
  252.       temp = temp->next;
  253.     }
  254.  
  255. /* if we didn't find a match, check if there is a special translator to call */
  256.  
  257.    if((Matched == 0) && (w->genTermEm.CurrentPoint->special != NULL))
  258.     {
  259.      Result = (w->genTermEm.CurrentPoint->special->func)(w,string,len,i,&num,
  260.                                                         w->genTermEm.CurrentPoint->special->arglist,
  261.                                                         w->genTermEm.CurrentPoint->special->position);
  262.  
  263. /* special parsers return a 0 for a bad match 1 for a complete match and 2 */
  264. /* for an incomplete match */
  265.      if(Result == 1)
  266.       {
  267.        w->genTermEm.CurrentPoint = w->genTermEm.CurrentPoint->child;
  268. /* store matched characters in case we reject them later */
  269.        for(j = 0; j < num; j++)
  270.         w->genTermEm.InputStack[w->genTermEm.TopStack++] = string[i+j];
  271.        if(num >= 0)
  272.     i += num - 1;
  273.        else
  274.     i += num;
  275.        Matched = 1;
  276.       }
  277.      else if (Result == 2)
  278.       {
  279.        for(j = 0; j < num; j++)
  280.         w->genTermEm.InputStack[w->genTermEm.TopStack++] = string[i+j];
  281.        i += num;
  282.        Matched = 1;
  283.       }
  284.      else    /* was a batch match, reject it */
  285.       {
  286.        Matched = 0;
  287.       }
  288.     }
  289.  
  290. /* okay, by now we have either matched the character or not.  If it is match */
  291. /* execute any translator bound to if any */
  292.  
  293.    if(Matched)
  294.     {
  295.      if(w->genTermEm.CurrentPoint->translators != NULL)
  296.       {
  297.        if(StorePoint != 0)
  298.         {
  299.          GtOutput(w,Storage,StorePoint); /* emit all stored chars before */
  300.          StorePoint = 0;                 /* calling the translators */
  301.         }
  302. /* before we call the translators we reset the parser just incase one of the */
  303. /* translators will cause the parser to re-entered */
  304.        StartTrans = trans = w->genTermEm.CurrentPoint->translators;
  305.        w->genTermEm.TopStack = 0;
  306.        w->genTermEm.CurrentPoint = w->genTermEm.ParseTable;
  307.        while(trans != NULL)
  308.         {
  309.          ReturnVal = (trans->func)(w,trans->arglist);
  310.      if(ReturnVal == TRANSERROR)
  311.       break;
  312.      else if(ReturnVal == TRANSOKAY)
  313.       trans = trans->next;
  314.      else if(ReturnVal == TRANSREJECT)
  315.       {     
  316.        w->genTermEm.CurrentPoint = w->genTermEm.ParseTable;
  317.        for(j = 0; j < w->genTermEm.TopStack; j++)
  318.         Storage[StorePoint++] = w->genTermEm.InputStack[j];
  319.        w->genTermEm.TopStack = 0;
  320.        Storage[StorePoint++] = string[i];
  321.        break;
  322.       }
  323.      else
  324.       {
  325.        trans = StartTrans;
  326.        while((trans != NULL) &&(trans->label != ReturnVal))
  327.         trans = trans->next;
  328.       }
  329.     }
  330. /* okay, here walk input argument list and free what ever needed */
  331. /* hmm... bug alert, InputArgs is not re-entrant if a translator causes the */
  332. /* input parser routine to be recalled it will over write the argumentlist */
  333. /* I don't know how to fix this right now, perhaps the proper thing to do is */
  334. /* to not allow translators to call the parse function (usually through a */
  335. /* kbdCallBack and instead queue up output to emit later... */
  336.        for(k = 0; k < NUMARGS; k++)
  337.         if(w->genTermEm.InputArgs[k].valid & AMALLOCED)
  338.          {
  339.           XtFree(w->genTermEm.InputArgs[k].string);
  340.           w->genTermEm.InputArgs[k].valid = 0;
  341.          }
  342.       }
  343.     }
  344.    else   /* wasn't matched, reject the characters already on the stack */
  345.     {
  346.      w->genTermEm.CurrentPoint = w->genTermEm.ParseTable;
  347.      for(j = 0; j < w->genTermEm.TopStack; j++)
  348.       Storage[StorePoint++] = w->genTermEm.InputStack[j];
  349.      w->genTermEm.TopStack = 0;
  350.      Storage[StorePoint++] = string[i];
  351.     }
  352.  
  353. /* The previous operation might have caused the screen to be scrolled.  In */
  354. /* this case we must hold off further processing because we don't know if */
  355. /* the X server was able to fufill the XCopyArea request.  Therefore, we */
  356. /* must store the characters which are waiting to be processed and break out */
  357. /* of this loop so we can return and process any graphics expose events */
  358. /* which might be waiting for us.  We must also stop listening to our input */
  359. /* descriptor because we can't service any more requests until all the */
  360. /* graphics exposures are processed */
  361.    if(w->genTerm.ExposureCount > 0)
  362.     break;
  363.   }
  364.  if(StorePoint != 0)
  365.   GtOutput(w,Storage,StorePoint);
  366.  if(w->genTerm.ExposureCount > 0)
  367.   GtESetWaitForGraphicsExpose(w,string,i+1,len);
  368. }
  369.  
  370. /* GtEPushArgs:  This function cause a new input argument list to be created */
  371. /*  and the old one is returned to the calling function for storage.  It is */
  372. /*  used to make the GtEParse function re-entrant. */
  373.  
  374. struct InputArgument *GtEPushArgs(w)
  375.  
  376. GenTermEmWidget w;
  377.  
  378. {
  379.  int i;
  380.  char *store;
  381.  struct InputArgument *temp = w->genTermEm.InputArgs;
  382.  
  383.  w->genTermEm.InputArgs = (struct InputArgument *)
  384.   XtMalloc(sizeof(struct InputArgument) * NUMARGS);
  385.  for(i = 0; i < NUMARGS; i++)
  386.   {
  387.    w->genTermEm.InputArgs[i].valid = 0;
  388.    if((temp[i].valid & ADEFINED) && ((temp[i].valid & AMALLOCED) == 0))
  389.     {
  390.      store = XtMalloc(temp[i].length + 1);
  391.      memcpy(store,temp[i].string,temp[i].length);
  392.      temp[i].string = store;
  393.      temp[i].valid |= AMALLOCED;
  394.     }
  395.   }
  396.  return(temp);
  397. }
  398.  
  399. /* GtEPopArgs: This function causes the input argument list to be reset to */
  400. /*   its previously stored value.  The current input list is freed. */
  401.  
  402. void GtEPopArgs(w,New)
  403.  
  404. GenTermEmWidget w;
  405. struct InpuArgument *New;
  406.  
  407. {
  408.  int i;
  409.  
  410.  for(i = 0; i < NUMARGS; i++)
  411.   if(w->genTermEm.InputArgs[i].valid & AMALLOCED)
  412.    XtFree(w->genTermEm.InputArgs[i].string);
  413.  XtFree(w->genTermEm.InputArgs);
  414.  
  415.  w->genTermEm.InputArgs = New;
  416. }
  417.  
  418. /* Start of special matching functions for the parser */
  419.  
  420. /* GtEMatchInt:  This function attemprs to match a string of digits from the */
  421. /*  input stream and collect them into an integer. It takes as an arguement */
  422. /*  the number of digits to match.  If no argument is given then it matches */
  423. /*  upto the next non-digit character. */
  424.  
  425. static int GtEMatchInt(w,string,len,start,num,args,position)
  426.  
  427. GenTermEmWidget w;
  428. char *string;
  429. int len;
  430. int start;
  431. int *num;
  432. struct ArgumentList *args;
  433. int position;
  434.  
  435. {
  436.  int i;
  437.  
  438.  if(w->genTermEm.SpecialVars.Started == 0)   /* first time called? */
  439.   {
  440.    w->genTermEm.SpecialVars.Started = 1;
  441.    w->genTermEm.InputArgs[position].valid = 0;
  442.    w->genTermEm.InputArgs[position].length = 0;
  443.    w->genTermEm.SpecialVars.store.NumToGo = ArgToInt(w,args,1,-1);
  444.   }
  445.  
  446.  *num = 0;
  447.  for(i = start; i < len; i++)
  448.   {
  449.    if(isdigit(string[i]) || ((w->genTermEm.SpecialVars.Started == 1) && 
  450.                  (string[i] == '-')))
  451.     {
  452.      w->genTermEm.SpecialVars.Started = 2;
  453.      if(w->genTermEm.InputArgs[position].valid == 0)
  454.       {
  455. /* this is a bit of a kludge.  We need to remember the characters matched */
  456. /* so we can get them later.  We make the string point to the top of the */
  457. /* input stack because we know GtEParse will store the characters there */
  458.        w->genTermEm.InputArgs[position].string = 
  459.     &(w->genTermEm.InputStack[w->genTermEm.TopStack]);
  460.        w->genTermEm.InputArgs[position].valid = ADEFINED;
  461.       }
  462.      *num += 1;
  463.      w->genTermEm.InputArgs[position].length++;
  464.      w->genTermEm.SpecialVars.store.NumToGo--;
  465.      if(w->genTermEm.SpecialVars.store.NumToGo == 0)
  466.       {
  467.        w->genTermEm.SpecialVars.Started = 0;
  468.        return(1);
  469.       }
  470.     }
  471.    else
  472.     {
  473.      w->genTermEm.SpecialVars.Started = 0;
  474.  
  475. /* found a non integer character, if we were to match a unknown number of */
  476. /* characters and have matched some then return success, otherwise flag an */
  477. /* error */
  478.  
  479.      if((w->genTermEm.SpecialVars.store.NumToGo < 0) && 
  480.     (w->genTermEm.InputArgs[position].length > 0))
  481.       {
  482.        if(i == start)  /* if we failed on first character force a reparse */
  483.     *num -= 1;
  484.        return(1);
  485.       }
  486.      else
  487.       {
  488.        w->genTermEm.InputArgs[position].valid = 0;
  489.        return(0);
  490.       }
  491.     }
  492.   }
  493.  return(2);
  494. }
  495.  
  496. /* GtEMatchDigits:  This translator attempts to match a list of zero or more */
  497. /*  digits from the input stream and collect them into a list of integers. */
  498. /*  It takes as its arguments, the default value to return is no arguments */
  499. /*  are given and the character which is used to seperate the list. An */
  500. /*  optional third argument exists to specify the number of digits in each */
  501. /*  number otherwise an arbirtrary number is matched. */
  502.  
  503. static int GtEMatchDigits(w,string,len,start,num,args,position)
  504.  
  505. GenTermEmWidget w;
  506. char *string;
  507. int len;
  508. int start;
  509. int *num;
  510. struct ArgumentList *args;
  511. int position;
  512.  
  513. {
  514.  int i;
  515.  char buffer[1024];
  516.  int place;
  517.  
  518.  if(w->genTermEm.SpecialVars.Started == 0)   /* first time called? */
  519.   {
  520.    w->genTermEm.SpecialVars.Started = 1;
  521.    w->genTermEm.InputArgs[position].valid = 0;
  522.    w->genTermEm.InputArgs[position].length = 0;
  523.    ArgToString(w,args,2," ",w->genTermEm.SpecialVars.store.DigitsVars.Sep,1);
  524.    w->genTermEm.SpecialVars.store.DigitsVars.NumToGo = ArgToInt(w,args,3,-1);
  525.    w->genTermEm.SpecialVars.store.DigitsVars.Store = position;
  526.   }
  527.  
  528.  *num = 0;
  529.  place = w->genTermEm.SpecialVars.store.DigitsVars.Store;
  530.  for(i = start; i < len; i++)
  531.   {
  532.    if(isdigit(string[i]))
  533.     {
  534.      if(w->genTermEm.InputArgs[place].valid == 0)
  535.       {
  536. /* this is a bit of a kludge.  We need to remember the characters matched */
  537. /* so we can get them later.  We make the string point to the top of the */
  538. /* input stack because we know GtEParse will store the characters there */
  539.        w->genTermEm.InputArgs[place].string = 
  540.     &(w->genTermEm.InputStack[w->genTermEm.TopStack + *num]);
  541.        w->genTermEm.InputArgs[place].valid = ADEFINED;
  542.       }
  543.      *num += 1;
  544.      w->genTermEm.InputArgs[place].length++;
  545.      w->genTermEm.SpecialVars.store.DigitsVars.NumToGo--;
  546.      if(w->genTermEm.SpecialVars.store.DigitsVars.NumToGo == 0)
  547.       {
  548.        w->genTermEm.SpecialVars.Started = 0;
  549.        return(1);
  550.       }
  551.     }
  552.    else if(string[i] == w->genTermEm.SpecialVars.store.DigitsVars.Sep[0])
  553.     {    /* found end of one integer start next one in list */
  554.      if(w->genTermEm.InputArgs[place].length == 0)
  555.       {
  556.        ArgToString(w,args,1,"",buffer,1023);
  557.        StringToInputArg(w,place,buffer,strlen(buffer));
  558.       }
  559.      w->genTermEm.SpecialVars.store.DigitsVars.Store += 1;
  560.      place++;
  561.  
  562.      w->genTermEm.InputArgs[place].valid = 0;
  563.      w->genTermEm.InputArgs[place].length = 0;
  564.      w->genTermEm.SpecialVars.store.DigitsVars.NumToGo = ArgToInt(w,args,3,-1);
  565.      *num += 1;
  566.     }
  567.    else
  568.     {
  569.      w->genTermEm.SpecialVars.Started = 0;
  570.  
  571. /* found a non integer character, if we haven't matched any characters then */
  572. /* return the default.  If we found some, but not the right number then */
  573. /* return an error.  If we were to match a unknown number of characters and */
  574. /*  have matched some then return success */
  575.  
  576.      if(w->genTermEm.InputArgs[place].length == 0)
  577.       {
  578.        ArgToString(w,args,1,"",buffer,1023);
  579.        StringToInputArg(w,place,buffer,strlen(buffer));
  580.        StringToInputArg(w,place+1,buffer,strlen(buffer));
  581.        return(1);
  582.       }
  583.      else if((w->genTermEm.SpecialVars.store.DigitsVars.NumToGo < 0) && 
  584.     (w->genTermEm.InputArgs[place].length > 0))
  585.       {
  586. /* set the next token to the default to signal end of the list */
  587.        ArgToString(w,args,1,"",buffer,1023);
  588.        StringToInputArg(w,place+1,buffer,strlen(buffer));
  589.        if(i == start) 
  590.     *num -= 1;
  591.        return(1);
  592.       }
  593.      else
  594.       {
  595.        w->genTermEm.InputArgs[place].valid = 0;
  596.        return(0);
  597.       }
  598.     }
  599.   }
  600.  return(2);
  601. }
  602. /* GtEMatchSelect:  This function attempts to match a character against */
  603. /*  any of the characters given as arguements. */
  604.  
  605. static int GtEMatchSelect(w,string,len,start,num,args,position)
  606.  
  607. GenTermEmWidget w;
  608. char *string;
  609. int len;
  610. int start;
  611. int *num;
  612. struct ArgumentList *args;
  613. int position;
  614.  
  615. {
  616.  int i;
  617.  char match[2];
  618.  
  619.  for(i = 1; i <= args->NumArgs; i++)
  620.   {
  621.    ArgToString(w,args,i," ",match,1);
  622.    if(match[0] == string[start])    /* do we have a match? */
  623.     {
  624.      *num = 1;
  625.      w->genTermEm.InputArgs[position].string = 
  626.       &(w->genTermEm.InputStack[w->genTermEm.TopStack]);
  627.      w->genTermEm.InputArgs[position].valid = ADEFINED;
  628.      w->genTermEm.InputArgs[position].length = 1;
  629.      return(1);
  630.     }
  631.   }
  632.  return(0);
  633. }
  634.  
  635. /* GtEMatchFloat: This function attempts to match a floating point number */
  636. /*  It does not consider exponentional notation */
  637.  
  638. static int GtEMatchFloat(w,string,len,start,num,args,position)
  639.  
  640. GenTermEmWidget w;
  641. char *string;
  642. int len;
  643. int start;
  644. int *num;
  645. struct ArgumentList *args;
  646. int position;
  647.  
  648. {
  649.  int i;
  650.  int good;
  651.  
  652.  if(w->genTermEm.SpecialVars.Started == 0)
  653.   {
  654.    w->genTermEm.SpecialVars.Started = 1;
  655.    w->genTermEm.InputArgs[position].valid = 0;
  656.    w->genTermEm.InputArgs[position].length = 0;
  657.    w->genTermEm.SpecialVars.store.FloatVars.IntNumToGo = ArgToInt(w,args,1,-1);
  658.    w->genTermEm.SpecialVars.store.FloatVars.FracNumToGo = ArgToInt(w,args,2,-1);
  659.    w->genTermEm.SpecialVars.store.FloatVars.SeenDot = 0;
  660.   }
  661.  
  662.  *num = 0;
  663.  for(i = start; i < len; i++)
  664.   {
  665.    good = False;
  666.    if(string[i] == '.')
  667.     {
  668.      if(w->genTermEm.SpecialVars.store.FloatVars.SeenDot == 0)
  669.       {
  670.        good = True;
  671.        w->genTermEm.SpecialVars.store.FloatVars.SeenDot = 1;
  672.       }
  673.     }
  674.    else if(isdigit(string[i]))
  675.     {
  676.      if(w->genTermEm.SpecialVars.store.FloatVars.SeenDot == 0)
  677.       {
  678.        if(w->genTermEm.SpecialVars.store.FloatVars.IntNumToGo == 0)
  679.     {   /* bad number of digits in the integer part! */
  680.      w->genTermEm.InputArgs[position].valid = 0;
  681.      return(0);
  682.     }
  683.        w->genTermEm.SpecialVars.store.FloatVars.IntNumToGo--;
  684.        good = True;
  685.       }
  686.      else
  687.       {
  688.        good = True;
  689.        w->genTermEm.SpecialVars.store.FloatVars.FracNumToGo--;
  690.       }
  691.     }
  692.    else
  693.     {
  694.      w->genTermEm.SpecialVars.Started = 0;
  695. /* found a non valid character, if we were to match an unknown number of */
  696. /* digits in the decimal part then return success. */
  697.      
  698.      if((w->genTermEm.SpecialVars.store.FloatVars.FracNumToGo < 0) &&
  699.     (w->genTermEm.InputArgs[position].length > 0))
  700.       {
  701.        if(i == start)
  702.     *num -= 1;
  703.        return(1);
  704.       }
  705.      else
  706.       {
  707.        w->genTermEm.InputArgs[position].valid = 0;
  708.        return(0);
  709.       }
  710.     }
  711.    if(good)
  712.     {
  713.      if(w->genTermEm.InputArgs[position].valid == 0)
  714.       w->genTermEm.InputArgs[position].string =
  715.        &(w->genTermEm.InputStack[w->genTermEm.TopStack]);
  716.      w->genTermEm.InputArgs[position].valid = ADEFINED;
  717.     }
  718.    *num += 1;
  719.    w->genTermEm.InputArgs[position].length++;
  720.    if(w->genTermEm.SpecialVars.store.FloatVars.FracNumToGo == 0)
  721.     return(1);
  722.   }
  723.  return(2);
  724. }
  725.  
  726. /* GtEMatchString:  This function attempts to match an arbitrary string of */
  727. /*  characters of a given length.  Right now it will keep waiting for a */
  728. /*  match even if the character never shows up.  Perhaps it should time out */
  729. /*  after a while but then, what would the appropriate thing be to do? */
  730.  
  731. static int GtEMatchString(w,string,len,start,num,args,position)
  732.  
  733. GenTermEmWidget w;
  734. char *string;
  735. int len;
  736. int start;
  737. int *num;
  738. struct ArgumentList *args;
  739. int position;
  740.  
  741. {
  742.  int i;
  743.  
  744.  if(w->genTermEm.SpecialVars.Started == 0)   /* first time called? */
  745.   {
  746.    *num = 0;
  747.    w->genTermEm.SpecialVars.Started = 1;
  748.    w->genTermEm.InputArgs[position].valid = 0;
  749.    w->genTermEm.InputArgs[position].length = 0;
  750.    w->genTermEm.SpecialVars.store.NumToGo = ArgToInt(w,args,1,-1);
  751.  
  752.    if((w->genTermEm.SpecialVars.store.NumToGo == -1) || 
  753.       (w->genTermEm.SpecialVars.store.NumToGo == 0))
  754.     /*XtAppError(XtWidgetToApplicationContext(w),
  755.       "Error in GenTermEm widget, String matching function needs a non-zero argument!");*/
  756.     return(1);
  757.    
  758.    w->genTermEm.InputArgs[position].string = 
  759.     &(w->genTermEm.InputStack[w->genTermEm.TopStack]);
  760.    w->genTermEm.InputArgs[position].valid = ADEFINED;
  761.   }
  762.  
  763.  *num = 0;
  764.  for(i = start; i <len; i++)
  765.   {
  766.    *num += 1;
  767.    w->genTermEm.InputArgs[position].length += 1;
  768.    w->genTermEm.SpecialVars.store.NumToGo -= 1;
  769.  
  770.    if(w->genTermEm.SpecialVars.store.NumToGo == 0)
  771.     {
  772.      w->genTermEm.SpecialVars.Started = 0;
  773.      return(1);
  774.     }
  775.   }
  776.  return(2);
  777. }
  778.  
  779. /* GtEMatchUpto:  This function attempts to match an arbitrary input stream */
  780. /*  upto the specified character.  That specified character is not returned */
  781. /*  on the input stack. */
  782.  
  783. static int GtEMatchUpto(w,string,len,start,num,args,position)
  784.  
  785. GenTermEmWidget w;
  786. char *string;
  787. int len;
  788. int start;
  789. int *num;
  790. struct ArgumentList *args;
  791. int position;
  792.  
  793. {
  794.  int i;
  795.  char input[2];
  796.  
  797.  if(w->genTermEm.SpecialVars.Started == 0)   /* first time called? */
  798.   {
  799.    w->genTermEm.SpecialVars.Started = 1;
  800.    w->genTermEm.InputArgs[position].valid = 0;
  801.    w->genTermEm.InputArgs[position].length = 0;
  802.    ArgToString(w,args,1,"",input,1);
  803.    w->genTermEm.SpecialVars.store.NumToGo = (int) input[0];
  804.  
  805.    if(w->genTermEm.SpecialVars.store.NumToGo == 0-1)
  806.     XtAppError(XtWidgetToApplicationContext(w),
  807.            "Error in GenTermEm widget, Upto matching function needs a non-zero argument!");
  808.    
  809.    w->genTermEm.InputArgs[position].string = 
  810.     &(w->genTermEm.InputStack[w->genTermEm.TopStack]);
  811.    w->genTermEm.InputArgs[position].valid = ADEFINED;
  812.   }
  813.  
  814.  *num = 0;
  815.  for(i = start; i <len; i++)
  816.   {
  817.    *num += 1;
  818.    w->genTermEm.InputArgs[position].length += 1;
  819.    if(string[i] == (char)w->genTermEm.SpecialVars.store.NumToGo)
  820.     {
  821.      w->genTermEm.SpecialVars.Started = 0;
  822.      return(1);
  823.     }
  824.   }
  825.  return(2);
  826. }
  827.  
  828. /* ArgToInt:  This function converts parser argument list element into an */
  829. /*  integer value.  If the requested argument is not is not in the list then */
  830. /*  the default value is returned. */
  831.  
  832. static int ArgToInt(w,args,position,def)
  833.  
  834. GenTermEmWidget w;
  835. struct ArgumentList *args;
  836. int position;
  837. int def;
  838.  
  839. {
  840.  int n;
  841.  char string [1024];
  842.  
  843.  if(args->NumArgs < position)
  844.   return(def);
  845.  else
  846.   {
  847.    switch(args->args[position-1].type)
  848.     {
  849.    case AINT:
  850.      return(args->args[position-1].n);
  851.    case APOSITION:
  852.      n = args->args[position-1].n;
  853.      if(w->genTermEm.InputArgs[n].valid)
  854.       {
  855.        memcpy(string,w->genTermEm.InputArgs[n].string,
  856.            w->genTermEm.InputArgs[n].length);
  857.        string[w->genTermEm.InputArgs[n].length] = NULL;
  858.        return(atoi(string));
  859.       }
  860.      else
  861.       return(def);
  862.    case ASTRING:
  863.      return(atoi(args->args[position-1].string));
  864.     }
  865.   }
  866. }
  867.  
  868. /* ArgToFloat: This function converts an input parser argument into a */
  869. /* float. */
  870.  
  871. static float ArgToFloat(w,args,position,def)
  872.  
  873. GenTermEmWidget w;
  874. struct ArgumentList *args;
  875. int position;
  876. float def;
  877.  
  878. {
  879.  int n;
  880.  char string[1024];
  881.  
  882.  if(args->NumArgs < position)
  883.   return(def);
  884.  else
  885.   {
  886.    switch(args->args[position-1].type)
  887.     {
  888.    case AINT:
  889.      return((float)args->args[position-1].n);
  890.    case APOSITION:
  891.      n = args->args[position-1].n;
  892.      if(w->genTermEm.InputArgs[n].valid)
  893.       {
  894.        memcpy(string,w->genTermEm.InputArgs[n].string,
  895.            w->genTermEm.InputArgs[n].length);
  896.        string[w->genTermEm.InputArgs[n].length] = NULL;
  897.        return((float)atof(string));
  898.       }
  899.      else
  900.       return(def);
  901.    case ASTRING:
  902.      return((float)atof(args->args[position-1].string));
  903.     }
  904.   }
  905. }
  906.  
  907. /* ArgToString:  This function converts an input parser argument into a  */
  908. /*  string.  The output is stored in the given string which must be big */
  909. /*  enough to store everything.  */
  910.  
  911. static char *ArgToString(w,args,position,def,string,len)
  912.  
  913. GenTermEmWidget w;
  914. struct ArgumentList *args;
  915. int position;
  916. char *def;
  917. char *string;
  918. int len;
  919.  
  920. {
  921.  int n;
  922.  char store[1024];
  923.  
  924.   if(args->NumArgs < position)
  925.   {
  926.    memcpy(string,def,len);
  927.    string[len] = NULL;
  928.    return(string);
  929.   }
  930.  else
  931.   {
  932.    position--;
  933.    switch(args->args[position].type)
  934.     {
  935.    case AINT:
  936.      GtEIntToStringConvert(args->args[position].n,store);
  937.      memcpy(string,store,len);
  938.      string[len] = NULL;
  939.      return(string);
  940.    case APOSITION:
  941.      n = args->args[position].n;
  942.      if(w->genTermEm.InputArgs[n].valid)
  943.       {
  944.        if(w->genTermEm.InputArgs[n].length < len)
  945.     len = w->genTermEm.InputArgs[n].length;
  946.        memcpy(string,w->genTermEm.InputArgs[n].string,len);
  947.        string[len] = NULL;
  948.       }
  949.      else
  950.       {
  951.        memcpy(string,def,len);
  952.        string[len] = NULL;
  953.       }
  954.      return(string);
  955.    case ASTRING:
  956.      if(args->args[position].n < len)
  957.       len= args->args[position].n;
  958.      memcpy(string,args->args[position].string,len);
  959.      string[len] = NULL;
  960.      return(string);
  961.     }
  962.   }
  963. }
  964.  
  965. /* GtEIntToStringConvert:  This function takes an integer and converts it */
  966. /*   into a string*/
  967.  
  968. static char *GtEIntToStringConvert(num,string)
  969.  
  970. int num;
  971. char *string;
  972.  
  973. {
  974.  int len,j,digit;
  975.  int flag = 0;
  976.  char store[200];
  977.  
  978.  if(num == 0)
  979.   strcpy(string,"0");
  980.  else
  981.   {
  982.    j = 0;
  983.    if(num < 0)
  984.     {
  985.      flag = 1;
  986.      num = num * -1;
  987.     }
  988.    while(num > 0)
  989.     {
  990.      digit = num / 10;
  991.      store[j++] = '0' + num - digit * 10;
  992.      num = digit;
  993.     }
  994.    string[j+flag] = NULL;
  995.    if(flag == 1)
  996.     string[0] = '-';
  997.    for(num = 0; num < j; num++)
  998.     string[num+flag] = store[j-1-num];
  999.   }
  1000.  return(string);
  1001. }
  1002.  
  1003. /* IntToInputArg:  This function takes an integer and stores it as an input */
  1004. /*  argument in the given argument position */
  1005.  
  1006. static int IntToInputArg(w,position,num)
  1007.  
  1008. GenTermEmWidget w;
  1009. int position;
  1010. int num;
  1011.  
  1012. {
  1013.  char string[1024];
  1014.  int len;
  1015.  int j;
  1016.  int digit;
  1017.  
  1018.  if((position < 0) || (position >= NUMARGS))
  1019.   {
  1020.    XtAppWarning(XtWidgetToApplicationContext(w),
  1021.            "GenTermEm Widget: Invalid position number in IntToInputArg");
  1022.    return(-1);
  1023.   }
  1024.  
  1025.  GtEIntToStringConvert(num,string);
  1026.  j = strlen(string);
  1027.  
  1028.  if((w->genTermEm.InputArgs[position].valid & ADEFINED) &&
  1029.     (w->genTermEm.InputArgs[position].valid & AMALLOCED))
  1030.   XtFree(w->genTermEm.InputArgs[position].string);
  1031.  
  1032.  w->genTermEm.InputArgs[position].valid = ADEFINED | AMALLOCED;
  1033.  w->genTermEm.InputArgs[position].length = j;
  1034.  w->genTermEm.InputArgs[position].string = 
  1035.   (char *) XtMalloc(sizeof(char)*j+1);
  1036.  w->genTermEm.InputArgs[position].string[j] = NULL;
  1037.  strcpy(w->genTermEm.InputArgs[position].string,string);
  1038. }
  1039.  
  1040. /* StringToInputArg:  This function takes a string and stores it as an input */
  1041. /*  argumet in the given argument position */
  1042.  
  1043. static int StringToInputArg(w,position,string,len)
  1044.  
  1045. GenTermEmWidget w;
  1046. int position;
  1047. char *string;
  1048. int len;
  1049.  
  1050. {
  1051.  
  1052.  if((position < 0) || (position >= NUMARGS))
  1053.   {
  1054.    XtAppWarning(XtWidgetToApplicationContext(w),
  1055.         "GenTermEm Widget: Invalid argument number in StringToInputArg");
  1056.    return(-1);
  1057.   }
  1058.  
  1059.  if((w->genTermEm.InputArgs[position].valid & ADEFINED) &&
  1060.     (w->genTermEm.InputArgs[position].valid & AMALLOCED))
  1061.   XtFree(w->genTermEm.InputArgs[position].string);
  1062.  
  1063.  w->genTermEm.InputArgs[position].valid = ADEFINED | AMALLOCED;
  1064.  w->genTermEm.InputArgs[position].length = len;
  1065.  w->genTermEm.InputArgs[position].string =
  1066.   (char *) XtMalloc(sizeof(char)*(len + 1));
  1067.  memcpy(w->genTermEm.InputArgs[position].string,string,len);
  1068.  w->genTermEm.InputArgs[position].string[len] = NULL;
  1069. }
  1070.  
  1071. /*  We now begin the second of the parser which implement the individual */
  1072. /*  translators. */
  1073.  
  1074. /* GtENewLine:  This translator implements the newline function.  It moves */
  1075. /*  the current position down one line and will force a scroll at the bottom */
  1076. /*  of a scroll region. */
  1077.  
  1078. static int GtENewLine(w,args)
  1079.  
  1080. GenTermEmWidget w;
  1081. struct ArgumentList *args;
  1082.  
  1083. {
  1084.  GtNewLine(w,1);
  1085.  return(TRANSOKAY);
  1086. }
  1087.  
  1088. /* GtEDownLine:  This translator moves the cursor down n lines.  If wrap=0 */
  1089. /*  the screen will be scrolled up at the bottom of the screen.  If wrap=1 */
  1090. /*  the cursor will wrap around to the top. If wrap=2, then the cursor */
  1091. /*  sticks at the bottom. */
  1092.  
  1093. static int GtEDownLine(w,args)
  1094.  
  1095. GenTermEmWidget w;
  1096. struct ArgumentList *args;
  1097.  
  1098. {
  1099.  int n = 0;
  1100.  int wrap;
  1101.  
  1102.  n = ArgToInt(w,args,1,1);
  1103.  wrap = ArgToInt(w,args,2,0);
  1104.  GtCursorDown(w,n,wrap);
  1105.  return(TRANSOKAY);
  1106. }
  1107.  
  1108. /* GtEUpLine: This translator moves the cursor up n lines.  If wrap=0, the */
  1109. /*  screen is scrolled down when the cursor moves passed the top.  If wrap=1,*/
  1110. /*  the cursor will wrap around to the bottom. If wrap=2, the cursor will */
  1111. /*  stick at the top of the screen. */
  1112.  
  1113. static int GtEUpLine(w,args)
  1114.  
  1115. GenTermEmWidget w;
  1116. struct ArgumentList *args;
  1117.  
  1118. {
  1119.  int n,wrap;
  1120.  
  1121.  n = ArgToInt(w,args,1,1);
  1122.  wrap = ArgToInt(w,args,2,0);
  1123.  GtCursorUp(w,n,wrap);
  1124.  return(TRANSOKAY);
  1125. }
  1126.  
  1127. /* GtEMoveLeft:  This translator moves the cursor left n lines.  If wrap = 0 */
  1128. /*  the cursor will remain at the column 0 when it hits it.  If wrap = 1 the */
  1129. /*  cursor will wrap around to the rightmost column. */
  1130.  
  1131. static int GtEMoveLeft(w,args)
  1132.  
  1133. GenTermEmWidget w;
  1134. struct ArgumentList *args;
  1135.  
  1136. {
  1137.  int n = 0;
  1138.  int wrap;
  1139.  int roll;
  1140.  
  1141.  n = ArgToInt(w,args,1,1);
  1142.  wrap = ArgToInt(w,args,2,0);
  1143.  roll = ArgToInt(w,args,3,0); 
  1144.  GtCursorLeft(w,n,wrap,roll);
  1145.  return(TRANSOKAY);
  1146. }
  1147.  
  1148. /* GtEMoveRight:  This translator ove the cursor right n lines.  If wrap = 0 */
  1149. /*  the cursor remains at the rightmost column.  Otherwise, it wraps around */
  1150. /*  to the leftmost one. If roll=0 the cursor will wrap from the bottom right*/
  1151. /*  of the screen to the top left, otherwise it the screen is rolled up */
  1152.  
  1153. static int GtEMoveRight(w,args)
  1154.  
  1155. GenTermEmWidget w;
  1156. struct ArgumentList *args;
  1157.  
  1158. {
  1159.  int n;
  1160.  int wrap;
  1161.  int roll;
  1162.  
  1163.  n = ArgToInt(w,args,1,1);
  1164.  wrap = ArgToInt(w,args,2,0);
  1165.  roll = ArgToInt(w,args,3,0);
  1166.  GtCursorRight(w,n,wrap,roll);
  1167.  return(TRANSOKAY);
  1168. }
  1169.  
  1170. /* GtEMoveCursor:  Move the cursor to the position given by the row and */
  1171. /*  column argument.  If this position is invalid, GtSetCursorPosition will */
  1172. /*  move to the closest valid position. */
  1173.  
  1174. static int GtEMoveCursor(w,args)
  1175.  
  1176. GenTermEmWidget w;
  1177. struct ArgumentList *args;
  1178.  
  1179. {
  1180.  int row,column;
  1181.  
  1182.  row = ArgToInt(w,args,1,0);
  1183.  column = ArgToInt(w,args,2,0);
  1184.  
  1185.  GtSetCursorPosition(w,row,column);
  1186.  return(TRANSOKAY);
  1187. }
  1188.  
  1189. /* GtECarriageReturn:  This translator moves the current position to column 0*/
  1190.  
  1191. static int GtECarriageReturn(w,args)
  1192.  
  1193. GenTermEmWidget w;
  1194. struct ArgumentList *args;
  1195.  
  1196. {
  1197.  GtCursorReturn(w);
  1198.  return(TRANSOKAY);
  1199. }
  1200.  
  1201. /* GtENextTab:  This translator moves the cursor to the next tab stop.  If */
  1202. /*  destructive tabs are set, the movement is performed by outputing spaces */
  1203. /*  otherwise a simple cursor move is performed. */
  1204.  
  1205. static int GtENextTab(w,args)
  1206.  
  1207. GenTermEmWidget w;
  1208. struct ArgumntList *args;
  1209.  
  1210. {
  1211.  int crow,ccolumn;
  1212.  int i;
  1213.  int fcolumn;
  1214.  int dist;
  1215.  char buffer[80];
  1216.  
  1217.  GtGetCursorPosition(w,&crow,&ccolumn);
  1218.  for(i = 0; i < NTABS; i++)
  1219.   if(w->genTermEm.TabStops[i] > ccolumn)
  1220.    break;
  1221.  if(i == NTABS)
  1222.   fcolumn = w->genTermEm.TabStops[NTABS - 1];
  1223.  else
  1224.   fcolumn = w->genTermEm.TabStops[i];
  1225.  
  1226.  dist = fcolumn - ccolumn;
  1227.  if(w->genTermEm.DestructiveTab == TRUE)
  1228.   {
  1229.    for(i = 0; i < dist; i++)
  1230.     buffer[i] = ' ';
  1231.    GtOutput(w,buffer,dist);
  1232.   }
  1233.  else
  1234.   GtCursorRight(w,dist,1,1);
  1235.  return(TRANSOKAY);
  1236. }
  1237.  
  1238. /* PreviousTab:  This translator moves the cursor to the previous tab stop */
  1239. /*  If there are no tab stops to the left then the cursor is moved to column */
  1240. /*  zero. */
  1241.  
  1242. static int GtEPreviousTab(w,args)
  1243.  
  1244. GenTermEmWidget w;
  1245. struct ArgumentList *args;
  1246.  
  1247. {
  1248.  int crow,ccolumn;
  1249.  int i;
  1250.  int fcolumn = 0;
  1251.  int dist;
  1252.  
  1253.  GtGetCursorPosition(w,&crow,&ccolumn);
  1254.  for(i = NTABS - 1; i >= 0; i--)
  1255.   if(w->genTermEm.TabStops[i] <= ccolumn)
  1256.    {
  1257.     fcolumn = w->genTermEm.TabStops[i];
  1258.     break;
  1259.    }
  1260.  
  1261.  dist = ccolumn - fcolumn;
  1262.  GtCursorLeft(w,dist,0,1);
  1263.  return(TRANSOKAY);
  1264. }
  1265.  
  1266. /* GtESetTab:  This function sets a new tab stop at the passed column */
  1267. /*   position. */
  1268.  
  1269. static int GtESetTab(w,args)
  1270.  
  1271. GenTermEmWidget w;
  1272. struct ArgumentList *args;
  1273.  
  1274. {
  1275.  int newtab;
  1276.  int i,j;
  1277.  
  1278.  newtab = ArgToInt(w,args,1,-1);
  1279.  
  1280.  if(newtab == -1)
  1281.   {
  1282.    XtAppWarning(XtWidgetToApplicationContext(w),
  1283.         "Invalid number of arguments for SetTab translator");
  1284.    return(TRANSERROR);
  1285.   }
  1286.  else
  1287.   {
  1288.    for(i = 0; i < NTABS; i++)
  1289.     {
  1290.      if(w->genTermEm.TabStops[i] > newtab)
  1291.       break;
  1292.     }
  1293.    if(i == NTABS)
  1294.     i = NTABS - 1;
  1295.    for(j = NTABS - 2; j >= i; j--)
  1296.     {
  1297.      w->genTermEm.TabStops[j+1] = w->genTermEm.TabStops[j];
  1298.     }
  1299.    w->genTermEm.TabStops[i] = newtab;
  1300.   }
  1301.  return(TRANSOKAY);
  1302. }
  1303.  
  1304. /* GtEUnSetTab:  This translator clears a tab stop at the passed column. */
  1305. /*  If the position is -1, all tab stops are cleared. */
  1306.  
  1307. static int GtEUnSetTab(w,args)
  1308.  
  1309. GenTermEmWidget w;
  1310. struct ArgumentList *args;
  1311.  
  1312. {
  1313.  int tab;
  1314.  int i;
  1315.  
  1316.  tab = ArgToInt(w,args,1,-1);
  1317.  
  1318.  if(tab == -1)
  1319.   {
  1320.    for(i = 0; i < NTABS; i++)
  1321.     w->genTermEm.TabStops[i] = 0;
  1322.   }
  1323.  else
  1324.   {
  1325.    for(i = 0; i < NTABS; i++)
  1326.     if(w->genTermEm.TabStops[i] == tab)
  1327.      {
  1328.       if(i == 0)
  1329.        w->genTermEm.TabStops[i] = 0;
  1330.       else
  1331.        w->genTermEm.TabStops[i] = w->genTermEm.TabStops[i-1];
  1332.      }
  1333.   }
  1334.  return(TRANSOKAY);
  1335. }
  1336.  
  1337. /* GtESoundBell:  This translator causes the terminal to beep. */
  1338.  
  1339. static int GtESoundBell(w,args)
  1340.  
  1341. GenTermEmWidget w;
  1342. struct ArgumentList *args;
  1343.  
  1344. {
  1345.  XBell(XtDisplay(w),50);
  1346.  return(TRANSOKAY);
  1347. }
  1348.  
  1349. /* GtEGetBottomText:  This translator determines the last row on the screen */
  1350. /*  which has any text on it.  The row number is returned in the passed */
  1351. /*  argument number.  */
  1352.  
  1353. static int GtEGetBottomText(w,args)
  1354.  
  1355. GenTermEmWidget w;
  1356. struct ArgumentList *args;
  1357.  
  1358. {
  1359.  int position;
  1360.  char string[1024];
  1361.  int len;
  1362.  int i;
  1363.  int rows,cols;
  1364.  
  1365.  position = ArgToInt(w,args,1,1);
  1366.  GtGetScreenSize(w,&rows,&cols);
  1367.  
  1368.  for(i = rows - 1; i >= 0; i--)
  1369.   {
  1370.    GtGetLine(w,i,string,&len);
  1371.    if(len != 0)
  1372.     break;
  1373.   }
  1374.  
  1375.  IntToInputArg(w,position,i);
  1376.  return(TRANSOKAY);
  1377. }
  1378.  
  1379. /* GtEGetPosition: This translator returns the current row and column  */
  1380. /*  position in the passed argument numbers. */
  1381.  
  1382. static int GtEGetPosition(w,args)
  1383.  
  1384. GenTermEmWidget w;
  1385. struct ArgumentList *args;
  1386.  
  1387. {
  1388.  int rpos,cpos;
  1389.  int row,col;
  1390.  
  1391.  rpos = ArgToInt(w,args,1,1);
  1392.  cpos = ArgToInt(w,args,2,2);
  1393.  
  1394.  GtGetCursorPosition(w,&row,&col);
  1395.  IntToInputArg(w,rpos,row);
  1396.  IntToInputArg(w,cpos,col);
  1397.  return(TRANSOKAY);
  1398. }
  1399.  
  1400. /* GtESetFont:  This translators set the font to the base font if the */
  1401. /*  argument is 0 and to the alternate font if the argument is 1 */
  1402.  
  1403. static int GtESetFont(w,args)
  1404.  
  1405. GenTermEmWidget w;
  1406. struct ArgumentList *args;
  1407.  
  1408. {
  1409.  int flag;
  1410.  
  1411.  flag = ArgToInt(w,args,1,0);
  1412.  
  1413.  if((flag == 0) || (flag == 1))
  1414.   {
  1415.    GtSetAttribute(w,GTFONT,flag);
  1416.    return(TRANSOKAY);
  1417.   }
  1418.  else
  1419.   return(TRANSERROR); 
  1420. }
  1421.  
  1422. /* GtESetPen: This translator sets the pen number to the given argument. */
  1423.  
  1424. static int GtESetPen(w,args)
  1425.  
  1426. GenTermEmWidget w;
  1427. struct ArgumentList *args;
  1428.  
  1429. {
  1430.  int num = ArgToInt(w,args,1,0);
  1431.  
  1432.  GtSetAttribute(w,GTPEN,num);
  1433.  return(TRANSOKAY);
  1434. }
  1435.  
  1436. /* GtEGetFont:  This translator returns 0 if the current font is the base */
  1437. /*  font or 1 if it isthe alternate font. */
  1438.  
  1439. static int GtEGetFont(w,args)
  1440.  
  1441. GenTermEmWidget w;
  1442. struct ArgumentList *args;
  1443.  
  1444. {
  1445.  int value;
  1446.  int pos = ArgToInt(w,args,1,1);
  1447.  
  1448.  GtGetAttribute(w,GTFONT,&value);
  1449.  
  1450.  IntToInputArg(w,pos,value);
  1451.  return(TRANSOKAY);
  1452. }
  1453.  
  1454. /* GtEGetPen:  This translator returns the number of the pen which is */
  1455. /*  currently in use. */
  1456.  
  1457. static int GtEGetPen(w,args)
  1458.  
  1459. GenTermEmWidget w;
  1460. struct ArgumentList *args;
  1461.  
  1462. {
  1463.  int value;
  1464.  int pos = ArgToInt(w,args,1,1);
  1465.  
  1466.  GtGetAttribute(w,GTPEN,&value);
  1467.  
  1468.  IntToInputArg(w,pos,value);
  1469.  return(TRANSOKAY);
  1470. }
  1471.  
  1472. /* GtESetInverseVideo:  This translator puts the widget int inverse video */
  1473. /*  mode if the argument is 1 and sets it to normal if the argument is 0 */
  1474.  
  1475. static int GtESetInverseVideo(w,args)
  1476.  
  1477. GenTermEmWidget w;
  1478. struct ArgumentList *args;
  1479.  
  1480. {
  1481.  int flag = ArgToInt(w,args,1,0);
  1482.  
  1483.  if((flag == 0) || (flag == 1))
  1484.   {
  1485.    GtSetAttribute(w,GTINVERSEVIDEO,flag);
  1486.    return(TRANSOKAY);
  1487.   }
  1488.  else
  1489.   return(TRANSERROR);
  1490. }
  1491.  
  1492. /* GtESetUnderLineMode:  This translator puts the widget into underline mode */
  1493. /*  if the argument is 1 and sets it to normal if the argument is 0 */
  1494.  
  1495. static int GtESetUnderLineMode(w,args)
  1496.  
  1497. GenTermEmWidget w;
  1498. struct ArgumentList *args;
  1499.  
  1500. {
  1501.  int flag = ArgToInt(w,args,1,0);
  1502.  
  1503.  if((flag == 0) || (flag == 1))
  1504.   {
  1505.    GtSetAttribute(w,GTUNDERLINE,flag);
  1506.    return(TRANSOKAY);
  1507.   }
  1508.  else
  1509.   return(TRANSERROR);
  1510. }
  1511.  
  1512. /* GtESetHalfBrightMote:  This translator turns the half bright mode on or */
  1513. /*  off. */
  1514.  
  1515. static int GtESetHalfBrightMode(w,args)
  1516.  
  1517. GenTermEmWidget w;
  1518. struct ArgumentList *args;
  1519.  
  1520. {
  1521.  int flag = ArgToInt(w,args,1,0);
  1522.  
  1523.  if((flag == 0) || (flag == 1))
  1524.   {
  1525.    GtSetAttribute(w,GTHALFBRIGHT,flag);
  1526.    return(TRANSOKAY);
  1527.   }
  1528.  else
  1529.   return(TRANSERROR);
  1530. }
  1531.  
  1532. /* GtESetBlinkMode: This translator turns the blink mode on or off */
  1533.  
  1534. static int GtESetBlinkMode(w,args)
  1535.  
  1536. GenTermEmWidget w;
  1537. struct ArgumentList *args;
  1538.  
  1539. {
  1540.  int flag = ArgToInt(w,args,1,0);
  1541.  
  1542.  if((flag == 0) || (flag == 1))
  1543.   {
  1544.    GtSetAttribute(w,GTBLINKMODE,flag);
  1545.    return(TRANSOKAY);
  1546.   }
  1547.  else
  1548.   return(TRANSERROR);
  1549. }
  1550.  
  1551. /* GtESetField:  This translator causes the GenTerm widget to extend the */
  1552. /*  current attribute through out the rest of the field.  A field ends at */
  1553. /*  the next non-blank character or the end of the line. */
  1554.  
  1555. static int GtESetField(w,args)
  1556.  
  1557. GenTermEmWidget w;
  1558. struct ArgumentList *args;
  1559.  
  1560. {
  1561.  int type = ArgToInt(w,args,1,0);
  1562.  
  1563.  GtSetFieldAttribute(w,type);
  1564.  return(TRANSOKAY);
  1565. }
  1566.  
  1567. /* GtEClearLine:  This translator clears the current line.  If the argument */
  1568. /*   is 0 the entire line is cleared, if line = 1 then the line is cleared */
  1569. /*   from the  cursor to the end of the line. If line = 2 then the line is */
  1570. /*   cleared from the beginning of the line upto the cursor */
  1571.  
  1572. static int GtEClearLine(w,args)
  1573.  
  1574. GenTermEmWidget w;
  1575. struct ArgumentList *args;
  1576.  
  1577. {
  1578.  int flag;
  1579.  int crow,ccolumn;
  1580.  int rows,columns;
  1581.  
  1582.  flag = ArgToInt(w,args,1,1);
  1583.  GtGetCursorPosition(w,&crow,&ccolumn);
  1584.  GtGetScreenSize(w,&rows,&columns);
  1585.  
  1586.  if(flag == 0)
  1587.   GtClearRegion(w,crow,0,crow,columns);
  1588.  else if(flag == 1)
  1589.   GtClearRegion(w,crow,ccolumn,crow,columns);
  1590.  else if(flag == 2)
  1591.   GtClearRegion(w,crow,0,crow,ccolumn-1);
  1592.  else
  1593.   {
  1594.    XtAppWarning(XtWidgetToApplicationContext(w),
  1595.         "Bad line mode in ClearLine translator");
  1596.    return(TRANSERROR);
  1597.   }
  1598.  return(TRANSOKAY);
  1599. }
  1600.  
  1601. /* GtEClearDisplay:  This translator clears the display starting given line */
  1602. /*  and going down to the given bottom lines or the bottom of the screen if */
  1603. /*  none given. */
  1604.  
  1605. static int GtEClearDisplay(w,args)
  1606.  
  1607. GenTermEmWidget w;
  1608. struct ArgumentList *args;
  1609.  
  1610. {
  1611.  int line;
  1612.  int bottom; 
  1613.  int rows,columns;
  1614.  
  1615.  GtGetScreenSize(w,&rows,&columns);
  1616.  line = ArgToInt(w,args,1,0);
  1617.  bottom = ArgToInt(w,args,2,rows);
  1618.  if(line < rows)
  1619.   GtClearRegion(w,line,0,bottom,columns);
  1620.  return(TRANSOKAY);
  1621. }
  1622.  
  1623. /* GtEMath:  This translator performs a math operation on its arguments and */
  1624. /*  returns the result in another argument.  The first and third arguments */
  1625. /*  are the two operands.  The second argument is a string which is used to */
  1626. /*  define the operation to be carried out.  The fourth argument is the */
  1627. /*  number of the argument in which the result is to be returned. */
  1628.  
  1629. static int GtEMath(w,args)
  1630.  
  1631. GenTermEmWidget w;
  1632. struct ArgumentList *args;
  1633.  
  1634. {
  1635.  int op1,op2;
  1636.  int result;
  1637.  int pos;
  1638.  int type = 1;
  1639.  char operation[2];
  1640.  char string1[100];
  1641.  char string2[100];
  1642.  char string3[100];
  1643.  
  1644.  op1 = ArgToInt(w,args,1,0);
  1645.  op2 = ArgToInt(w,args,3,0);
  1646.  pos = ArgToInt(w,args,4,1);
  1647.  ArgToString(w,args,2," ",operation,1);
  1648.  
  1649.  switch(operation[0])
  1650.   {
  1651.  case '+':
  1652.    result = op1 + op2;
  1653.    break;
  1654.  case '-':
  1655.    result = op1 - op2;
  1656.    break;
  1657.  case '*':
  1658.    result = op1 * op2;
  1659.    break;
  1660.  case '/':
  1661.    if(op2 == 0)
  1662.     result = 0;
  1663.    else
  1664.     result = op1 / op2;
  1665.    break;
  1666.  case '%':
  1667.    result = op1 % op2;
  1668.    break;
  1669.  case '>':
  1670.    result = op1 >> op2;
  1671.    break;
  1672.  case '<' :
  1673.   result = op1 << op2;
  1674.    break;
  1675.  case '&':
  1676.    ArgToString(w,args,1," ",string1,99);
  1677.    ArgToString(w,args,3," ",string2,99);
  1678.    strcpy(string3,string1);
  1679.    strcat(string3,string2);
  1680.    type = 2;
  1681.    break;
  1682.  default:
  1683.    result = 0;
  1684.   }
  1685.  if(type == 1)
  1686.   IntToInputArg(w,pos,result);
  1687.  else
  1688.   StringToInputArg(w,pos,string3,strlen(string3));
  1689.  return(TRANSOKAY);
  1690. }
  1691.  
  1692. /* GtEIf:  This translators implements an if function.  The first and third */
  1693. /*  are the conditionals to be evaluated.  The second argument is the boolean*/
  1694. /*  expression to be evaluated.  The fourth argument is the function label */
  1695. /*  which will be branched to if the expression evaluates to true. */
  1696.  
  1697. static int GtEIf(w,args)
  1698.  
  1699. GenTermEmWidget w;
  1700. struct ArgumentList *args;
  1701.  
  1702. {
  1703.  int op1,op2;
  1704.  char operation[10];
  1705.  int result;
  1706.  int label;
  1707.  
  1708.  op1 = ArgToInt(w,args,1,0);
  1709.  op2 = ArgToInt(w,args,3,0);
  1710.  label = ArgToInt(w,args,4,1);
  1711.  ArgToString(w,args,2," ",operation,9);
  1712.  
  1713.  if(strcmp(operation,"=") == 0)
  1714.   result = (op1 == op2);
  1715.  else if(strcmp(operation,">") == 0)
  1716.   result = (op1 > op2);
  1717.  else if(strcmp(operation,">=") == 0)
  1718.   result = (op1 >= op2);
  1719.  else if(strcmp(operation,"<") == 0)
  1720.   result = (op1 < op2);
  1721.  else if(strcmp(operation,"<=") == 0)
  1722.   result = (op1 <= op2);
  1723.  else if(strcmp(operation,"!=") == 0)
  1724.   result = (op1 != op2);
  1725.  else
  1726.   result = 0;
  1727.  
  1728.  if(result)
  1729.   return(label);
  1730.  else
  1731.   return(TRANSOKAY);
  1732. }
  1733.  
  1734. /* GtELoadAttribute:  This translator caused the GenTerm widget to load its */
  1735. /*  current attribute with the attribute settings of the character at */
  1736. /*  the position given by the first (row) and second (column arguments */
  1737.  
  1738. static int GtELoadAttribute(w,args)
  1739.  
  1740. GenTermEmWidget w;
  1741. struct ArgumentList *args;
  1742.  
  1743. {
  1744.  int row,col;
  1745.  
  1746.  row = ArgToInt(w,args,1,0);
  1747.  col = ArgToInt(w,args,2,0);
  1748.  
  1749.  GtLoadAttribute(w,row,col);
  1750.  return(TRANSOKAY);
  1751. }
  1752.  
  1753. /* GtEClearMemory:  This translator causes the GenTerm widget to clear its */
  1754. /*  virtual screen.  If the argument=0 then the entire virtual screen is */
  1755. /*  cleared.  If it is equal to 1 then the portion of the virtual screen */
  1756. /*  currently below the real screen is cleared.  If it is equal to 2 then */
  1757. /*  portion of the virtual screen above the real screen is cleared. */
  1758.  
  1759. static int GtEClearMemory(w,args)
  1760.  
  1761. GenTermEmWidget w;
  1762. struct ArgumentList *args;
  1763.  
  1764. {
  1765.  int which;
  1766.  
  1767.  which = ArgToInt(w,args,1,0);
  1768.  
  1769.  if((which >= 0) && (which <= 3))
  1770.   {
  1771.    GtClearMemory(w,which);
  1772.    return(TRANSOKAY);
  1773.   }
  1774.  else
  1775.   return(TRANSOKAY);
  1776. }
  1777.  
  1778. /* GtEInsertLines:  This translator inserts a number of lines into the */
  1779. /*  virtual screen.  The first argument is the number of lines to insert. */
  1780. /*  The second is the offset from the current position where the insertion */
  1781. /* is to take place. */
  1782.  
  1783. static int GtEInsertLines(w,args)
  1784.  
  1785. GenTermEmWidget w;
  1786. struct ArgumentList *args;
  1787.  
  1788. {
  1789.  int n,where;
  1790.  int row,column;
  1791.  
  1792.  n = ArgToInt(w,args,1,1);
  1793.  where = ArgToInt(w,args,2,1);
  1794.  
  1795.  GtGetCursorPosition(w,&row,&column);
  1796.  row += where;
  1797.  GtInsertLines(w,row,n);
  1798.  return(TRANSOKAY);
  1799. }
  1800.  
  1801. /* GtEDeleteLines:  This translator deletes a number of lines in the virtual */
  1802. /*  screen.  The argument is the number of lines to delete. */
  1803.  
  1804. static int GtEDeleteLines(w,args)
  1805.  
  1806. GenTermEmWidget w;
  1807. struct ArgumentList *args;
  1808.  
  1809. {
  1810.  int num;
  1811.  
  1812.  num = ArgToInt(w,args,1,1);
  1813.  
  1814.  GtDeleteLines(w,num);
  1815.  return(TRANSOKAY);
  1816. }
  1817.  
  1818. /* GtESetTop:  This translator sets the line number of the top of the screen */
  1819. /*  to correspond to the argument */
  1820. static int GtESetTop(w,args)
  1821.  
  1822. GenTermEmWidget w;
  1823. struct ArgumentList *args;
  1824.  
  1825. {
  1826.  int position = ArgToInt(w,args,1,0);
  1827.  
  1828.  GtSetTopOfScreen(w,position);
  1829.  return(TRANSOKAY);
  1830. }
  1831.  
  1832. /* GtEDeleteCharacters:  This translator deletes n characters starting at the*/
  1833. /*  current position.  The argument is the number of characters to delete. */
  1834.  
  1835. static int GtEDeleteCharacters(w,args)
  1836.  
  1837. GenTermEmWidget w;
  1838. struct ArgumentList *args;
  1839.  
  1840. {
  1841.  int num = ArgToInt(w,args,1,1);
  1842.  
  1843.  GtDeleteCharacters(w,num);
  1844.  return(TRANSOKAY);
  1845. }
  1846.  
  1847. /* GtEGetTop:  This translator determine the line number of the top of the */
  1848. /*  screen and returns it in the passed argument number. */
  1849.  
  1850. static int GtEGetTop(w,args)
  1851.  
  1852. GenTermEmWidget w;
  1853. struct ArgumentList *args;
  1854.  
  1855. {
  1856.  int pos = ArgToInt(w,args,1,1);
  1857.  int top;
  1858.  
  1859.  top = GtGetTopOfScreen(w);
  1860.  
  1861.  IntToInputArg(w,pos,top);
  1862.  return(TRANSOKAY);
  1863. }
  1864.  
  1865. /* GtEGetScreenSize: This translator returns the size of the screen in the */
  1866. /*  passed arguments. */
  1867.  
  1868. static int GtEGetScreenSize(w,args)
  1869.  
  1870. GenTermEmWidget w;
  1871. struct ArgumentList *args;
  1872.  
  1873. {
  1874.  int rows,columns;
  1875.  int rpos = ArgToInt(w,args,1,1);
  1876.  int cpos = ArgToInt(w,args,2,2);
  1877.  
  1878.  GtGetScreenSize(w,&rows,&columns);
  1879.  IntToInputArg(w,rpos,rows);
  1880.  IntToInputArg(w,cpos,columns);
  1881.  return(TRANSOKAY);
  1882. }
  1883.  
  1884. /* GtESetInsertMode:  This translator sets the terminal widget's insert mode */
  1885. /*  If the passed argument is a one then insert mode is turned on.  If it is */
  1886. /*  a zero, it is turned off. */
  1887.  
  1888. static int GtESetInsertMode(w,args)
  1889.  
  1890. GenTermEmWidget w;
  1891. struct ArgumentList *args;
  1892.  
  1893. {
  1894.  int flag;
  1895.  Arg Xargs[10];
  1896.  int n = 0;
  1897.  
  1898.  flag = ArgToInt(w,args,1,0);
  1899.  
  1900.  if(flag == 0)
  1901.   {
  1902.    XtSetArg(Xargs[n],XtNinsertMode,False);
  1903.    n++;
  1904.   }
  1905.  else if(flag == 1)
  1906.   {
  1907.    XtSetArg(Xargs[n],XtNinsertMode,True);
  1908.    n++;
  1909.   }
  1910.  else
  1911.   {
  1912.    XtAppWarning(XtWidgetToApplicationContext(w),
  1913.         "Invalid argument for SetInsertMode translator");
  1914.    return(TRANSERROR);
  1915.   }
  1916.  
  1917.  XtSetValues(w,Xargs,n);
  1918.  return(TRANSOKAY);
  1919. }
  1920.  
  1921. /* GtESetParseTable: This translator changes the current parse table to */
  1922. /*  the one specified by the given name.  If no parse table exists under */
  1923. /*  that name, a warning is issued and the request is ignored. */
  1924.  
  1925. static int GtESetParseTable(w,args)
  1926.  
  1927. GenTermEmWidget w;
  1928. struct ArgumentList *args;
  1929.  
  1930. {
  1931.  char name[80];
  1932.  struct GtEList *temp;
  1933.  
  1934.  ArgToString(w,args,1,"Default",name,79);
  1935.  temp = w->genTermEm.ParseList;
  1936.  while(temp != NULL)
  1937.   {
  1938.    if(strcmp(name,temp->Name) == 0)
  1939.     break;
  1940.    temp = temp->Next;
  1941.   }
  1942.  if(temp == NULL)
  1943.   {
  1944.    XtAppWarning(XtWidgetToApplicationContext(w),
  1945.         "Bad parse table name given to SetParseTable translator");
  1946.    return(TRANSERROR);
  1947.   }
  1948.  else
  1949.   {
  1950.    w->genTermEm.ParseTable = temp->Point.ParseTable;
  1951.    return(TRANSOKAY);
  1952.   }
  1953. }
  1954.  
  1955. /* GtESetKeyTable:  This translator changes the current key translation */
  1956. /*  table to the one specified by the given name.  If no key table exists */
  1957. /*  under that name, a warning is issued and the request is ignored. */
  1958.  
  1959. static int GtESetKeyTable(w,args)
  1960.  
  1961. GenTermEmWidget w;
  1962. struct ArgumentList *args;
  1963.  
  1964. {
  1965.  char name[80];
  1966.  struct GtEList *temp;
  1967.  
  1968.  ArgToString(w,args,1,"Default",name,79);
  1969.  temp = w->genTermEm.KeyList;
  1970.  while(temp != NULL)
  1971.   {
  1972.    if(strcmp(name,temp->Name) == 0)
  1973.     break;
  1974.    temp = temp->Next;
  1975.   }
  1976.  if(temp == NULL)
  1977.   {
  1978.    XtAppWarning(XtWidgetToApplicationContext(w),
  1979.         "Bad parse table name given to SetKeyTable translator");
  1980.    return(TRANSERROR);
  1981.   }
  1982.  else
  1983.   {
  1984.    w->genTermEm.Keys = temp->Point.KeyTable;
  1985.    w->genTermEm.NumKeys = temp->Num;
  1986.    return(TRANSOKAY);
  1987.   }
  1988. }
  1989.  
  1990. /* GtESetResource:  This translator sets the specified resource to the given*/
  1991. /*  value.  Note currently is can only set integer values. */
  1992.  
  1993. static int GtESetResource(w,args)
  1994.  
  1995. GenTermEmWidget w;
  1996. struct ArgumentList *args;
  1997.  
  1998. {
  1999.  char resource[80];
  2000.  int value;
  2001.  Arg Xargs[10];
  2002.  int n = 0;
  2003.  
  2004.  ArgToString(w,args,1," ",resource,79);
  2005.  value = ArgToInt(w,args,2,0);
  2006.  
  2007.  XtSetArg(Xargs[n],resource,value);
  2008.  n++;
  2009.  XtSetValues(w,Xargs,n);
  2010.  return(TRANSOKAY);
  2011. }
  2012.  
  2013. /* GtEGetResource:  This translator gets the specified resource and returns */
  2014. /*  it in the passed variable. */
  2015.  
  2016. static int GtEGetResource(w,args)
  2017.  
  2018. GenTermEmWidget w;
  2019. struct ArgumentList *args;
  2020.  
  2021. {
  2022.  char resource[80];
  2023.  int value;
  2024.  Arg Xargs[10];
  2025.  int n = 0;
  2026.  int position = ArgToInt(w,args,2,1);
  2027.  
  2028.  ArgToString(w,args,1," ",resource,79);
  2029.  
  2030.  XtSetArg(Xargs[n],resource,&value); n++;
  2031.  XtGetValues(w,Xargs,n);
  2032.  IntToInputArg(w,position,value);
  2033.  return(TRANSOKAY);
  2034. }
  2035.  
  2036. /* GtEEmit:  This function emits the passed character strings.  The data is */
  2037. /*  is passed to the parent functions via the keyboard callback. */
  2038.  
  2039. static int GtEEmit(w,args)
  2040.  
  2041. GenTermEmWidget w;
  2042. struct ArgumentList *args;
  2043.  
  2044. {
  2045.  GenTermEmCallback reason;
  2046.  char string[1024];
  2047.  int i;
  2048.  
  2049.  reason.reason = GTE_INPUT;
  2050.  reason.event = NULL;
  2051.  reason.string = string;
  2052.  
  2053.  for(i = 1; i <= args->NumArgs; i++)
  2054.   {
  2055.    ArgToString(w,args,i,"",string,1023);
  2056.    reason.len = strlen(string);
  2057.  
  2058.    XtCallCallbacks(w,XtNkbdCallback,(caddr_t) &reason);
  2059.   }
  2060.  return(TRANSOKAY);
  2061. }
  2062.  
  2063. /* GtEOutputString: This function outputs the passed character strings on */
  2064. /*   the terminal widget.  WARNING!!! This function causes the GtEParse */
  2065. /*   function to be called recursively which can cause the input stack to be */
  2066. /*   over written. Call this translator with care */
  2067.  
  2068. static int GtEOutputString(w,args)
  2069.  
  2070. GenTermEmWidget w;
  2071. struct ArgumentList *args;
  2072.  
  2073. {
  2074.  char string[1024];
  2075.  int i;
  2076.  struct InputArgument *Store;
  2077.  
  2078.  for(i = 1; i <= args->NumArgs; i++)
  2079.   {
  2080.    ArgToString(w,args,i,"",string,1023);
  2081.    Store = GtEPushArgs(w);
  2082.    GtEOutput(w,string,strlen(string));
  2083.    GtEPopArgs(w,Store);
  2084.   }
  2085.  return(TRANSOKAY);
  2086. }
  2087.  
  2088. /* GtEGetLine:  This translator returns the characters on the screen  */
  2089. /*  starting at the given position and continueing to the end of the line */
  2090.  
  2091. static int GtEGetLine(w,args)
  2092.  
  2093. GenTermEmWidget w;
  2094. struct ArgumentList *args;
  2095.  
  2096. {
  2097.  int row;
  2098.  int col;
  2099.  int pos;
  2100.  int len;
  2101.  char string[1024];
  2102.  
  2103.  row = ArgToInt(w,args,1,0);
  2104.  col = ArgToInt(w,args,2,0);
  2105.  pos = ArgToInt(w,args,3,1);
  2106.  
  2107.  GtGetLine(w,row,string,&len);
  2108.  len -= col;
  2109.  if(len < 0)
  2110.   len = 0;
  2111.  StringToInputArg(w,pos,&(string[col]),len);
  2112.  return(TRANSOKAY);
  2113. }
  2114.  
  2115. /* GtESetScrollRegion:  This translator sets the scroll region for the given */
  2116. /*  range and scroll region number. */
  2117.  
  2118. static int GtESetScrollRegion(w,args)
  2119.  
  2120. GenTermEmWidget w;
  2121. struct ArgumentList *args;
  2122.  
  2123. {
  2124.  int rows,columns;
  2125.  int start = ArgToInt(w,args,1,0);
  2126.  int end = ArgToInt(w,args,2,-1);
  2127.  int num = ArgToInt(w,args,3,0);
  2128.  
  2129.  GtGetScreenSize(w,&rows,&columns);
  2130.  if(end == -1)
  2131.   end = rows - 1;
  2132.  GtSetScrollRegion(w,start,end,num);
  2133.  return(TRANSOKAY);
  2134. }
  2135.  
  2136. /* GtEReject:  This translator causes the parser to reject the currently */
  2137. /*  matched and to reset the parser. */
  2138.  
  2139. static int GtEReject(w,args)
  2140.  
  2141. GenTermEmWidget w;
  2142. struct ArgumentList *args;
  2143.  
  2144. {
  2145.  return(TRANSREJECT);
  2146. }
  2147.  
  2148. /* GtEGetTopOfScrollRegion: This translator returns the row number */
  2149. /*  corresponding to the top of the given scroll region.  If the scroll */
  2150. /*  region doesn't exist then a zero is returned. */
  2151.  
  2152. static int GtEGetTopOfScrollRegion(w,args)
  2153.  
  2154. GenTermEmWidget w;
  2155. struct ArgumentList *args;
  2156.  
  2157. {
  2158.  int num;
  2159.  int pos;
  2160.  int top,bottom;
  2161.  
  2162.  num = ArgToInt(w,args,1,0);
  2163.  pos = ArgToInt(w,args,2,1);
  2164.  
  2165.  GtGetScrollRegion(w,num,&top,&bottom);
  2166.  if(top == -1)
  2167.   top = 0;
  2168.  IntToInputArg(w,pos,top);
  2169.  
  2170.  return(TRANSOKAY);
  2171. }
  2172.  
  2173. /* GtEQuit:  This translator causes the parser to quite executing translators*/
  2174. /*  and to parse the next character. */
  2175.  
  2176. static int GtEQuit(w,args)
  2177.  
  2178. GenTermEmWidget w;
  2179. struct ArgumentList *args;
  2180.  
  2181. {
  2182.  return(TRANSERROR);
  2183. }
  2184.  
  2185. /* GtEProgramKey:  This translator sets the information for a specific */
  2186. /*  function key.  The first agrument is the type of function to assign to */
  2187. /*  the key.  The second aregument is the key number.  The third argument */
  2188. /*  is the key label and the final argument is the string to be bound to the */
  2189. /*  key. */
  2190.  
  2191. static int GtEProgramKey(w,args)
  2192.  
  2193. GenTermEmWidget w;
  2194. struct ArgumentList *args;
  2195.  
  2196. {
  2197.  int type = ArgToInt(w,args,1,0);
  2198.  int number = ArgToInt(w,args,2,1);
  2199.  char label[20];
  2200.  char string[1000];
  2201.  char buffer[100];
  2202.  Arg xargs[20];
  2203.  int n = 0;
  2204.  
  2205.  ArgToString(w,args,3," ",label,19);
  2206.  ArgToString(w,args,4,"",string,999);
  2207.  
  2208.  number--;
  2209.  if((number >= 0) && (number < NKEYS))
  2210.   {
  2211.    if(strlen(label) > 0)
  2212.     {
  2213.      XtFree(w->genTermEm.FKeys[number].Label);
  2214.      w->genTermEm.FKeys[number].Label = 
  2215.       XtMalloc(sizeof(char)*(strlen(label)+1));
  2216.     strcpy(w->genTermEm.FKeys[number].Label,label); 
  2217.     }
  2218.    if(strlen(string) > 0)
  2219.     {
  2220.      XtFree(w->genTermEm.FKeys[number].String);
  2221.      w->genTermEm.FKeys[number].String = XtMalloc(sizeof(char) *
  2222.                          (strlen(string) + 1));
  2223.      strcpy(w->genTermEm.FKeys[number].String,string);
  2224.     }
  2225.    
  2226.    w->genTermEm.FKeys[number].Type = type;
  2227.  
  2228.    if(strlen(label) > w->genTermEm.FuncLabelWidth)
  2229.     {
  2230.      memcpy(buffer,label,w->genTermEm.FuncLabelWidth);
  2231.      buffer[w->genTermEm.FuncLabelWidth] = '\n';
  2232.      strcpy(&(buffer[w->genTermEm.FuncLabelWidth + 1]),
  2233.         &(label[w->genTermEm.FuncLabelWidth]));
  2234.     }
  2235.    else
  2236.     strcpy(buffer,label);
  2237.  
  2238.    if(w->genTermEm.FunctionRealized == True)
  2239.     {
  2240.      XtSetArg(xargs[n],XmNlabelString,
  2241.           XmStringCreateLtoR(buffer,XmSTRING_DEFAULT_CHARSET)); n++;
  2242.      
  2243.      XtSetValues(w->genTermEm.FKeys[number].FuncKey,xargs,n);
  2244.     }
  2245.   }
  2246.  
  2247. }
  2248.  
  2249. /* GtEIgnore:  This translator is do nothing function.  It is effectively a */
  2250. /*  no-op */
  2251.  
  2252. static int GtEIgnore(w,args)
  2253.  
  2254. GenTermEmWidget w;
  2255. struct ArgumentList *args;
  2256.  
  2257. {
  2258.  return(TRANSOKAY);
  2259. }
  2260.  
  2261. /* GtEDefinePen:  This translator defines the foreground and background */
  2262. /*  colour of a pen.  The first arguement is the pen number to be defined. */
  2263. /*  The next three arguments specify the colours of the foreground.  These */
  2264. /*  values run from 0 to 1 and are either rgb or hsl values depending on */
  2265. /*  DefineColor resource. The final three arguements is the colour */
  2266. /*  specification of the background. */
  2267.  
  2268. static int GtEDefinePen(w,args)
  2269.  
  2270. GenTermEmWidget w;
  2271. struct ArgumentList *args;
  2272.  
  2273. {
  2274.  int npen = ArgToInt(w,args,1,0);
  2275.  float fr = ArgToFloat(w,args,2,0);
  2276.  float fg = ArgToFloat(w,args,3,0);
  2277.  float fb = ArgToFloat(w,args,4,0);
  2278.  float br = ArgToFloat(w,args,5,0);
  2279.  float bg = ArgToFloat(w,args,6,0);
  2280.  float bb = ArgToFloat(w,args,7,0);
  2281.  
  2282.  GtDefinePenColour(w,npen,fr,fg,fb,br,bg,bb);
  2283.  return(TRANSOKAY);
  2284. }
  2285.  
  2286. /* GtEExecuteFunctionKey:  This translator executes a specific function key */
  2287. /*  just as if the user had pressed it. */
  2288.  
  2289. static int GtEExecuteFunctionKey(w,args)
  2290.  
  2291. GenTermEmWidget w;
  2292. struct ArgumentList *args;
  2293.  
  2294. {
  2295.  int key = ArgToInt(w,args,1,1);
  2296.  GenTermEmCallback ReasonSent;
  2297.  char buffer[1024];
  2298.  
  2299.  if((key > 0) && (key < w->genTermEm.NumberFunctionKeys))
  2300.   {
  2301.    ReasonSent.reason = GTE_INPUT;
  2302.    ReasonSent.event = NULL;
  2303.    ReasonSent.string = buffer;
  2304.    ReasonSent.len = 0;
  2305.  
  2306.    if((w->genTermEm.FKeys[key].Type == 0) || (w->genTermEm.FKeys[key].Type == 2))
  2307.     {
  2308.      strcpy(buffer,w->genTermEm.FKeys[key].String);
  2309.      ReasonSent.len = strlen(buffer);
  2310.     }
  2311.    if((w->genTermEm.FKeys[key].Type == 0) || (w->genTermEm.FKeys[key].Type == 1))
  2312.     {
  2313.      GtEOutput(w,w->genTermEm.FKeys[key].String,
  2314.            strlen(w->genTermEm.FKeys[key].String));
  2315.     }
  2316.    if(ReasonSent.len > 0)
  2317.     XtCallCallbacks(w,XtNkbdCallback,(caddr_t) &ReasonSent);
  2318.  
  2319.    return(TRANSOKAY);
  2320.   }
  2321.  else
  2322.   return(TRANSERROR);
  2323. }
  2324.  
  2325. /* GtEEscapeCallback:  This translator causes any escape callbacks that are */
  2326. /*  bound to the widget to be executed.  */
  2327.  
  2328. static int GtEEscapeCallback(w,args)
  2329.  
  2330. GenTermEmWidget w;
  2331. struct ArgumentList *args;
  2332.  
  2333. {
  2334.  GenTermEmCallback callback;
  2335.  int i;
  2336.  int nargs = args->NumArgs;
  2337.  char buffer[1024];
  2338.  
  2339.  callback.reason = GTE_ESCAPE;
  2340.  callback.event = NULL;
  2341.  callback.escapes = (char **) XtMalloc(sizeof(char *) * (nargs + 1));
  2342.  
  2343.  for(i = 1; i <= nargs; i++)
  2344.   {
  2345.    ArgToString(w,args,i,"",buffer,1023);
  2346.    callback.escapes[i-1] = (char *) XtMalloc(sizeof(char) * strlen(buffer)+1);
  2347.    strcpy(callback.escapes[i-1],buffer);
  2348.   }
  2349.  callback.escapes[nargs] = NULL;
  2350.  
  2351.  XtCallCallbacks(w,XtNescCallback,(caddr_t)&callback);
  2352.  
  2353.  for(i = 0; i <nargs; i++)
  2354.   XtFree(callback.escapes[i]);
  2355.  XtFree(callback.escapes);
  2356.  return(TRANSOKAY);
  2357. }
  2358.  
  2359. /* GtELoadMapTable:  This translator loads the specified output mapping */
  2360. /*  table. */
  2361.  
  2362. static int GtELoadMapTable(w,args)
  2363.  
  2364. GenTermEmWidget w;
  2365. struct ArgumentList *args;
  2366.  
  2367. {
  2368.  int num = ArgToInt(w,args,1,0);
  2369.  
  2370.  if((num < 0) || (num >= w->genTermEm.NumMapTables))
  2371.   {
  2372.    XtAppWarning(XtWidgetToApplicationContext(w),
  2373.         "Invalid table number in LoadMapTable translator");
  2374.    return(TRANSERROR);
  2375.   }
  2376.  GtSetMapTable(w,w->genTermEm.MapTables[num]);
  2377.  return(TRANSOKAY);
  2378. }
  2379.  
  2380. /* GtEProgramMapTable: This translator sets the values in the specied */
  2381. /*  mapping table.  The values are specified by the starting and ending */
  2382. /*  positions in the table and the value to set the starting position to and */
  2383. /*  the value to set the ending value to.  All intermediate values are set to*/
  2384. /*  the linear points inbetween. */
  2385.  
  2386. static int GtEProgramMapTable(w,args)
  2387.  
  2388. GenTermEmWidget w;
  2389. struct ArgumentList *args;
  2390.  
  2391. {
  2392.  int num = ArgToInt(w,args,1,0);
  2393.  int StartPoint = ArgToInt(w,args,2,0);
  2394.  int EndPoint = ArgToInt(w,args,3,NMAP-1);
  2395.  int StartValue = ArgToInt(w,args,4,0);
  2396.  int EndValue = ArgToInt(w,args,5,NMAP-1);
  2397.  int i;
  2398.  int val,step;
  2399.  
  2400.  if((num < 0) || (num >= w->genTermEm.NumMapTables))
  2401.   {
  2402.    XtAppWarning(XtWidgetToApplicationContext(w),
  2403.         "Invalid table number in ProgramMapTable translator");
  2404.    return(TRANSERROR);
  2405.   }
  2406.  
  2407.  if((StartPoint < 0) || (StartPoint >= NMAP) || (EndPoint < 0) ||
  2408.     (EndPoint >= NMAP))
  2409.   {
  2410.    XtAppWarning(XtWidgetToApplicationContext(w),
  2411.         "Invalid range in PorgramMapTable translator");
  2412.    return(TRANSERROR);
  2413.   }
  2414.  
  2415.  val = StartValue;
  2416.  step = (EndValue - StartValue)/(EndPoint - StartPoint - 1);
  2417.  
  2418.  for(i = StartPoint; i <= EndPoint; i++, val += step)
  2419.   w->genTermEm.MapTables[num][i] = val;
  2420.  
  2421.  return(TRANSOKAY);
  2422. }
  2423.  
  2424. /* GtEStore: This translator takes an input argument and copies it to the */
  2425. /*  the global input stack so that it can be recalled at a later date */
  2426.  
  2427. static int GtEStore(w,args)
  2428.  
  2429. GenTermEmWidget w;
  2430. struct ArgumentList *args;
  2431.  
  2432. {
  2433.  int position = ArgToInt(w,args,2,1);
  2434.  char string[1024];
  2435.  
  2436.  ArgToString(w,args,1," ",string,1023);
  2437.  
  2438.  if((position < 0 ) || (position >= w->genTermEm.NumStoreArgs))
  2439.   {
  2440.    XtAppWarning(XtWidgetToApplicationContext(w),
  2441.         "Invalid storage position in Store translator");
  2442.    return(TRANSERROR);
  2443.   }
  2444.  
  2445.  if(w->genTermEm.StoreArgs[position].valid & AMALLOCED)
  2446.   XtFree(w->genTermEm.StoreArgs[position].string);
  2447.  
  2448.  w->genTermEm.StoreArgs[position].valid = ADEFINED | AMALLOCED;
  2449.  w->genTermEm.StoreArgs[position].length = strlen(string);
  2450.  w->genTermEm.StoreArgs[position].string = 
  2451.   (char *) XtMalloc(sizeof(char) *
  2452.             (w->genTermEm.StoreArgs[position].length + 1));
  2453.  strcpy(w->genTermEm.StoreArgs[position].string,string);
  2454.  
  2455.  return(TRANSOKAY);
  2456. }
  2457.  
  2458. /* GtEFetch:  This translator takes the global argument at the given position*/
  2459. /*  position and returns it in the position specified from the second */
  2460. /*  argument. */
  2461.  
  2462. static int GtEFetch(w,args)
  2463.  
  2464. GenTermEmWidget w;
  2465. struct ArgumentList *args;
  2466.  
  2467. {
  2468.  int from = ArgToInt(w,args,1,1);
  2469.  int to = ArgToInt(w,args,2,1);
  2470.  
  2471.  if((from < 0) || (from >= w->genTermEm.NumStoreArgs))
  2472.   {
  2473.    XtAppWarning(XtWidgetToApplicationContext(w),
  2474.         "Invalid storage position in Fetch translator");
  2475.    return(TRANSERROR);
  2476.   }
  2477.  
  2478.  if((w->genTermEm.StoreArgs[from].valid & ADEFINED) == 0)
  2479.   StringToInputArg(w,to," ",1);
  2480.  else
  2481.   StringToInputArg(w,to,w->genTermEm.StoreArgs[from].string,
  2482.            w->genTermEm.StoreArgs[from].length);
  2483.  
  2484.  return(TRANSOKAY);
  2485. }
  2486.  
  2487. /* GtEGetArg:  This translator implements an indirect reference to an input */
  2488. /*  argument.  Its first argument is the number of the input argument to get */
  2489. /*  The second argument is the store the referenced value in. */
  2490.  
  2491. static int GtEGetArg(w,args)
  2492.  
  2493. GenTermEmWidget w;
  2494. struct ArgumentList *args;
  2495.  
  2496. {
  2497.  int from = ArgToInt(w,args,1,1);
  2498.  int to = ArgToInt(w,args,2,2);
  2499.  
  2500.  if(w->genTermEm.InputArgs[to].valid & AMALLOCED)
  2501.   XtFree(w->genTermEm.InputArgs[to].string);
  2502.  
  2503.  w->genTermEm.InputArgs[to].valid = w->genTermEm.InputArgs[from].valid;
  2504.  w->genTermEm.InputArgs[to].length = w->genTermEm.InputArgs[from].length;
  2505.  
  2506.  if(w->genTermEm.InputArgs[to].valid & AMALLOCED)
  2507.   {
  2508.    w->genTermEm.InputArgs[to].string = 
  2509.     XtMalloc(sizeof(char) * (w->genTermEm.InputArgs[to].length + 1));
  2510.    memcpy(w->genTermEm.InputArgs[to].string,w->genTermEm.InputArgs[from].string,
  2511.       w->genTermEm.InputArgs[from].length);
  2512.   }
  2513.  else
  2514.   w->genTermEm.InputArgs[to].string = w->genTermEm.InputArgs[from].string;
  2515.  
  2516.  return(TRANSOKAY);
  2517. }
  2518.  
  2519. /* GtEGetLastButtonEvent:  This translator returns the information in the */
  2520. /*  stored last button event.  It returns the button that was pressed, the */
  2521. /*  x and y positions and the modifiers that were active. */
  2522.  
  2523. static int GtEGetLastButtonEvent(w,args)
  2524.  
  2525. GenTermEmWidget w;
  2526. struct ArgumentList *args;
  2527.  
  2528. {
  2529.  int ButtonPos = ArgToInt(w,args,1,1);
  2530.  int XPos = ArgToInt(w,args,2,2);
  2531.  int YPos = ArgToInt(w,args,3,3);
  2532.  int ModPos = ArgToInt(w,args,4,4);
  2533.  
  2534.  if((w->genTermEm.LastEvent.type != ButtonPress) && 
  2535.     (w->genTermEm.LastEvent.type != ButtonRelease))
  2536.   {
  2537.    XtAppWarning(XtWidgetToApplicationContext(w),
  2538.         "GenTermEm Widget: Last event is not a button event");
  2539.    return(TRANSERROR);
  2540.   }
  2541.  
  2542.  IntToInputArg(w,ButtonPos,w->genTermEm.LastEvent.xbutton.button);
  2543.  IntToInputArg(w,XPos,w->genTermEm.LastEvent.xbutton.x);
  2544.  IntToInputArg(w,YPos,w->genTermEm.LastEvent.xbutton.y);
  2545.  IntToInputArg(w,ModPos,w->genTermEm.LastEvent.xbutton.state);
  2546.  
  2547.  return(TRANSOKAY);
  2548. }
  2549.  
  2550. /* GtEToAscii:  This translator takes an integer and converts it to its */
  2551. /*  ascii equivalent. */
  2552.  
  2553. static int GtEToAscii(w,args)
  2554.  
  2555. GenTermEmWidget w;
  2556. struct ArgumentList *args;
  2557.  
  2558. {
  2559.  int num = ArgToInt(w,args,1,0);
  2560.  int Pos = ArgToInt(w,args,2,1);
  2561.  char buff[2];
  2562.  
  2563.  if((num < 0) || (num >= 256))
  2564.   {
  2565.    XtAppWarning(XtWidgetToApplicationContext(w),
  2566.         "GenTermEm Widget: Value can not be converted to ascii");
  2567.    return(TRANSERROR);
  2568.   }
  2569.  
  2570.  buff[0] = (char) num;
  2571.  buff[1] = NULL;
  2572.  
  2573.  StringToInputArg(w,Pos,buff,1);
  2574.  
  2575.  return(TRANSOKAY);
  2576. }
  2577.  
  2578. /* GtEConvertPosition:  This translator takes a pixel position (x,y) and */
  2579. /*  converts it to the corresponding row and column number. */
  2580.  
  2581. static int GtEConvertPosition(w,args)
  2582.  
  2583. GenTermEmWidget w;
  2584. struct ArgumentList *args;
  2585.  
  2586. {
  2587.  int X = ArgToInt(w,args,1,0);
  2588.  int Y = ArgToInt(w,args,2,0);
  2589.  int RowPos = ArgToInt(w,args,3,1);
  2590.  int ColPos = ArgToInt(w,args,4,2);
  2591.  int Row,Col;
  2592.  
  2593.  
  2594.  GtPositionToRowColumn(w,(Dimension)X,(Dimension)Y,&Row,&Col);
  2595.  IntToInputArg(w,RowPos,Row);
  2596.  IntToInputArg(w,ColPos,Col);
  2597.  
  2598.  return(TRANSOKAY);
  2599. }
  2600.  
  2601. /* GtECheckModifiers:  This translator takes an event modifier and */
  2602. /*  if a specified modifier was present during the event.  The first */
  2603. /*  parameter is the value of the modifier (set GtEGetLastButtonEvent).  The */
  2604. /*  second parameter is the modifier to check for, either Shift Control or */
  2605. /*  Meta.  The final parameter is the position to return the answer in */
  2606.  
  2607. static int GtECheckModifiers(w,args)
  2608.  
  2609. GenTermEmWidget w;
  2610. struct ArgumentList *args;
  2611.  
  2612. {
  2613.  int mods = ArgToInt(w,args,1,0);
  2614.  int pos = ArgToInt(w,args,3,1);
  2615.  char string[100];
  2616.  int i = 0;
  2617.  int val = 0;
  2618.  
  2619.  ArgToString(w,args,2," ",string,99);
  2620.  
  2621.  while((w->genTermEm.Mods[i].Name != NULL) && 
  2622.        (strcmp(w->genTermEm.Mods[i].Name,string) != 0))
  2623.   i++;
  2624.  if(w->genTermEm.Mods[i].Name == NULL)
  2625.   {
  2626.    XtAppWarning(XtWidgetToApplicationContext(w),
  2627.         "GenTermEm Widget: Invalid modifier name");
  2628.    return(TRANSERROR);
  2629.   }
  2630.  
  2631.  if(mods & w->genTermEm.Mods[i].Mask)
  2632.   val = 1;
  2633.  
  2634.  IntToInputArg(w,pos,val);
  2635.  
  2636.  return(TRANSOKAY);
  2637. }
  2638.  
  2639. /* GtEGetStringLength:  This translator determines the length of the string */
  2640. /* given as the first parameter and returns it in the parameter given by */
  2641. /* the second argument */
  2642.  
  2643. static int GtEGetStringLength(w,args)
  2644.  
  2645. GenTermEmWidget w;
  2646. struct ArgumentList *args;
  2647.  
  2648. {
  2649.  int pos = ArgToInt(w,args,2,1);
  2650.  int n;
  2651.  char string[100];
  2652.  
  2653.  ArgToString(w,args,1," ",string,99);
  2654.  n = strlen(string);
  2655.  IntToInputArg(w,pos,n);
  2656.  
  2657.  return(TRANSOKAY);
  2658. }
  2659.  
  2660. /* GtEGetSubString:  This translator gets the contents of the substring of */
  2661. /*  the string in the first parameter with in the bounds of the substring */
  2662. /*  given by the second and third argument.  The result is returned in the */
  2663. /*  parameter specified by the fourth argument. */
  2664.  
  2665. static int GtEGetSubString(w,args)
  2666.  
  2667. GenTermEmWidget w;
  2668. struct ArgumentList *args;
  2669.  
  2670. {
  2671.  int start = ArgToInt(w,args,2,0);
  2672.  int end = ArgToInt(w,args,3,1);
  2673.  int pos = ArgToInt(w,args,4,1);
  2674.  char string[100];
  2675.  int n;
  2676.  int len;
  2677.  
  2678.  ArgToString(w,args,1," ",string,99);
  2679.  n = strlen(string);
  2680.  
  2681.  if((n < start) || (start < 0) || (end < 0))
  2682.   {
  2683.    XtAppWarning(XtWidgetToApplicationContext(w),
  2684.         "GenTermEm Widget: Invalid substring specified in GetSubString");
  2685.    return(TRANSERROR);
  2686.   }
  2687.  if(end > n)
  2688.   end = n;
  2689.  
  2690.  len = (end - start);
  2691.  StringToInputArg(w,pos,&(string[start]),len);
  2692.  return(TRANSOKAY);
  2693. }
  2694.  
  2695. /* GtEIntToString:  This translator performs an explicit integer to string */
  2696. /* conversion.  The first argument is the number of convert.  The second */
  2697. /* argument is the number of characters in the final string and the final */
  2698. /* argument is where to store the result */
  2699.  
  2700. static int GtEIntToString(w,args)
  2701.  
  2702. GenTermEmWidget w;
  2703. struct ArgumentList *args;
  2704.  
  2705. {
  2706.  int n = ArgToInt(w,args,1,0);
  2707.  int len = ArgToInt(w,args,2,1);
  2708.  int pos = ArgToInt(w,args,3,1);
  2709.  char buffer[20];
  2710.  char string[20]; 
  2711.  int i,size,diff;
  2712.  
  2713.  if(len <= 0)
  2714.   {
  2715.    XtAppWarning(XtWidgetToApplicationContext(w),
  2716.         "GenTermEm Widget: Invalid string length in IntToString");
  2717.    return(TRANSERROR);
  2718.   }
  2719.  
  2720.  GtEIntToStringConvert(n,buffer);
  2721.  size = strlen(buffer);
  2722.  
  2723.  if(size < len)
  2724.   {
  2725.    diff = len - size;
  2726.    for(i = 0; i < diff; i++)
  2727.     string[i] = '0';
  2728.    memcpy(&(string[diff]),buffer,size);
  2729.   }
  2730.  else if(size > len)
  2731.   {
  2732.    memcpy(string,&(buffer[size-len]),len);
  2733.   }
  2734.  else
  2735.   memcpy(string,buffer,len);
  2736.  
  2737.  StringToInputArg(w,pos,string,len);
  2738.  return(TRANSOKAY);
  2739. }
  2740.  
  2741. /* GtESetFlow:  This translators envokes the flow callback so that the */
  2742. /*  parent widget knows that the underlying application has asserted flow */
  2743. /*  control.  It asserts an XOFF passed argument is a 0 and sends an */
  2744. /*  XON otherwise */
  2745.  
  2746. static int GtESetFlow(w,args)
  2747.  
  2748. GenTermEmWidget w;
  2749. struct ArgumentList args;
  2750.  
  2751. {
  2752.  int flow = ArgToInt(w,args,1,1);
  2753.  GenTermEmCallback reason;
  2754.  
  2755.  if(flow == 0)
  2756.   {
  2757.    reason.reason = GTE_XOFF;
  2758.   }
  2759.  else
  2760.   {
  2761.    reason.reason = GTE_XON;
  2762.   }
  2763.   XtCallCallbacks(w,XtNflowCallback,(caddr_t) &reason);
  2764.  return(TRANSOKAY);
  2765. }
  2766. @EOF
  2767. set `wc -lwc <GenTerm/Parse.c`
  2768. if test $1$2$3 != 2734773667395
  2769. then
  2770.     echo ERROR: wc results of GenTerm/Parse.c are $* should be 2734 7736 67395
  2771. fi
  2772.  
  2773. chmod 644 GenTerm/Parse.c
  2774.  
  2775. echo x - GenTerm/Pty.c
  2776. cat >GenTerm/Pty.c <<'@EOF'
  2777. /* Pty.c -- A Pty managment widget */
  2778. /* History:                                 */
  2779. /*         Written by G. R. Strachan 1992 */
  2780.  
  2781. /*  Copyright Gordon R. Strachan 1992 */
  2782. /*  This code is provided as is, neither the University of Waterloo nor */
  2783. /*  the author is liable for any damage caused by the use or misuse of this */
  2784. /*  code.  */
  2785.  
  2786. /* Permission is granted to copy, use and modify this code provided it is */
  2787. /* not sold for profit and the above copyright remains intact. */
  2788.  
  2789. #include <stdio.h>
  2790. #include <fcntl.h>
  2791. #include <unistd.h>
  2792. #include <termios.h>
  2793. #include <bsdtty.h>
  2794. #include <sys/pty.h>
  2795. #include <sys/errno.h>
  2796. #include <X11/X.h>
  2797. #include <X11/Xlib.h>
  2798. #include <X11/StringDefs.h>
  2799. #include <X11/IntrinsicP.h>
  2800. #include <X11/CoreP.h>
  2801. #include <X11/CompositeP.h>
  2802. #include <X11/Xatom.h>
  2803. #include "PtyP.h"
  2804. #include "Pty.h"
  2805.  
  2806. #define True 1
  2807. #define False 0
  2808. char *GetNextWord();
  2809.  
  2810. extern GenTermEmClassRec genTermEmClassRec;
  2811.  
  2812. static struct TtyMode TtyModes[] = 
  2813. {
  2814.  {"parenb",True,TTYCMODE,TTYLATER,PARENB},
  2815.  {"parodd",True,TTYCMODE,TTYLATER,PARODD},
  2816.  {"cs5",False,TTYCMODE,TTYLATER,CS5},
  2817.  {"cs6",False,TTYCMODE,TTYLATER,CS6},
  2818.  {"cs7",False,TTYCMODE,TTYLATER,CS7},
  2819.  {"cs8",False,TTYCMODE,TTYLATER,CS8},
  2820.  {"0",False,TTYSPEED,TTYNOW,B0},
  2821.  {"50",False,TTYSPEED,TTYNOW,B50},
  2822.  {"75",False,TTYSPEED,TTYNOW,B75},
  2823.  {"110",False,TTYSPEED,TTYNOW,B110},
  2824.  {"134.5",False,TTYSPEED,TTYNOW,B134},
  2825.  {"150",False,TTYSPEED,TTYNOW,B150},
  2826.  {"200",False,TTYSPEED,TTYNOW,B200},
  2827.  {"300",False,TTYSPEED,TTYNOW,B300},
  2828.  {"600",False,TTYSPEED,TTYNOW,B600},
  2829.  {"900",False,TTYSPEED,TTYNOW,B900},
  2830.  {"1200",False,TTYSPEED,TTYNOW,B1200},
  2831.  {"1800",False,TTYSPEED,TTYNOW,B1800},
  2832.  {"2400",False,TTYSPEED,TTYNOW,B2400},
  2833.  {"3600",False,TTYSPEED,TTYNOW,B3600},
  2834.  {"4800",False,TTYSPEED,TTYNOW,B4800},
  2835.  {"7200",False,TTYSPEED,TTYNOW,B7200},
  2836.  {"9600",False,TTYSPEED,TTYNOW,B9600},
  2837.  {"19200",False,TTYSPEED,TTYNOW,B19200},
  2838.  {"38400",False,TTYSPEED,TTYNOW,B38400},
  2839.  {"exta",False,TTYCMODE,TTYNOW,EXTA},
  2840.  {"extb",False,TTYCMODE,TTYNOW,EXTB},
  2841.  {"hupcl",True,TTYCMODE,TTYLATER,HUPCL},
  2842.  {"hup",True,TTYCMODE,TTYLATER,HUPCL},
  2843.  {"cstopb",True,TTYCMODE,TTYLATER,CSTOPB},
  2844.  {"cread",True,TTYCMODE,TTYLATER,CREAD},
  2845.  {"clocal",True,TTYCMODE,TTYLATER,CLOCAL},
  2846.  {"loblk",True,TTYCMODE,TTYLATER,LOBLK},
  2847.  {"ignbrk",True,TTYIMODE,TTYLATER,IGNBRK},
  2848.  {"ienqak",True,TTYIMODE,TTYLATER,IENQAK},
  2849.  {"brkint",True,TTYIMODE,TTYLATER,BRKINT},
  2850.  {"ignpar",True,TTYIMODE,TTYLATER,IGNPAR},
  2851.  {"parmrk",True,TTYIMODE,TTYLATER,PARMRK},
  2852.  {"inpck",True,TTYIMODE,TTYLATER,INPCK},
  2853.  {"istrip",True,TTYIMODE,TTYLATER,ISTRIP},
  2854.  {"inlcr",True,TTYIMODE,TTYLATER,INLCR},
  2855.  {"igncr",True,TTYIMODE,TTYLATER,IGNCR},
  2856.  {"icrnl",True,TTYIMODE,TTYLATER,ICRNL},
  2857.  {"iuclc",True,TTYIMODE,TTYLATER,IUCLC},
  2858.  {"ixon",True,TTYIMODE,TTYLATER,IXON},
  2859.  {"ixany",True,TTYIMODE,TTYLATER,IXANY},
  2860.  {"ixoff",True,TTYIMODE,TTYLATER,IXOFF},
  2861.  {"opost",True,TTYOMODE,TTYLATER,OPOST},
  2862.  {"olcuc",True,TTYOMODE,TTYLATER,OLCUC},
  2863.  {"onlcr",True,TTYOMODE,TTYLATER,ONLCR},
  2864.  {"ocrnl",True,TTYOMODE,TTYLATER,OCRNL},
  2865.  {"onocr",True,TTYOMODE,TTYLATER,ONOCR},
  2866.  {"onlret",True,TTYOMODE,TTYLATER,ONLRET},
  2867.  {"ofill",True,TTYOMODE,TTYLATER,OFILL},
  2868.  {"ofdel",True,TTYOMODE,TTYLATER,OFDEL},
  2869.  {"cr0",False,TTYOMODE,TTYLATER,CR0},
  2870.  {"cr1",False,TTYOMODE,TTYLATER,CR1},
  2871.  {"cr2",False,TTYOMODE,TTYLATER,CR2},
  2872.  {"cr3",False,TTYOMODE,TTYLATER,CR3},
  2873.  {"nl0",False,TTYOMODE,TTYLATER,NL0},
  2874.  {"nl1",False,TTYOMODE,TTYLATER,NL1},
  2875.  {"tab0",False,TTYOMODE,TTYLATER,TAB0},
  2876.  {"tab1",False,TTYOMODE,TTYLATER,TAB1},
  2877.  {"tab2",False,TTYOMODE,TTYLATER,TAB2},
  2878.  {"tab3",False,TTYOMODE,TTYLATER,TAB3},
  2879.  {"bs0",False,TTYOMODE,TTYLATER,BS0},
  2880.  {"bs1",False,TTYOMODE,TTYLATER,BS1},
  2881.  {"ff0",False,TTYOMODE,TTYLATER,FF0},
  2882.  {"ff1",False,TTYOMODE,TTYLATER,FF1},
  2883.  {"vt0",False,TTYOMODE,TTYLATER,VT0},
  2884.  {"vt1",False,TTYOMODE,TTYLATER,VT1},
  2885.  {"isig",True,TTYLMODE,TTYLATER,ISIG},
  2886.  {"icanon",True,TTYLMODE,TTYLATER,ICANON},
  2887.  {"iexten",True,TTYLMODE,TTYLATER,IEXTEN},
  2888.  {"xcase",True,TTYLMODE,TTYLATER,XCASE},
  2889.  {"echo",True,TTYLMODE,TTYLATER,ECHO},
  2890.  {"echoe",True,TTYLMODE,TTYLATER,ECHOE},
  2891.  {"echok",True,TTYLMODE,TTYLATER,ECHOK},
  2892.  {"lfkc",True,TTYLMODE,TTYLATER,ECHOK},
  2893.  {"echonl",True,TTYLMODE,TTYLATER,ECHONL},
  2894.  {"noflsh",True,TTYLMODE,TTYLATER,NOFLSH},
  2895.  {"tostop",True,TTYLMODE,TTYLATER,TOSTOP},
  2896.  {"erase",False,TTYCCHAR,TTYLATER,VERASE},
  2897.  {"kill",False,TTYCCHAR,TTYLATER,VKILL},
  2898.  {"intr",False,TTYCCHAR,TTYLATER,VINTR},
  2899.  {"quit",False,TTYCCHAR,TTYLATER,VQUIT},
  2900.  {"eof",False,TTYCCHAR,TTYLATER,VEOF},
  2901.  {"eol",False,TTYCCHAR,TTYLATER,VEOL},
  2902.  {"min",False,TTYCCHAR,TTYLATER,VMIN},
  2903.  {"time",False,TTYCCHAR,TTYLATER,VTIME},
  2904.  {"susp",False,TTYCCHAR,TTYLATER,VSUSP},
  2905.  {"dsusp",False,TTYCCHAR,TTYLATER,VSUSP},
  2906.  {"swtch",False,TTYCCHAR,TTYLATER,VSWTCH},
  2907.  {"stop",False,TTYCCHAR,TTYLATER,VSTOP},
  2908.  {"start",False,TTYCCHAR,TTYLATER,VSTART},
  2909.  {"rows",False,TTYSIZE,TTYNOW,TTYROW},
  2910.  {"columns",False,TTYSIZE,TTYNOW,TTYCOLUMN},
  2911.  {NULL,NULL,NULL,NULL,NULL}
  2912. };
  2913.  
  2914. static char *BaseMaster = "/dev/pty";
  2915. static char *BaseSlave = "/dev/tty";
  2916. static char *Offset = "pqr";
  2917. static char *Index =  "0123456789abcdef";
  2918.  
  2919. static void PtyInitialize();
  2920. static void PtyRealize();
  2921. static void PtyResize();
  2922. static Boolean PtySetValues();
  2923. static void PtyDestroy();
  2924. static void PtyExceptionCB();
  2925. static void PtyDoPtyCallbacks();
  2926. static void PtyWriteCB();
  2927. static void PtyWriteAction();
  2928. static void PtySetModeAction();
  2929.  
  2930. static XtResource resources[] = {
  2931.  {XtNmasterPtyName,XtCMasterPtyName,XtRString,sizeof(char *),
  2932.    XtOffset(PtyWidget,pty.MasterPtyName),XtRString,""},
  2933.  {XtNslavePtyName,XtCSlavePtyName,XtRString,sizeof(char *),
  2934.    XtOffset(PtyWidget,pty.SlavePtyName),XtRString,""},
  2935.  {XtNmasterPtyDescriptor,XtCMasterPtyDescriptor,XtRInt,sizeof(int),
  2936.    XtOffset(PtyWidget,pty.MasterDescriptor),XtRImmediate,(caddr_t)-1},
  2937.  {XtNslavePtyDescriptor,XtCSlavePtyDescriptor,XtRInt,sizeof(int),
  2938.    XtOffset(PtyWidget,pty.SlaveDescriptor),XtRImmediate,(caddr_t)-1},
  2939.  {XtNmasterPtyOpenMode,XtCMasterPtyOpenMode,XtRInt,sizeof(int),
  2940.    XtOffset(PtyWidget,pty.MasterPtyOpenModes),XtRImmediate,
  2941.    (caddr_t)(O_RDWR | O_NDELAY)},
  2942.  {XtNslavePtyOpenMode,XtCSlavePtyOpenMode,XtRInt,sizeof(int),
  2943.    XtOffset(PtyWidget,pty.SlavePtyOpenModes),XtRImmediate,(caddr_t)O_RDWR},
  2944.  {XtNttyMode,XtCTtyMode,XtRString,sizeof(char *),
  2945.    XtOffset(PtyWidget,pty.TtyModes),XtRString,"-icanon min 1"},
  2946.  {XtNptyCallback,XtCPtyCallback,XtRCallback,sizeof(caddr_t),
  2947.    XtOffset(PtyWidget,pty.PtyCallbacks),XtRCallback,NULL},
  2948. };
  2949.  
  2950. static XtActionsRec actions[] =
  2951. {
  2952.  {"ptywrite",PtyWriteAction},
  2953.  {"ptysetmode",PtySetModeAction},
  2954. };
  2955.  
  2956. PtyClassRec ptyClassRec =
  2957. {
  2958.  
  2959.  {  /* core fields */
  2960.     /* superclass               */      (WidgetClass) &genTermEmClassRec,
  2961.     /* class_name               */      "Pty",
  2962.     /* widget_size              */      sizeof(PtyRec),
  2963.     /* class_initialize         */      NULL,
  2964.     /* class_part_initialize    */      NULL,
  2965.     /* class_inited             */      FALSE,
  2966.     /* initialize               */      PtyInitialize,
  2967.     /* initialize_hook          */      NULL,
  2968.     /* realize                  */      PtyRealize,
  2969.     /* actions                  */      actions,
  2970.     /* num_actions              */      XtNumber(actions),
  2971.     /* resources                */      resources,
  2972.     /* num_resources            */      XtNumber(resources),
  2973.     /* xrm_class                */      NULLQUARK,
  2974.     /* compress_motion          */      TRUE,
  2975.     /* compress_exposure        */      FALSE,
  2976.     /* compress_enterleave      */      TRUE,
  2977.     /* visible_interest         */      FALSE,
  2978.     /* destroy                  */      PtyDestroy,
  2979.     /* resize                   */      PtyResize,
  2980.     /* expose                   */      XtInheritExpose,
  2981.     /* set_values               */      PtySetValues,
  2982.     /* set_values_hook          */      NULL,
  2983.     /* set_values_almost        */      XtInheritSetValuesAlmost,
  2984.     /* get_values_hook          */      NULL,
  2985.     /* accept_focus             */      XtInheritAcceptFocus,
  2986.     /* version                  */      XtVersion,
  2987.     /* callback_private         */      NULL,
  2988.     /* tm_table                 */      XtInheritTranslations,
  2989.     /* query_geometry           */      XtInheritQueryGeometry,
  2990.     /* display_accelerator      */      XtInheritDisplayAccelerator,
  2991.     /* extension                */      NULL
  2992.   },
  2993.      { /* composite_class fields */
  2994.     /* geometry_manager   */   XtInheritGeometryManager,
  2995.     /* change_managed     */   XtInheritChangeManaged,
  2996.     /* insert_child       */   XtInheritInsertChild,
  2997.     /* delete_child       */   XtInheritDeleteChild,
  2998.     /* extension          */   NULL
  2999.   },
  3000.      { NULL},
  3001.      { NULL},
  3002.  
  3003. };
  3004.  
  3005. WidgetClass ptyWidgetClass = (WidgetClass) &ptyClassRec;
  3006.  
  3007. /* PtyInitialize:  This is the initialization method for the widget.  Right */
  3008. /*  now it is a no-op.  All the real work is done in the realize method. */
  3009.  
  3010. static void PtyInitialize(request,new)
  3011.  
  3012. PtyWidget request,new;
  3013.  
  3014. {
  3015.  new->pty.StartChar = 021;   /* control Q */
  3016.  new->pty.StartAny = False;
  3017.  new->pty.FlowEnabled = True;
  3018.  new->pty.WriteEnabled = False;
  3019.  new->pty.NumStore = 0;
  3020.  new->pty.StoreSize = 20;
  3021.  new->pty.Storage = (char *) XtMalloc(sizeof(char) * new->pty.StoreSize);
  3022. };
  3023.  
  3024. /* PtyRealize:  This is the realize method for the widget.  It opens the Pty */
  3025. /*  makes sure it has the correct modes and sets up all the handling routines*/
  3026.  
  3027. static void PtyRealize(w,valueMask,attributes)
  3028.  
  3029. PtyWidget w;
  3030. XtValueMask *valueMask;
  3031. XSetWindowAttributes *attributes;
  3032.  
  3033. {
  3034.  Arg args[20];
  3035.  int n = 0;
  3036.  WidgetClass superclass;
  3037.  char *Names[2];
  3038.  
  3039.  superclass = (WidgetClass)genTermEmWidgetClass;
  3040.  (*superclass->core_class.realize)(w,valueMask,attributes);
  3041.  
  3042.  OpenPty(&(w->pty.MasterDescriptor),&(w->pty.SlaveDescriptor),
  3043.      w->pty.MasterPtyOpenModes,w->pty.SlavePtyOpenModes,Names);
  3044.  
  3045.  if((w->pty.MasterDescriptor == -1) || (w->pty.SlaveDescriptor == -1))
  3046.   {
  3047.    XtAppError(XtWidgetToApplicationContext(w),
  3048.           "Pty Widget can not open an pty!");
  3049.   }
  3050.  
  3051.  w->pty.MasterPtyName = Names[0];
  3052.  w->pty.SlavePtyName = Names[1];
  3053.  
  3054.  SetPtyMode(w->pty.MasterDescriptor,w->pty.TtyModes);
  3055.  
  3056.  XtSetArg(args[n],XtNoutputFile,w->pty.MasterDescriptor); n++;
  3057.  XtSetValues(w,args,n);
  3058.  
  3059.  w->pty.ExceptId = XtAppAddInput(XtWidgetToApplicationContext(w),
  3060.                  w->pty.MasterDescriptor,XtInputExceptMask,
  3061.                  PtyExceptionCB,(XtPointer)w);
  3062.  n = 1;
  3063.  ioctl(w->pty.MasterDescriptor,TIOCMONITOR,&n);
  3064.  ioctl(w->pty.MasterDescriptor,TIOCTRAP,&n);
  3065.  
  3066.  PtyDoPtyCallbacks(w,PTY_OPEN,NULL);
  3067. }
  3068.  
  3069. /* PtyResize:  This is the resize method for the widget.  It first calls the */
  3070. /*  superclass's resize method and then does the ioctl on the pty to inform */
  3071. /*  the underlying application that the window size changed. */
  3072.  
  3073. static void PtyResize(w)
  3074.  
  3075. PtyWidget w;
  3076.  
  3077. {
  3078.  Arg args[10];
  3079.  int n = 0;
  3080.  int row,col;
  3081.  char mode[80];
  3082.  WidgetClass superclass = (WidgetClass)genTermEmWidgetClass;
  3083.  
  3084.  (*superclass->core_class.resize)(w);
  3085.  
  3086.  XtSetArg(args[n],XtNrows,&row); n++;
  3087.  XtSetArg(args[n],XtNcolumns,&col); n++;
  3088.  XtGetValues(w,args,n);
  3089.  
  3090.  sprintf(mode,"rows %d columns %d",row,col);
  3091.  SetPtyMode(w->pty.MasterDescriptor,mode);
  3092. }
  3093.  
  3094. /* PtySetValues:  This is the set values method for the widget.  Most values */
  3095. /*  for this widget can not be set after initialization.  This function will */
  3096. /*  detect this, correct the value and return an error. */
  3097.  
  3098. static Boolean PtySetValues(current,request,new)
  3099.  
  3100. PtyWidget current,request,new;
  3101. {
  3102.  int Error = False;
  3103.  
  3104.  if((current->pty.TtyModes != new->pty.TtyModes) &&
  3105.     (strcmp(current->pty.TtyModes,new->pty.TtyModes) != 0) &&
  3106.     (XtIsRealized(new)))
  3107.   {
  3108.    SetPtyMode(new->pty.MasterDescriptor,new->pty.TtyModes);
  3109.   }
  3110.  if((current->pty.MasterPtyOpenModes != new->pty.MasterPtyOpenModes) &&
  3111.     (XtIsRealized(new)))
  3112.   {
  3113.    Error = True;
  3114.    new->pty.MasterPtyOpenModes = current->pty.MasterPtyOpenModes;
  3115.   }
  3116.  if((current->pty.SlavePtyOpenModes != new->pty.SlavePtyOpenModes) &&
  3117.     (XtIsRealized(new)))
  3118.   {
  3119.    Error = True;
  3120.    new->pty.SlavePtyOpenModes = current->pty.SlavePtyOpenModes;
  3121.   }
  3122.  if((current->pty.MasterPtyName != new->pty.MasterPtyName) &&
  3123.     (XtIsRealized(new)))
  3124.   {
  3125.    Error = True;
  3126.    new->pty.MasterPtyName = current->pty.MasterPtyName;
  3127.   }
  3128.  if((current->pty.SlavePtyName != new->pty.SlavePtyName) &&
  3129.     (XtIsRealized(new)))
  3130.   {
  3131.    Error = True;
  3132.    new->pty.SlavePtyName = current->pty.SlavePtyName;
  3133.   }
  3134.  if((current->pty.MasterDescriptor != new->pty.MasterDescriptor) &&
  3135.     (XtIsRealized(new)))
  3136.   {
  3137.    Error = True;
  3138.    new->pty.MasterDescriptor = current->pty.MasterDescriptor;
  3139.   }
  3140.  if((current->pty.SlaveDescriptor != new->pty.SlaveDescriptor) &&
  3141.     (XtIsRealized(new)))
  3142.   {
  3143.    Error = True;
  3144.    new->pty.SlaveDescriptor = current->pty.SlaveDescriptor;
  3145.   }
  3146.  
  3147.  if(Error)
  3148.   XtAppWarning(XtWidgetToApplicationContext(new),
  3149.            "Attempt to set a read only resource in Pty widget");
  3150.  return(False);
  3151. }
  3152.  
  3153. /* PtyDestroy:  This is the pty destroy method for the widget.  It frees up */
  3154. /*  all allocated memory and removes any input handlers. */
  3155.  
  3156. static void PtyDestroy(w)
  3157.  
  3158. PtyWidget w;
  3159.  
  3160. {
  3161.  XtRemoveInput(w->pty.ExceptId);
  3162.  if(w->pty.WriteEnabled)
  3163.   XtRemoveInput(w->pty.OutputId);
  3164.  close(w->pty.MasterDescriptor);
  3165.  close(w->pty.SlaveDescriptor);
  3166.  XtFree(w->pty.MasterPtyName);
  3167.  XtFree(w->pty.SlavePtyName);
  3168.  XtFree(w->pty.Storage);
  3169. }
  3170.  
  3171. /* PtyExceptionCB:  This is the input exception handler for the widget.  It */
  3172. /*  is used to monitor the changes to the pty the underlying processes is */
  3173. /*  requesting.  This is done so we can handle flow control properly and to */
  3174. /*  determine if there even is a process attatched to us. */
  3175.  
  3176. static void PtyExceptionCB(client,source,id)
  3177.  
  3178. XtPointer client;
  3179. int *source;
  3180. XtInputId *id;
  3181.  
  3182. {
  3183.  PtyWidget w = (PtyWidget) client;
  3184.  struct request_info request;
  3185.  char c;
  3186.  int size;
  3187.  union buffer
  3188.   {
  3189.    struct termios termios;
  3190.    struct ltchars ltchars;
  3191. #ifdef TIOCGWINSZ
  3192.    struct winsize winsize;
  3193. #endif
  3194.    long value;
  3195.   } argument;
  3196.  
  3197. /* first we complete the Pty Monitor handshake */
  3198.  
  3199.  if(ioctl(w->pty.MasterDescriptor,TIOCREQCHECK,&request) != EINVAL)
  3200.   {
  3201.    switch(request.request)
  3202.     {
  3203.    case TIOCOPEN:
  3204.      PtyDoPtyCallbacks(w,PTY_SLAVEOPEN,NULL);
  3205.      break;
  3206.    case TIOCCLOSE:
  3207.      PtyDoPtyCallbacks(w,PTY_SLAVECLOSE,NULL);
  3208.      break;
  3209.    default:
  3210.      break;
  3211.     }
  3212.    if(request.argget != 0)
  3213.     ioctl(w->pty.MasterDescriptor,request.argget,&argument);
  3214.    if(request.argset != 0)
  3215.     ioctl(w->pty.MasterDescriptor,request.argset,&argument);
  3216.    request.return_value = 0;
  3217.    ioctl(w->pty.MasterDescriptor,TIOCREQSET,&request);
  3218.  
  3219. /* we have now completed the handshake so let's look at what changed */
  3220.    
  3221.    tcgetattr(w->pty.MasterDescriptor,&argument);
  3222.  
  3223.    w->pty.StartChar = argument.termios.c_cc[VSTART];
  3224.    
  3225.    if((argument.termios.c_iflag & IXANY) &&
  3226.       (argument.termios.c_lflag & IEXTEN))
  3227.     w->pty.StartAny = True;
  3228.    else
  3229.     w->pty.StartAny = False;
  3230.    if(argument.termios.c_iflag & IXOFF)
  3231.     w->pty.FlowEnabled = True;
  3232.    else
  3233.     w->pty.FlowEnabled = False;
  3234.  
  3235. /* finally tell application program about changes */
  3236.   
  3237.    PtyDoPtyCallbacks(w,PTY_IOCTL,&(argument.termios));
  3238.   }
  3239. }
  3240.  
  3241. /* PtyDoPtyCallbacks:  This function envokes the PtyCallback.  It allocates */
  3242. /*  the callback structures and executes the callback. */
  3243.  
  3244. static void PtyDoPtyCallbacks(w,why,term)
  3245.  
  3246. PtyWidget w;
  3247. int why;
  3248. struct termios *term;
  3249.  
  3250. {
  3251.  PtyCallback reason;
  3252.  
  3253.  reason.reason = why;
  3254.  reason.MasterPtyDescriptor = w->pty.MasterDescriptor;
  3255.  reason.SlavePtyDescriptor = w->pty.SlaveDescriptor;
  3256.  reason.Termios = term;
  3257.  XtCallCallbacks(w,XtNptyCallback,(caddr_t)&reason);
  3258. }
  3259.  
  3260. /* PtyWrite:  This is the input routine to the widget.  It allows the calling*/
  3261. /*  application to write data to the pty with out fear of blocking.  It */
  3262. /*  handles all necessary flow control. */
  3263.  
  3264. PtyWrite(w,string,len)
  3265.  
  3266. PtyWidget w;
  3267. char *string;
  3268. int len;
  3269.  
  3270. {
  3271.  int i;
  3272.  
  3273.  if(len + w->pty.NumStore >= w->pty.StoreSize)
  3274.   {
  3275.    w->pty.StoreSize = (len + w->pty.NumStore) * 2;
  3276.    w->pty.Storage = (char *) XtRealloc(w->pty.Storage,
  3277.                        sizeof(char)*w->pty.StoreSize);
  3278.   }
  3279.  
  3280.  memcpy(&(w->pty.Storage[w->pty.NumStore]),string,len);
  3281.  w->pty.NumStore += len;
  3282.  
  3283.  if(w->pty.FlowEnabled)
  3284.   {
  3285.    if(w->pty.StartAny)
  3286.     tcflow(w->pty.MasterDescriptor,TCOON);
  3287.    else
  3288.     for(i = 0; i < len; i++)
  3289.      if(string[i] == w->pty.StartChar)
  3290.       tcflow(w->pty.MasterDescriptor,TCOON);
  3291.   }
  3292.  
  3293.  if(w->pty.WriteEnabled == False)
  3294.   {
  3295.    w->pty.OutputId = XtAppAddInput(XtWidgetToApplicationContext(w),
  3296.                   w->pty.MasterDescriptor,XtInputWriteMask,
  3297.                   PtyWriteCB,(XtPointer)w);
  3298.    w->pty.WriteEnabled = True;
  3299.   }
  3300. }
  3301.  
  3302. /* PtyWriteCB:  This is the write event handler.  It is called when ever the */
  3303. /*  the pty is ready to write more data and there is data to be sent to it. */
  3304.  
  3305. static void PtyWriteCB(client,source,id)
  3306.  
  3307. XtPointer client;
  3308. int *source;
  3309. XtInputId *id;
  3310.  
  3311. {
  3312.  PtyWidget w = (PtyWidget)client;
  3313.  int n;
  3314.  int start = 0;
  3315.  
  3316.  while((w->pty.NumStore > 0) && ((n = write(w->pty.MasterDescriptor,
  3317.                         &(w->pty.Storage[start]),
  3318.                         w->pty.NumStore)) > 0))
  3319.   {
  3320.    w->pty.NumStore -= n;
  3321.    start += n;
  3322.   }
  3323.  
  3324.  if(w->pty.NumStore != 0)
  3325.   {
  3326.    for(n = 0; n < w->pty.NumStore; n++)
  3327.     w->pty.Storage[n] = w->pty.Storage[start + n];
  3328.   }
  3329.  else
  3330.   {
  3331.    XtRemoveInput(w->pty.OutputId);
  3332.    w->pty.WriteEnabled = False;
  3333.   }
  3334. }
  3335.  
  3336. /* PtyWriteAction:  This is the write action handler for the widget.  It */
  3337. /*  simply sends all the strings to the pty. */
  3338.  
  3339. static void PtyWriteAction(w,event,strings,num)
  3340.  
  3341. PtyWidget w;
  3342. XEvent *event;
  3343. char *strings[];
  3344. Cardinal *num;
  3345.  
  3346. {
  3347.  int i;
  3348.  
  3349.  for(i = 0; i < *num; i++)
  3350.   PtyWrite(w,strings[i],strlen(strings[i]));
  3351. }
  3352.  
  3353. /* PtySetModeAction:  Thisis the set mode action handler for the widget.  It */
  3354. /*  sets the tty mode of the master pty to the values given in the first */
  3355. /*  string. */
  3356.  
  3357. static void PtySetModeAction(w,event,strings,num)
  3358.  
  3359. PtyWidget w;
  3360. XEvent *event;
  3361. char *strings[];
  3362. Cardinal *num;
  3363.  
  3364. {
  3365.  if(*num > 0)
  3366.   SetPtyMode(w->pty.MasterDescriptor,strings[0]);
  3367. }
  3368.  
  3369. /* PtySignal:  This function sends a signal to the process group associated */
  3370. /*  with the slave side of the Pty. */
  3371.  
  3372. void PtySignal(w,Sig)
  3373.  
  3374. PtyWidget w;
  3375. int Sig;
  3376.  
  3377. {
  3378.  ioctl(w->pty.MasterDescriptor,TIOCSIGSEND,Sig);
  3379. }
  3380.  
  3381. OpenPty(master,slave,master_mode,slave_mode,names)
  3382.  
  3383. int *master;
  3384. int *slave;
  3385. int master_mode;
  3386. int slave_mode;
  3387. char *names[2];
  3388.  
  3389. {
  3390.  char Filename[80];
  3391.  int i,j;
  3392.  int offsize,indexsize;
  3393.  int basesize;
  3394.  
  3395.  offsize = strlen(Offset);
  3396.  indexsize = strlen(Index);
  3397.  basesize = strlen(BaseMaster) - 1;
  3398.  strcpy(Filename,BaseMaster);
  3399.  Filename[basesize+3] = NULL;
  3400.  *master = *slave = -1;
  3401.  
  3402.  for(i = 0; i <= offsize; i++)
  3403.   for(j = 0; j <= indexsize;j++)
  3404.    {
  3405.     Filename[basesize+1] = Offset[i];
  3406.     Filename[basesize+2] = Index[j];
  3407.     if((*master = open(Filename,master_mode)) >= 0)
  3408.      {
  3409.       names[0] = XtMalloc(sizeof(char)*(strlen(Filename) + 1));
  3410.       strcpy(names[0],Filename);
  3411.       strcpy(Filename,BaseSlave);
  3412.       basesize = strlen(BaseSlave) - 1;
  3413.       Filename[basesize+1] = Offset[i];
  3414.       Filename[basesize+2] = Index[j];
  3415.       Filename[basesize+3] = NULL;
  3416.       if((*slave = open(Filename,slave_mode)) < 0)
  3417.        {
  3418.         fprintf(stderr,"Error can not open slave pty %s\n",Filename);
  3419.         close(*master);
  3420.         *master = *slave = -1;
  3421.     strcpy(Filename,BaseMaster);
  3422.        }
  3423.       else
  3424.        {
  3425.     names[1] = XtMalloc(sizeof(char)*(strlen(Filename) + 1));
  3426.     strcpy(names[1],Filename);
  3427.     return;
  3428.        }
  3429.      }
  3430.    }
  3431. }
  3432.  
  3433. SetPtyMode(fd,ModeList)
  3434.  
  3435. int fd;
  3436. char *ModeList;
  3437.  
  3438. {
  3439.  int i = 0;
  3440.  char name[1024];
  3441.  int which;
  3442.  char arg;
  3443.  struct termios buf;
  3444. #ifdef TIOCGWINSZ
  3445.  struct winsize size;
  3446. #endif
  3447.  int invert;
  3448.  
  3449.  if(tcgetattr(fd,&buf) != 0)
  3450.   {
  3451.    perror("SetPtyMode");
  3452.    return(-1);
  3453.   }
  3454. #ifdef TIOCGWINSZ
  3455.  if(ioctl(fd,TIOCGWINSZ,&size) != 0)
  3456.   {
  3457.    perror("SetPtyMode");
  3458.    return(-1);
  3459.   }
  3460. #endif
  3461.  
  3462.  while(*ModeList != NULL)
  3463.   {
  3464.    ModeList = GetNextWord(ModeList,name,&invert,True);
  3465.    i = 0;
  3466.    which = -1;
  3467.    
  3468.    while(TtyModes[i].Name != NULL)
  3469.     {
  3470.      if(strcmp(TtyModes[i].Name,name) == 0)
  3471.       {
  3472.        which = i;
  3473.        break;
  3474.       }
  3475.      i++;
  3476.     }
  3477.    if(which == -1)
  3478.     {
  3479.      fprintf(stderr,"Bad tty mode %s\n",name);
  3480.      return(-1);
  3481.     }
  3482.    if((invert == 1) && (TtyModes[i].Invertable == False))
  3483.     {
  3484.      fprintf(stderr,"%s can not be complimented\n",name);
  3485.      return(-1);
  3486.     }
  3487.    switch(TtyModes[which].Type)
  3488.     {
  3489.    case TTYIMODE:
  3490.      SetMode(&buf.c_iflag,TtyModes[which].Mask,invert);
  3491.      break;
  3492.    case TTYOMODE:
  3493.      SetMode(&buf.c_oflag,TtyModes[which].Mask,invert);
  3494.      break;
  3495.    case TTYCMODE:
  3496.      SetMode(&buf.c_cflag,TtyModes[which].Mask,invert);
  3497.      break;
  3498.    case TTYLMODE:
  3499.      SetMode(&buf.c_lflag,TtyModes[which].Mask,invert);
  3500.      break;
  3501.    case TTYSPEED:
  3502.      cfsetospeed(&buf,TtyModes[which].Mask);
  3503.      cfsetispeed(&buf,TtyModes[which].Mask);
  3504.      break;
  3505.    case TTYSIZE:
  3506.      ModeList = GetNextWord(ModeList,name,&invert,False);
  3507. #ifdef TIOCGWINSZ
  3508.      if(TtyModes[which].Mask == TTYROW)
  3509.       size.ws_row = atoi(name);
  3510.      else
  3511.       size.ws_col = atoi(name);
  3512. #endif
  3513.      break;
  3514.    case TTYCCHAR:
  3515.      ModeList = GetNextWord(ModeList,name,&invert,False);
  3516.      if((TtyModes[which].Mask == VMIN) || (TtyModes[which].Mask == VTIME))
  3517.       {
  3518.        buf.c_cc[TtyModes[which].Mask] = atoi(name);
  3519.       }
  3520.      else
  3521.       {
  3522.        if(name[0] = '^')
  3523.     {
  3524.      if(strlen(name) != 2)
  3525.       {
  3526.        fprintf(stderr,"%s is an invalid keyword\n",name);
  3527.        return(-1);
  3528.       }
  3529.      if(islower(name[1]))
  3530.       buf.c_cc[TtyModes[which].Mask] = toupper(name[1]) & 077;
  3531.      else
  3532.       buf.c_cc[TtyModes[which].Mask] = name[1] & 077;
  3533.     }
  3534.        else
  3535.     {
  3536.      if(strlen(name) != 1)
  3537.       {
  3538.        fprintf(stderr,"%s is an invalid keyword\n",name);
  3539.        return(-1);
  3540.       }
  3541.      buf.c_cc[TtyModes[which].Mask] = name[0];
  3542.     }
  3543.       }
  3544.      break;
  3545.     }
  3546.    if(TtyModes[which].When == TTYNOW)
  3547.     {
  3548.      if(tcsetattr(fd,TCSANOW,&buf))
  3549.       {
  3550.        perror("SetPtyMode");
  3551.        return(-1);
  3552.       }
  3553. #ifdef TIOCSWINSZ
  3554.      if(ioctl(fd,TIOCSWINSZ,&size))
  3555.       {
  3556.        perror("SetPtyMode");
  3557.        return(-1);
  3558.       }
  3559. #endif
  3560.      if(tcgetattr(fd,&buf))
  3561.       {
  3562.        perror("SetPtyMode");
  3563.        return(-1);
  3564.       }
  3565. #ifdef TIOCGWINSZ
  3566.      if(ioctl(fd,TIOCGWINSZ,&size))
  3567.       {
  3568.        perror("SetPtyMode");
  3569.        return(-1);
  3570.       }
  3571. #endif
  3572.     }
  3573.   }
  3574.  if(tcsetattr(fd,TCSANOW,&buf))
  3575.   {
  3576.    perror("SetPtyMode");
  3577.    return(-1);
  3578.   }
  3579. #ifdef TIOCSWINSZ
  3580.  if(ioctl(fd,TIOCSWINSZ,&size))
  3581.   {
  3582.    perror("SetPtyMode");
  3583.    return(-1);
  3584.   }
  3585. #endif
  3586.  return(0);
  3587. }
  3588.  
  3589.  
  3590.  
  3591. SetMode(mode,mask,invert)
  3592.  
  3593. tcflag_t *mode;
  3594. tcflag_t mask;
  3595. int invert;
  3596.  
  3597. {
  3598.  if(invert)
  3599.   *mode &= ~mask;
  3600.  else
  3601.   *mode |= mask;
  3602. }
  3603.  
  3604. char *GetNextWord(List,name,invert,flag)
  3605.  
  3606. char *List;
  3607. char *name;
  3608. int *invert;
  3609. int flag;
  3610.  
  3611. {
  3612.  *invert = False;
  3613.  
  3614.  while((*List != NULL) && (*List == ' '))
  3615.   List++;
  3616.  
  3617.  if(flag)
  3618.   {
  3619.    if(*List == '-')
  3620.     {
  3621.      *invert = True;
  3622.      List++;
  3623.     }
  3624.   }
  3625.  while((*List != NULL) && (*List != ' '))
  3626.   *(name++) = *(List++);
  3627.  *name = NULL;
  3628.  return(List);
  3629. }
  3630. @EOF
  3631. set `wc -lwc <GenTerm/Pty.c`
  3632. if test $1$2$3 != 853192422746
  3633. then
  3634.     echo ERROR: wc results of GenTerm/Pty.c are $* should be 853 1924 22746
  3635. fi
  3636.  
  3637. chmod 644 GenTerm/Pty.c
  3638.  
  3639. echo x - GenTerm/Pty.man
  3640. sed 's/^@//' >GenTerm/Pty.man <<'@EOF'
  3641. @.\" Man page for the GenTermEm Widget -*-nroff-*-
  3642. @.\"
  3643. @.\"  Written by G. Strachan 1992
  3644. @.\"
  3645. @.de KS  \"      Keep start
  3646. @.br
  3647. @.in 0
  3648. @.di KP
  3649. @..
  3650. @.de KE  \"      Keep end
  3651. @.br
  3652. @.di
  3653. @.ne \\n(dnu
  3654. @.nr fI \\n(.u
  3655. @.nf
  3656. @.KP
  3657. @.if \\n(fI .fi
  3658. @.in
  3659. @..
  3660. @.TH Pty 3X
  3661. @.SH NAME
  3662. \fBPty \- The Pty widget class.\fP
  3663. @.sp 1
  3664. @.SH SYNOPSIS
  3665. \fB#include "/usr/local/include/Pty.h"\fP
  3666. @.SH DESCRIPTION
  3667. The \fBPty\fP widget is a pty management and terminal emulator widget.
  3668. In inherits all
  3669. capabilities and resource of the \fBGenTermEm\fP widget and adds
  3670. management capabilities specific to handling pty's  The widget will
  3671. allocate and initialize pty's for the application code.  In addition,
  3672. the widget will handle all pty flow control and blocking.  Finally,
  3673. the widget has been constructed in such a manner that it will not
  3674. deadlock if the application is reading and writing from the same pty.
  3675. After finding and allocating the pty, the widget will set its line
  3676. discipline properly and then control the master side of the pty.  Any
  3677. data written to the slave side of the pty will be displayed in the
  3678. terminal emulator widget's window.  Any data entered from the keyboard
  3679. into the widget will be written to the master side of the pty and can
  3680. be read from the slave side.  In addition, the widget performs some
  3681. monitoring of the pty and can inform the application of changes in
  3682. line discipline and when processes attach and detach themselves from
  3683. the slave pty.  Finally, on system which support \fISIGWINCH\fP, the
  3684. widget will automatically inform process attached to the slave pty
  3685. about changes in the widget's dimensions.
  3686. @.SH CLASSES
  3687. \fBPty\fP inherits behavior and resources from \fBGenTermEm\fP,
  3688. \fBGenTerm\fP, \fBCore\fP and \fBComposite\fP classes.
  3689. @.PP
  3690. The class pointer it \fBptyWidgetClass\fP
  3691. @.PP
  3692. The class name is \fBPty\fP
  3693. @.SH "NEW RESOURCES"
  3694. The following table lists the resources recognized by the \fBPty\fP
  3695. widget.  The programmer can also set the resource of the inherited
  3696. classes.  To set these resources in the resource database, remove the
  3697. \fBXtN\fP and \fBXtC\fp prefixes to the resource names.
  3698. @.sp 1
  3699. @.KS
  3700. @.sp 1
  3701. @.TS
  3702. center;
  3703. cB sss
  3704. lB lB lB lB
  3705. l l l l.
  3706. Pty Resource Set
  3707. Name    Class    Type    Default
  3708. _
  3709. XtNmasterPtyDescriptor    XtCMasterPtyDescriptor    Int    Dynamic
  3710. XtNmasterPtyName    XtCMasterPtyName    String    Dynamic
  3711. XtNmasterPtyOpenMode    XtCMasterPtyOpenMode    Int    O_RDWR | O_NDELAY
  3712. XtNptyCallback    XtCPtyCallback    Callback    NULL
  3713. XtNslavePtyDescriptor    XtCSlavePtyDescriptor    Int    Dynamic
  3714. XtNslavePtyName    XtCSlavePtyName    String    Dynamic
  3715. XtNslavePtyOpenMode    XtCSlavePtyOpenMode    Int    O_RDWR
  3716. XtNttyMode    XtCTtyMode    String    "-icanon min 1"
  3717. @.TE
  3718. @.KE
  3719. @.sp 1
  3720. @.IP \fBXtNmasterPtyDescriptor\fP
  3721. This read only resource will contain the file descriptor associated
  3722. with the master side of the pty after the widget has been realized and has
  3723. issued its first pty callback.
  3724. @.IP \fBXtNmasterPtyName\fP
  3725. This read only resource will contain the complete path name of the
  3726. master side if the pty after the widget has been realized and has
  3727. issued its first pty callback.
  3728. @.IP \fBXtNmasterPtyOpenMode\fP
  3729. This resource specifies the modes to use when opening the master side
  3730. of the pty.  See man (2) open for details on the values to specify.
  3731. This resource can not be changed after the widget has been realized.
  3732. @.IP \fBXtNptyCallback\fP
  3733. This resource specifies the list of callbacks to call when ever the widget
  3734. asserts a pty callback.  These callbacks are generated when ever the
  3735. widget first opens the pty or when ever an exception is pending on the
  3736. master side of the pty.  The callback will be passed the reason for
  3737. the callback.
  3738. @.IP \fBXtNslavePtyDescriptor\fP
  3739. This read only resource will contain the file descriptor associated
  3740. with the slave side of the pty after the widget has been realized and
  3741. has issued its first pty callback.
  3742. @.IP \fBXtNslavePtyName\fP
  3743. This read only resource will contain the complete path name of the
  3744. slave side of the pty after the widget has been realized and has
  3745. issued it first pty callback.
  3746. @.IP \fBXtNslavePtyOpenMode\fP
  3747. This resource specifies the modes to use when opening the slave side of
  3748. the pty.  See man (2) open for details on the values to specify.  This
  3749. resource can not be changed after the widget has been realized.
  3750. @.IP \fBXtNttyMode\fP
  3751. This resource specifies the tty modes to use to set the line discipline
  3752. on the pty.  The modes are specified as a character string.  The mode
  3753. names are the same as those used in the \fIstty\fP program.  See man
  3754. stty and man 7 termio for more information on tty modes.
  3755. @.SH "CALLBACK INFORMATION"
  3756. A pointer to the following structure is passed to each callback:
  3757. @.sp 0.5
  3758. @.nf
  3759. @.ta 0.25i 1.5i
  3760. \fBtypedef struct\fP
  3761. {
  3762.     \fBint\fP    \fIreason\fP
  3763.     \fBint\fP    \fIMasterPtyDescriptor\fP
  3764.     \fBint\fP    \fISlavePtyDescriptor\fP
  3765.     \fBstruct termios *\fP    \fITermios\fP
  3766. } \fBPtyCallback;
  3767. @.fi
  3768. @.sp 0.5
  3769. @.IP \fIreason\fP
  3770. Indicates the reason the callback was called.  If \fIreason\fP equals
  3771. \fBPTY_OPEN\fP the the widget has successfully opened the pty and it
  3772. is ready for processing.  If \fIreason\fP equals \fBPTY_IOCTL\fP then
  3773. either the widget or a process associated with the slave side of the
  3774. pty has altered the tty line settings.  The application program should
  3775. respond accordingly.  If \fIreason\fP equals \fBPTY_SLAVEOPEN\fP then
  3776. a process has opened the slave side of the pty.  More than one process
  3777. may have the slave side open at a time.  If \fIreason\fP equals
  3778. \fBPTY_SLAVECLOSE\fP then a process has closed the slave side of the
  3779. pty.  There may still be other processes associated with the slave
  3780. side.
  3781. @.IP \fIMasterPtyDescriptor\fP
  3782. Specifies the file descriptor that is associated with the master pty.
  3783. @.IP \fISlavePtyDescriptor\fP
  3784. Specifies the file descriptor that is associated with the slave pty.
  3785. @.IP \fITermios\fP
  3786. If \fIreason\fP equals \fBPTY_IOCTL\fP then \fITermios\fP contains a
  3787. copy of the current termio line settings.
  3788. @.SH TRANSLATIONS
  3789. The \fIPty\fP widget defines no new translations.
  3790. @.SH ACTIONS
  3791. The \fIPty\fP action routines are:
  3792. @.IP \fBptywrite()\fP
  3793. Writes the argument string to the master side of the pty as if it was
  3794. entered from the keyboard.
  3795. @.IP \fBptysetmode()\fP
  3796. Alters the pty line discipline to correspond the modes specified in the
  3797. argument string.
  3798. @.SH "ENTRY POINTS"
  3799. In addition to the normal widget functions, the \fIPty\fP widget also
  3800. defines the following functions that may be called from the
  3801. application program.
  3802. @.ta .2i 1.2i
  3803. @.\"
  3804. @.IP "\fBvoid PtyWrite(Term,String,Len)\fP"
  3805. @.sp
  3806. @.nf
  3807. \fB\tWidget\tTerm
  3808. \tchar *\tString
  3809. \tint\tLen\fP
  3810. @.fi
  3811. @.sp
  3812. This function writes to the master side of the pty with out fear of
  3813. blocking or deadlocking.  \fBTerm\fP is the widget instance record.
  3814. \fBString\fP is the character string to write and \fBLen\fP is the
  3815. number of characters in \fBString\fP
  3816. @.\"
  3817. @.IP "\fBvoid PtySignal(Term,Sig)\fP"
  3818. @.sp
  3819. @.nf
  3820. \fB\tWidget\tTerm
  3821. \tint\tSig\fP
  3822. @.fi
  3823. @.sp
  3824. This function sends a signal to all processes who have the slave side
  3825. as their controlling terminal.  \fBTerm\fP is the widget instance
  3826. record. \fBSig\fP is the number of the signal to send.
  3827. @.SH "RELATED INFORMATION"
  3828. \fBGenTermEm(3X)\fP, \fBGenTerm(3X)\fP, \fBComposite(3X)\fP,
  3829. \fBCore(3X)\fP
  3830. @EOF
  3831. set `wc -lwc <GenTerm/Pty.man`
  3832. if test $1$2$3 != 18910907082
  3833. then
  3834.     echo ERROR: wc results of GenTerm/Pty.man are $* should be 189 1090 7082
  3835. fi
  3836.  
  3837. chmod 644 GenTerm/Pty.man
  3838.  
  3839.  
  3840. rm -f /tmp/uud$$
  3841. (echo "begin 666 /tmp/uud$$\n#;VL*n#6%@x\n \nend" | uudecode) >/dev/null 2>&1
  3842. if [ X"`cat /tmp/uud$$ 2>&1`" = Xok ]
  3843. then
  3844.     unpacker=uudecode
  3845. else
  3846.     echo Compiling unpacker for non-ascii files
  3847.     pwd=`pwd`; cd /tmp
  3848.     cat >unpack$$.c <<'EOF'
  3849. #include <stdio.h>
  3850. #define C (*p++ - ' ' & 077)
  3851. main()
  3852. {
  3853.     int n;
  3854.     char buf[128], *p, a,b;
  3855.  
  3856.     scanf("begin %o ", &n);
  3857.     gets(buf);
  3858.  
  3859.     if (freopen(buf, "w", stdout) == NULL) {
  3860.         perror(buf);
  3861.         exit(1);
  3862.     }
  3863.  
  3864.     while (gets(p=buf) && (n=C)) {
  3865.         while (n>0) {
  3866.             a = C;
  3867.             if (n-- > 0) putchar(a << 2 | (b=C) >> 4);
  3868.             if (n-- > 0) putchar(b << 4 | (a=C) >> 2);
  3869.             if (n-- > 0) putchar(a << 6 | C);
  3870.         }
  3871.     }
  3872.     exit(0);
  3873. }
  3874. EOF
  3875.     cc -o unpack$$ unpack$$.c
  3876.     rm unpack$$.c
  3877.     cd $pwd
  3878.     unpacker=/tmp/unpack$$
  3879. fi
  3880. rm -f /tmp/uud$$
  3881.  
  3882. echo x - GenTerm/TAGS '[non-ascii]'
  3883. $unpacker <<'@eof'
  3884. begin 644 GenTerm/TAGS
  3885. M# I'96Y497)M+F,L,CDU-0IS=&%T:6,@=F]I9"!'=$%L;&]C871E4V-R965NX
  3886. M*'\Q,S,X+#0R,3(Q"G-T871I8R!V;VED($=T0FQI;FM#86QL0F%C:RA_-SDPX
  3887. M+#(V,SDR"G-T871I8R!V;VED($=T0VAA;F=E0V]L;W5R*'\S.#(W+#$Q,#$TX
  3888. M,PIS=&%T:6,@=F]I9"!'=$-H86YG94-U<G-O<D-O;&]U<BA_,S@P-"PQ,#DVX
  3889. M-#$*<W1A=&EC('9O:60@1W1#:&%N9V5&;VYT<RA_,S<V,2PQ,#@T,#D*<W1AX
  3890. M=&EC('9O:60@1W1#:&%N9V5096XH?S,X-S(L,3$Q,3DY"G-T871I8R!V;VEDX
  3891. M($=T0VAE8VM0;W-I=&EO;BA_,34Y,"PU,3 P-@IS=&%T:6,@:6YT($=T0VAEX
  3892. M8VM686QI9%!O<VET:6]N*'\R.3$X+#@W-#(R"G-T871I8R!I;G0@1W1#;&5AX
  3893. M<DQI;F4H?S(Q-S@L-C8T.#0*:6YT($=T0VQE87)-96UO<GDH?S(Y-3,L.#@SX
  3894. M,#,*:6YT($=T0VQE87)296=I;VXH?S(X-3 L.#4S,#<*<W1A=&EC($)O;VQEX
  3895. M86X@1W1#;VYV97)T4')O8RA_,S4R."PQ,#,P-3 *<W1A=&EC(&-H87(@*D=TX
  3896. M0V]P>5-E8W1I;VXH?S,V,C,L,3 U,S0R"G-T871I8R!V;VED($=T0W)E871EX
  3897. M4&5N<RA_,S8V+#$S-#@S"FEN="!'=$-U<G-O<D1O=VXH?S$V.#,L-3,W-S(*X
  3898. M:6YT($=T0W5R<V]R3&5F="A_,3DQ-2PU.38X,@II;G0@1W1#=7)S;W)2971UX
  3899. M<FXH?S$Y-S<L-C W.3,*:6YT($=T0W5R<V]R4FEG:'0H?S$X-C$L-3@T.#@*X
  3900. M:6YT($=T0W5R<V]R57 H?S$W-S$L-38R,3D*<W1A=&EC('9O:60@1W1$969IX
  3901. M;F5(86QF0G)I9VAT4&5N*'\V-C0L,C(W-S@*<W1A=&EC('9O:60@1W1$969IX
  3902. M;F5096XH?S4Q,RPQ.# S, I'=$1E9FEN95!E;D-O;&]U<BA_-3@V+#(P-3$VX
  3903. M"FEN="!'=$1E;&5T94-H87)A8W1E<G,H?S,Q-3DL.30Q.34*:6YT($=T1&5LX
  3904. M971E3&EN97,H?S,P.3,L.3(R,S$*<W1A=&EC('9O:60@1W1$97-T<F]Y*'\WX
  3905. M,CDL,C0S-S,*<W1A=&EC('9O:60@1W1$97-T<F]Y4&5N0V]L;W5R<RA_-#DUX
  3906. M+#$W-C@R"G-T871I8R!V;VED($=T1&],;V-K0V%L;&)A8VLH?S(R,S8L-C@PX
  3907. M,S<*<W1A=&EC('9O:60@1W1$;U1O<$-A;&QB86-K*'\R,C4R+#8X,S<S"G-TX
  3908. M871I8R!V;VED($=T17AP;W-E*'\Q,#8V+#,S,C8R"G-T871I8R!V;VED($=TX
  3909. M17AT96YD4V5L96-T:6]N*'\S,S(Y+#DW-S<Q"FEN="!'=$=E=$%T=')I8G5TX
  3910. M92A_,C<P,"PX,3(R. II;G0@1W1'971#=7)S;W)0;W-I=&EO;BA_,3DV,BPVX
  3911. M,#4R.0II;G0@1W1'971,:6YE*'\R-3,T+#<V,C@T"FEN="!'=$=E=$UA<%1AX
  3912. M8FQE*'\S,C<T+#DV-S8Y"FEN="!'=$=E=%-C<F5E;E-I>F4H?S,W-#,L,3 XX
  3913. M,# R"FEN="!'=$=E=%-C<F]L;%)E9VEO;BA_,S(T,"PY-C$Y-PII;G0@1W1'X
  3914. M9714;W!/9E-C<F5E;BA_,C0P,RPW,C4U-PIS=&%T:6,@=F]I9"!'=$A33'1OX
  3915. M4D="*'\S.34V+#$Q-#<T,PIS=&%T:6,@=F]I9"!'=$AI9VA,:6=H=%-E8W1IX
  3916. M;VXH?S,S-34L.3@S,S,*<W1A=&EC('9O:60@1W1);FET:6%L:7IE*'\R,S,LX
  3917. M.38S-@IS=&%T:6,@=F]I9"!'=$EN<'5T*'\X.#,L,C@X-S<*<W1A=&EC('9OX
  3918. M:60@1W1);G-E<G1#86QL8F%C:RA_,S<P-"PQ,#<Q-CD*:6YT($=T26YS97)TX
  3919. M3&EN97,H?S,P,3 L.#DW.#4*<W1A=&EC('9O:60@1W1);G-E<G1396QE8W1IX
  3920. M;VXH?S,V-S<L,3 V-C0V"FEN="!'=$QO861!='1R:6)U=&4H?S(X,S(L.#0XX
  3921. M,CD*<W1A=&EC(&EN="!'=$QO861&;VYT<RA_,C8Q+#$P-#8U"G-T871I8R!VX
  3922. M;VED($=T3&]S95-E;&5C=&EO;BA_,S4W-RPQ,#0S,S(*<W1A=&EC('9O:60@X
  3923. M1W1-86ME4V5L96-T:6]N*'\S-#4V+#$P,3$T,@II;G0@1W1-87)G:6Y"96QLX
  3924. M*'\Y,#,L,CDR-#@*<W1A=&EC('9O:60@1W1-;W9E4V-R965N*'\R,C T+#8WX
  3925. M,3$U"FEN="!'=$YE=TQI;F4H?S$V-# L-3(U,# *<W1A=&EC('9O:60@1W1.X
  3926. M97AT3&EN92A_,38Q,2PU,3<S-PIS=&%T:6,@=F]I9"!'=$YO17AP;W-E*'\QX
  3927. M,#@U+#,S-C,Y"FEN="!'=$]U='!U="A_.30Q+#,P,CDX"G-T871I8R!V;VEDX
  3928. M($=T3W5T<'5T06-T:6]N*'\Y,3<L,CDV,# *:6YT($=T4&]S:71I;VY4;U)OX
  3929. M=T-O;'5M;BA_,3 T-RPS,C@X,@IS=&%T:6,@=F]I9"!'=%)'0G1O2%-,*'\TX
  3930. M,#(R+#$Q-38T,@IS=&%T:6,@=F]I9"!'=%)E86QI>F4H?S(Y,BPQ,3,Y-0ISX
  3931. M=&%T:6,@=F]I9"!'=%)E86QL;V-38W)E96XH?S$Q,S L,S0Y-#$*<W1A=&ECX
  3932. M('9O:60@1W12961I<W!L87DH?SDX."PS,3(V- IS=&%T:6,@=F]I9"!'=%)EX
  3933. M<VEZ92A_,3 Y-RPS,S@V.0IS=&%T:6,@:6YT($=T4V-R;VQL4F5G:6]N4V-RX
  3934. M;VQL*'\R,3 U+#8T,CDQ"G-T871I8R!I;G0@1W138W)O;&Q296=I;VY38W)OX
  3935. M;&Q38W)E96XH?S(T,30L-S(W.38*<W1A=&EC('9O:60@1W138W)O;&Q38W)EX
  3936. M96XH?S(S,#@L-CDW-#D*:6YT($=T4V-R;VQL57 H?S(P,C,L-C$X,C *:6YTX
  3937. M($=T4V5T071T<FEB=71E*'\R-34U+#<V-C@Y"FEN="!'=%-E=$-U<G-O<E!OX
  3938. M<VET:6]N*'\Q.3DW+#8Q,C0U"FEN="!'=%-E=$9I96QD071T<FEB=71E*'\RX
  3939. M-S4X+#@R-S4S"FEN="!'=%-E=$UA<%1A8FQE*'\S,CDP+#DW,#(U"FEN="!'X
  3940. M=%-E=%-C<F]L;%)E9VEO;BA_,S(Q,BPY-38V. II;G0@1W139714;W!/9E-CX
  3941. M<F5E;BA_,C(V."PV.#<T.0IS=&%T:6,@0F]O;&5A;B!'=%-E=%9A;'5E<RA_X
  3942. M,3$X-RPS-C@R-0IS=&%T:6,@=F]I9"!'=%-E='5P4&5N0V]L;W5R<RA_-#,YX
  3943. M+#$V,38Q"G-T871I8R!V;VED($=T4VAO=T-U<G-O<BA_,34S-BPT.3(V-0ISX
  3944. M=&%T:6,@=F]I9"!'=%-H;W=,:6YE*'\Q-#DS+#0X,#8Q"G-T871I8R!V;VEDX
  3945. M($=T4V]R=%-T87)T16YD*'\S-3DT+#$P-#@T.0IS=&%T:6,@=F]I9"!'=%-TX
  3946. M87)T4V5L96-T:6]N*'\S,S S+#DW,3@T"G-T871I8R!V;VED($=T4W1O<F53X
  3947. M=')I;F<H?S$S.#<L-#0Q-3,*<W1A=&EC('9O:60@1W15;DAI9VA,:6=H=%-EX
  3948. M8W1I;VXH?S,T,C L,3 P,CDW"G-T871I8R!V;VED($=T56Y3:&]W0W5R<V]RX
  3949. M*'\Q-34X+#0Y.#@Q"G-T871I8R!V;VED($=T57!D871E4F5G:6]N*'\Q,#$TX
  3950. M+#,R,#(U"B-D969I;F4@34E.*'\Q.2PT,#,*;65M<F5P*'\T,#8W+#$Q-C4XX
  3951. M,0H,"D=E;E1E<FU%;2YC+#$P,#8*<W1A=&EC('9O:60@1W1%05=A:71'<F%PX
  3952. M:&EC<T5X<&]S92A_-C(Y+#(Q-S4V"G-T871I8R!V;VED($=T14%D9%1O4W1OX
  3953. M<F%G92A_-S$Q+#(T-C(Y"G-T871I8R!V;VED($=T14-L87-S26YI=&EA;&EZX
  3954. M92A_,3@X+#<T,3 *<W1A=&EC('9O:60@1W1%1&5S=')O>2A_.38U+#,R.34WX
  3955. M"G-T871I8R!V;VED($=T141E<W1R;WE&=6YC=&EO;DME>7,H?S$P,#@L,S0PX
  3956. M-#8*1W1%1&]786ME57!#86QL8F%C:W,H?S$R-#$L,SDW.#8*:6YT($=T145XX
  3957. M96-U=&5087)S951A8FQE*'\Q,#8P+#,U,38Q"G-T871I8R!I;G0@1W1%1G5NX
  3958. M8W1I;VY+97E0<F5S<RA_-#4P+#$V,S R"G-T871I8R!8=$=E;VUE=')Y4F5SX
  3959. M=6QT($=T14=E;VUE=')Y36%N86=E<BA_-#@W+#$W-#4U"G-T871I8R!";V]LX
  3960. M96%N($=T14=E=$-L87-S4&%R<V5&:6QE*'\R.#<L,3 Y-#,*<W1A=&EC('9OX
  3961. M:60@1W1%26YI=&EA;&EZ92A_,C Q+#<Y-C<*<W1A=&EC('9O:60@1W1%26YPX
  3962. M=70H?S4Q,"PQ.#4S- IS=&%T:6,@=F]I9"!'=$5);G-E<G1#86QL8F%C:RA_X
  3963. M,3$U,BPS-S0S, IS=&%T:6,@=F]I9"!'=$5);G-E<G1396QE8W1I;VXH?S$QX
  3964. M,C L,S8V-#$*<W1A=&EC('9O:60@1W1%26YV;VME5')A;G-L871I;VXH?S4XX
  3965. M,2PR,#,P.0IS=&%T:6,@=F]I9"!'=$5,;V-K0V%L;&)A8VLH?S$Q.30L,S@UX
  3966. M,#D*:6YT($=T14]U='!U="A_-S0T+#(V,30Q"G-T871I8R!V;VED($=T14]UX
  3967. M='!U=$%C=&EO;BA_-C Q+#(P-S,S"G-T871I8R!V;VED($=T14]U='!U=$1EX
  3968. M<V-R:7!T;W)#86QL0F%C:RA_,3 S.2PS-#8U, IS=&%T:6,@=F]I9"!'=$50X
  3969. M<F538W)O;&PH?S$R-C,L-# V-#4*<W1A=&EC('9O:60@1W1%4F5A;&EZ92A_X
  3970. M,S0T+#$R-#DX"G-T871I8R!V;VED($=T15)E86QI>F5&=6YC=&EO;DME>7,HX
  3971. M?S,X-2PQ-# P,@IS=&%T:6,@=F]I9"!'=$5297-I>F4H?SDS,BPS,C$T.0ISX
  3972. M=&%T:6,@0F]O;&5A;B!'=$53971686QU97,H?S<X,"PR-CDT. IV;VED($=TX
  3973. M15-E=%=A:71&;W)'<F%P:&EC<T5X<&]S92A_-C<V+#(S-S8R"@P*4&%R<V4NX
  3974. M8RPR.30W"G-T871I8R!F;&]A="!!<F=4;T9L;V%T*'\X,S L,C0Q,#<*<W1AX
  3975. M=&EC(&EN="!!<F=4;TEN="A_-SDQ+#(S,S(P"G-T871I8R!C:&%R("I!<F=4X
  3976. M;U-T<FEN9RA_.#<P+#(U,#(R"G-T871I8R!I;G0@1W1%0V%R<FEA9V52971UX
  3977. M<FXH?S$Q-3 L,S$U,C8*<W1A=&EC(&EN="!'=$5#:&5C:TUO9&EF:65R<RA_X
  3978. M,C4V-BPV,S0R,@IS=&%T:6,@:6YT($=T14-L96%R1&ES<&QA>2A_,34V-"PSX
  3979. M.38Y-PIS=&%T:6,@:6YT($=T14-L96%R3&EN92A_,34S,2PS.#DT- IS=&%TX
  3980. M:6,@:6YT($=T14-L96%R365M;W)Y*'\Q-S$X+#0S,C<T"G-T871I8R!I;G0@X
  3981. M1W1%0V]N=F5R=%!O<VET:6]N*'\R-30P+#8R-C8Q"G-T871I8R!I;G0@1W1%X
  3982. M1&5F:6YE4&5N*'\R,C(W+#4T,S4Y"G-T871I8R!I;G0@1W1%1&5L971E0VAAX
  3983. M<F%C=&5R<RA_,3<Y-"PT-#@Q. IS=&%T:6,@:6YT($=T141E;&5T94QI;F5SX
  3984. M*'\Q-S8S+#0T,3DY"G-T871I8R!I;G0@1W1%1&]W;DQI;F4H?S$P-3(L,CDSX
  3985. M,#$*<W1A=&EC(&EN="!'=$5%;6ET*'\Q.3DX+#0Y,#0T"G-T871I8R!I;G0@X
  3986. M1W1%17-C87!E0V%L;&)A8VLH?S(R.#<L-34X.#0*<W1A=&EC(&EN="!'=$5%X
  3987. M>&5C=71E1G5N8W1I;VY+97DH?S(R-#@L-30X.#0*<W1A=&EC(&EN="!'=$5&X
  3988. M971C:"A_,C0R,2PU.30U-0IS=&%T:6,@:6YT($=T14=E=$%R9RA_,C0U,"PVX
  3989. M,#(S-PIS=&%T:6,@:6YT($=T14=E=$)O='1O;51E>'0H?S$S,3(L,S0V.3@*X
  3990. M<W1A=&EC(&EN="!'=$5'971&;VYT*'\Q,SDX+#,V,C0V"G-T871I8R!I;G0@X
  3991. M1W1%1V5T3&%S=$)U='1O;D5V96YT*'\R-#@R+#8Q,C,X"G-T871I8R!I;G0@X
  3992. M1W1%1V5T3&EN92A_,C U,"PU,#(S,0IS=&%T:6,@:6YT($=T14=E=%!E;BA_X
  3993. M,30Q-BPS-C4U.0IS=&%T:6,@:6YT($=T14=E=%!O<VET:6]N*'\Q,S0Q+#,UX
  3994. M,3DW"G-T871I8R!I;G0@1W1%1V5T4F5S;W5R8V4H?S$Y-S4L-#@U-#@*<W1AX
  3995. M=&EC(&EN="!'=$5'97138W)E96Y3:7IE*'\Q.#(W+#0U-#,W"G-T871I8R!IX
  3996. M;G0@1W1%1V5T4W1R:6YG3&5N9W1H*'\R-C R+#8T,C(Q"G-T871I8R!I;G0@X
  3997. M1W1%1V5T4W5B4W1R:6YG*'\R-C(T+#8T-S8S"G-T871I8R!I;G0@1W1%1V5TX
  3998. M5&]P*'\Q.# Y+#0U,3,Q"G-T871I8R!I;G0@1W1%1V5T5&]P3V938W)O;&Q2X
  3999. M96=I;VXH?S(Q,3$L-3$T-S4*<W1A=&EC(&EN="!'=$5)9BA_,38U-BPT,3<TX
  4000. M,0IS=&%T:6,@:6YT($=T14EG;F]R92A_,C(Q,2PU,S@S.0IS=&%T:6,@:6YTX
  4001. M($=T14EN<V5R=$QI;F5S*'\Q-S0R+#0S-S<Y"G-T871I8R!I;G0@1W1%26YTX
  4002. M5&]3=')I;F<H?S(V-3DL-C4V,S0*<W1A=&EC(&-H87(@*D=T14EN=%1O4W1RX
  4003. M:6YG0V]N=F5R="A_.3(W+#(V,C(S"G-T871I8R!I;G0@1W1%3&]A9$%T=')IX
  4004. M8G5T92A_,38Y-RPT,C8X,PIS=&%T:6,@:6YT($=T14QO861-87!486)L92A_X
  4005. M,C,R,2PU-C8W, IS=&%T:6,@:6YT($=T14UA=&-H1&EG:71S*'\T-C(L,30PX
  4006. M.#8*<W1A=&EC(&EN="!'=$5-871C:$9L;V%T*'\U.3<L,3@P.#0*<W1A=&ECX
  4007. M(&EN="!'=$5-871C:$EN="A_,S@T+#$Q-S T"G-T871I8R!I;G0@1W1%36%TX
  4008. M8VA396QE8W0H?S4V-"PQ-S,T- IS=&%T:6,@:6YT($=T14UA=&-H4W1R:6YGX
  4009. M*'\V.3 L,C V,C *<W1A=&EC(&EN="!'=$5-871C:%5P=&\H?S<T,BPR,C PX
  4010. M-0IS=&%T:6,@:6YT($=T14UA=&@H?S$U.#@L-# S.3$*<W1A=&EC(&EN="!'X
  4011. M=$5-;W9E0W5R<V]R*'\Q,3,S+#,Q,C(S"G-T871I8R!I;G0@1W1%36]V94QEX
  4012. M9G0H?S$P.3 L,S Q.3D*<W1A=&EC(&EN="!'=$5-;W9E4FEG:'0H?S$Q,3(LX
  4013. M,S W-S$*<W1A=&EC(&EN="!'=$5.97=,:6YE*'\Q,#,W+#(X.3(Q"G-T871IX
  4014. M8R!I;G0@1W1%3F5X=%1A8BA_,3$V-"PS,3@V-@IS=&%T:6,@:6YT($=T14]UX
  4015. M='!U=%-T<FEN9RA_,C R-RPT.3<S-PI'=$5087)S92A_,3@P+#4R,#4*=F]IX
  4016. M9"!'=$50;W!!<F=S*'\S-C$L,3$P.3 *<W1A=&EC(&EN="!'=$50<F5V:6]UX
  4017. M<U1A8BA_,3(P,2PS,C8R-@IS=&%T:6,@:6YT($=T15!R;V=R86U+97DH?S(QX
  4018. M-3 L-3(S,C8*<W1A=&EC(&EN="!'=$50<F]G<F%M36%P5&%B;&4H?S(S-#4LX
  4019. M-3<S.3$*<W1R=6-T($EN<'5T07)G=6UE;G0@*D=T15!U<VA!<F=S*'\S,S,LX
  4020. M,3 S-C4*<W1A=&EC(&EN="!'=$51=6ET*'\R,3,U+#4Q.3 S"G-T871I8R!IX
  4021. M;G0@1W1%4F5J96-T*'\R,#DX+#4Q,3<R"G-T871I8R!I;G0@1W1%4V5T0FQIX
  4022. M;FM-;V1E*'\Q-#DS+#,X,#$P"G-T871I8R!I;G0@1W1%4V5T1FEE;&0H?S$UX
  4023. M,30L,S@T-S8*<W1A=&EC(&EN="!'=$53971&;&]W*'\R-S U+#8V-C,V"G-TX
  4024. M871I8R!I;G0@1W1%4V5T1F]N="A_,3,V,BPS-38R.0IS=&%T:6,@:6YT($=TX
  4025. M15-E=$AA;&9"<FEG:'1-;V1E*'\Q-#<T+#,W-C@Q"G-T871I8R!I;G0@1W1%X
  4026. M4V5T26YS97)T36]D92A_,3@T-RPT-3DR-0IS=&%T:6,@:6YT($=T15-E=$ENX
  4027. M=F5R<V56:61E;RA_,30S-"PS-CDR- IS=&%T:6,@:6YT($=T15-E=$ME>51AX
  4028. M8FQE*'\Q.3$X+#0W-#$S"G-T871I8R!I;G0@1W1%4V5T4&%R<V5486)L92A_X
  4029. M,3@X-"PT-C8S.0IS=&%T:6,@:6YT($=T15-E=%!E;BA_,3,X,RPS-3DU-PISX
  4030. M=&%T:6,@:6YT($=T15-E=%)E<V]U<F-E*'\Q.34R+#0X,3(W"G-T871I8R!IX
  4031. M;G0@1W1%4V5T4V-R;VQL4F5G:6]N*'\R,#<W+#4P-S$V"G-T871I8R!I;G0@X
  4032. M1W1%4V5T5&%B*'\Q,C(X+#,S,3$S"G-T871I8R!I;G0@1W1%4V5T5&]P*'\QX
  4033. M-S<Y+#0T-#@W"G-T871I8R!I;G0@1W1%4V5T56YD97),:6YE36]D92A_,30UX
  4034. M-"PS-S,S- IS=&%T:6,@:6YT($=T15-O=6YD0F5L;"A_,3(Y."PS-#,X. ISX
  4035. M=&%T:6,@:6YT($=T15-T;W)E*'\R,S@V+#4X-#8T"G-T871I8R!I;G0@1W1%X
  4036. M5&]!<V-I:2A_,C4Q,BPV,C X-@IS=&%T:6,@:6YT($=T155N4V5T5&%B*'\QX
  4037. M,C8V+#,S.#4U"G-T871I8R!I;G0@1W1%57!,:6YE*'\Q,#<R+#(Y-S@V"G-TX
  4038. M871I8R!I;G0@26YT5&]);G!U=$%R9RA_.38U+#(V.#8W"G-T871I8R!I;G0@X
  4039. M4W1R:6YG5&]);G!U=$%R9RA_,3 P,BPR-S@U,PH,"DQO861087)S97(N8RPTX
  4040. M.#,*<W1A=&EC(&EN="!"=69F97)'971C*'\R,#4L-3 W-0IS=&%T:6,@8VAAX
  4041. M<B J0G5F9F5R1V5T<RA_,30S+#,Y,S0*<W1A=&EC('-T<G5C="!!<F=U;65NX
  4042. M=$QI<W0@*D)U:6QD07)G3&ES="A_-C@X+#$V-C(T"G-T871I8R!S=')U8W0@X
  4043. M4&%R<V5)=&5M("I#<F5A=&50271E;2A_-#<R+#$R,3$P"G-T871I8R!V;VEDX
  4044. M($=E=$9U;F-T:6]N5&]K96XH?S8U."PQ-C S-0IS=&%T:6,@:6YT($=E=$YEX
  4045. M>'14;VME;BA_-#@X+#$R,S8Q"G-T871I8R!S=')U8W0@4W!E8VEA;$ET96T@X
  4046. M*D=E=%-P96-I86Q4;VME;BA_-C W+#$T.#DT"G-T871I8R!S=')U8W0@5')AX
  4047. M;G-L871O<B J1V5T5')A;G-L871O<E1O:V5N*'\U-3(L,3,U,3,*1W1%3&]AX
  4048. M9%!A<G-E1FEL92A_-#(L.3(Y"G-T871I8R!S=')U8W0@4&%R<V5)=&5M("I'X
  4049. M=$5,;V%D4&%R<V5486)L92A_,C8S+#8R,C0*<W1A=&EC('-T<G5C="!+97E4X
  4050. M<F%N<VQA=&EO;G,@*DQO861+97E486)L92A_,S@P+#DV,S(*# I0='DN8RPUX
  4051. M,#$*8VAA<B J1V5T3F5X=%=O<F0H?S@Q."PR,3DU,PI/<&5N4'1Y*'\U.34LX
  4052. M,3<U.#8*<W1A=&EC('9O:60@4'1Y1&5S=')O>2A_,S<P+#$R-#,X"G-T871IX
  4053. M8R!V;VED(%!T>41O4'1Y0V%L;&)A8VMS*'\T-3@L,30V-C(*<W1A=&EC('9OX
  4054. M:60@4'1Y17AC97!T:6]N0T(H?S,Y,"PQ,S R- IS=&%T:6,@=F]I9"!0='E)X
  4055. M;FET:6%L:7IE*'\R,C0L.#,U- IS=&%T:6,@=F]I9"!0='E296%L:7IE*'\RX
  4056. M-#$L.#@T- IS=&%T:6,@=F]I9"!0='E297-I>F4H?S(X-RPQ,#$V. IS=&%TX
  4057. M:6,@=F]I9"!0='E3971-;V1E06-T:6]N*'\U-S$L,3<Q.#8*<W1A=&EC($)OX
  4058. M;VQE86X@4'1Y4V5T5F%L=65S*'\S,3(L,3 W.#0*=F]I9"!0='E3:6=N86PHX
  4059. M?S4X-BPQ-S0X-@I0='E7<FET92A_-#<X+#$U,3@S"G-T871I8R!V;VED(%!TX
  4060. M>5=R:71E06-T:6]N*'\U-3,L,38X,3<*<W1A=&EC('9O:60@4'1Y5W)I=&5#X
  4061. M0BA_-3$Y+#$V,30V"E-E=$UO9&4H?S@P-2PR,3@R- I39710='E-;V1E*'\VX
  4062. )-#<L,3@X,3,*                                                X
  4063.                                                              X
  4064. end
  4065. @eof
  4066. set `wc -lwc <GenTerm/TAGS`
  4067. if test $1$2$3 != 2256027974
  4068. then
  4069.     echo ERROR: wc results of GenTerm/TAGS are $* should be 225 602 7974
  4070. fi
  4071.  
  4072. chmod 644 GenTerm/TAGS
  4073.  
  4074. echo x - GenTerm/ctest.c
  4075. cat >GenTerm/ctest.c <<'@EOF'
  4076. #include <stdio.h>
  4077. #include <fcntl.h>
  4078. #include <termios.h>
  4079. #include <bsdtty.h>
  4080. #include <sys/pty.h>
  4081. #include <sys/ptyio.h>
  4082. #include <sys/errno.h>
  4083. #include <X11/X.h>
  4084. #include <X11/Intrinsic.h>
  4085. #include <X11/StringDefs.h>
  4086. #include <Xm/Xm.h>
  4087. #include <Xm/ScrollBar.h>
  4088. #include <X11/IntrinsicP.h>
  4089. #include <X11/CoreP.h>
  4090. #include <X11/CompositeP.h>
  4091. #include "GenTermP.h"
  4092. #include "GenTermEmP.h"
  4093. #include "PtyP.h"
  4094. #include "Pty.h"
  4095.  
  4096.  
  4097. #define COLORS "Default:Default:red:Default:green:Default:yellow:Default:blue:Default:magenta:Default:cyan:Default:black:yellow"
  4098.  
  4099. struct Terminal
  4100. {
  4101.  XtAppContext app_con;
  4102.  Widget term;
  4103.  Widget scrollbar;
  4104.  Widget top_level;
  4105.  int log;
  4106.  int logging;
  4107.  int xterm;
  4108. };
  4109.  
  4110. void QuitCB();
  4111. void RunCB();
  4112. void KeyHit();
  4113. void TopCB();
  4114. void ScrollCB();
  4115. void EscapeCB();
  4116. int TimeOut();
  4117. void LogCB();
  4118. void ResizeCB();
  4119. void WakeCB();
  4120. void WriteCB();
  4121. void ExceptCB();
  4122. void FlowCB();
  4123. void KillTimeOut();
  4124. void LaunchCB();
  4125. void PtyCB();
  4126. void DropCB();
  4127. void DoneDropCB();
  4128.  
  4129. static char translations[]=
  4130. "\
  4131. <ButtonPress>:invokeTranslation(ButtonTranslator)\n\
  4132. <ButtonRelease>:invokeTranslation(ButtonReleaseTranslator)\n\
  4133. ";
  4134.  
  4135. char mode[]=
  4136. "\
  4137. rows 24 columns 80 \
  4138. 9600 susp ^z dsusp ^z intr ^c quit ^\\ erase ^H kill ^u swtch ^@ eof ^d \
  4139. eol ^@ stop ^s start ^q -parenb -parodd cs8 -cstopb hupcl cread -clocal \
  4140. -loblk -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr \
  4141. icrnl -iuclc ixon -ixany ixoff -ienqak isig icanon iexten -xcase echo echoe \
  4142. echok -echonl -noflsh opost -olcuc onlcr -ocrnl -onocr -onlret -ofill \
  4143. -ofdel -tostop tab3";
  4144.  
  4145. int WindowCount = 0;
  4146. main(argc,argv)
  4147. int argc;
  4148. char **argv;
  4149.  
  4150. {
  4151.  int i;
  4152.  struct Terminal Terminal;
  4153.  
  4154.  Terminal.top_level = XtAppInitialize(&(Terminal.app_con),"GenTerm",NULL,0,
  4155.                       &argc,argv,NULL,0,0);
  4156.  XvAppInit(Terminal.app_con,XtDisplay(Terminal.top_level),argv[0]);
  4157.  
  4158.  Terminal.logging = 0;
  4159.  Terminal.xterm = 0;
  4160.  for(i = 1; i < argc; i++)
  4161.   {
  4162.    if(strcmp(argv[i],"-xterm") == 0)
  4163.     Terminal.xterm = 1;
  4164.    else if(strcmp(argv[i],"-log") == 0)
  4165.     Terminal.logging = 1;
  4166.   }
  4167.  
  4168.  BuildTerminal(&Terminal,Terminal.top_level,True);
  4169.  XtAppMainLoop(Terminal.app_con);
  4170. }
  4171.  
  4172. BuildTerminal(Terminal,Top,flag)
  4173.  
  4174. struct Terminal *Terminal;
  4175. Widget Top;
  4176. Boolean flag;
  4177.  
  4178. {
  4179.  Arg args[20];
  4180.  int n = 0;
  4181.  XtInputId OutId;
  4182.  XtInputId ExceptId;
  4183.  Widget main_window;
  4184.  Widget menu_bar;
  4185.  Widget quit_button;
  4186.  Widget run_button;
  4187.  Widget launch_button;
  4188.  int maxline;
  4189.  int rows;
  4190.  int IncX;
  4191.  int IncY;
  4192.  Dimension Height,Width;
  4193.  
  4194.  Terminal->top_level = Top;
  4195.  WindowCount++;
  4196.  
  4197.  if(Terminal->logging)
  4198.   Terminal->log = openlogwindow(Terminal->xterm);
  4199.  
  4200.  if(Terminal->logging)
  4201.   {
  4202.    OutId = XtAppAddInput(Terminal->app_con,Terminal->log,XtInputReadMask,LogCB,
  4203.              (XtPointer)Terminal);
  4204.    fprintf(stderr,"Starting Logging");
  4205.   }
  4206.  
  4207.  main_window = XmCreateMainWindow(Terminal->top_level,"main",args,n);
  4208.  XtManageChild(main_window);
  4209.  
  4210.  menu_bar = XmCreateMenuBar(main_window,"menu",args,n);
  4211.  XtManageChild(menu_bar);
  4212.  
  4213.  n = 0;
  4214.  quit_button = XmCreateCascadeButton(menu_bar,"Quit",args,n);
  4215.  XtManageChild(quit_button);
  4216.  XtAddCallback(quit_button,XmNactivateCallback,QuitCB,(XtPointer)Terminal);
  4217.    
  4218.  if(flag)
  4219.   {
  4220.    n = 0;
  4221.    run_button = XmCreateCascadeButton(menu_bar,"Run",args,n);
  4222.    XtManageChild(run_button);
  4223.    XtAddCallback(run_button,XmNactivateCallback,RunCB,(XtPointer)Terminal);
  4224.  
  4225.    n = 0;
  4226.    launch_button = XmCreateCascadeButton(menu_bar,"New Window",args,n);
  4227.    XtManageChild(launch_button);
  4228.    XtAddCallback(launch_button,XmNactivateCallback,LaunchCB,
  4229.          (XtPointer)Terminal);
  4230.    XvRegisterDropCallback(DropCB);
  4231.   }
  4232.  
  4233.  n = 0;
  4234.  XtSetArg(args[n],XmNorientation,XmVERTICAL); n++;
  4235.  XtSetArg(args[n],XmNwidth,13); n++;
  4236.  Terminal->scrollbar = XmCreateScrollBar(main_window,"scroll",args,n);
  4237.  XtManageChild(Terminal->scrollbar);
  4238.  
  4239.  XtAddCallback(Terminal->scrollbar,XmNdecrementCallback,ScrollCB,
  4240.            (XtPointer)Terminal);
  4241.  XtAddCallback(Terminal->scrollbar,XmNincrementCallback,ScrollCB,
  4242.            (XtPointer)Terminal);
  4243.  XtAddCallback(Terminal->scrollbar,XmNpageDecrementCallback,ScrollCB,
  4244.            (XtPointer)Terminal);
  4245.  XtAddCallback(Terminal->scrollbar,XmNpageIncrementCallback,ScrollCB,
  4246.            (XtPointer)Terminal);
  4247.  XtAddCallback(Terminal->scrollbar,XmNtoTopCallback,ScrollCB,
  4248.            (XtPointer)Terminal);
  4249.  XtAddCallback(Terminal->scrollbar,XmNtoBottomCallback,ScrollCB,
  4250.            (XtPointer)Terminal);
  4251.  XtAddCallback(Terminal->scrollbar,XmNdragCallback,ScrollCB,
  4252.            (XtPointer)Terminal);
  4253.  
  4254.  n = 0;
  4255.  XtSetArg(args[n],XtNliteralMode,FALSE); n++;
  4256.  XtSetArg(args[n],XtNautoLineWrap,TRUE); n++;
  4257.  XtSetArg(args[n],XtNsaveLines,48); n++;
  4258.  XtSetArg(args[n],XtNdestructiveTab,False); n++;
  4259.  XtSetArg(args[n],XtNttyMode,mode); n++;
  4260.  if(Terminal->logging)
  4261.   {
  4262.    XtSetArg(args[n],XtNlogFile,Terminal->log); n++;
  4263.    XtSetArg(args[n],XtNlogging,True); n++;
  4264.   }
  4265.  
  4266. if(Terminal->xterm == 1)
  4267.   {
  4268.    XtSetArg(args[n],XtNparseFile,"./xterm.par"); n++;
  4269.    XtSetArg(args[n],XtNfieldAttributes,False); n++;
  4270.    XtSetArg(args[n],XtNsaveScrollRegion,True);n++;
  4271.    XtSetArg(args[n],XtNscrollOnOutput,True);n++;
  4272.    XtSetArg(args[n],XtNnumberMapTables,4);n++;
  4273.    XtSetArg(args[n],XtNcursorFloats,False);n++;
  4274.    XtSetArg(args[n],XtNscrollDownClear,True);n++;
  4275.    XtSetArg(args[n],XtNscrollOnOutput,True);n++;
  4276.    XtSetArg(args[n],XtNfullScroll,False);n++;
  4277.    XtSetArg(args[n],XtNcursorKeyScrollRegion,True);n++;
  4278.    XtSetArg(args[n],XtNeolStick,True);n++;
  4279.   }
  4280.  else
  4281.   {
  4282.    XtSetArg(args[n],XtNfieldAttributes,True);n++;
  4283.    XtSetArg(args[n],XtNsaveScrollRegion,True); n++;
  4284.    XtSetArg(args[n],XtNpenColors,COLORS); n++;
  4285.    XtSetArg(args[n],XtNcursorFloats,True);n++;
  4286.    /*XtSetArg(args[n],XtNpreScroll,True);n++;*/
  4287.   }
  4288.  Terminal->term = XtCreateManagedWidget("TERM",ptyWidgetClass,
  4289.                        main_window,args,n);
  4290.  XtManageChild(Terminal->term);
  4291.  XtAddCallback(Terminal->term,XtNkbdCallback,KeyHit,(XtPointer)Terminal);
  4292.  XtAddCallback(Terminal->term,XtNtopCallback,TopCB,(XtPointer)Terminal);
  4293.  XtAddCallback(Terminal->term,XtNescCallback,EscapeCB,(XtPointer)Terminal);
  4294.  XtAddCallback(Terminal->term,XtNresizeCallback,ResizeCB,(XtPointer)Terminal);
  4295.  XtAddCallback(Terminal->term,XtNwakeUpCallback,WakeCB,(XtPointer)Terminal);
  4296.  XtAddCallback(Terminal->term,XtNflowCallback,FlowCB,(XtPointer)Terminal);
  4297.  XtAddCallback(Terminal->term,XtNptyCallback,PtyCB,(XtPointer)Terminal);
  4298.  
  4299.  n = 0;
  4300.  XtSetArg(args[n],XtNsaveLines,&maxline); n++;
  4301.  XtSetArg(args[n],XtNrows,&rows); n++;
  4302.  XtGetValues(Terminal->term,args,n);
  4303.  
  4304.  n = 0;
  4305.  XtSetArg(args[n],XmNmaximum,maxline); n++;
  4306.  XtSetArg(args[n],XmNsliderSize,rows); n++;
  4307.  XtSetValues(Terminal->scrollbar,args,n);
  4308.  
  4309.  XtRealizeWidget(Terminal->top_level);
  4310.  
  4311.  n = 0;
  4312.  XtSetArg(args[n],XtNcharacterWidth,&IncX); n++;
  4313.  XtSetArg(args[n],XtNcharacterHeight,&IncY); n++;
  4314.  XtGetValues(Terminal->term,args,n);
  4315.  
  4316.  n = 0;
  4317.  XtSetArg(args[n],XtNheight,&Height); n++;
  4318.  XtSetArg(args[n],XtNwidth,&Width); n++;
  4319.  XtGetValues(Terminal->top_level,args,n);
  4320.  
  4321.  Height += IncY;
  4322.  Height = Height - Height % IncY;
  4323.  Width += IncX;
  4324.  Width = Width - Width % IncX;
  4325.  
  4326.  n = 0;
  4327.  XtSetArg(args[n],XtNheight,Height); n++;
  4328.  XtSetArg(args[n],XtNwidth,Width); n++;
  4329.  XtSetValues(Terminal->top_level,args,n);
  4330.  
  4331. }
  4332.  
  4333. openwind(which,master,slave,Name)
  4334.  
  4335. int which;
  4336. int master;
  4337. int slave;
  4338. char *Name;
  4339. {
  4340.  int pid;
  4341.  char string[20];
  4342.  char *Names[2];
  4343.  struct termios t;
  4344.  int f1,f2,f3;
  4345.  
  4346.  
  4347.  if((pid = fork()) == 0)
  4348.   {
  4349.    close(0);
  4350.    close(1);
  4351.    close(2);
  4352.    setpgrp(getpid(),0);
  4353.    /*f1 = dup(slave);
  4354.    f2 = dup(slave);
  4355.    f3 = dup(slave);*/
  4356.    close(slave);
  4357.    close(master);
  4358.    slave = open(Name,O_RDWR);
  4359.    f1 = dup(slave);
  4360.    f2 = dup(slave);
  4361.    f3= dup(slave);
  4362.  
  4363.    if(which == 1)
  4364.     putenv("TERM=xterms");
  4365.    fprintf(stderr,"opening shell %d %d %d\n",f1,f2,f3);
  4366.    execl("/bin/csh","csh",(char *) NULL);
  4367.   }
  4368.  close(slave);
  4369.  return(master);
  4370. }
  4371.  
  4372. void KeyHit(w,Terminal,reason)
  4373.  
  4374. Widget w;
  4375. struct Terminal *Terminal;
  4376. GenTermEmCallback *reason;
  4377.  
  4378. {
  4379.  PtyWrite(w,reason->string,reason->len);
  4380. }
  4381.  
  4382. void TopCB(w,Terminal,reason)
  4383.  
  4384. Widget w;
  4385. struct Terminal *Terminal;
  4386. GenTermCallback *reason;
  4387.  
  4388. {
  4389.  int n = 0;
  4390.  Arg args[20];
  4391.  
  4392.  XtSetArg(args[n],XmNvalue,reason->TopLine); n++;
  4393.  XtSetValues(Terminal->scrollbar,args,n);
  4394. }
  4395.  
  4396. void ResizeCB(w,Terminal,reason)
  4397.  
  4398. Widget w;
  4399. struct Terminal *Terminal;
  4400. GenTermCallback *reason;
  4401.  
  4402. {
  4403.  char string[80];
  4404.  Arg args[20];
  4405.  int n = 0;
  4406.  int IncX,IncY;
  4407.  Dimension Height,Width;
  4408.  int maxline,rows;
  4409.  
  4410.  XtSetArg(args[n],XtNcharacterWidth,&IncX); n++;
  4411.  XtSetArg(args[n],XtNcharacterHeight,&IncY); n++;
  4412.  XtGetValues(Terminal->term,args,n);
  4413.  
  4414.  n = 0;
  4415.  XtSetArg(args[n],XtNheight,&Height); n++;
  4416.  XtSetArg(args[n],XtNwidth,&Width); n++;
  4417.  XtGetValues(Terminal->top_level,args,n);
  4418.  
  4419.  if(Height % IncY != 0)
  4420.   {
  4421.    Height += IncY;
  4422.    Height = Height - Height % IncY;
  4423.   }
  4424.  if(Width % IncX != 0)
  4425.   {
  4426.    Width += IncX;
  4427.    Width = Width - Width % IncX;
  4428.   }
  4429.  
  4430.  n = 0;
  4431.  XtSetArg(args[n],XtNheight,Height); n++;
  4432.  XtSetArg(args[n],XtNwidth,Width); n++;
  4433.  XtSetValues(Terminal->top_level,args,n);
  4434.  
  4435.  n = 0;
  4436.  XtSetArg(args[n],XtNsaveLines,&maxline); n++;
  4437.  XtSetArg(args[n],XtNrows,&rows); n++;
  4438.  XtGetValues(Terminal->term,args,n);
  4439.  
  4440.  n = 0;
  4441.  XtSetArg(args[n],XmNmaximum,maxline); n++;
  4442.  XtSetArg(args[n],XmNsliderSize,rows); n++;
  4443.  XtSetValues(Terminal->scrollbar,args,n);
  4444.  
  4445.  
  4446. }
  4447.  
  4448. void ScrollCB(w,Terminal,data)
  4449.  
  4450. Widget w;
  4451. XmScrollBarCallbackStruct *data;
  4452. struct Terminal *Terminal;
  4453.  
  4454. {
  4455.  int line;
  4456.  
  4457.  line = GtGetTopOfScreen(Terminal->term);
  4458.  
  4459.  switch(data->reason)
  4460.   {
  4461.  case XmCR_DECREMENT:
  4462.    line--;
  4463.    break;
  4464.  case XmCR_INCREMENT:
  4465.    line++;
  4466.    break;
  4467.  case XmCR_PAGE_DECREMENT:
  4468.    line -= 24;
  4469.    break;
  4470.  case XmCR_PAGE_INCREMENT:
  4471.    line += 24;
  4472.    break;
  4473.  case XmCR_TO_TOP:
  4474.    line = 0;
  4475.    break;
  4476.  case XmCR_TO_BOTTOM:
  4477.    line = 512;
  4478.    break;
  4479.  case XmCR_DRAG:
  4480.    line = data->value;
  4481.    break;
  4482.   }
  4483.  GtSetTopOfScreen(Terminal->term,line);
  4484. }
  4485. void QuitCB(w,Terminal)
  4486.  
  4487. Widget w;
  4488. struct Terminal *Terminal;
  4489.  
  4490. {
  4491.  XtAppAddTimeOut(Terminal->app_con,1000,KillTimeOut,(XtPointer)Terminal);
  4492. }
  4493.  
  4494. void KillTimeOut(Terminal)
  4495.  
  4496. struct Terminal *Terminal;
  4497.  
  4498. {
  4499.  XtDestroyWidget(Terminal->top_level);
  4500.  if(--WindowCount == 0)
  4501.   exit(0);
  4502. }
  4503.  
  4504. void LaunchCB(w,Terminal)
  4505.  
  4506. Widget w;
  4507. struct Terminal *Terminal;
  4508.  
  4509. {
  4510.  Widget popup;
  4511.  Arg args[10];
  4512.  int n = 0;
  4513.  struct Terminal *NewTerminal;
  4514.  
  4515.  popup = XtAppCreateShell(NULL,"GenTerm",applicationShellWidgetClass,
  4516.               XtDisplay(w),args,n);
  4517.  NewTerminal = (struct Terminal *)XtMalloc(sizeof(struct Terminal));
  4518.  memcpy(NewTerminal,Terminal,sizeof(struct Terminal));
  4519.  BuildTerminal(NewTerminal,popup,False);
  4520.  
  4521.  XtPopup(popup,XtGrabNone);
  4522. }
  4523.  
  4524.   
  4525. void RunCB(w,Terminal)
  4526.  
  4527. Widget w;
  4528. struct Terminal *Terminal;
  4529.  
  4530. {
  4531.  XtAppAddTimeOut(Terminal->app_con,1000,TimeOut,(XtPointer)Terminal);
  4532. }
  4533.  
  4534. TimeOut(Terminal)
  4535.  
  4536. struct Terminal *Terminal;
  4537.  
  4538. {
  4539.  static char buffer[100];
  4540.  static int count = 0;
  4541.  Arg args[30];
  4542.  int n = 0;
  4543.  XrmValue from,to;
  4544.  Pixel top,bottom;
  4545.  char name[80];
  4546.  char buf1[1024],buf2[1024];
  4547.  Pixmap bitmap;
  4548.  unsigned int height,width;
  4549.  static char *types="File";
  4550.  static char *files="maxwell - /users/gordon/general/myterm/ttt";
  4551.  
  4552.  if(count == 0)
  4553.   {
  4554.    n = XReadBitmapFile(XtDisplay(Terminal->term),XtWindow(Terminal->term),
  4555.            "/usr/local/lib/X11/bitmaps/code.s.bm",&width,&height,&bitmap,0,0);
  4556.    n = 0;
  4557.    XtSetArg(args[n],XmNtopShadowColor,&top); n++;
  4558.    XtSetArg(args[n],XmNbottomShadowColor,&bottom); n++;
  4559.    XtGetValues(Terminal->term,args,n);
  4560.    XvInitiateDragOperation(True,True,DoneDropCB,XtDisplay(Terminal->term),
  4561.                XtWindow(Terminal->term),bitmap,
  4562.                DefaultRootWindow(XtDisplay(Terminal->term)),0,0,
  4563.                types,files);
  4564.  
  4565.   }
  4566. }
  4567.  
  4568. void EscapeCB(w,Terminal,reason)
  4569.  
  4570. Widget w;
  4571. struct Terminal *Terminal;
  4572. GenTermEmCallback *reason;
  4573.  
  4574. {
  4575.  int i = 0;
  4576.  
  4577.  fprintf(stderr,"Got an escape callback: ");
  4578.  
  4579.  while(reason->escapes[i] != NULL)
  4580.   fprintf(stderr,"%s ",reason->escapes[i++]);
  4581.  fprintf(stderr,"\n");
  4582. }
  4583.  
  4584. openlogwindow(which)
  4585.  
  4586. int which;
  4587.  
  4588. {
  4589.  int master;
  4590.  int slave;
  4591.  int pid;
  4592.  char string[20];
  4593.  char *Names[2];
  4594.  
  4595.  OpenPty(&master,&slave,O_RDWR,O_RDWR | O_NDELAY,Names);
  4596.  
  4597.  if((pid = fork()) == 0)
  4598.   {
  4599.    sprintf(string,"-Sqa.%d",master);
  4600.    if(which == 0)
  4601.     execl("/usr/bin/X11/hpterm","hpterm","-sb","-title","Test Input",string,
  4602.           NULL);
  4603.    else
  4604.     {
  4605.      sprintf(string,"-Sqa%d",master);
  4606.      execl("/usr/bin/X11/xterm","xterm","-sb","-title","Test Input",string,
  4607.            NULL);
  4608.     }
  4609.    wait();
  4610.   }
  4611.  return(slave);
  4612. }
  4613.  
  4614. void LogCB(Terminal,source)
  4615.  
  4616. struct Terminal *Terminal;
  4617. int *source;
  4618.  
  4619.  
  4620. {
  4621.  char buffer[1024];
  4622.  int nread;
  4623.  
  4624.  while((nread = read(Terminal->log,buffer,1024)) > 0)
  4625.   {
  4626.    GtOutput(Terminal->term,buffer,nread);
  4627.   }
  4628. }
  4629.  
  4630. void WakeCB()
  4631.  
  4632. {
  4633.  /*fprintf(stderr,"Got a wakeup callback!\n");*/
  4634. }
  4635.  
  4636. void FlowCB(w,Terminal,reason)
  4637.  
  4638. Widget w;
  4639. struct Terminal *Terminal;
  4640. GenTermEmCallback *reason;
  4641.  
  4642. {
  4643.  if(reason->reason == GTE_XOFF)
  4644.   fprintf(stderr,"Flow got turned off!\n");
  4645.  else if(reason->reason == GTE_XON)
  4646.   fprintf(stderr,"Flow got turned back on!\n");
  4647.  else
  4648.   fprintf(stderr,"Got a bad flow callback!\n");
  4649. }
  4650.  
  4651. void PtyCB(w,Terminal,reason)
  4652.  
  4653. Widget w;
  4654. struct Terminal *Terminal;
  4655. PtyCallback *reason;
  4656.  
  4657. {
  4658.  XtInputId ExceptId;
  4659.  Arg args[20];
  4660.  int n = 0;
  4661.  Pixel top,bottom;
  4662.  char *name;
  4663.  
  4664.  if(reason->reason == PTY_OPEN)
  4665.   {
  4666.    XtSetArg(args[n],XtNslavePtyName,&name);n++;
  4667.    XtGetValues(w,args,n);
  4668.  
  4669.    openwind(Terminal->xterm,reason->MasterPtyDescriptor,
  4670.         reason->SlavePtyDescriptor,name);
  4671.    
  4672.    n = 0;
  4673.    XtSetArg(args[n],XmNtopShadowColor,&top); n++;
  4674.    XtSetArg(args[n],XmNbottomShadowColor,&bottom); n++;
  4675.    XtGetValues(w,args,n);
  4676.    XvRegisterDragWindow(XtDisplay(w),XtWindow(w),1,top,bottom,
  4677.             "=100x000+10+10-FileEdit","=300x300+50+50-FileEdit",
  4678.             (XtPointer)Terminal);
  4679.   }
  4680.  /*else
  4681.   fprintf(stderr,"Funny calback in PtyCB!\n");*/
  4682. }
  4683.  
  4684. void DropCB(display,win,x,y,root,root_x,root_y,mods,types,objects,Terminal)
  4685.  
  4686. Display *display;
  4687. Window win;
  4688. Position x,y;
  4689. Window root;
  4690. Position root_x,root_y;
  4691. unsigned int mods;
  4692. char *types;
  4693. char *objects;
  4694. struct Terminal *Terminal;
  4695.  
  4696. {
  4697.  fprintf(stderr,"Got a drop callback!\n%s\n%s\n",types,objects);
  4698. }
  4699.  
  4700. void DoneDropCB()
  4701.  
  4702. {
  4703.  fprintf(stderr,"Got done drop callback\n");
  4704. }
  4705. @EOF
  4706. set `wc -lwc <GenTerm/ctest.c`
  4707. if test $1$2$3 != 629106713929
  4708. then
  4709.     echo ERROR: wc results of GenTerm/ctest.c are $* should be 629 1067 13929
  4710. fi
  4711.  
  4712. chmod 644 GenTerm/ctest.c
  4713.  
  4714. echo x - GenTerm/hpterm.par '[non-ascii]'
  4715. $unpacker <<'@eof'
  4716. begin 644 GenTerm/hpterm.par
  4717. M(R!4:&ES(&ES('1E<FUI;F%L(&5M=6QA=&]R('!A<G-E('1A8FQE(&9O<B!TX
  4718. M:&4@=&5R;3 @96UU;&%T;W(*(PHC+RH@2&ES=&]R>3H@(" @(" @(" @(" @X
  4719. M(" @(" @(" @(" @(" @(" @(" J+PHC+RH@(" @(" @("!7<FET=&5N(&)YX
  4720. M($<N(%(N(%-T<F%C:&%N(#$Y.3(@*B\*(PHC+RH@($-O<'ER:6=H="!';W)DX
  4721. M;VX@4BX@4W1R86-H86X@,3DY,B J+PHC+RH@(%1H:7,@8V]D92!I<R!P<F]VX
  4722. M:61E9"!A<R!I<RP@;F5I=&AE<B!T:&4@56YI=F5R<VET>2!O9B!7871E<FQOX
  4723. M;R!N;W(@*B\*(R\J("!T:&4@875T:&]R(&ES(&QI86)L92!F;W(@86YY(&1AX
  4724. M;6%G92!C875S960@8GD@=&AE('5S92!O<B!M:7-U<V4@;V8@=&AI<R J+PHCX
  4725. M+RH@(&-O9&4N(" J+PHC"B,O*B!097)M:7-S:6]N(&ES(&=R86YT960@=&\@X
  4726. M8V]P>2P@=7-E(&%N9"!M;V1I9GD@=&AI<R!C;V1E('!R;W9I9&5D(&ET(&ESX
  4727. M("HO"B,O*B!N;W0@<V]L9"!F;W(@<')O9FET(&%N9"!T:&4@86)O=F4@8V]PX
  4728. M>7)I9VAT(')E;6%I;G,@:6YT86-T+B J+PH*(R!F:7)S="!C;VUE<R!T:&4@X
  4729. M:V5Y8V]D92!D969I;FET:6]N<PH*"@I+97E486)L92A$969A=6QT*3T*>PI5X
  4730. M<"Q/+%Y;00I5<"A3:&EF="DL3RQ>6U,*1&]W;BQ/+%Y;0@I$;W=N*%-H:69TX
  4731. M*2Q/+%Y;5 I2:6=H="Q/+%Y;0PI,969T+$\L7EM$"E)E<V5T+$\L7EMG"DAOX
  4732. M;64L3RQ>6T@*5&%B+$DL7EM)"D-L96%R+$DL7EM*"D-L96%R3&EN92Q/+%Y;X
  4733. M2PI);G-E<G1,:6YE+$\L7EM,"D1E;&5T94QI;F4L3RQ>6TT*1&5L971E0VAAX
  4734. M<BQ/+%Y;4 I);G-E<G1#:&%R+$\L7EM1"DYE>'0L3RQ>6U4*4')I;W(L3RQ>X
  4735. M6U8*365N=2Q/+%Y;)FI$"DUE;G4H4VAI9G0I+$\L7ELF:D0*?0H*2V5Y5&%BX
  4736. M;&4H5')A;G-M:71&=6YC=&EO;DME>7,I/0I["E5P+$DL7EM!"E5P*%-H:69TX
  4737. M*2Q)+%Y;4PI$;W=N+$DL7EM""D1O=VXH4VAI9G0I+$DL7EM4"E)I9VAT+$DLX
  4738. M7EM#"DQE9G0L22Q>6T0*4F5S970L22Q>6V<*2&]M92Q)+%Y;2 I486(L22Q>X
  4739. M6TD*0VQE87(L22Q>6TH*0VQE87),:6YE+$DL7EM+"DEN<V5R=$QI;F4L22Q>X
  4740. M6TP*1&5L971E3&EN92Q)+%Y;30I$96QE=&5#:&%R+$DL7EM0"DEN<V5R=$-HX
  4741. M87(L22Q>6U$*3F5X="Q)+%Y;50I0<FEO<BQ)+%Y;5@I-96YU+$\L7ELF:D0*X
  4742. M365N=2A3:&EF="DL3RQ>6R9J1 I]"B,@;F]W(&-O;65S('1H92!I;G!U="!PX
  4743. M87)S92!T86)L90H*4&%R<V5486)L92A$969A=6QT*3T*>PI>2GM.97=,:6YEX
  4744. M*"E]"EY->T-A<G)I86=E4F5T=7)N*"E]"EY;07M5<$QI;F4H,2PQ*7T*7EM"X
  4745. M>T1O=VY,:6YE*#$L,2E]"EY;0WM-;W9E4FEG:'0H,2PQ*7T*7EM$>TUO=F5,X
  4746. M969T*#$L,2E]"EY;1GM'971";W1T;VU497AT*#$I.TUO=F5#=7)S;W(H)#$LX
  4747. M,"D[1&]W;DQI;F4H,2PP*7T*7EM'>T-A<G)I86=E4F5T=7)N*"E]"EY;2'M'X
  4748. M9714;W!/9E-C<F]L;%)E9VEO;B@Q+#$I.TUO=F5#=7)S;W(H)#$L,"D[4V5TX
  4749. M5&]P*# I?0I>6VA[1V5T5&]P3V938W)O;&Q296=I;VXH,2PQ*3M-;W9E0W5RX
  4750. M<V]R*"0Q+# I.U-E=%1O<"@P*7T*7EM)>TYE>'1486(H*7T*(PHC($=O9"!HX
  4751. M<'1E<FTG<R!D;R!W:65R9"!T:&EN9W,@=VET:"!T:&5I<B!A='1R:6)U=&4@X
  4752. M9FEE;&1S"B,@5VAA="!T:&ES(&1O97,@:7,@9&5T97)M:6YE<R!T:&4@871TX
  4753. M<FEB=71E<R!O9B!T:&4@8VAA<F%C=&5R('1O('1H92!L969T+ HC(&1E;&5TX
  4754. M97,@86QL('1H92!C:&%R86-T97)S('1O('1H92!R:6=H="!A;F0@=&AE;B!SX
  4755. M971S('1H92!F:65L9"!A='1R:6)U=&5S"B,@9F]R('1H92!R97-T(&]F('1HX
  4756. M92!L:6YE+B @270@=&AE;B!D96QE=&5S('1H92!R97-T(&]F(&QI;F5S(&]NX
  4757. M('1H92!S8W)E96X*(PI>6TI[1V5T4&]S:71I;VXH,2PR*3M-871H*"0R+"(MX
  4758. M(BPQ+#,I.TQO861!='1R:6)U=&4H)#$L)#,I.T-L96%R3&EN92@Q*3M<"@E3X
  4759. M971&:65L9"@S*3M-871H*"0Q+"(K(BPQ+#0I.T-L96%R1&ES<&QA>2@D-"D[X
  4760. M0VQE87)-96UO<GDH,2E]"EY;2WM'9710;W-I=&EO;B@Q+#(I.TUA=&@H)#(LX
  4761. M(BTB+#$L,RD[3&]A9$%T=')I8G5T92@D,2PD,RD[0VQE87),:6YE*#$I.UP*X
  4762. M"5-E=$9I96QD*#,I?0I>6TQ[26YS97)T3&EN97,H,2PP*3M#87)R:6%G95)EX
  4763. M='5R;B@I?0I>6TU[1&5L971E3&EN97,H,2D[0V%R<FEA9V52971U<FXH*7T*X
  4764. M7EM0>T1E;&5T94-H87)A8W1E<G,H,2E]"EY;47M3971);G-E<G1-;V1E*#$IX
  4765. M?0I>6U)[4V5T26YS97)T36]D92@P*7T*7EM3>T=E=%1O<"@Q*3M-871H*"0QX
  4766. M+"(K(BPQ+#(I.U-E=%1O<"@D,BE]"EY;5'M'9714;W H,2D[36%T:"@D,2PBX
  4767. M+2(L,2PR*3M39714;W H)#(I?0I>6U5[1V5T5&]P*#$I.T=E=%-C<F5E;E-IX
  4768. M>F4H,BPS*3M-871H*"0Q+"(K(BPD,BPT*3M39714;W H)#0I.TUO=F5#=7)SX
  4769. M;W(H,"PP*7T*7EM6>T=E=%1O<"@Q*3M'97138W)E96Y3:7IE*#(L,RD[36%TX
  4770. M:"@D,2PB+2(L)#(L-"D[4V5T5&]P*"0T*3M-;W9E0W5R<V]R*# L,"E]"EY;X
  4771. M6'M)9VYO<F4H*7T*7EM9>U-E=%)E<V]U<F-E*")L:71E<F%L36]D92(L,2D[X
  4772. M4V5T4&%R<V5486)L92@B1&ES<&QA>4UO9&4B*7T*7ELQ>T=E=%!O<VET:6]NX
  4773. M*#$L,BD[4V5T5&%B*"0R*7T*7ELR>T=E=%!O<VET:6]N*#$L,BD[56Y39714X
  4774. M86(H)#(I?0I>6S-[56Y3971486(H+3$I?0HC"B,@;F]T(')E86QL>2!A('!RX
  4775. M;W!E<B!S=&%T=7,@9G5N8W1I;VXL('=E(&%L=V%Y<R!R97!L>2!T:&4@9&5FX
  4776. M875L= HC"EY;7%Y[16UI="@B7EM<7%Q<-# P.# P,%Y-(BE]"EY;8'M'9710X
  4777. M;W-I=&EO;B@Q+#(I.TEN=%1O4W1R:6YG*"0R+#,L,RD[26YT5&]3=')I;F<HX
  4778. M)#$L,RPT*3M<"@E%;6ET*")>6R9A(BPD,RPB8R(L)#0L(EE>32(I?0I>6V%[X
  4779. M1V5T5&]P*#$I.T=E=%!O<VET:6]N*#(L,RD[36%T:"@D,2PB*R(L)#(L-"D[X
  4780. M16UI="@B7ELF82(L)#,L(F,B+"0T+")27DTB*7T*7EMB>TEG;F]R92@I?0I>X
  4781. M6V-[26=N;W)E*"E]"EY;9'M'9710;W-I=&EO;B@Q+#(I.T=E=$QI;F4H)#$LX
  4782. M)#(L,RD[16UI="@D,RE]"EY;9GM)9VYO<F4H*7T*7EMI>TUO=F5,969T*#$LX
  4783. M,2PQ*3M0<F5V:6]U<U1A8B@I?0I>6VI[26=N;W)E*"E]"EY;:WM)9VYO<F4HX
  4784. M*7T*7EML>T=E=%!O<VET:6]N*#$L,BD[1V5T4V-R965N4VEZ92@S+#0I.TUAX
  4785. M=&@H)#,L(BTB+#$L-2D[7 H)4V5T4V-R;VQL4F5G:6]N*# L)#4L,"D[4V5TX
  4786. M4V-R;VQL4F5G:6]N*"0Q+"0U+#$I?0I>6VU[1V5T4V-R965N4VEZ92@Q+#(IX
  4787. M.TUA=&@H)#$L(BTB+#$L,RD[4V5T4V-R;VQL4F5G:6]N*# L)#,L,"E]"EY;X
  4788. M<'M)9VYO<F4H*7T*7EMQ>TEG;F]R92@I?0I>6W)[26=N;W)E*"E]"EY;<WM)X
  4789. M9VYO<F4H*7T*7EMT>TEG;F]R92@I?0I>6W5[26=N;W)E*"E]"EY;=GM)9VYOX
  4790. M<F4H*7T*7EMW>TEG;F]R92@I?0I>6WI[26=N;W)E*"E]"EY;?GM)9VYO<F4HX
  4791. M*7T*7EM;>TEG;F]R92@I?0I>6UU[26=N;W)E*"E]"EY)>TYE>'1486(H*7T*X
  4792. M7DA[36]V94QE9G0H,2PP*7T*7D=[4V]U;F1"96QL*"E]"EY.>T=E=%!O<VETX
  4793. M:6]N*#$L,BD[3&]A9$%T=')I8G5T92@D,2PD,BD[4V5T1F]N="@Q*3M3971&X
  4794. M:65L9"@S*7T*7D][1V5T4&]S:71I;VXH,2PR*3M,;V%D071T<FEB=71E*"0QX
  4795. M+"0R*3M3971&;VYT*# I.U-E=$9I96QD*#,I?0I>4WM3971&;&]W*# I?0I>X
  4796. M47M3971&;&]W*#$I?0I>6R9J0'M3971297-O=7)C92@B<VAO=T9U;F-T:6]NX
  4797. M(BPP*3M3=&]R92@P+#$I?0I>6R9J07M3971297-O=7)C92@B<VAO=T9U;F-TX
  4798. M:6]N(BPQ*3M3=&]R92@Q+#$I?0I>6R9J0GM3971297-O=7)C92@B<VAO=T9UX
  4799. M;F-T:6]N(BPQ*3M3=&]R92@Q+#$I?0HC(%1H:7,@;F5X="!T<F%N<VQA=&]RX
  4800. M(&ES;B=T(&$@=')U92!T97)M,"!F=6YC=&EO;BX@($D@861D960@:70@<V\@X
  4801. M22!C86X*(R!I;7!L96UE;G0@82!T;V=G;&4@;VX@=&AE(&UE;G4@8G5T=&]NX
  4802. M"EY;)FI$>T9E=&-H*#$L,2D[268H)#$L(CTB+#$L,2D[4V5T4F5S;W5R8V4HX
  4803. M(G-H;W=&=6YC=&EO;B(L,2D[4W1O<F4H,2PQ*3M<"@D)475I="@I.UP*"5-EX
  4804. M=%)E<V]U<F-E*")S:&]W1G5N8W1I;VXB+# I+#$[4W1O<F4H,"PQ*7T*7ELFX
  4805. M:E)[26=N;W)E*"E]"B,*(R!S8W)E96X@<F5L871I=F4@861D<F5S<VEN9PHCX
  4806. M"EY;)F$\26YT*"DL,3YC/$EN="@I+#(^67M-;W9E0W5R<V]R*"0R+"0Q*7T*X
  4807. M7ELF83Q);G0H*2PQ/GD\26YT*"DL,CY#>TUO=F5#=7)S;W(H)#$L)#(I?0I>X
  4808. M6R9A/$EN="@I+#$^0WM'9710;W-I=&EO;B@R+#,I.TUO=F5#=7)S;W(H)#(LX
  4809. M)#$I?0I>6R9A/$EN="@I+#$^67M'9710;W-I=&EO;B@R+#,I.TUO=F5#=7)SX
  4810. M;W(H)#$L)#,I?0HC"B,@<V-R965N(&%B<V]L=71E(&%D9')E<W-I;F<*(PI>X
  4811. M6R9A/$EN="@I+#$^8SQ);G0H*2PR/E)[1V5T5&]P*#,I.UP*"4EF*"0S+"(^X
  4812. M(BPD,BPQ*3M<"@E'97138W)E96Y3:7IE*#0L-2D[36%T:"@D,RPB*R(L)#0LX
  4813. M-BD[36%T:"@D-BPB+2(L,2PV*3M)9B@D-BPB/"(L)#(L,BD[7 H)36%T:"@DX
  4814. M,BPB+2(L)#,L-"D[36]V94-U<G-O<B@D-"PD,2D[475I="@I.UP*"5-E=%1OX
  4815. M<"@D,BDL,3M-;W9E0W5R<V]R*# L)#$I.U%U:70H*3M<"@E-871H*"0R+"(MX
  4816. M(BPD-"PV*2PR.TUA=&@H)#8L(BLB+#$L-BD[4V5T5&]P*"0V*3M-;W9E0W5RX
  4817. M<V]R*"0T+"0Q*7T*(PI>6R9A/$EN="@I+#$^4GM'9710;W-I=&EO;B@R+#<IX
  4818. M.T=E=%1O<"@S*3M<"@E)9B@D,RPB/B(L)#$L,2D[7 H)1V5T4V-R965N4VEZX
  4819. M92@T+#4I.TUA=&@H)#,L(BLB+"0T+#8I.TUA=&@H)#8L(BTB+#$L-BD[268HX
  4820. M)#8L(CPB+"0Q+#(I.UP*"4UA=&@H)#$L(BTB+"0S+#0I.TUO=F5#=7)S;W(HX
  4821. M)#0L)#<I.U%U:70H*3M<"@E39714;W H)#$I+#$[36]V94-U<G-O<B@P+"0WX
  4822. M*3M1=6ET*"D[7 H)36%T:"@D,2PB+2(L)#0L-BDL,CM-871H*"0V+"(K(BPQX
  4823. M+#8I.U-E=%1O<"@D-BD[36]V94-U<G-O<B@D-"PD-RE]"B,*(R!C=7)S;W(@X
  4824. M<F5L871I=F4@<V-R965N(')E;&%T:79E(&%D9')E<W-I;F<*(PI>6R9A*SQ)X
  4825. M;G0H*2PQ/G@K/$EN="@I+#(^67M'9710;W-I=&EO;B@S+#0I.TUA=&@H)#,LX
  4826. M(BLB+"0R+#4I.UP*"4UA=&@H)#0L(BLB+"0Q+#8I.TUO=F5#=7)S;W(H)#4LX
  4827. M)#8I?0I>6R9A+3Q);G0H*2PQ/G@K/$EN="@I+#(^67M'9710;W-I=&EO;B@SX
  4828. M+#0I.TUA=&@H)#,L(BLB+"0R+#4I.UP*"4UA=&@H)#0L(BTB+"0Q+#8I.TUOX
  4829. M=F5#=7)S;W(H)#4L)#8I?0I>6R9A*SQ);G0H*2PQ/G@M/$EN="@I+#(^67M'X
  4830. M9710;W-I=&EO;B@S+#0I.TUA=&@H)#,L(BTB+"0R+#4I.UP*"4UA=&@H)#0LX
  4831. M(BLB+"0Q+#8I.TUO=F5#=7)S;W(H)#4L)#8I?0I>6R9A+3Q);G0H*2PQ/G@MX
  4832. M/$EN="@I+#(^67M'9710;W-I=&EO;B@S+#0I.TUA=&@H)#,L(BTB+"0R+#4IX
  4833. M.UP*"4UA=&@H)#0L(BTB+"0Q+#8I.TUO=F5#=7)S;W(H)#4L)#8I?0HC"EY;X
  4834. M)F$K/$EN="@I+#$^6'M'9710;W-I=&EO;B@S+#0I.TUA=&@H)#0L(BLB+"0QX
  4835. M+#8I.TUO=F5#=7)S;W(H)#,L)#8I?0I>6R9A+3Q);G0H*2PQ/EA[1V5T4&]SX
  4836. M:71I;VXH,RPT*3M-871H*"0T+"(M(BPD,2PV*3M-;W9E0W5R<V]R*"0S+"0VX
  4837. M*7T*7ELF82L\26YT*"DL,3Y9>T=E=%!O<VET:6]N*#,L-"D[36%T:"@D,RPBX
  4838. M*R(L)#$L-2D[36]V94-U<G-O<B@D-2PD-"E]"EY;)F$M/$EN="@I+#$^67M'X
  4839. M9710;W-I=&EO;B@S+#0I.TUA=&@H)#,L(BTB+"0Q+#4I.TUO=F5#=7)S;W(HX
  4840. M)#4L)#0I?0HC"B,@8W5R<V]R(')E;&%T:79E('-C<F5E;B!A8G-O;'5T92!AX
  4841. M9&1R97-S:6YG"B,*7ELF82L\26YT*"DL,3YC*SQ);G0H*2PR/E)[1V5T4&]SX
  4842. M:71I;VXH,RPT*3M-871H*"0Q+"(K(BPD-"PQ*3M<"@E-871H*"0R+"(K(BPDX
  4843. M,RPR*3M'9714;W H,RD[7 H)268H)#,L(CXB+"0R+#$I.UP*"4=E=%-C<F5EX
  4844. M;E-I>F4H-"PU*3M-871H*"0S+"(K(BPD-"PV*3M-871H*"0V+"(M(BPQ+#8IX
  4845. M.TEF*"0V+"(\(BPD,BPR*3M<"@E-871H*"0R+"(M(BPD,RPT*3M-;W9E0W5RX
  4846. M<V]R*"0T+"0Q*3M1=6ET*"D[7 H)4V5T5&]P*"0R*2PQ.TUO=F5#=7)S;W(HX
  4847. M,"PD,2D[475I="@I.UP*"4UA=&@H)#(L(BTB+"0T+#8I+#([36%T:"@D-BPBX
  4848. M*R(L,2PV*3M39714;W H)#8I.TUO=F5#=7)S;W(H)#0L)#$I?0I>6R9A*SQ)X
  4849. M;G0H*2PQ/F,M/$EN="@I+#(^4GM'9710;W-I=&EO;B@S+#0I.TUA=&@H)#$LX
  4850. M(BLB+"0T+#$I.UP*"4UA=&@H)#,L(BTB+"0R+#(I.T=E=%1O<"@S*3M<"@E)X
  4851. M9B@D,RPB/B(L)#(L,2D[7 H)1V5T4V-R965N4VEZ92@T+#4I.TUA=&@H)#,LX
  4852. M(BLB+"0T+#8I.TUA=&@H)#8L(BTB+#$L-BD[268H)#8L(CPB+"0R+#(I.UP*X
  4853. M"4UA=&@H)#(L(BTB+"0S+#0I.TUO=F5#=7)S;W(H)#0L)#$I.U%U:70H*3M<X
  4854. M"@E39714;W H)#(I+#$[36]V94-U<G-O<B@P+"0Q*3M1=6ET*"D[7 H)36%TX
  4855. M:"@D,BPB+2(L)#0L-BDL,CM-871H*"0V+"(K(BPQ+#8I.U-E=%1O<"@D-BD[X
  4856. M36]V94-U<G-O<B@D-"PD,2E]"EY;)F$M/$EN="@I+#$^8RL\26YT*"DL,CY2X
  4857. M>T=E=%!O<VET:6]N*#,L-"D[36%T:"@D-"PB+2(L)#$L,2D[7 H)36%T:"@DX
  4858. M,BPB*R(L)#,L,BD[1V5T5&]P*#,I.UP*"4EF*"0S+"(^(BPD,BPQ*3M<"@E'X
  4859. M97138W)E96Y3:7IE*#0L-2D[36%T:"@D,RPB*R(L)#0L-BD[36%T:"@D-BPBX
  4860. M+2(L,2PV*3M)9B@D-BPB/"(L)#(L,BD[7 H)36%T:"@D,BPB+2(L)#,L-"D[X
  4861. M36]V94-U<G-O<B@D-"PD,2D[475I="@I.UP*"5-E=%1O<"@D,BDL,3M-;W9EX
  4862. M0W5R<V]R*# L)#$I.U%U:70H*3M<"@E-871H*"0R+"(M(BPD-"PV*2PR.TUAX
  4863. M=&@H)#8L(BLB+#$L-BD[4V5T5&]P*"0V*3M-;W9E0W5R<V]R*"0T+"0Q*7T*X
  4864. M7ELF82T\26YT*"DL,3YC+3Q);G0H*2PR/E)[1V5T4&]S:71I;VXH,RPT*3M-X
  4865. M871H*"0T+"(M(BPD,2PQ*3M<"@E-871H*"0S+"(M(BPD,BPR*3M'9714;W HX
  4866. M,RD[7 H)268H)#,L(CXB+"0R+#$I.UP*"4=E=%-C<F5E;E-I>F4H-"PU*3M-X
  4867. M871H*"0S+"(K(BPD-"PV*3M-871H*"0V+"(M(BPQ+#8I.TEF*"0V+"(\(BPDX
  4868. M,BPR*3M<"@E-871H*"0R+"(M(BPD,RPT*3M-;W9E0W5R<V]R*"0T+"0Q*3M1X
  4869. M=6ET*"D[7 H)4V5T5&]P*"0R*2PQ.TUO=F5#=7)S;W(H,"PD,2D[475I="@IX
  4870. M.UP*"4UA=&@H)#(L(BTB+"0T+#8I+#([36%T:"@D-BPB*R(L,2PV*3M39714X
  4871. M;W H)#8I.TUO=F5#=7)S;W(H)#0L)#$I?0HC"EY;)F$K/$EN="@I+#$^0WM'X
  4872. M9710;W-I=&EO;B@S+#0I.TUA=&@H)#0L(BLB+"0Q+#8I.TUO=F5#=7)S;W(HX
  4873. M)#,L)#8I?0I>6R9A+3Q);G0H*2PQ/D-[1V5T4&]S:71I;VXH,RPT*3M-871HX
  4874. M*"0T+"(M(BPD,2PV*3M-;W9E0W5R<V]R*"0S+"0V*7T*7ELF82L\26YT*"DLX
  4875. M,3Y2>T=E=%!O<VET:6]N*#(L-RD[36%T:"@D,BPB*R(L)#$L,BD[1V5T5&]PX
  4876. M*#,I.UP*"4EF*"0S+"(^(BPD,BPQ*3M<"@E'97138W)E96Y3:7IE*#0L-2D[X
  4877. M36%T:"@D,RPB*R(L)#0L-BD[36%T:"@D-BPB+2(L,2PV*3M)9B@D-BPB/"(LX
  4878. M)#(L,BD[7 H)36%T:"@D,BPB+2(L)#,L-"D[36]V94-U<G-O<B@D-"PD-RD[X
  4879. M475I="@I.UP*"5-E=%1O<"@D,BDL,3M-;W9E0W5R<V]R*# L)#<I.U%U:70HX
  4880. M*3M<"@E-871H*"0R+"(M(BPD-"PV*2PR.TUA=&@H)#8L(BLB+#$L-BD[4V5TX
  4881. M5&]P*"0V*3M-;W9E0W5R<V]R*"0T+"0W*7T*7ELF82T\26YT*"DL,3Y2>T=EX
  4882. M=%!O<VET:6]N*#(L-RD[36%T:"@D,BPB+2(L)#$L,BD[1V5T5&]P*#,I.UP*X
  4883. M"4EF*"0S+"(^(BPD,BPQ*3M<"@E'97138W)E96Y3:7IE*#0L-2D[36%T:"@DX
  4884. M,RPB*R(L)#0L-BD[36%T:"@D-BPB+2(L,2PV*3M)9B@D-BPB/"(L)#(L,BD[X
  4885. M7 H)36%T:"@D,BPB+2(L)#,L-"D[36]V94-U<G-O<B@D-"PD-RD[475I="@IX
  4886. M.UP*"5-E=%1O<"@D,BDL,3M-;W9E0W5R<V]R*# L)#<I.U%U:70H*3M<"@E-X
  4887. M871H*"0R+"(M(BPD-"PV*2PR.TUA=&@H)#8L(BLB+#$L-BD[4V5T5&]P*"0VX
  4888. M*3M-;W9E0W5R<V]R*"0T+"0W*7T*(PHC('1H:7,@8VQE87)S(&%L;"!A='1RX
  4889. M:6)U=&5S+"!U;F9O<G1U;F%T96QY(&AP(&1O97-N)W0@8V]N<VED97(@82!FX
  4890. M;VYT(&%N"B,@871T<FEB=71E('-O('=E('-T;W)E(&ET(&%N9"!S970@:70@X
  4891. M86=A:6X@;&%T97(*(PI>6R9D0'M'971&;VYT*#$I.T=E=%!E;B@R*3M,;V%DX
  4892. M071T<FEB=71E*"TQ+"TQ*3M3971&;VYT*"0Q*3M3971096XH)#(I.UP*"5-EX
  4893. M=$9I96QD*#,I?0I>6R9D07M'971&;VYT*#$I.T=E=%!E;B@R*3M,;V%D071TX
  4894. M<FEB=71E*"TQ+"TQ*3M3971&;VYT*"0Q*3M3971096XH)#(I.UP*"5-E=$)LX
  4895. M:6YK36]D92@Q*3M3971&:65L9"@S*7T*7ELF9$)[1V5T1F]N="@Q*3M'9710X
  4896. M96XH,BD[3&]A9$%T=')I8G5T92@M,2PM,2D[4V5T1F]N="@D,2D[4V5T4&5NX
  4897. M*"0R*3M<"@E3971);G9E<G-E5FED96\H,2D[4V5T1FEE;&0H,RE]"EY;)F1#X
  4898. M>T=E=$9O;G0H,2D[1V5T4&5N*#(I.TQO861!='1R:6)U=&4H+3$L,2D[4V5TX
  4899. M1F]N="@D,2D[4V5T4&5N*"0R*3M<"@E3971);G9E<G-E5FED96\H,2D[4V5TX
  4900. M0FQI;FM-;V1E*#$I.U-E=$9I96QD*#,I?0I>6R9D1'M'971&;VYT*#$I.T=EX
  4901. M=%!E;B@R*3M,;V%D071T<FEB=71E*"TQ+"TQ*3M3971&;VYT*"0Q*3M39710X
  4902. M96XH)#(I.UP*"5-E=%5N9&5R3&EN94UO9&4H,2D[4V5T1FEE;&0H,RE]"EY;X
  4903. M)F1%>T=E=$9O;G0H,2D[1V5T4&5N*#(I.TQO861!='1R:6)U=&4H+3$L+3$IX
  4904. M.U-E=$9O;G0H)#$I.U-E=%!E;B@D,BD[7 H)4V5T56YD97),:6YE36]D92@QX
  4905. M*3M3971";&EN:TUO9&4H,2D[4V5T1FEE;&0H,RE]"EY;)F1&>T=E=$9O;G0HX
  4906. M,2D[1V5T4&5N*#(I.TQO861!='1R:6)U=&4H+3$L+3$I.U-E=$9O;G0H)#$IX
  4907. M.U-E=%!E;B@D,BD[7 H)4V5T26YV97)S959I9&5O*#$I.U-E=%5N9&5R3&ENX
  4908. M94UO9&4H,2D[4V5T1FEE;&0H,RE]"EY;)F1'>T=E=$9O;G0H,2D[1V5T4&5NX
  4909. M*#(I.TQO861!='1R:6)U=&4H+3$L+3$I.U-E=$9O;G0H)#$I.U-E=%!E;B@DX
  4910. M,BD[7 H)4V5T26YV97)S959I9&5O*#$I.U-E=%5N9&5R3&EN94UO9&4H,2D[X
  4911. M4V5T0FQI;FM-;V1E*#$I.U-E=$9I96QD*#,I?0I>6R9D2'M'971&;VYT*#$IX
  4912. M.T=E=%!E;B@R*3M,;V%D071T<FEB=71E*"TQ+"TQ*3M3971&;VYT*"0Q*3M3X
  4913. M971096XH)#(I.UP*"5-E=$AA;&9"<FEG:'1-;V1E*#$I.U-E=$9I96QD*#,IX
  4914. M?0I>6R9D27M'971&;VYT*#$I.T=E=%!E;B@R*3M,;V%D071T<FEB=71E*"TQX
  4915. M+"TQ*3M3971&;VYT*"0Q*3M3971096XH)#(I.UP*"5-E=$AA;&9"<FEG:'1-X
  4916. M;V1E*#$I.U-E=$)L:6YK36]D92@Q*3M3971&:65L9"@S*7T*7ELF9$I[1V5TX
  4917. M1F]N="@Q*3M'971096XH,BD[3&]A9$%T=')I8G5T92@M,2PM,2D[4V5T1F]NX
  4918. M="@D,2D[4V5T4&5N*"0R*3M<"@E3971(86QF0G)I9VAT36]D92@Q*3M3971)X
  4919. M;G9E<G-E5FED96\H,2D[4V5T1FEE;&0H,RE]"EY;)F1+>T=E=$9O;G0H,2D[X
  4920. M1V5T4&5N*#(I.TQO861!='1R:6)U=&4H+3$L+3$I.U-E=$9O;G0H)#$I.U-EX
  4921. M=%!E;B@D,BD[7 H)4V5T2&%L9D)R:6=H=$UO9&4H,2D[4V5T26YV97)S959IX
  4922. M9&5O*#$I.U-E=$)L:6YK36]D92@Q*3M3971&:65L9"@S*7T*7ELF9$Q[1V5TX
  4923. M1F]N="@Q*3M'971096XH,BD[3&]A9$%T=')I8G5T92@M,2PM,2D[4V5T1F]NX
  4924. M="@D,2D[4V5T4&5N*"0R*3M<"@E3971(86QF0G)I9VAT36]D92@Q*3M39715X
  4925. M;F1E<DQI;F5-;V1E*#$I.U-E=$9I96QD*#,I?0I>6R9D37M'971&;VYT*#$IX
  4926. M.T=E=%!E;B@R*3M,;V%D071T<FEB=71E*"TQ+"TQ*3M3971&;VYT*"0Q*3M3X
  4927. M971096XH)#(I.UP*"5-E=$AA;&9"<FEG:'1-;V1E*#$I.U-E=%5N9&5R3&ENX
  4928. M94UO9&4H,2D[4V5T0FQI;FM-;V1E*#$I.U-E=$9I96QD*#,I?0I>6R9D3GM'X
  4929. M971&;VYT*#$I.T=E=%!E;B@R*3M,;V%D071T<FEB=71E*"TQ+"TQ*3M3971&X
  4930. M;VYT*"0Q*3M3971096XH)#(I.UP*"5-E=$AA;&9"<FEG:'1-;V1E*#$I.U-EX
  4931. M=$EN=F5R<V56:61E;R@Q*3M39715;F1E<DQI;F5-;V1E*#$I.UP*"5-E=$9IX
  4932. M96QD*#,I?0I>6R9D3WM'971&;VYT*#$I.T=E=%!E;B@R*3M,;V%D071T<FEBX
  4933. M=71E*"TQ+"TQ*3M3971&;VYT*"0Q*3M3971096XH)#(I.UP*"5-E=$AA;&9"X
  4934. M<FEG:'1-;V1E*#$I.U-E=$EN=F5R<V56:61E;R@Q*3M39715;F1E<DQI;F5-X
  4935. M;V1E*#$I.UP*"5-E=$)L:6YK36]D92@Q*3M3971&:65L9"@S*7T*(PHC($YOX
  4936. M=&4@22!D;VXG="!C;W9E<B!A;&P@<&]S<VEB;&4@8V]M8FEN871I;VYS+B @X
  4937. M5&\@9&\@=&AA="!)('-H;W5L9"!R97!L86-E"B,@=&AE(%-E;&5C="=S('=IX
  4938. M=&@@26YT)W,@86YD(&-H96-K(&%F=&5R=V%R9',@=&\@<V5E(&EF($D@9V]TX
  4939. M(&$@=F%L:60@;G5M8F5R"B,*7ELF9CQ);G0H*2PQ/F$\4V5L96-T*"(P(BPBX
  4940. M,2(L(C(B+"(S(BPB-"(L(C4B+"(V(BPB-R(L(C@B*2PR/FL\26YT*"DL,SYDX
  4941. M/$EN="@I+#0^3#Q3=')I;F<H)#,I+#4^/%-T<FEN9R@D-"DL-CY[4')O9W)AX
  4942. M;4ME>2@D,2PD,BPD-2PD-BE]"EY;)F8\26YT*"DL,3YK/$EN="@I+#(^9#Q)X
  4943. M;G0H*2PS/DP\4W1R:6YG*"0R*2PT/CQ3=')I;F<H)#,I+#4^7 H)>TEF*"0SX
  4944. M+"(](BPM,2PQ*3M0<F]G<F%M2V5Y*# L)#$L)#0L)#4I.U%U:70H*3M<"@D)X
  4945. M36%T:"@D,2PB*R(L,3$Q+#<I+#$[5&]!<V-I:2@D-RPX*3M-871H*")>6R(LX
  4946. M(B8B+"0X+#DI.UP*"0E0<F]G<F%M2V5Y*# L)#$L)#0L)#DI?0I>6R9F/$ENX
  4947. M="@I+#$^:SQ);G0H*2PR/F$\26YT*"DL,SYD/$EN="@I+#0^3#Q3=')I;F<HX
  4948. M)#,I+#4^/%-T<FEN9R@D-"DL-CY<"@E[268H)#0L(CTB+"TQ+#$I.U!R;V=RX
  4949. M86U+97DH)#(L)#$L)#4L)#8I.U%U:70H*3M<"@D)36%T:"@D,2PB*R(L,3$QX
  4950. M+#<I+#$[5&]!<V-I:2@D-RPX*3M-871H*")>6R(L(B8B+"0X+#DI.UP*"0E0X
  4951. M<F]G<F%M2V5Y*"0R+"0Q+"0U+"0Y*7T*7ELF9CQ);G0H*2PQ/F$\4V5L96-TX
  4952. M*"(P(BPB,2(L(C(B+"(S(BPB-"(L(C4B+"(V(BPB-R(L(C@B*2PR/FL\26YTX
  4953. M*"DL,SYL/$EN="@I+#0^1#Q3=')I;F<H)#0I+#4^/%-T<FEN9R@D,RDL-CY[X
  4954. M4')O9W)A;4ME>2@D,2PD,BPD-2PD-BE]"EY;)F8\26YT*"DL,3Y%>T5X96-UX
  4955. M=&5&=6YC=&EO;DME>2@D,2E]"B,*7ELF:SQ396QE8W0H(C B+"(Q(BDL,3X\X
  4956. M4V5L96-T*")!(BPB0B(L(D,B+")$(BPB22(L(DHB+"),(BPB32(L(DXB+")0X
  4957. M(BPB4B(I+#(^>TEG;F]R92@I?0I>6R9Q/%-E;&5C="@B,"(L(C$B*2PQ/DQ[X
  4958. M26=N;W)E*"E]"EY;)G(\26YT*"DL,3Y5>T=E=%1O<"@R*3M-871H*"0Q+"(KX
  4959. M(BPD,BPS*3M39714;W H)#,I?0I>6R9R/$EN="@I+#$^1'M'9714;W H,BD[X
  4960. M36%T:"@D,BPB+2(L)#$L,RD[4V5T5&]P*"0S*7T*7ELF<S!!>U-E=$ME>51AX
  4961. M8FQE*")$969A=6QT(BE]"EY;)G,Q07M3971+97E486)L92@B5')A;G-M:71&X
  4962. M=6YC=&EO;DME>7,B*7T*7ELF<T%[4V5T2V5Y5&%B;&4H(D1E9F%U;'0B*7T*X
  4963. M7ELF<S!">TEG;F]R92@I?0I>6R9S,4)[26=N;W)E*"E]"EY;)G,P0WM39712X
  4964. M97-O=7)C92@B875T;TQI;F57<F%P(BPQ*7T*7ELF<S%#>U-E=%)E<V]U<F-EX
  4965. M*")A=71O3&EN95=R87 B+# I?0I>6R9V/$9L;V%T*"DL,3Y3>T=E=%!O<VETX
  4966. M:6]N*#(L,RD[3&]A9$%T=')I8G5T92@D,BPD,RD[4V5T4&5N*"0Q*3M3971&X
  4967. M:65L9"@S*7T*7ELF=CQ&;&]A="@I+#$^37M)9B@D,2PB/2(L,"PQ*3M)9B@DX
  4968. M,2PB/2(L,2PQ*3M296IE8W0H*3M<"@E3971297-O=7)C92@B9&5F:6YE0V]LX
  4969. M;W(B+"0Q*2PQ?0I>6RID47M3971297-O=7)C92@B<VAO=T-U<G-O<B(L,2E]X
  4970. M"EY;*F12>U-E=%)E<V]U<F-E*")S:&]W0W5R<V]R(BPP*7T*7ELJ<UQ>>T5MX
  4971. M:70H(E@M:'!T97)M7DTB*7T*7EM</#Q);G0H*2PQ/D%[26=N;W)E*"E]"EY;X
  4972. M7#X\26YT*"DL,3Y!>TEG;F]R92@I?0HC"B,@;VYC92!A9V%I;B!)(&1O;B=TX
  4973. M(&5N=6UE<F%T92!A;&P@<&]S:6)I;&ET97,L('1H97)E(&%R92!T;V\@;6%NX
  4974. M>0HC"EY;)G8\1FQO870H*2PQ/F$\1FQO870H*2PR/F(\1FQO870H*2PS/F,\X
  4975. M1FQO870H*2PT/G@\1FQO870H*2PU/GD\1FQO870H*2PV/GH\1FQO870H*2PWX
  4976. M/DE[1&5F:6YE4&5N*"0W+"0Q+"0R+"0S+"0T+"0U+"0V*7T*7ELF=CQ&;&]AX
  4977. M="@I+#$^83Q&;&]A="@I+#(^83Q&;&]A="@I+#,^8CQ&;&]A="@I+#0^8SQ&X
  4978. M;&]A="@I+#4^>#Q&;&]A="@I+#8^>3Q&;&]A="@I+#<^>CQ&;&]A="@I+#@^X
  4979. M27M3971297-O=7)C92@B9&5F:6YE0V]L;W(B+"0Q*3M<"@E$969I;F5096XHX
  4980. M)#@L)#(L)#,L)#0L)#4L)#8L)#<I?0HC7ELF9C!K/$EN="@I+#$^1#Q3=')IX
  4981. M;F<H)#$I+#(^>T5S8V%P94-A;&QB86-K*"))8V]N5&ET;&4B+"0R*7T*(UY;X
  4982. M)F8M,6L\26YT*"DL,3Y$/%-T<FEN9R@D,2DL,CY[17-C87!E0V%L;&)A8VLHX
  4983. M(E=I;F1O=U1I=&QE(BPD,BE]"GT*"B,*(R @5&AI<R!P87)S92!T86)L92!IX
  4984. M<R!U<V5D('=H96X@:6X@9&ES<&QA>2!F=6YC=&EO;G,@;6]D90HC"@I087)SX
  4985. M951A8FQE*$1I<W!L87E-;V1E*3T*>PI>37M.97=,:6YE*#$I.T-A<G)I86=EX
  4986. M4F5T=7)N*"E]"EY;6GM3971297-O=7)C92@B;&ET97)A;$UO9&4B+# I.U-EX
  4987. M=%!A<G-E5&%B;&4H(D1E9F%U;'0B*7T*?0H*(PHC("!4:&ES(&1U;6UY('!AX
  4988. M<G-E('1A8FQE(&ES(&5X96-U=&5D(&1U<FEN9R!T:&4@:6YI=&EA;&EZ871IX
  4989. M;VX@;V8@=&AE('=I9&=E= HC"@I087)S951A8FQE*%-T87)T57 I/0I["GM0X
  4990. M<F]G<F%M2V5Y*# L,2PB1C$B+")>6W B*3M0<F]G<F%M2V5Y*# L,BPB1C(BX
  4991. M+")>6W$B*3M<"@E0<F]G<F%M2V5Y*# L,RPB1C,B+")>6W(B*3M0<F]G<F%MX
  4992. M2V5Y*# L-"PB1C0B+")>6W,B*3M<"@E0<F]G<F%M2V5Y*# L-2PB1C4B+")>X
  4993. M6W0B*3M0<F]G<F%M2V5Y*# L-BPB1C8B+")>6W4B*3M<"@E0<F]G<F%M2V5YX
  4994. M*# L-RPB1C<B+")>6W8B*3M0<F]G<F%M2V5Y*# L."PB1C@B+")>6W<B*7T*X
  4995. !?3 L                                                        X
  4996.                                                              X
  4997. end
  4998. @eof
  4999. set `wc -lwc <GenTerm/hpterm.par`
  5000. if test $1$2$3 != 33459812511
  5001. then
  5002.     echo ERROR: wc results of GenTerm/hpterm.par are $* should be 334 598 12511
  5003. fi
  5004.  
  5005. chmod 644 GenTerm/hpterm.par
  5006.  
  5007. echo x - GenTerm/test.c
  5008. cat >GenTerm/test.c <<'@EOF'
  5009. #include <stdio.h>
  5010. #include <fcntl.h>
  5011. #include <termios.h>
  5012. #include <X11/X.h>
  5013. #include <X11/Intrinsic.h>
  5014. #include <X11/StringDefs.h>
  5015. #include <Xm/Xm.h>
  5016. #include <Xm/ScrollBar.h>
  5017. #include "GenTermEm.h"
  5018.  
  5019.  
  5020. #define COLORS "Default:Default:red:Default:green:Default:yellow:Default:blue:Default:magenta:Default:cyan:Default:black:yellow"
  5021.  
  5022. void QuitCB();
  5023. void RunCB();
  5024. void KeyHit();
  5025. void TopCB();
  5026. void ScrollCB();
  5027. void EscapeCB();
  5028. void ResizeCB();
  5029. int TimeOut();
  5030.  
  5031. XtAppContext app_con;
  5032. Widget top_level;
  5033. Widget main_window;
  5034. Widget term;
  5035. Widget menu_bar;
  5036. Widget quit_button;
  5037. Widget run_button;
  5038. Widget frame;
  5039. Widget test;
  5040. Widget scrollbar;
  5041. int pipe;
  5042.  
  5043. static char translations[] =
  5044. "\
  5045. <ButtonPress>:invokeTranslation(ButtonTranslator)\n\
  5046. <ButtonRelease>:invokeTranslation(ButtonReleaseTranslator)\n\
  5047. ";
  5048.  
  5049.  
  5050. main(argc,argv)
  5051. int argc;
  5052. char **argv;
  5053.  
  5054. {
  5055.  Arg args[100];
  5056.  int n = 0;
  5057.  struct termios buf;
  5058.  int maxline;
  5059.  int rows;
  5060.  int xterm;
  5061.  int IncX;
  5062.  int IncY;
  5063.  Dimension Height,Width;
  5064.  XtTranslations mytrans;
  5065.  
  5066.  top_level = XtAppInitialize(&app_con,"GenTerm",NULL,0,&argc,argv,NULL,0,0);
  5067.  
  5068.  if((argc > 1) && (strcmp(argv[1],"-xterm") == 0))
  5069.   xterm = 1;
  5070.  else
  5071.   xterm = 0;
  5072.  
  5073.  pipe = openwind(xterm);
  5074.  ioctl(pipe,TCGETATTR,&buf);
  5075.  buf.c_lflag &= ~ICANON;
  5076.  buf.c_cc[VMIN] = 1;
  5077.  ioctl(pipe,TCSETATTR,&buf);
  5078.  main_window = XmCreateMainWindow(top_level,"main",args,n);
  5079.  XtManageChild(main_window);
  5080.  
  5081.  menu_bar = XmCreateMenuBar(main_window,"menu",args,n);
  5082.  XtManageChild(menu_bar);
  5083.  
  5084.  n = 0;
  5085.  quit_button = XmCreateCascadeButton(menu_bar,"Quit",args,n);
  5086.  XtManageChild(quit_button);
  5087.  XtAddCallback(quit_button,XmNactivateCallback,QuitCB,NULL);
  5088.  
  5089.  n = 0;
  5090.  run_button = XmCreateCascadeButton(menu_bar,"Run",args,n);
  5091.  XtManageChild(run_button);
  5092.  XtAddCallback(run_button,XmNactivateCallback,RunCB,NULL);
  5093.  
  5094.  n = 0;
  5095.  XtSetArg(args[n],XmNorientation,XmVERTICAL); n++;
  5096.  XtSetArg(args[n],XmNwidth,13); n++;
  5097.  scrollbar = XmCreateScrollBar(main_window,"scroll",args,n);
  5098.  XtManageChild(scrollbar);
  5099.  
  5100.  XtAddCallback(scrollbar,XmNdecrementCallback,ScrollCB,NULL);
  5101.  XtAddCallback(scrollbar,XmNincrementCallback,ScrollCB,NULL);
  5102.  XtAddCallback(scrollbar,XmNpageDecrementCallback,ScrollCB,NULL);
  5103.  XtAddCallback(scrollbar,XmNpageIncrementCallback,ScrollCB,NULL);
  5104.  XtAddCallback(scrollbar,XmNtoTopCallback,ScrollCB,NULL);
  5105.  XtAddCallback(scrollbar,XmNtoBottomCallback,ScrollCB,NULL);
  5106.  XtAddCallback(scrollbar,XmNdragCallback,ScrollCB,NULL);
  5107.  
  5108.  n = 0;
  5109.  XtSetArg(args[n],XtNliteralMode,FALSE); n++;
  5110.  XtSetArg(args[n],XtNautoLineWrap,TRUE); n++;
  5111.  XtSetArg(args[n],XtNoutputFile,pipe); n++;
  5112.  XtSetArg(args[n],XtNsaveLines,48); n++;
  5113.  XtSetArg(args[n],XtNdestructiveTab,False); n++;
  5114.  XtSetArg(args[n],XtNignoreNull,True); n++;
  5115.  
  5116.  if(xterm == 1)
  5117.   {
  5118.    XtSetArg(args[n],XtNparseFile,"./xterm.par"); n++;
  5119.    XtSetArg(args[n],XtNfieldAttributes,False); n++;
  5120.    XtSetArg(args[n],XtNsaveScrollRegion,True);n++;
  5121.    XtSetArg(args[n],XtNnumberMapTables,4); n++;
  5122.    XtSetArg(args[n],XtNcursorFloats,False); n++;
  5123.    XtSetArg(args[n],XtNscrollDownClear,True); n++;
  5124.    XtSetArg(args[n],XtNscrollOnOutput,True); n++;
  5125.    XtSetArg(args[n],XtNfullScroll,False); n++;
  5126.    XtSetArg(args[n],XtNcursorKeyScrollRegion,True);n++;
  5127.    XtSetArg(args[n],XtNeolStick,True);n++;
  5128.   }
  5129.  else
  5130.   {
  5131.    XtSetArg(args[n],XtNfieldAttributes,TRUE); n++;
  5132.    XtSetArg(args[n],XtNcursorFloats,TRUE); n++;
  5133.    XtSetArg(args[n],XtNsaveScrollRegion,True); n++;
  5134.    XtSetArg(args[n],XtNpenColors,COLORS); n++;
  5135.    XtSetArg(args[n],XtNfullScroll,TRUE); n++;
  5136.   }
  5137.  term = XtCreateManagedWidget("TERM",genTermEmWidgetClass,main_window,args,n);
  5138.  XtManageChild(term);
  5139.  XtAddCallback(term,XtNkbdCallback,KeyHit,NULL);
  5140.  XtAddCallback(term,XtNtopCallback,TopCB,NULL);
  5141.  XtAddCallback(term,XtNescCallback,EscapeCB,NULL);
  5142.  XtAddCallback(term,XtNresizeCallback,ResizeCB,NULL);
  5143.  
  5144.  if(xterm == 1)
  5145.   {
  5146.    mytrans = XtParseTranslationTable(translations);
  5147.    XtAugmentTranslations(term,mytrans); 
  5148.   }
  5149.  
  5150.  n = 0;
  5151.  XtSetArg(args[n],XtNsaveLines,&maxline); n++;
  5152.  XtSetArg(args[n],XtNrows,&rows); n++;
  5153.  XtGetValues(term,args,n);
  5154.  
  5155.  n = 0;
  5156.  XtSetArg(args[n],XmNmaximum,maxline); n++;
  5157.  XtSetArg(args[n],XmNsliderSize,rows); n++;
  5158.  XtSetValues(scrollbar,args,n);
  5159.  
  5160.  XtRealizeWidget(top_level);
  5161.  
  5162.  n = 0;
  5163.  XtSetArg(args[n],XtNcharacterWidth,&IncX); n++;
  5164.  XtSetArg(args[n],XtNcharacterHeight,&IncY); n++;
  5165.  XtGetValues(term,args,n);
  5166.  
  5167.  n = 0;
  5168.  XtSetArg(args[n],XtNheight,&Height); n++;
  5169.  XtSetArg(args[n],XtNwidth,&Width); n++;
  5170.  XtGetValues(top_level,args,n);
  5171.  
  5172.  Height += IncY;
  5173.  Height = Height - Height % IncY;
  5174.  Width += IncX;
  5175.  Width = Width - Width % IncX;
  5176.  
  5177.  n = 0;
  5178.  XtSetArg(args[n],XtNwidthInc,IncX); n++;
  5179.  XtSetArg(args[n],XtNheightInc,IncY); n++;
  5180.  XtSetArg(args[n],XtNheight,Height); n++;
  5181.  XtSetArg(args[n],XtNwidth,Width); n++;
  5182.  XtSetValues(top_level,args,n);
  5183.  
  5184.  XtAppMainLoop(app_con);
  5185. }
  5186.  
  5187. openwind(which)
  5188.  
  5189. int which;
  5190.  
  5191. {
  5192.  int master;
  5193.  int slave;
  5194.  int pid;
  5195.  char string[20];
  5196.  
  5197.  if((master = open("/dev/ptyqa",O_RDWR)) < 0)
  5198.   {
  5199.    fprintf(stderr,"Can't open pty\n");
  5200.    exit(0);
  5201.   }
  5202.  slave = open("/dev/ttyqa",O_RDWR | O_NDELAY);
  5203.  if((pid = fork()) == 0)
  5204.   {
  5205.    sprintf(string,"-Sqa.%d",master);
  5206.    if(which == 0)
  5207.     execl("/usr/bin/X11/hpterm","hpterm","-sb","-title","Test Input",string,
  5208.       NULL);
  5209.    else
  5210.     {
  5211.      sprintf(string,"-Sqa%d",master);
  5212.      execl("/usr/bin/X11/xterm","xterm","-sb","-title","Test Input",string,
  5213.        NULL);
  5214.     }
  5215.   }
  5216.  return(slave);
  5217. }
  5218.  
  5219. void KeyHit(w,type,reason)
  5220.  
  5221. Widget w;
  5222. int type;
  5223. GenTermEmCallback *reason;
  5224.  
  5225. {
  5226.  GtEOutput(term,reason->string,reason->len);
  5227.  write(pipe,reason->string,reason->len);
  5228. }
  5229.  
  5230. void TopCB(w,type,reason)
  5231.  
  5232. Widget w;
  5233. int type;
  5234. GenTermCallback *reason;
  5235.  
  5236. {
  5237.  int n = 0;
  5238.  Arg args[20];
  5239.  
  5240.  XtSetArg(args[n],XmNvalue,reason->TopLine); n++;
  5241.  XtSetValues(scrollbar,args,n);
  5242. }
  5243.  
  5244. void ScrollCB(w,type,data)
  5245.  
  5246. Widget w;
  5247. int type;
  5248. XmScrollBarCallbackStruct *data;
  5249. {
  5250.  int line;
  5251.  
  5252.  line = GtGetTopOfScreen(term);
  5253.  
  5254.  switch(data->reason)
  5255.   {
  5256.  case XmCR_DECREMENT:
  5257.    line--;
  5258.    break;
  5259.  case XmCR_INCREMENT:
  5260.    line++;
  5261.    break;
  5262.  case XmCR_PAGE_DECREMENT:
  5263.    line -= 24;
  5264.    break;
  5265.  case XmCR_PAGE_INCREMENT:
  5266.    line += 24;
  5267.    break;
  5268.  case XmCR_TO_TOP:
  5269.    line = 0;
  5270.    break;
  5271.  case XmCR_TO_BOTTOM:
  5272.    line = 512;
  5273.    break;
  5274.  case XmCR_DRAG:
  5275.    line = data->value;
  5276.    break;
  5277.   }
  5278.  GtSetTopOfScreen(term,line);
  5279. }
  5280. void QuitCB()
  5281.  
  5282. {
  5283.  exit(0);
  5284. }
  5285.  
  5286. void RunCB()
  5287.  
  5288. {
  5289.  XtAppAddTimeOut(app_con,1000,TimeOut,NULL);
  5290. }
  5291.  
  5292. TimeOut()
  5293.  
  5294. {
  5295.  static char buffer[100];
  5296.  static int count = 0;
  5297.  static int fd = -1;
  5298.  
  5299.  if(fd == -1)
  5300.   {
  5301.    if((fd = open("test.input",O_RDONLY)) < 0)
  5302.     {
  5303.      fprintf(stderr,"Can't open file\n");
  5304.      exit(1);
  5305.     }
  5306.   }
  5307.  if((count = read(fd,buffer,100)) > 0)
  5308.   {
  5309.    GtEOutput(term,buffer,count);
  5310.    write(pipe,buffer,count);
  5311.    XtAppAddTimeOut(app_con,1000,TimeOut,NULL);
  5312.   }
  5313.  else
  5314.   close(fd);
  5315. /* while((count = read(fd,buffer,10)) > 0)
  5316.   {
  5317.    GtEOutput(term,buffer,count);
  5318.    write(pipe,buffer,count);
  5319.   }
  5320.  close(fd);*/
  5321.  
  5322. }
  5323.  
  5324. void EscapeCB(w,type,reason)
  5325.  
  5326. Widget w;
  5327. int type;
  5328. GenTermEmCallback *reason;
  5329.  
  5330. {
  5331.  int i = 0;
  5332.  
  5333.  fprintf(stderr,"Got an escape callback: ");
  5334.  
  5335.  while(reason->escapes[i] != NULL)
  5336.   fprintf(stderr,"%s ",reason->escapes[i++]);
  5337.  fprintf(stderr,"\n");
  5338. }
  5339.  
  5340. void ResizeCB(w,type,reason)
  5341.  
  5342. Widget w;
  5343. int type;
  5344. GenTermCallback *reason;
  5345.  
  5346. {
  5347.  int n;
  5348.  Arg args[20];
  5349.  
  5350.  n = 0;
  5351.  XtSetArg(args[n],XmNmaximum,reason->Save); n++;
  5352.  XtSetArg(args[n],XmNsliderSize,reason->Rows); n++;
  5353.  XtSetValues(scrollbar,args,n);
  5354. }
  5355. @EOF
  5356. set `wc -lwc <GenTerm/test.c`
  5357. if test $1$2$3 != 3465517316
  5358. then
  5359.     echo ERROR: wc results of GenTerm/test.c are $* should be 346 551 7316
  5360. fi
  5361.  
  5362. chmod 644 GenTerm/test.c
  5363.  
  5364. echo x - xcontrol/ParseString.c
  5365. cat >xcontrol/ParseString.c <<'@EOF'
  5366. /* ParseString.c -- This file contains the code to parse the command string */
  5367. /* History:                                 */
  5368. /*         Written by G. R. Strachan 1992 */
  5369.  
  5370. /*  Copyright Gordon R. Strachan 1992 */
  5371. /*  This code is provided as is, neither the University of Waterloo nor */
  5372. /*  the author is liable for any damage caused by the use or misuse of this */
  5373. /*  code.  */
  5374.  
  5375. /* Permission is granted to copy, use and modify this code provided it is */
  5376. /* not sold for profit and the above copyright remains intact. */
  5377.  
  5378. #include <stdio.h>
  5379. #include <signal.h>
  5380. #include <X11/X.h>
  5381. #include <X11/Intrinsic.h>
  5382. #include "XControl.h"
  5383.  
  5384. struct CommandList *BuildFunction();
  5385. extern char *LoadString();
  5386.  
  5387. struct CommandList *ParseString(XControl,string)
  5388.  
  5389. struct XControl *XControl;
  5390. char *string;
  5391.  
  5392. {
  5393.  struct CommandList *temp;
  5394.  struct CommandList *List = NULL;
  5395.  struct CommandList *new;
  5396.  int i = 0;
  5397.  char buffer[1024];
  5398.  int k;
  5399.  int len;
  5400.  
  5401.  while(string[i] != NULL)
  5402.   {
  5403.    k = 0;
  5404.    while((string[i] != NULL) && ((buffer[k++] = string[i++]) != '('));
  5405.    if(string[i] == NULL)
  5406.     Error(XControl,"Invalid command string\n");
  5407.    buffer[--k] = 0;
  5408.    
  5409.    k = 0;
  5410.    len = strlen(buffer);
  5411.    while(XControl->Functions[k].Name != NULL)
  5412.     {
  5413.      if(strncmp(XControl->Functions[k].Name,buffer,len) == 0)
  5414.       break;
  5415.      k++;
  5416.     }
  5417.    if(XControl->Functions[k].Name == NULL)
  5418.     Error(XControl,"Invalid function name found in command string\n");
  5419.    new = BuildFunction(XControl);
  5420.    new->Command = XControl->Functions[k].Function;
  5421.    ParseFunctionArguments(XControl,new,string,&i,XControl->Functions[k].Name);
  5422.    if(List == NULL)
  5423.     {
  5424.      List = new;
  5425.      temp = new;
  5426.     }
  5427.    else
  5428.     {
  5429.      temp->Next = new;
  5430.      temp = new;
  5431.     }
  5432.    if((string[i] != NULL) && (string[i] != ';'))
  5433.     Error(XControl,"Expect ; in command string\n");
  5434.    else
  5435.     if(string[i] != NULL)
  5436.      i++;
  5437.   }
  5438.  return(List);
  5439. }
  5440.  
  5441. ParseFunctionArguments(XControl,temp,string,start,name)
  5442.  
  5443. struct XControl *XControl;
  5444. struct CommandList *temp;
  5445. char *string;
  5446. int *start;
  5447. char *name;
  5448.  
  5449. {
  5450.  int i = *start;
  5451.  int k;
  5452.  int type;
  5453.  char buffer[1024];
  5454.  char delim;
  5455.  
  5456.  while((string[i] != ')') && (string[i] != NULL))
  5457.   {
  5458.    while((string[i] == ' ') && (string[i] != NULL))
  5459.     i++;
  5460.    k = 0;
  5461.    switch(string[i])
  5462.     {
  5463.    case '"':                  /* start of a string */
  5464.    case '\'':
  5465.      delim = string[i];
  5466.      type = STRINGARG;
  5467.      while(string[++i] != delim)
  5468.       {
  5469.        switch(string[i])
  5470.     {
  5471.        case '\\':
  5472.      buffer[k++] = string[++i];
  5473.      break;
  5474.        case '^':
  5475.      buffer[k++] = string[++i] &077;
  5476.      break;
  5477.        default:
  5478.      buffer[k++] = string[i];
  5479.     }
  5480.       }
  5481.      i++;
  5482.      break;
  5483.    case '$':
  5484.      type = POSITIONARG;
  5485.      while((isdigit(string[++i])) && (string[i] != NULL))
  5486.       buffer[k++] = string[i];
  5487.      break;
  5488.    default:
  5489.      type = INTEGERARG;
  5490.      while((isdigit(string[i])) && (string[i] != NULL))
  5491.       buffer[k++] = string[i++];
  5492.     }
  5493.    temp->NumberArguments++;
  5494.    temp->Args = (struct Argument *) XtRealloc(temp->Args,
  5495.                           temp->NumberArguments * 
  5496.                           sizeof(struct Argument));
  5497.    buffer[k] = NULL;
  5498.    k = temp->NumberArguments - 1;
  5499.    temp->Args[k].Type = type;
  5500.    if(type == STRINGARG)
  5501.     {
  5502.      temp->Args[k].String = (char *) XtMalloc(sizeof(char) * 
  5503.                           (strlen(buffer) + 1));
  5504.      strcpy(temp->Args[k].String,buffer);
  5505.      temp->Args[k].Value = 0;
  5506.     }
  5507.    else
  5508.     {
  5509.      temp->Args[k].Value = atoi(buffer);
  5510.      temp->Args[k].String = NULL;
  5511.     }
  5512.  
  5513.    while((string[i] != ',') && (string[i] != ')'))
  5514.     {
  5515.      if(string[i] != ' ')
  5516.       Error(XControl,"Bad argument found in command %s\n",name);
  5517.      i++;
  5518.     }
  5519.    if(string[i] == ',')
  5520.     i++;
  5521.   }
  5522.  if(string[i] != NULL)
  5523.   i++;
  5524.  *start = i;
  5525. }
  5526.  
  5527. struct CommandList *BuildFunction(XControl)
  5528.  
  5529. struct XControl *XControl;
  5530.  
  5531. {
  5532.  struct CommandList *new;
  5533.  
  5534.  new = (struct CommandList *)XtMalloc(sizeof(struct CommandList));
  5535.  
  5536.  new->Command = NULL;
  5537.  new->Args = NULL;
  5538.  new->NumberArguments = 0;
  5539.  new->Next = NULL;
  5540. }
  5541.  
  5542. DestroyCommandList(XControl,Commands)
  5543.  
  5544. struct XControl *XControl;
  5545. struct CommandList *Commands;
  5546.  
  5547. {
  5548.  struct CommandList *temp;
  5549.  int i;
  5550.  
  5551.  while(Commands != NULL)
  5552.   {
  5553.    for(i = 0; i < Commands->NumberArguments; i++)
  5554.     XtFree(Commands->Args[i].String);
  5555.    XtFree(Commands->Args);
  5556.    temp = Commands->Next;
  5557.    XtFree(Commands);
  5558.    Commands = temp;
  5559.   }
  5560. }
  5561.  
  5562. /* DumpCommandList:  This function writes the command list into a given file */
  5563. /*  in an internal format which is easy to read back in. */
  5564.  
  5565. DumpCommandList(XControl,Commands,File)
  5566.  
  5567. struct XControl *XControl;
  5568. struct CommandList *Commands;
  5569. FILE *File;
  5570.  
  5571. {
  5572.  int i;
  5573.  
  5574.  while(Commands != NULL)
  5575.   {
  5576.    i = 0;
  5577.    while(XControl->Functions[i].Name != NULL)
  5578.     {
  5579.      if(XControl->Functions[i].Function == Commands->Command)
  5580.       break;
  5581.      i++;
  5582.     }
  5583.    if(XControl->Functions[i].Name == NULL)
  5584.     Error(XControl,"Bad Command list given to DumpCommandList!");
  5585.    fprintf(File,"%d\n$%s\n",strlen(XControl->Functions[i].Name),
  5586.        XControl->Functions[i].Name);
  5587.    fprintf(File,"%d\n",Commands->NumberArguments);
  5588.    for(i = 0; i < Commands->NumberArguments; i++)
  5589.     {
  5590.      if(Commands->Args[i].Type == STRINGARG)
  5591.       fprintf(File,"%d %d\n%d\n$%s\n",Commands->Args[i].Type,
  5592.           Commands->Args[i].Value,strlen(Commands->Args[i].String),
  5593.           Commands->Args[i].String);
  5594.      else
  5595.       fprintf(File,"%d %d\n",Commands->Args[i].Type,Commands->Args[i].Value);
  5596.     }
  5597.    Commands = Commands->Next;
  5598.   }
  5599.  fprintf(File,"%d\n",-1);
  5600. }
  5601.  
  5602. /* LoadCommandList:  This function loads a command list from its internal */
  5603. /*  representation.  It is used to recover a command list from a session */
  5604. /*  file. */
  5605.  
  5606. struct CommandList *LoadCommandList(XControl,File)
  5607.  
  5608. struct XControl *XControl;
  5609. FILE *File;
  5610.  
  5611. {
  5612.  struct CommandList *Commands = NULL;
  5613.  struct CommandList *temp;
  5614.  struct CommandList *List;
  5615.  char *string;
  5616.  int i;
  5617.  
  5618.  while((string = LoadString(XControl,File)) != NULL)
  5619.   {
  5620.    i = 0;
  5621.    while(XControl->Functions[i].Name != NULL)
  5622.     {
  5623.      if(strcmp(string,XControl->Functions[i].Name) == 0)
  5624.       break;
  5625.      i++;
  5626.     }
  5627.    if(XControl->Functions[i].Name == NULL)
  5628.     Error(XControl,"Bad command name in session file %s\n",string);
  5629.    temp = BuildFunction(XControl);
  5630.    temp->Command = XControl->Functions[i].Function;
  5631.    if(Commands == NULL)
  5632.     Commands = List = temp;
  5633.    else
  5634.     {
  5635.      List->Next = temp;
  5636.      List = temp;
  5637.     }
  5638.    if(fscanf(File,"%d\n",&temp->NumberArguments) != 1)
  5639.     Error(XControl,"Can't get number of arguments in session file!\n");
  5640.    if(temp->NumberArguments > 0)
  5641.     {
  5642.      temp->Args = (struct Argument *) XtMalloc(sizeof(struct Argument) *
  5643.                            temp->NumberArguments);
  5644.      for(i = 0; i < temp->NumberArguments; i++)
  5645.       {
  5646.        if(fscanf(File,"%d%d\n",&(temp->Args[i].Type),&(temp->Args[i].Value))
  5647.       != 2)
  5648.     Error(File,"Can't read argument in session file\n");
  5649.        if(temp->Args[i].Type == STRINGARG)
  5650.     temp->Args[i].String = LoadString(XControl,File);
  5651.        else
  5652.     temp->Args[i].String = NULL;
  5653.       }
  5654.     }
  5655.    XtFree(string);
  5656.   }
  5657.  return(Commands);
  5658. }
  5659. @EOF
  5660. set `wc -lwc <xcontrol/ParseString.c`
  5661. if test $1$2$3 != 2937556995
  5662. then
  5663.     echo ERROR: wc results of xcontrol/ParseString.c are $* should be 293 755 6995
  5664. fi
  5665.  
  5666. chmod 644 xcontrol/ParseString.c
  5667.  
  5668. echo x - xcontrol/TAGS '[non-ascii]'
  5669. $unpacker <<'@eof'
  5670. begin 644 xcontrol/TAGS
  5671. M# I80V]N=')O;"YC+#8R-PIV;VED($%C=&EO;D-"*'\W-S4L,C$W.3D*8VAAX
  5672. M<B J*D)U:6QD07)G3&ES="A_-#,S+#$S-34U"EAT4&]I;G1E<B!"=6EL9$-AX
  5673. M;&Q3=')U8W0H?S,W,RPQ,C P-@I"=6EL9$-H:6QD0V]M;6%N9"A_,SDW+#$RX
  5674. M-34S"G9O:60@0V]M;6%N9$-"*'\W,S L,C W,C$*0V]M;6%N9$QI<W1#;VYVX
  5675. M97)T97(H?S4W-BPQ-CDS-0IV;VED($1R;W!#0BA_.3$Q+#(V,# S"D5R<F]RX
  5676. M*'\S,S@L,3$T,#4*=F]I9"!+97E#0BA_-S$W+#(P-#(U"DQA=6YC:$-H:6QDX
  5677. M*'\V-S L,3DT,#@*3&]A9%-E<W-I;VXH?S@Q,BPR,C4U.0IC:&%R("I,;V%DX
  5678. M4W1R:6YG*'\X-SDL,C4R-S$*=F]I9"!0;W!$;W=N0T(H?S<Y.2PR,C(Y-PIVX
  5679. M;VED(%!T>4-"*'\V,#(L,3<U.#@*=F]I9"!297%U97-T0T(H?SDW-RPR-S,VX
  5680. M, IV;VED(%)E<VEZ94-"*'\Y-C<L,C<R,SD*4V5T1')A9U=I;F1O=RA_-C(XX
  5681. M+#$X,#DQ"E-E=%5P4VEG;F%L<RA_-#DU+#$T.34Q"B-D969I;F4@4VEG4F5SX
  5682. M;W5R8V4H?S,Q+#DW- IV;VED(%-I9VYA;$-"*'\U-#<L,38R-S@*=F]I9"!3X
  5683. M:6=N86Q(86YD;&5R*'\U,S0L,34Y-#8*=F]I9"!4:6UE3W5T0T(H?S<V,2PRX
  5684. M,30W, I787)N:6YG*'\S-34L,3$V-#(*6%=A<FYI;F<H?SDU,2PR-CDV, IMX
  5685. M86EN*'\R,#,L-S W, H,"E!A<G-E4W1R:6YG+F,L,C$W"G-T<G5C="!#;VUMX
  5686. M86YD3&ES=" J0G5I;&1&=6YC=&EO;BA_,38R+#,W,# *1&5S=')O>4-O;6UAX
  5687. M;F1,:7-T*'\Q-S<L,SDV, I$=6UP0V]M;6%N9$QI<W0H?S(P,"PT-#4T"G-TX
  5688. M<G5C="!#;VUM86YD3&ES=" J3&]A9$-O;6UA;F1,:7-T*'\R-#$L-38P,PI0X
  5689. M87)S949U;F-T:6]N07)G=6UE;G1S*'\W-BPQ.#@Y"G-T<G5C="!#;VUM86YDX
  5690. M3&ES=" J4&%R<V53=')I;F<H?S(R+#8Y.0H,"D-O;6UA;F0N8RPX-30*06)OX
  5691. M<G1#;VUM86YD*'\T,S<L,3$P-S(*07)G5&]);G0H?S4T+#$S.3(*07)G5&]3X
  5692. M=')I;F<H?S@Y+#(P-S,*17AE8W5T94-O;6UA;F1,:7-T*'\R.2PX.3<*1V5TX
  5693. M0VAI;&10:61#;VUM86YD*'\U-C@L,30T,S(*1V5T1')O<$1I<F5C=&]R>4-OX
  5694. M;6UA;F0H?S@U,BPR,3@Q, I'971$<F]P1FEL94-O;6UA;F0H?S@W,RPR,C,TX
  5695. M-0I'971$<F]P2&]S=$-O;6UA;F0H?S@Q-"PR,#<V,PI'971$<F]P3G5M8F5RX
  5696. M0V]M;6%N9"A_-SDU+#(P,C,T"D=E=$1R;W!4>7!E0V]M;6%N9"A_.#,R+#(QX
  5697. M,C$V"D=E=$5N=D-O;6UA;F0H?S0U,BPQ,30S- I'971);G0H?S$Y,RPT-#$QX
  5698. M"D=E=%!I9$-O;6UA;F0H?S4X-BPQ-#@R,0I'9713=')I;F<H?S(P."PT-S$XX
  5699. M"D=E=%1E<FUI;F%L5'EP94-O;6UA;F0H?S@Y-"PR,CDQ, I'9717:6YD;W=3X
  5700. M:7IE0V]M;6%N9"A_.3$R+#(S,S8R"DEF0V]M;6%N9"A_-3 W+#$R.#,V"DUAX
  5701. M=&A#;VUM86YD*'\V,#4L,34S,C(*4')O;7!T0V]M;6%N9"A_,S$S+#<R,#D*X
  5702. M475I=$-O;6UA;F0H?S(U,2PU-C,S"FEN="!296%P0V]M;6%N9"A_,C(V+#4QX
  5703. M-38*4F5M;W9E5&EM94]U=$-O;6UA;F0H?S0P,RPQ,#,W-@I3879E4V5S<VEOX
  5704. M;D-O;6UA;F0H?S<P,BPQ-S(X-PI3971%;G9#;VUM86YD*'\T-S<L,3(P-#@*X
  5705. M4VEG;F%L0V]M;6%N9"A_,C@W+#8S,3@*4VQE97!#;VUM86YD*'\T,C L,3 WX
  5706. M-S(*4W1O<F5);G0H?S$R.2PR.#$Y"E-T;W)E4W1R:6YG*'\Q-C(L,S8S.0I3X
  5707. M=&]R95-T<FEN9T-O;6UA;F0H?S8U-"PQ-C(P. I3=')I;F=#871#;VUM86YDX
  5708. M*'\V-S8L,38V.#8*5&EM94]U=$-O;6UA;F0H?S,W-2PY-#DQ"E=A<FYI;F=#X
  5709. I;VUM86YD*'\W-S0L,3DW,C8*5W)I=&5#;VUM86YD*'\R-C8L-3@Y. II    X
  5710.                                                              X
  5711. end
  5712. @eof
  5713. set `wc -lwc <xcontrol/TAGS`
  5714. if test $1$2$3 != 70891751
  5715. then
  5716.     echo ERROR: wc results of xcontrol/TAGS are $* should be 70 89 1751
  5717. fi
  5718.  
  5719. chmod 644 xcontrol/TAGS
  5720.  
  5721. echo x - xcontrol/XControl.ad
  5722. cat >xcontrol/XControl.ad <<'@EOF'
  5723. *Pty*literalMode:    False
  5724. *Pty*autoLineWrap:    True
  5725. *Pty*saveLines:        48
  5726. *Pty*destructiveTab:    False
  5727. *Pty*ttyMode:        rows 24 columns 80 \
  5728. 9600 susp ^z dsusp ^z intr ^c quit ^\\ erase ^H kill ^u swtch ^@ eof ^d \
  5729. eol ^@ stop ^s start ^q -parenb -parodd cs8 -cstopb hupcl cread -clocal \
  5730. -loblk -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr \
  5731. icrnl -iuclc ixon -ixany ixoff -ienqak isig icanon iexten -xcase echo echoe \
  5732. echok -echonl -noflsh opost -olcuc onlcr -ocrnl -onocr -onlret -ofill \
  5733. -ofdel -tostop tab3
  5734. *Pty*ignoreNull:    True
  5735. *hpterm*parseFile:    PARSEDIR/hpterm.par
  5736. *hpterm*fieldAttributes: True
  5737. *hpterm*saveScrollRegion:    True
  5738. *hpterm*penColors:    Default:Default:red:Default:green:Default:yellow:\
  5739. Default:blue:Default:magenta:Default:cyan:Default:black:yellow"
  5740. *xterm*parseFile:    PARSEDIR/xterm.par
  5741. *xterm*fieldAttributes:    False
  5742. *xterm*saveScrollRegion:    True
  5743. *xterm*scrollOnOutput:    True
  5744. *xterm*numberMapTables:    4
  5745. *xterm*cursorFloats:    False
  5746. *xterm*scrollDownClear:    True
  5747. *xterm*fullScroll:    False
  5748. *xterm*cursorKeyScrollRegion:    True
  5749. *xterm*eolStick:    True
  5750. *xterm*translations:    #override\n\
  5751. <ButtonPress>:invokeTranslation(ButtonTranslator)\n\
  5752. <ButtonRelease>:invokeTranslation(ButtonReleaseTranslator)\n
  5753. !
  5754. *closeWindowCommands:    Signal(9);Quit(0);
  5755. *remoteDropsAllowed:    True
  5756. *dropCommands:        GetDropNumber(1,2);GetDropHost(3);GetDropDirectory(4);\
  5757. GetDropType(1,5);GetDropFile(1,6);\
  5758. Write("T=",$1," F=",$2," Host ",$3," Dir ",$4," Type ",$5," Name ",$6);
  5759. *dropZoneType:        FileEdit
  5760. *sigChildCommands:    Reap(1);GetChildPid(2);If($1,"==",$2,"Quit(0)",\
  5761. "Abort()")
  5762. *childForkCommands:    GetTerminalType(2);SetEnv("TERM",$2);
  5763. *saveSessionCommands:    SaveSession();
  5764. *startupCommands:    GetWindowSize(1,2);SetEnv("LINES",$1);\
  5765. SetEnv("COLUMNS",$2);
  5766. @EOF
  5767. set `wc -lwc <xcontrol/XControl.ad`
  5768. if test $1$2$3 != 431481740
  5769. then
  5770.     echo ERROR: wc results of xcontrol/XControl.ad are $* should be 43 148 1740
  5771. fi
  5772.  
  5773. chmod 644 xcontrol/XControl.ad
  5774.  
  5775. rm -f /tmp/unpack$$
  5776. exit 0
  5777.