home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / sys / hp / 15254 < prev    next >
Encoding:
Text File  |  1993-01-24  |  149.4 KB  |  4,310 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 2/4
  5. Message-ID: <C1CAM2.FKH@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:14 GMT
  10. Lines: 4298
  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:42 1993
  17. #
  18. # This archive contains:
  19. #    GenTerm/GenTerm.man    GenTerm/GenTermEm.c    
  20. #    GenTerm/GenTermEm.man    GenTerm/LoadParser.c    
  21. #    GenTerm/Makefile    GenTerm/Parser.h    
  22. #    GenTerm/Pty.h        GenTerm/PtyP.h        
  23. #    GenTerm/Xmu.h        xcontrol/Makefile    
  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/GenTerm.man
  31. sed 's/^@//' >GenTerm/GenTerm.man <<'@EOF'
  32. @.\" Man page for the GenTerm Widget -*-nroff-*-
  33. @.\"
  34. @.\"  Written by G. Strachan 1992
  35. @.\"
  36. @.de KS  \"      Keep start
  37. @.br
  38. @.in 0
  39. @.di KP
  40. @..
  41. @.de KE  \"      Keep end
  42. @.br
  43. @.di
  44. @.ne \\n(dnu
  45. @.nr fI \\n(.u
  46. @.nf
  47. @.KP
  48. @.if \\n(fI .fi
  49. @.in
  50. @..
  51. @.TH GenTerm 3X
  52. @.SH NAME
  53. \fBGenTerm \- The Generalized terminal widget class.\fP
  54. @.sp 1
  55. @.SH SYNOPSIS
  56. \fB#include "/usr/local/include/GenTerm.h"\fP
  57. @.SH DESCRIPTION
  58. The \fBGenTerm\fP widget is a general terminal widget.  It does not
  59. emulate any specific terminal but rather implements a set of support
  60. functions that any terminal would require.  Widgets emulating specific
  61. terminals can then be built on top of this.
  62. @.PP
  63. The \fBGenTerm\fP widget
  64. presents a window into which text can be written and manipulated.  The
  65. widget supports two simultaneous fonts, but both must be the same size
  66. and fixed space.  The text can be written in a number of different
  67. colours.  In addition, the widget implements an off screen memory to
  68. store text which has scrolled off the visible screen.  Finally, the
  69. widget implements a number of functions for manipulating the text and
  70. for moving the visible screen around the scroll memory.
  71. @.SH CLASSES
  72. GenTerm inherits behavior and resources from \fBCore\fP and
  73. \fBComposite\fP classes.
  74. @.PP
  75. The class pointer is \fBgenTermWidgetClass\fP
  76. @.PP
  77. The class name is \fBGenTerm\fP
  78. @.SH "NEW RESOURCES"
  79. The following table lists the resources recognized by the
  80. \fBGenTerm\fP widget.  The programmer can also set the resources of
  81. the inherited classes.  To set these resources in the resource database
  82. remove the \fBXtN\fP and \fBXtC\fP portions of the resource name.
  83. @.sp 1
  84. @.KS
  85. @.sp 1
  86. @.TS
  87. center;
  88. cB sss
  89. lB lB lB lB
  90. llll.
  91. GenTerm Resource Set
  92. Name    Class    Type    Default
  93. _
  94. XtNalternateFont    XtCAlternateFont    String    7x13bold
  95. XtNautoLineWrap    XtCAutoLineWrap    Boolean    False
  96. XtNbackground    XtCBackground    Pixel    DefaultBackground
  97. XtNbaseFont    XtCBaseFont    String    7x13
  98. XtNblinkRate    XtCBlinkRate    Int    500
  99. XtNbottomMargin    XtCBottomMargin    Dimension    0
  100. XtNcharacterHeight    XtCCharacterHeight    Int    13
  101. XtNcharacterWidgth    XtCCharacterWidth    Int    7
  102. XtNcolumns    XtCColumns    Int    80
  103. XtNcursorColor    XtCCursorColor    Pixel    orange
  104. XtNcursorFloats    XtCCursorFloats    Boolean    True
  105. XtNcursorKeyScrollRegion    XtCCursorKeyScrollRegion    Boolean    False
  106. XtNdefineColor    XtCDefineColor    Int    GTRGB
  107. XtNeolStick    XtCEolStick    Boolean    False
  108. XtNfieldAttributes    XtCFieldAttributes    Boolean    True
  109. XtNforeground    XtCForeground    Pixel    DefaultForeground
  110. XtNfullScroll    XtCFullScroll    Boolean    False
  111. XtNignoreNull    XtCIgnoreNull    Boolean    False
  112. XtNinsertMode    XtCInsertMode    Boolean    False
  113. XtNkbdCallback    XtCKbdCallback    Callback    Null
  114. XtNliteralMode    XtCLiteralMode    Boolean    False
  115. XtNlockCallback    XtCLockCallback    Callback    Null
  116. XtNlockScreen    XtCLockScreen    Boolean    False
  117. XtNmargin    XtCMargin    Int    8
  118. XtNmarginBell    XtCMarginBell    Boolean    False
  119. XtNnumberColors    XtCNumberColors    Int    8
  120. XtNpenColors    XtCPenColors    String    Default:Default
  121. XtNresizeCallback    XtCResizeCallback    Callback    Null
  122. XtNrows    XtCRows    Int    24
  123. XtNsaveLines    XtCSaveLines    Int    512
  124. XtNsaveScrollRegion    XtCSaveScrollRegion    Boolean    False
  125. XtNscrollDownClear    XtCScrollDownClear    Boolean    False
  126. XtNscrollOnOutput    XtCScrollOnOutput    Boolean    False
  127. XtNshowCursor    XtCShowCursor    Boolean    True
  128. XtNtopCallback    XtCTopCallback    Callback    Null
  129. @.TE
  130. @.KE
  131. @.sp 1
  132. @.IP "\fBXtNalternateFont\fP"
  133. This resource specifies the name of the font to use when the alternate
  134. font attribute is in effect.  This is typically used to set a bold
  135. font.  The alternate font must be fixed space and have the same size
  136. as the \fBXtNbaseFont\fP resource.
  137. @.IP "\fBXtNautoLineWrap\fP"
  138. This resource controls the behavior of the cursor when it reaches the
  139. end of the line.  If the resource is \fBTrue\fP then the cursor will
  140. move automatically to the beginning of the next line, forcing a scroll
  141. if necessary.  If the resource is \fBFalse\fP then the cursor will
  142. remain at the end of the line and any new text sent to the widget will
  143. be truncated.
  144. @.IP "\fBXtNbackground\fP"
  145. This resource specifies the background colour to use in the window.
  146. It also specifies the colour to use for a pen whose background colour
  147. was given as \fBDefault\fP.
  148. @.IP "\fBXtNbaseFont\fP"
  149. This resource specifies the name of the font that is normally used.
  150. It must be a fixed space font and have the same size as the
  151. \fBXtNalternateFont\fP resource setting.
  152. @.IP "\fBXtNblinkRate\fP"
  153. This resource specifies the rate at which text which has the blink
  154. attribute set is flashed on the screen.  The time is specified in
  155. milliseconds.
  156. @.IP "\fBXtNbottomMargin\fP"
  157. This resource  specifies the amount of space that is left at the
  158. bottom of the window.  It is typically used to reserve space for
  159. function keys or other visual effects such as a status line.
  160. @.IP "\fBXtNcharacterHeight\fP"
  161. This is a read only resource which returns the height of the currently
  162. used font in pixels.  Any attempt to set this resource will have no
  163. effect.
  164. @.IP "\fBXtNcharacterWidth\fP"
  165. This is a read only resource which returns the width of the currently
  166. used font in pixels.  Any attempt to set this resource will have no
  167. effect.
  168. @.IP "\fBXtNcolumns\fP"
  169. This resource specifies the number of columns to show on the visible
  170. screen.  The window width will be adjust accordingly.
  171. @.IP "\fBXtNcursorColor\fP"
  172. This resource specifies the colour to use for the cursor.
  173. @.IP "\fBXtNcursorFloats\fP"
  174. This resource specifies the behavior of the cursor when the screen is
  175. scrolled.  If the resource is \fBTrue\fP then the cursor floats with
  176. respect to the text.  That is to say, the position of the cursor
  177. relative to the top of the screen remains fixed when a scroll takes
  178. place but the text moves.  With the resource set to \fBTrue\fP the
  179. cursor can not be scrolled off the screen.  If the resource is set to
  180. \fBFalse\fP then the cursor maintains its position relative to the
  181. text.  When a scroll takes place, the cursor position, relative to the
  182. top of the window changes.  With the resource set to \fBFalse\fP, the
  183. cursor can be scrolled off of the visible screen.
  184. @.IP "\fBXtNcursorKeyScrollRegion\fP"
  185. This resource defines the behavior of the cursor keys when a scroll
  186. region is encountered.  If the resource is \fBFalse\fP, then the
  187. cursor keys ignore the scroll region and the cursor can be moved about
  188. as if the scroll region was not defined.  If the resource if
  189. \fBTrue\fP then the cursor keys are sensitive to the scroll region.
  190. In this case, when the cursor encounters the boundary of a scroll
  191. region it behaves as it would if it encountered the boundary of the
  192. physical screen.  It may stick at the edge of the scroll region, wrap
  193. around to the other side or force a scroll depending on the desired
  194. behavior.
  195. @.IP "\fBXtNdefineColor\fB"
  196. This resource specifies how colours are defined through the
  197. \fIGtDefinePenColour\fP function.  If the resource is set to
  198. \fIGTRGB\fP then colour is specified through its red green blue
  199. triplet.  If the resource is set to \fIGTHSL\fP then the colour is
  200. defined by it hue saturation and luminance triplet.
  201. @.IP "\fBXtNeolStick\fB"
  202. This resource specifies the behavior of the cursor when it is put on
  203. the last column.  If it is \fBFalse\fP then the cursor will be brought
  204. to the next line.  If it is \fBTrue\fP then the cursor will stick at
  205. the end of the line until the next character is written.  The cursor
  206. will then move to the next line prior to printing the character.
  207. @.IP "\fBXtNfieldAttributes\fP"
  208. This resource specifies how attributes are associated with characters.
  209. Attributes are modes which affect the way text is displayed such as
  210. embolding, underlining or highlighting.  The widget supports two
  211. attribute modes: normal and field mode.  In normal mode, the character
  212. inherits the attribute that is in effect at the time it is written.
  213. In field attribute, the attributes are written into a section of the
  214. screen.  This is referred to as a field.  The character inherits its
  215. attribute from the field into which it is written.  If the resource is
  216. set to \fBTrue\fP, the field mode is in effect.  Otherwise, the normal
  217. attribute mode is used.
  218. @.IP "\fBXtNforeground\fP"
  219. This resource specifies the colour to use when drawing text with a pen
  220. colour whose foreground is given as \fIDefault\fP.
  221. @.IP "\fBXtNfullScroll\fP"
  222. This resource defines the behavior of the scrolling with in the saved
  223. screen.  If the resource is \fBTrue\fP then the visible screen can be
  224. scrolled through the entire saved screen buffer.  If the resource is
  225. \fBFalse\fP then the visible screen can only be scrolled through the
  226. portion of the saved screen which has saved text.  Areas which have
  227. not yet been accessed will be inaccessible.
  228. @.IP "\fBXtNignoreNull\fP"
  229. This resource defines the behavior of the widget when it is sent a
  230. null character.  If the resource is set to \fBTrue\fP, then the
  231. character is discarded.  If the resource is set to \fBFalse\fP then
  232. the character is translated through the current mapping table and
  233. printed (usually as a space).
  234. @.IP "\fBXtNinsertMode\fP"
  235. This resource controls how new text is placed on the screen.  If the
  236. resource is set to \fBFalse\fP then any text currently on the screen
  237. will be overwritten by the new text if they occupy the same screen
  238. location.  If the resource is set to \fBTrue\fP then the text that
  239. would have over written is pushed behind the inserted text.  The
  240. behavior of the moved text when it encounters the end of the line is
  241. controlled by the \fBXtNautoLineWrap\fP resource.
  242. @.IP "\fBXtNkbdCallback\fP"
  243. This resource specifies the list of callback function to call when
  244. ever a key press is encountered or an insert action takes place.  The
  245. reason will be set to \fBGT_INPUT\fP if a key press event happened or
  246. \fBGT_PASTE\fP if an insert action occurred.
  247. @.IP "\fBXtNliteralMode\fP"
  248. This resource controls the displaying to non displayable characters.
  249. If the resource is \fBFalse\fP then all non displayable characters are
  250. processed through the normal mapping table and printed.  If the
  251. resource is \fBTrue\fP then non displayable characters are displayed
  252. as a \fI^C\fP sequence.
  253. @.IP "\fBXtNlockCallback\fP"
  254. This resource specifies the list of callback functions to call when
  255. the lock state of the widget changes.  The lock state changes when
  256. either the resource \fBXtNlockScreen\fP is changed or the widget needs
  257. to freeze the screen pending some internal events.  An example is
  258. selecting text with the mouse.  The callback is called with a reason
  259. of \fBGT_LOCK\fP.
  260. @.IP "\fBXtNlockScreen\fP"
  261. This resource defines whether the screen is locked or not.  Usually
  262. this resource is controlled by the widget itself but it may also be
  263. set by external applications.  If the resource is \fBTrue\fP, then the
  264. widget will refuse to perform any action that will alter the
  265. appearance of the text on the screen.  When the lock state changes,
  266. the widget will invoke the \fBXtNlockCallback\fP call backs.  Note
  267. that the widget may alter the value of this resource at any time.
  268. @.IP "\fBXtNmargin\fP"
  269. This resource defines the size of the righthand margin.  When the cursor
  270. crosses into the righthand margin then the margin bell will sound
  271. providing the \fBXtNmarginBell\fP resource is set.
  272. @.IP "\fBXtNmarginBell\fP"
  273. This resource specifies whether the widget should sound the margin
  274. bell when the cursor enters the righthand margin.  If the resource is
  275. set to \fBTrue\fP then the bell will sound, otherwise it will not.
  276. @.IP "\fBXtNnumberColors\fP"
  277. This resource defines how many unique pens can be defined.  A pen is
  278. a foreground and background colour combination and is part of the text
  279. attribute.
  280. @.IP "\fBXtNpenColors\fP"
  281. This resource defines the colours of the pens.  The format is a colon
  282. separated list of valid colour names or the keyword \fIDefault\fP.  If
  283. the colour is specified as \fIDefault\fP then either the widget's
  284. current foreground or background colour will be substituted as
  285. appropriate.  For each pen, two colours must be specified, the
  286. foreground followed by the background.  Therefore the pen colour list
  287. should contain 2 * n colours where n is the value of the
  288. \fBXtNnumberColors\fP resource.  If not enough colours are specified
  289. then the remaining pens will use the default colours.
  290. @.IP "\fBXtNresizeCallback\fP"
  291. This resource specifies the list of callback functions to call when
  292. ever the widget resizes itself.  The reason for the callback will be
  293. set to \fIGT_RESIZE\fP.
  294. @.IP "\fBXtNrows\fP"
  295. This resource specifies the number of rows of text to be shown in the
  296. window.  The widget will be sized accordingly.
  297. @.IP "\fBXtNsaveLines\fP"
  298. This resources defines how many rows of text are to be stored in the
  299. off screen memory.  This area is for saving text so that it can be
  300. scrolled back onto the screen.  The value of this resource must be at
  301. least as big as the value of \fBXtNrows\fP.
  302. @.IP "\fBXtNsaveScrollRegion\fP"
  303. This resource specifies the behavior of the widget when scrolling
  304. takes place inside of a scroll region.  If it is set to \fBTrue\fP
  305. then text that is scrolled out of the scroll region is stored in the
  306. off screen memory.  If the value is \fBFalse\fP then the text is
  307. discarded.  Note that text will be saved in the proper order but that
  308. this order will no longer make sense once the scroll region is removed
  309. or changed.
  310. @.IP "\fBXtNscrollDownClear\fP"
  311. This resource defines the behavior of the widget when is scrolls down
  312. one line as the result of new text (as opposed to cursor movement or
  313. changing the top of screen).  If the resource is \fBTrue\fP then the
  314. new line will be cleared prior to being brought into the visible
  315. screen.  If it is \fBFalse\fP then any text on the new line remains in
  316. it when the text is brought onto the screen.
  317. @.IP "\fBXtNscrollOnOutput\fP"
  318. This resource controls the behavior of the widget when new text is
  319. output to the screen.  If the resource is set to \fBTrue\fP and the
  320. last line of text is currently not on the visible screen, then the
  321. widget forces a scroll until the last line becomes visible.  The text
  322. is then placed at the current cursor position.  If the resource is
  323. \fBFalse\fP, then the text is simply placed at the current cursor
  324. position.
  325. @.IP "\fBXtNtopCallback\fP"
  326. This resource specifies the list of callback functions to call when
  327. ever the widget changes the position of the top line of the visible
  328. screen in relation to the saved screen.  This typically takes place
  329. when a scroll occurs.  In the callback the reason will be set to
  330. \fIGT_TOP\fP.
  331. @.sp 1
  332. @.SH "CALLBACK INFORMATION"
  333. A pointer to the following structure is passed to each callback:
  334. @.sp .5
  335. @.nf
  336. @.ta .25i 1.1i
  337. \fBtypedef struct\fP
  338. {
  339.     \fBint\fP    \fIreason\fP;
  340.     \fBXEvent\fP    \fI* event\fP
  341.     \fBint\fP    \fITopLine\fP;
  342.     \fBint\fP    \fIRows\fP;
  343.     \fBint\fP    \fIColumns\fP;
  344.     \fBint\fP    \fISave\fP;
  345.     \fBchar\fP    \fI* Selection\fP;
  346.     \fBint\fP    \fIValue\fP;
  347. } \fBGenTermCallback\fP;
  348. @.fi
  349. @.sp .5
  350. @.IP "\fIreason\fP"
  351. Indicates why the callback was called.
  352. @.IP "\fIevent\fP"
  353. Points to the \fBXEvent\fP structure which triggered this callback.
  354. The value is defined on if \fIreason\fP is equal to \fBGT_INPUT\fP
  355. @.IP "\fITopLine\fP"
  356. Indicates the position of the top line of the screen is in the virtual
  357. screen.  Its value ranges from 0 to \fBXtNsaveLine\fP.  It defined
  358. only if the reason is \fBGT_TOP\fP.
  359. @.IP "\fIRows\fP"
  360. Indicates the current number of rows in the visible screen.  This
  361. value is defined only if the reason is \fBGT_RESIZE\fP.
  362. @.IP "\fIColumns\fP"
  363. Indicates the current number of columns in the visible screen.  This
  364. value is defined only if the reason is \fBGT_RESIZE\fP.
  365. @.IP "\fISave\fP"
  366. Indicates the number of rows that can be saved in the virtual screen.
  367. This value is defined only if the reason is \fBGT_RESIZE\fP.
  368. @.IP "\fISelection\fP"
  369. Points to the text was pasted by an insert selection action.  This
  370. value is defined if the reason is \fBGT_PASTE\fP.
  371. @.IP "\fIValue\fP"
  372. If reason is \fBGT_LOCK\fP then \fIValue\fP is the current value of
  373. the lock setting.
  374. @.SH "TRANSLATIONS"
  375. The \fIGenTerm\fP widget has the following default translations:
  376. \fB
  377. @.nf
  378. @.ta 1.8i
  379. @.sp 0.5
  380. <KeyPress>:    input()
  381. <Expose>:    expose()
  382. <GraphicsExpose>:    expose()
  383. <NoExpose>:    noexpose()
  384. <Btn1Down>:    StartSelection()
  385. <Btn1Motion>:    ExtendSelection()
  386. <Btn1Up>:    MakeSelection(PRIMARY,CUT_BUFFER0)
  387. <Btn2Up>:    InsertSelection(PRIMARY)
  388. @.fi
  389. \fP
  390. @.SH "ACTIONS"
  391. The \fIGenTerm\fP action routines are:
  392. @.IP "\fBinput()\fP"
  393. Invokes the \fBXtNkbdCallback\fP with a reason of \fBGT_INPUT\fP and
  394. the event field pointing to the event that caused this action.
  395. @.IP "\fBexpose()\fP"
  396. Causes the widget to redraw part of its screen.  If this action was
  397. caused by a graphics expose event then the exposure count will be
  398. decremented.
  399. @.IP "\fBExtendSelection()\fP"
  400. Alters the highlighted section on the screen to track the mouse
  401. motion.
  402. @.IP "\fBInsertSelection(Source)\fP"
  403. Inserts text from the specified source.  \fBSource\fP and be any of
  404. \fIPRIMARY\fP, \fISECONDARY\fP or \fICUT_BUFFERn\fP where n is an
  405. integer from 0 to 7.  You can specify multiple sources in which case
  406. the action takes the text from the first source that contains text.
  407. The action then invokes a \fIXtNkbdCallback\fP with a reason of \fBGT_PASTE\fP.
  408. @.IP "\fBMakeSelection(Destinations...)\fP"
  409. The selected region is copied into an internal buffer, the selected
  410. area is unhighlighted and the widget unlocks itself.  If the
  411. \fIDestination\fP is \fBPRIMARY\fP or \fBSECONDARY\fP, then the
  412. selection is copied into the appropriate X selection.  If
  413. \fIDestination\fP is of the form \fBCUT_BUFFERn\fP where n is a number
  414. from 0 to 7, then the selection is copied into the appropriate cut
  415. buffer.  Multiple destinations can be specified.
  416. @.IP "\fBnoexpose()\fP"
  417. Causes the widget to decrement its internal exposure count.
  418. @.IP "\fBoutput(String)\fP"
  419. The argument of the action is sent to the widget and show on the
  420. screen.
  421. @.IP "\fBStartSelection()\fP"
  422. Causes the widget to start a mouse selection.  It sets the starting
  423. point for the selected region.  The widget is locked to
  424. allow the selection to complete.
  425. @.sp 1
  426. @.SH "ENTRY POINTS"
  427. In addition to the normal widget functions the GenTerm widget also
  428. contains the following functions which can be called from the
  429. application program.
  430. @.ta .2i 1.2i
  431. @.\"
  432. @.IP "\fBint GtClearMemory(Term,Which)\fP"
  433. @.sp
  434. @.nf
  435. \fB\tWidget\tTerm
  436. \tint\tWhich\fP
  437. @.fi
  438. @.sp
  439. This function clears data from the screen save memory.  \fBTerm\fP is
  440. the widget instance record.  \fBWhich\fP specifies which memory is be
  441. cleared.  If \fBWhich\fP is equal to 1, then all data saved below the
  442. visible screen is deleted.  If \fBWhich\fP is equal to 2 then all data
  443. saved above the visible screen is deleted.  In both case, the data on
  444. the visible screen is not affected.  If \fBWhich\fP is equal to 0,
  445. then the entire memory is cleared and the visible screen is also
  446. cleared.  The function returns \fIGTGOOD\fP if the request completed
  447. successfully of \fIGTLOCKED\fP if the widget is currently locked.  In
  448. this case the calling routine should try again later.
  449. @.\"
  450. @.IP "\fBint GtClearRegion(Term,StartRow,StartColumn,EndRow,EndColumn)\fP"
  451. @.sp
  452. @.nf
  453. \fB\tWidget\tTerm
  454. \tint\tStartRow
  455. \tint\tStartColumn
  456. \tint\tEndRow
  457. \tint\tEndColumn\fP
  458. @.fi
  459. @.sp
  460. This function clears a rectangular region on the visible screen.
  461. \fBTerm\fP is the widget instance record.  \fBStartRow\fP and
  462. \fBStartColumn\fP specify of the upper left corner of the rectangle
  463. while \fBEndRow\fP and \fBEndColumn\fP specify the lower right corner.
  464. If any of the coordinates fall outside of the visible screen then they
  465. are truncated to the nearest edge.  The function returns \fIGTGOOD\fP
  466. if the request completed successfully or \fIGTLOCKED\fP if the widget
  467. is currently locked.  In this case the request is not performed and
  468. the calling routine should try again later.
  469. @.\"
  470. @.IP "\fBint GtCursorDown(Term,Dist,WrapType)\fP"
  471. @.sp
  472. @.nf
  473. \fB\tWidget\tTerm
  474. \tint\tDist
  475. \tint\tWrapType\fP
  476. @.fi
  477. @.sp
  478. This function moves the current cursor position down \fBDist\fP lines.
  479. \fBTerm\fP is the widget instance record.  \fBDist\fP is the number of
  480. lines to move the cursor down.  \fBWrapType\fP controls the behavior
  481. of the widget
  482. when the cursor hits the bottom of the screen.  If \fBWrapType\fP is
  483. equal to \fI0\fP then the screen is scrolled up the required number of
  484. lines.  If \fBWrapType\fP is equal to \fI1\fP then, when the cursor
  485. encounters the bottom of the screen, it will wrap around to the top.
  486. Finally, if \fBWrapType\fP is equal to \fI2\fP, then the cursor will
  487. stop and stick at the bottom of the screen.  The function returns
  488. \fIGTGOOD\fP if the request completed successfully.  It returns
  489. \fIGTLOCKED\fP is the widget is currently locked.  In this case the
  490. request is not performed and the calling routine should try again
  491. later.
  492. @.\"
  493. @.IP "\fBint GtCursorLeft(Term,Dist,WrapType,RollType)\fP"
  494. @.sp
  495. @.nf
  496. \fB\tWidget\tTerm
  497. \tint\tDist
  498. \tint\tWrapType
  499. \tint\tRollType\fP
  500. @.fi
  501. @.sp
  502. This function moves the current cursor position \fBDist\fP spaces to
  503. the left.  \fBTerm\fP is the widget instance record.  \fBDist\fP is
  504. the number of spaces to move the cursor.  \fBWrapType\fP controls the
  505. behavior of the widget when the cursor encounters the leftmost
  506. column of the screen.  If \fBWrapType\fP is equal to \fI0\fP then the
  507. cursor will stick in the leftmost column.  If \fBWrapType\fP is equal
  508. to \fI1\fP then the cursor will move to the rightmost column on the
  509. previous line.  \fBRollType\fP defines the behavior of the widget
  510. when the cursor is on the leftmost column of the top line.  If
  511. \fBRollType\fP is equal to \fI0\fP, then the cursor will move to the
  512. rightmost column of the bottom line.  If \fBRollType\fP is equal to
  513. \fI1\fP then the screen will be scrolled down and the cursor will move
  514. to the rightmost position on the previous line.  The function returns
  515. \fIGTGOOD\fP if the request completed successfully.  It returns
  516. \fIGTLOCKED\fP if the widget is currently locked.  In this case the
  517. request is not performed and the calling routine should try again
  518. later.
  519. @.\"
  520. @.IP "\fBint GtCursorReturn(Term)\fP"
  521. @.sp
  522. @.nf
  523. \fB\tWidget\tTerm\fP
  524. @.fi
  525. @.sp
  526. This function returns the current cursor position to the leftmost
  527. column on the current line.  \fBTerm\fP is the widget instance record.
  528. The function returns \fIGTGOOD\fP if the request completed
  529. successfully.  It returns \fIGTLOCKED\fP if the widget is locked.  In
  530. this case the current position is not changed and the calling routine
  531. should try again later.
  532. @.\"
  533. @.IP "\fBint GtCursorRight(Term,Dist,WrapType,RollType)\fP"
  534. @.sp
  535. @.nf
  536. \fB\tWidget\tTerm
  537. \tint\tDist
  538. \tint\tWrapType
  539. \tint\tRollType\fP
  540. @.fi
  541. @.sp
  542. This function moves the current cursor position \fBDist\fP spaces to
  543. the right.  \fBTerm\fP is the widget instance record.  \fBDist\fP is
  544. the number of spaces move the cursor.  \fBWrapType\fP controls
  545. the behavior of the widget when the cursor encounters the rightmost
  546. column of the screen.  If \fBWrapType\fP is equal to \fI0\fP then the
  547. cursor will stick in the rightmost column.  If \fBWrapType\fP is equal
  548. to \fI1\fP then the cursor will move to the leftmost column on the
  549. next line.  \fBRollType\fP defines the behavior of the widget when
  550. the cursor is on the rightmost column of the bottom line.  If
  551. \fBRollType\fP is equal to \fI0\fP, then the cursor will move to the
  552. leftmost column of the first line.  If \fBRollType\fP is equal to
  553. \fI1\fP then the screen will be scrolled up and the cursor will move
  554. to the leftmost column on the next line.  The function returns
  555. \fIGTGOOD\fP if the request completed successfully.  It returns
  556. \fIGTLOCKED\fP if the widget is currently locked.  In this case the
  557. request is not performed and the calling routine should try again later.
  558. @.\"
  559. @.IP "\fBint GtCursorUp(Term,Dist,WrapType)\fP"
  560. @.sp
  561. @.nf
  562. \fB\tWidget\tTerm
  563. \tint\tDist
  564. \tint\tWrapType\fP
  565. @.fi
  566. @.sp
  567. This function moves the current cursor position up \fBDist\fP lines.
  568. \fBTerm\fP is the widget instance record.  \fBDist\fP is the number of
  569. lines to move the cursor up.  \fBWrapType\fP controls the behavior of
  570. the widget when the cursor encounters the top of the screen.  If
  571. \fBWrapType\fP is equal to \fI0\fP then the screen is scrolled down
  572. the required number of lines.  If \fBWrapType\fP is equal to \fI1\fP
  573. then when the cursor encounters the top of the screen it will wrap
  574. around to the bottom.  If \fBWrapType\fP is equal to \fI2\fP then
  575. cursor will stop and stick at the top of the screen.  The function
  576. returns \fIGTGOOD\fP if the request completed successfully.  It
  577. returns \fIGTLOCKED\fP if the widget is currently locked.  In this
  578. case the request is not performed and the calling routine should try
  579. again later.
  580. @.\"
  581. @.IP "\fBint GtDefinePenColour(Term,Pen,FRed,FGreen,FBlue,BRed,BGreen,BBlue)\fP"
  582. @.sp 
  583. @.nf
  584. \fB\tWidget\tTerm
  585. \tint\tPen
  586. \tfloat\tFRed
  587. \tfloat\tFGreen
  588. \tfloat\tFBlue
  589. \tfloat\tBRed
  590. \tfloat\tBGreen
  591. \tfloat\tBBlue\fP
  592. @.fi
  593. @.sp
  594. This function defines the foreground and background colour of a
  595. specified pen. \fBTerm\fP is the widget instance record.  \fBPen\fP is
  596. the number of the pen to define the colour for.  If \fBPen\fP is not
  597. with in the range of 0 to \fBXtNnumberColors\fP - 1, then its value
  598. will be adjusted.  \fBFRed\fP, \fBFGreen\fP and \fBFBlue\fP are the
  599. RGB values of the foreground colours.  The values are ranges between 0
  600. and 1.  If the resource \fBXtNdefineColor\fP is equal to \fIGTHSL\fP
  601. then these values are the hue saturation and luminous values of the
  602. foreground colour.  Similarly, \fBBRed\fP, \fBBGreen\fP and
  603. \fBBBlue\fP specify the RGB (or HSL) values of the background colour.
  604. The function always returns the value \fIGTGOOD\fP.
  605. @.\"
  606. @.IP "\fBint GtDeleteCharacters(Term,Num)\fP"
  607. @.sp
  608. @.nf
  609. \fB\tWidget\tTerm
  610. \tint\tNum\fP
  611. @.fi
  612. @.sp
  613. This function deletes a number of characters from the current row
  614. starting at the current position.  \fBTerm\fP is widget instance
  615. record and \fBNum\fP is the number of characters to delete.  The
  616. characters to the right of the deleted characters are moved left
  617. \fBNum\fP positions.  The function returns \fIGTGOOD\fP if the request
  618. completed successfully or \fIGTLOCKED\fP if the widget is currently locked.
  619. @.\"
  620. @.IP "\fBint GtDeleteLines(Term,Num)\fP"
  621. @.sp
  622. @.nf
  623. \fB\tWidget\tTerm
  624. \tint\tNum\fP
  625. @.fi
  626. @.sp
  627. This function deletes a number of lines from the visible screen
  628. starting at the current row.  \fBTerm\fP is the widget instance
  629. record.  \fBNum\fP is the number of lines to delete.  When lines are
  630. deleted, the lines below them are pushed up on the screen.  Any data
  631. saved in the screen memory below the visible screen are scrolled onto
  632. the screen.  If there is no data in the memory then blank lines are
  633. pushed onto the bottom.  The function returns \fIGTGOOD\fP if the
  634. request completed successfully and \fIGTLOCKED\fP if the widget is
  635. currently locked.
  636. @.\"
  637. @.IP "\fBint GtInsertLines(Term,Row,Num)\fP"
  638. @.sp
  639. @.nf
  640. \fB\tWidget\tTerm
  641. \tint\tRow
  642. \tint\tNum\fP
  643. @.fi
  644. @.sp
  645. This function inserts a number of blank lines at a given position on
  646. the visible screen.  \fBTerm\fP is the widget instance record.
  647. \fBRow\fP is the row on the screen to insert the lines at.  \fBNum\fP
  648. is the number of blank lines to insert.  All lines below \fBRow\fP are
  649. pushed down.  Any lines pushed off of the visible screen are stored in
  650. the screen memory.  The function returns \fIGTBAD\fP if \fBRow\fP is not in
  651. the visible screen, \fIGtGOOD\fP if the request completed successfully
  652. and \fIGTLOCKED\fP if the widget is currently locked.
  653. @.\"
  654. @.IP "\fBint GtGetAttribute(Term,Attribute,Value)\fP"
  655. @.sp
  656. @.nf
  657. \fB\tWidget\tTerm
  658. \tint\tAttribute
  659. \tint *\tValue\fP
  660. @.fi
  661. @.sp
  662. This function returns the current setting of a specific attribute.
  663. \fBTerm\fP is the widget instance record.  \fBAttribute\fP specifies
  664. the attribute to return the value of.  Valid values are: \fIGTFONT\fP,
  665. \fIGTINVERSEVIDEO\fP, \fIGTUNDERLINE\fP, \fIGTHALFBRIGHT\fP,
  666. \fIGTBLINKMODE\fP or \fIGTPEN\fP.  Upon return, \fBValue\fP will
  667. contain the current setting of the attribute.  See the entry point
  668. \fBGtSetAttribute\fP for a list of values \fBValue\fP can take on.
  669. The function always returns the value \fIGTGOOD\fP.
  670. @.\"
  671. @.IP "\fBint GtGetCursorPosition(Term,Row,Column)\fP"
  672. @.sp
  673. @.nf
  674. \fB\tWidget\tTerm
  675. \tint *\tRow
  676. \tint *\tColumn\fP
  677. @.fi
  678. @.sp
  679. This function returns the row and column numbers of the current cursor
  680. position.  The topmost line is row 0 and the leftmost column is column
  681. 0.  \fBTerm\fP is the widget instance record.  \fBRow\fP and
  682. \fBColumn\fP are pointers to integers in which the row and column
  683. positions will be returned.  The function always returns a value of
  684. \fIGTGOOD\fP.
  685. @.\"
  686. @.IP "\fBint GtGetLine(Term,Row,String,Len)\fP"
  687. @.sp
  688. @.nf
  689. \fB\tWidget\tTerm
  690. \tint\tRow
  691. \tchar *\tString
  692. \tint *\tLen\fP
  693. @.fi
  694. @.sp
  695. This function gets the characters that are currently stored in a
  696. specified row.  \fBTerm\fP is the widget instance record.  \fBRow\fP
  697. is the number of the row in the visible screen to get the characters
  698. from.  \fBRow\fP can have a value ranging from \fI0\fP to
  699. \fBXtNRows\fP - 1.  \fBString\fP is the address of where to store the
  700. characters.  The calling routine is responsible for ensuring there is
  701. enough space to store the data in.  \fBLen\fP is a pointer to an
  702. integer to return the number of characters put into \fBString\fP.  The
  703. function returns \fIGTBAD\fP if \fBRow\fP contained an invalid value
  704. and \fIGTGOOD\fP otherwise.
  705. @.\"
  706. @.IP "\fBint GtGetMapTable(Term,Table)\fP"
  707. @.sp
  708. @.nf
  709. \fB\tWidget\tTerm
  710. \tchar\tTable[NMAP]\fP
  711. @.fi
  712. @.sp
  713. This function returns a copy of the current output mapping table.  The
  714. mapping table defines the translation table that is used for printing
  715. ascii characters.  Each character is used as an offset into the table.
  716. The value stored at that position will be the character that is
  717. printed.  \fBTerm\fP is the widget instance record.  Upon return
  718. \fBTable\fP contains a copy of the current table.  The function always
  719. returns \fIGTGOOD\fP
  720. @.\"
  721. @.IP "\fBint GtGetScreenSize(Term,Row,Column)\fP"
  722. @.sp
  723. @.nf
  724. \fB\tWidget\tTerm
  725. \tint *\tRow
  726. \tint *\tColumn\fP
  727. @.fi
  728. @.sp
  729. This function returns the number of rows and columns currently in the
  730. visible screen.  \fBTerm\fP is the widget instance record.  Upon
  731. return \fBRow\fP contains the number of rows and \fBColumn\fP contains
  732. the number of columns in the visible screen.  The function always
  733. returns \fIGTGOOD\fP.
  734. @.\"
  735. @.IP "\fBint GtGetScrollRegion(Term,Id,Start,End)\fP"
  736. @.sp
  737. @.nf
  738. \fB\tWidget\tTerm
  739. \tint\tId
  740. \tint *\tStart
  741. \tint *\tEnd\fP
  742. @.fi
  743. @.sp
  744. This function returns the starting and ending rows of a specific
  745. scroll region.  \fBTerm\fP is the widget instance record.  \fBId\fP is
  746. scroll region identifier corresponding to the scroll region to return.
  747. \fBStart\fP and \fBEnd\fP will contain the starting and end rows of
  748. the scroll region upon returning from the function.  If the scroll
  749. region is not currently defined then \fBStart\fP will have a value of
  750. \fI-1\fP.  The function always returns a value of \fIGTGOOD\fP.
  751. @.\"
  752. @.IP "\fBint GtGetTopOfScreen(Term)\fP"
  753. @.sp
  754. @.nf
  755. \fB\tWidget\tTerm\fP
  756. @.fi
  757. @.sp
  758. This function returns the position of the top line of the screen in
  759. the virtual save screen.  It returns a value between 0 (the top of the
  760. save screen) and \fBXtNsaveLines\fP - \fBXtNrows\fP (the bottom of the
  761. save screen).  \fBTerm\fP is the widget instance record.
  762. @.\"
  763. @.IP "\fBint GtLoadAttribute(Term,Row,Column)\fP"
  764. @.sp
  765. @.nf
  766. \fBWidget\tTerm
  767. \tint\tRow
  768. \tint\tColumn\fP
  769. @.fi
  770. @.sp
  771. This function sets the current attribute to match those of the
  772. character at position \fBRow\fP,\fBColumn\fP.  \fBTerm\fP is the
  773. widget instance record.  \fBRow\fP and \fBColumn\fP is the character
  774. position to copy the attributes from.  If the position is invalid or
  775. specifies a point that is not in the visible screen then the default
  776. attributes are loaded.  The function always returns \fIGTGOOD\fP.
  777. @.\"
  778. @.IP "\fBint GtMarginBell(Term)\fP"
  779. @.sp
  780. @.nf
  781. \fB\tWidget\tTerm\fP
  782. @.fi
  783. @.sp
  784. This function tests whether the margin bell should be rung.  If the
  785. answer is yes then it rings the bell.  \fBTerm\fP is the widget
  786. instance record.  The function always returns a value of \fIGTGOOD\fP.
  787. @.IP "\fBint GtNewLine(Term,Num)\fP"
  788. @.sp
  789. @.nf
  790. \fB\tWidget\tTerm
  791. \tint\tNum\fP
  792. @.fi
  793. @.sp
  794. This function causes the current cursor position to move down
  795. \fBNum\fP lines.  If this would cause the cursor to move off the
  796. bottom of the screen, a scroll is performed.  \fBTerm\fP is the widget
  797. instance records and \fBNum\fP is the number of lines to move down.
  798. The function returns \fIGTGOOD\fP if the request completed
  799. successfully.  It returns \fIGTLOCKED\fP if the widget is currently
  800. locked.  In this case, the request is not performed and the calling
  801. routine should try again later.
  802. @.IP "\fBint GtOutput(Term,String,Len)\fP"
  803. @.sp
  804. @.nf
  805. \fB\tWidget\tTerm
  806. \tchar *\tString
  807. \tint\tLen\fP
  808. @.fi
  809. @.sp
  810. This is the main output routine for the widget.  \fBTerm\fP is the
  811. widget instance record.  \fBString\fP is a pointer to a character
  812. string and \fBLen\fP is the number of characters in the string.  This
  813. function stores the string in the screen array at the cursor current
  814. cursor position.  If this is in the visible screen then the string
  815. will be printed.  The characters are stored with the current
  816. attributes, if \fBXtNfieldAttributes\fP is \fIFalse\fP.  Otherwise,
  817. the field attributes already in the screen array are used.  If
  818. \fBXtNliteralMode\fP is \fIFalse\fP then the characters in
  819. \fBString\fP are translated using the current mapping table prior to
  820. being stored.  If \fBXtNliteralMode\fP is \fITrue\fP, then any
  821. nondisplayable characters are are printed aS a \fI^\fP character
  822. followed by the character with its seventh bit set.  The function
  823. returns \fIGTGOOD\fP if the string was successfully stored.  The
  824. function returns \fIGTLOCKED\fP if the widget is currently locked.  In
  825. this case, the string was not saved and the caller should try again
  826. later after receiving an \fBXtNlockCallback\fP.
  827. @.\"
  828. @.IP "\fBint GtPositionToRowColumn(Term,X,Y,Row,Column)\fP"
  829. @.sp
  830. @.nf
  831. \fB\tWidget\tTerm
  832. \tDimension\tX
  833. \tDimension\tY
  834. \tint *\tRow
  835. \tint *\tColumn\fP
  836. @.fi
  837. @.sp
  838. This function takes an \fB(X,Y)\fP position, such as those returned by
  839. an XEvent and converts it to its equivalent \fBRow\fP and \fBColumn\fP
  840. with in the visible screen.  \fBTerm\fP is the widget instance record.
  841. \fBX\fP and \fBY\fP is the position coordinate relative to the top
  842. left of the widget's window.  \fBRow\fP and \fBColumn\fP are pointers
  843. to integers in which the result will be stored.  The function always
  844. returns the value \fIGTGOOD\fP.
  845. @.\"
  846. @.IP "\fBint GtSetCursorPosition(Term,Row,Column)\fP"
  847. @.sp
  848. @.nf
  849. \fB\tWidget\tTerm
  850. \tint\tRow
  851. \tint\tColumn\fP
  852. @.fi
  853. @.sp
  854. This function sets the cursor position.  \fBTerm\fP is the widget
  855. instance record.  \fBRow\fP and \fBColumn\fP are the row and column
  856. numbers of the new cursor position.  Row 0 is the top row of the screen
  857. and column 0 is the leftmost column.  If either the row of column are
  858. outside the visible screen then the cursor position will be set to the
  859. closest point that is still inside the screen.  The function returns
  860. \fIGTGOOD\fP if the request was completed and \fIGTLOCKED\fP if the
  861. widget is currently locked.  In the latter case, the request is not
  862. performed and the calling routine should try again later.
  863. @.\"
  864. @.IP "\fBint GtSetAttribute(Term,Attribute,Value)\fP"
  865. @.sp
  866. @.nf
  867. \fB\tWidget\tTerm
  868. \tint\tAttribute
  869. \tint\tPosition\fP
  870. @.fi
  871. @.sp
  872. This function sets the value of one of the attributes of the current
  873. text attribute.  \fBTerm\fP is the widget instance record.
  874. \fBAttribute\fP specifies which attribute's value is to be altered.
  875. Valid values are: \fIGTFONT\fP, \fIGTINVERSEVIDEO\fP,
  876. \fIGTUNDERLINE\fP, \fIGTHALFBRIGHT\fP, \fIGTBLINKMODE\fP or
  877. \fIGTPEN\fP.  If \fBAttribute\fP is equal to \fIGTFONT\fP and
  878. \fBValue\fP is equal to \fIGTBASE\fP then the normal font is set for
  879. the current attribute.  If \fBValue\fP is equal to \fIGTALTERNATE\fP
  880. then the current font is set to the alternate font.  If
  881. \fBAttribute\fP is equal to \fIGTINVERSEVIDEO\fP and \fBValue\fP is equal
  882. to \fIGTINVERSE\fP then the current foreground and background colours
  883. are swapped.  If \fBValue\fP is equal to \fIGTNORMAL\fP then the
  884. foreground and background correspond to the specified foreground and
  885. background colours.  If \fBAttribute\fP is equal to \fIGTUNDERLINE\fP
  886. and \fBValue\fP is equal to \fIGTON\fP then all text will be
  887. underlined as it is printed.  If \fBValue\fP is equal to \fIGTOFF\fP
  888. then all text is written as normal.  If \fBAttribute\fP is equal to
  889. \fIGTHALFBRIGHT\fP and \fBValue\fP is equal to \fIGTON\fP then the
  890. current default background colour is altered so that the difference in
  891. luminance between the foreground and background colours is
  892. approximately half the default value.  If \fBValue\fP is equal to
  893. \fIGTOFF\fP then the normal default background colour is used.  If
  894. \fBAttribute\fP is equal to \fIGTBLINKMODE\fP and \fBValue\fP is equal
  895. to \fIGTON\fP then the blink attribute is set.  All text written with
  896. this attribute will be flashed on the screen one and off.  If
  897. \fBValue\fP is equal to \fIGTOFF\fP, then the blink attribute is
  898. reset.  If \fBAttribute\fP is equal to \fIGTPEN\fP then the pen number
  899. of the attribute is set.  \fBValue\fP specifies the pen number to use
  900. and should be in the range of 0 to the \fINumberColors\fP resource.
  901. The pen number defines the normal default foreground and background
  902. colour pair.  An attribute remains in effect until it is explicitly
  903. reset.  Multiple resources (such as bold and underline) can be
  904. specified by multiple calls to this function.  If \fBValue\fP does not
  905. contains a valid value for the given value of \fBAttribute\fP then the
  906. request is ignored.  The function always
  907. returns a value of \fIGTGOOD\fP.
  908. @.\"
  909. @.IP "\fBint GtSetFieldAttribute(Term)\fP"
  910. @.sp
  911. @.nf
  912. \fB\tWidget\tTerm\fP
  913. @.fi
  914. @.sp
  915. This function copies the current attribute settings through out the current
  916. field.  As a side effect, it may also create a new field.  A field is
  917. a section of text on the screen which have the same attributes.  When
  918. text is written onto the screen it inherits its resources from the
  919. field it is written into and not the current settings.  If the current
  920. cursor position is at the beginning of a defined field, then the
  921. attribute is set through out that field.  If the current cursor
  922. position is inside a currently defined field then the current field is
  923. truncated to the position immediately to the left of the current
  924. position.  A new field is then defined from the current position to
  925. the end of the old field.  The current attribute is copied into this
  926. new field.  Initially, each line contains one field extending from the
  927. first to the last column.  The function sets the attributes only if the
  928. \fBFieldAttributes\fP resource is \fITrue\fP, otherwise a value of
  929. \fIGTBAD\fP is returned.  The function returns a value of \fIGTGOOD\fP
  930. if it succeeded to set the attributes and a value of \fIGTLOCKED\fP if
  931. the screen is currently locked.
  932. @.\"
  933. @.IP "\fBint GtSetMapTable(Term,Table)\fP"
  934. @.sp
  935. @.nf
  936. \fB\tWidget\tTerm
  937. \tchar\tTable[NMAP]\fP
  938. @.fi
  939. @.sp
  940. This function defines the output mapping table to use. The
  941. mapping table defines the translation table that is used printing
  942. ascii characters.  Each character is used as an offset into the table.
  943. The value stored at that position will be the character that is
  944. printed.  \fBTerm\fP is the widget instance record.
  945. \fBTable\fP is the new mapping table.  The function always returns \fIGTGOOD\fP
  946. @.\"
  947. @.IP "\fBint GtSetScrollRegion(Term,Start,End,Id)\fP"
  948. @.sp
  949. @.nf
  950. \fB\tWidget\tTerm
  951. \tint\tStart
  952. \tint\tEnd
  953. \tint\tId\fP
  954. @.fi
  955. @.sp
  956. This function enable a scroll region within a certain portion of the
  957. visible screen.  \fBTerm\fP is the widget instance record.
  958. \fBStart\fP and \fBEnd\fP specify the starting and end rows of the
  959. scroll region.  \fBId\fP the identify to assign to the scroll region.
  960. It should not be the same as any other currently defined scroll region
  961. unless you are overwritting that scroll region.  The function returns
  962. \fIGTBAD\fP if either the starting or ending rows are invalid.  It
  963. returns \fIGTGOOD\fP if the request completed successfully.
  964. @.\"
  965. @.IP "\fBint GtSetTopOfScreen(Term,Position)\fP"
  966. @.sp
  967. @.nf
  968. \fB\tWidget\tTerm
  969. \tint\tPosition\fP
  970. @.fi
  971. @.sp
  972. This function sets the position of the visible screen within the
  973. virtual screen save area.  \fBTerm\fP is the widget instance record.
  974. \fBPosition\fP is the position the top line of the visible screen
  975. should have in the save screen.  Its value can range from 0 (the top
  976. of the save screen) to \fBXtNsaveLines\fP - \fBXtNrows\fP (the bottom
  977. of the save screen).  If \fBPosition\fP is not within this range then
  978. its value will be adjusted accordingly.  The function returns
  979. \fIGTGOOD\fP if the request completed normally or \fIGTLOCKED\fP if
  980. the widget is currently locked.  In the latter case, the request is
  981. not performed and the calling routine should try again later.
  982. @.sp 1
  983. @.SH "RELATED INFORMATION"
  984. \fBCore(3X)\fP, \fBComposite(3X)\fP
  985. @EOF
  986. set `wc -lwc <GenTerm/GenTerm.man`
  987. if test $1$2$3 != 953611640490
  988. then
  989.     echo ERROR: wc results of GenTerm/GenTerm.man are $* should be 953 6116 40490
  990. fi
  991.  
  992. chmod 644 GenTerm/GenTerm.man
  993.  
  994. echo x - GenTerm/GenTermEm.c
  995. cat >GenTerm/GenTermEm.c <<'@EOF'
  996. /* GenTermEm -- A generalized terminal emulator widget */
  997. /* History:                                 */
  998. /*         Written by G. R. Strachan 1992 */
  999.  
  1000. /*  Copyright Gordon R. Strachan 1992 */
  1001. /*  This code is provided as is, neither the University of Waterloo nor */
  1002. /*  the author is liable for any damage caused by the use or misuse of this */
  1003. /*  code.  */
  1004.  
  1005. /* Permission is granted to copy, use and modify this code provided it is */
  1006. /* not sold for profit and the above copyright remains intact. */
  1007.  
  1008. #include <stdio.h>
  1009. #include <ctype.h>
  1010. #include <fcntl.h>
  1011. #include <X11/X.h>
  1012. #include <X11/Xlib.h>
  1013. #include <X11/StringDefs.h>
  1014. #include <X11/IntrinsicP.h>
  1015. #include <X11/CoreP.h>
  1016. #include <X11/CompositeP.h>
  1017. #include <X11/Shell.h>
  1018. #include <X11/keysym.h>
  1019. #include <X11/Xatom.h>
  1020. #include "GenTermEmP.h"
  1021. #include "Parser.h"
  1022.  
  1023. extern GenTermClassRec genTermClassRec;
  1024.  
  1025. extern struct InputArguments *GtEPushArgs();
  1026. extern void GtEPopArgs();
  1027.  
  1028. static XtResource resources[] = {
  1029.  {XtNwidth,XtCWidth,XtRDimension,sizeof(Dimension),
  1030.   XtOffset(GenTermEmWidget,core.width),XtRImmediate,(caddr_t)(7*80)},
  1031.  {XtNheight,XtCHeight,XtRDimension,sizeof(Dimension),
  1032.    XtOffset(GenTermEmWidget,core.height),XtRImmediate,(caddr_t)(13*24)},
  1033.  {XtNname,XtCName,XtRString,sizeof(char *),
  1034.    XtOffset(GenTermEmWidget,genTermEm.name),XtRString,"term0"},
  1035.  {XtNparseFile,XtCParseFile,XtRString,sizeof(char *),
  1036.    XtOffset(GenTermEmWidget,genTermEm.ParseFile),XtRString,"./hpterm.par"},
  1037.  {XtNshowFunction,XtCShowFunction,XtRBoolean,sizeof(Boolean),
  1038.    XtOffset(GenTermEmWidget,genTermEm.ShowKey),XtRImmediate,(caddr_t)FALSE},
  1039.  {XtNfunctionSize,XtCFunctionSize,XtRDimension,sizeof(Dimension),
  1040.    XtOffset(GenTermEmWidget,genTermEm.FuncKeyHeight),XtRImmediate,(caddr_t)39},
  1041.  {XtNfunctionLabelWidth,XtCFunctionLabelWidth,XtRInt,sizeof(int),
  1042.    XtOffset(GenTermEmWidget,genTermEm.FuncLabelWidth),XtRImmediate,(caddr_t)8},
  1043.  {XtNnumberFunctionKeys,XtCNumberFunctionKeys,XtRInt,sizeof(int),
  1044.    XtOffset(GenTermEmWidget,genTermEm.NumberFunctionKeys),XtRImmediate,
  1045.    (caddr_t)8},
  1046.  {XtNoutputFile,XtCOutputFile,XtRInt,sizeof(int),
  1047.    XtOffset(GenTermEmWidget,genTermEm.OutputDescriptor),XtRImmediate,
  1048.    (caddr_t)-1},
  1049.  {XtNlogging,XtCLogging,XtRBoolean,sizeof(Boolean),
  1050.    XtOffset(GenTermEmWidget,genTermEm.Logging),XtRImmediate,(caddr_t)False},
  1051.  {XtNlogFile,XtCLogFile,XtRInt,sizeof(int),
  1052.    XtOffset(GenTermEmWidget,genTermEm.LogFileDescriptor),XtRImmediate,
  1053.    (caddr_t)-1},
  1054.  {XtNdestructiveTab,XtCDestructiveTab,XtRBoolean,sizeof(Boolean),
  1055.    XtOffset(GenTermEmWidget,genTermEm.DestructiveTab),XtRImmediate,
  1056.    (caddr_t)TRUE},
  1057.  {XtNkbdCallback,XtCKbdCallback,XtRCallback,sizeof(caddr_t),
  1058.    XtOffset(GenTermEmWidget,genTermEm.KbdCallbacks),XtRCallback,(caddr_t)NULL},
  1059.  {XtNescCallback,XtCEscCallback,XtRCallback,sizeof(caddr_t),
  1060.    XtOffset(GenTermEmWidget,genTermEm.EscCallbacks),XtRCallback,(caddr_t)NULL},
  1061.  {XtNwakeUpCallback,XtCWakeUpCallback,XtRCallback,sizeof(caddr_t),
  1062.    XtOffset(GenTermEmWidget,genTermEm.WakeUpCallbacks),XtRCallback,
  1063.    (caddr_t)NULL},
  1064.  {XtNflowCallback,XtCFlowCallback,XtRCallback,sizeof(caddr_t),
  1065.    XtOffset(GenTermEmWidget,genTermEm.FlowCallbacks),XtRCallback,(caddr_t)NULL},
  1066.  {XtNnumberMapTables,XtCNumberMapTables,XtRInt,sizeof(int),
  1067.    XtOffset(GenTermEmWidget,genTermEm.NumMapTables),XtRImmediate,(caddr_t)1},
  1068.  {XtNnumberStorageArguments,XtCNumberStorageArguments,XtRInt,sizeof(int),
  1069.    XtOffset(GenTermEmWidget,genTermEm.NumStoreArgs),XtRImmediate,(caddr_t)20},
  1070.  {XtNpreScroll,XtCPreScroll,XtCBoolean,sizeof(Boolean),
  1071.    XtOffset(GenTermEmWidget,genTermEm.PreScroll),XtRImmediate,(caddr_t)False},
  1072.  {XtNscrollChar,XtCScrollChar,XtRUnsignedChar,sizeof(unsigned char),
  1073.    XtOffset(GenTermEmWidget,genTermEm.ScrollChar),XtRImmediate,(caddr_t)'\n'},
  1074.  {XtNscrollAbortChar,XtCScrollAbortChar,XtRUnsignedChar,sizeof(unsigned char),
  1075.    XtOffset(GenTermEmWidget,genTermEm.ScrollAbortChar),XtRImmediate,
  1076.    (caddr_t)'\033'},
  1077.  };
  1078.  
  1079. static void GtEClassInitialize();
  1080. static void GtEInput();
  1081. int GtEOutput();
  1082. static void GtEOutputAction();
  1083. static void GtEInvokeTranslation();
  1084. static void GtEInitialize();
  1085. static void GtERealize();
  1086. static void GtERealizeFunctionKeys();
  1087. static void GtEDestroy();
  1088. static void GtEResize();
  1089. static Boolean GtESetValues();
  1090. static void GtEDestroyFunctionKeys();
  1091. static void GtEOutputDescriptorCallBack();
  1092. static XtGeometryResult GtEGeometryManager();
  1093. static int GtEFunctionKeyPress();
  1094. static void GtEAWaitGraphicsExpose();
  1095. static void GtEInsertSelection();
  1096. static void GtEInsertCallback();
  1097. static void GtELockCallback();
  1098. static void GtEAddToStorage();
  1099. static void GtEPreScroll();
  1100. static Boolean GtEGetClassParseFile();
  1101.  
  1102. static XtActionsRec actions[] = {
  1103.  {"input",GtEInput},
  1104.  {"output",GtEOutputAction},
  1105.  {"invokeTranslation",GtEInvokeTranslation},
  1106.  {"awaitgraphicsexpose",GtEAWaitGraphicsExpose},
  1107.  {"InsertSelection",GtEInsertSelection},
  1108. };
  1109.  
  1110. static char translations[] =
  1111. "\
  1112. <KeyPress>:input()\n\
  1113. <Expose>:expose()\n\
  1114. <GraphicsExpose>:expose() awaitgraphicsexpose()\n\
  1115. <NoExpose>:noexpose() awaitgraphicsexpose()\n\
  1116. <Btn1Down>:StartSelection()\n\
  1117. <Btn1Motion>:ExtendSelection()\n\
  1118. <Btn1Up>:MakeSelection(PRIMARY,CUT_BUFFER0)\n\
  1119. <Btn2Up>:InsertSelection(PRIMARY,CUT_BUFFER0)\n\
  1120. ";
  1121.  
  1122. GenTermEmClassRec genTermEmClassRec =
  1123. {
  1124.  {  /* core fields */
  1125.     /* superclass               */      (WidgetClass) &genTermClassRec,
  1126.     /* class_name               */      "GenTermEm",
  1127.     /* widget_size              */      sizeof(GenTermEmRec),
  1128.     /* class_initialize         */      GtEClassInitialize,
  1129.     /* class_part_initialize    */      NULL,
  1130.     /* class_inited             */      FALSE,
  1131.     /* initialize               */      GtEInitialize,
  1132.     /* initialize_hook          */      NULL,
  1133.     /* realize                  */      GtERealize,
  1134.     /* actions                  */      actions,
  1135.     /* num_actions              */      XtNumber(actions),
  1136.     /* resources                */      resources,
  1137.     /* num_resources            */      XtNumber(resources),
  1138.     /* xrm_class                */      NULLQUARK,
  1139.     /* compress_motion          */      TRUE,
  1140.     /* compress_exposure        */      FALSE,
  1141.     /* compress_enterleave      */      TRUE,
  1142.     /* visible_interest         */      FALSE,
  1143.     /* destroy                  */      GtEDestroy,
  1144.     /* resize                   */      GtEResize,
  1145.     /* expose                   */      XtInheritExpose,
  1146.     /* set_values               */      GtESetValues,
  1147.     /* set_values_hook          */      NULL,
  1148.     /* set_values_almost        */      XtInheritSetValuesAlmost,
  1149.     /* get_values_hook          */      NULL,
  1150.     /* accept_focus             */      XtInheritAcceptFocus,
  1151.     /* version                  */      XtVersion,
  1152.     /* callback_private         */      NULL,
  1153.     /* tm_table                 */      translations,
  1154.     /* query_geometry           */      XtInheritQueryGeometry,
  1155.     /* display_accelerator      */      XtInheritDisplayAccelerator,
  1156.     /* extension                */      NULL
  1157.   },
  1158.      { /* composite_class fields */
  1159.     /* geometry_manager   */   GtEGeometryManager,
  1160.     /* change_managed     */   XtInheritChangeManaged,
  1161.     /* insert_child       */   XtInheritInsertChild,
  1162.     /* delete_child       */   XtInheritDeleteChild,
  1163.     /* extension          */   NULL
  1164.   },
  1165.      { NULL},
  1166.  
  1167. };
  1168.  
  1169.  
  1170. WidgetClass genTermEmWidgetClass = (WidgetClass) &genTermEmClassRec;
  1171.  
  1172. static struct StateTable Mods[] =
  1173. {
  1174.  {"Shift",ShiftMask},
  1175.  {"Caps",LockMask},
  1176.  {"Control",ControlMask},
  1177.  {"Mod1",Mod1Mask},
  1178.  {"Mod2",Mod2Mask},
  1179.  {"Mod3",Mod3Mask},
  1180.  {"Mod4",Mod4Mask},
  1181.  {"Mod5",Mod5Mask},
  1182.  {"Button1",Button1Mask},
  1183.  {"Button2",Button2Mask},
  1184.  {"Button3",Button3Mask},
  1185.  {"Button4",Button4Mask},
  1186.  {"Button5",Button5Mask},
  1187.  {NULL,0},
  1188. };
  1189.  
  1190. /* GtEClassInitialize:  This is the class initialization method for the GtEm */
  1191. /*  class widget.  It simply initializes all class fields to NULL. */
  1192.  
  1193. static void GtEClassInitialize()
  1194.  
  1195. {
  1196.  genTermEmClassRec.genTermEm_class.ParseFiles = NULL;
  1197. }
  1198.  
  1199. /* GtEInitialize:  This is the initialization method for the widget.  It */
  1200. /*  initializes all fields in the widget structure, allocates any needed */
  1201. /*  memory and then loads the parse table.  It first checks to see if the */
  1202. /*  parse file has already been loaded.  If it has it extracts the parse */
  1203. /*  table from the class structure.  If it hasn't, it loads the parse file */
  1204. /*  and then adds it to the list of parse file loaded in the class structure */
  1205.  
  1206. static void GtEInitialize(request,new)
  1207.  
  1208. GenTermEmWidget request,new;
  1209.  
  1210. {
  1211.  int i,j,count;
  1212.  int rows,columns;
  1213.  struct GtEParseFile *temp;
  1214.  
  1215.  new->genTermEm.FKeys = (struct FunctionKey *) 
  1216.   XtMalloc(sizeof(struct FunctionKey)* new->genTermEm.NumberFunctionKeys);
  1217.  for(i = 0; i < new->genTermEm.NumberFunctionKeys; i++)
  1218.   {
  1219.    new->genTermEm.FKeys[i].Label = (char *) XtMalloc(sizeof(char)*3);
  1220.    sprintf(new->genTermEm.FKeys[i].Label,"F%d",i+1);
  1221.  
  1222.    new->genTermEm.FKeys[i].String = (char *) XtMalloc(sizeof(char) * 3);
  1223.    strcpy(new->genTermEm.FKeys[i].String,new->genTermEm.FKeys[i].Label);
  1224.  
  1225.    new->genTermEm.FKeys[i].Type = 0;
  1226.   }
  1227.  new->genTermEm.FunctionRealized = FALSE;
  1228.  new->genTermEm.Mods = Mods;
  1229.  
  1230.  if(!GtEGetClassParseFile(new))
  1231.   {
  1232.    GtELoadParseFile(new);
  1233.    temp = (struct GtEParseFile *)XtMalloc(sizeof(struct GtEParseFile));
  1234.    temp->Name = (char *) XtMalloc(strlen(new->genTermEm.ParseFile)+1);
  1235.    strcpy(temp->Name,new->genTermEm.ParseFile);
  1236.    temp->ParseTables = new->genTermEm.ParseList;
  1237.    temp->KeyTables = new->genTermEm.KeyList;
  1238.    temp->Next = genTermEmClassRec.genTermEm_class.ParseFiles;
  1239.    genTermEmClassRec.genTermEm_class.ParseFiles = temp;
  1240.   }
  1241.  
  1242.  new->genTermEm.CurrentPoint = new->genTermEm.ParseTable;
  1243.  new->genTermEm.TopStack = 0;
  1244.  
  1245.  GtGetScreenSize(new,&rows,&columns);
  1246.  count = columns / 8;
  1247.  
  1248.  for(i = 0; i < count; i++)
  1249.   new->genTermEm.TabStops[i] = (i + 1) * 8;
  1250.  for(i = 10; i < NTABS; i++)
  1251.   new->genTermEm.TabStops[i] = columns;
  1252.  
  1253.  new->genTermEm.MapTables = (char **) XtMalloc(sizeof(char *) * 
  1254.                           new->genTermEm.NumMapTables);
  1255.  for(i = 0; i < new->genTermEm.NumMapTables; i++)
  1256.   {
  1257.    new->genTermEm.MapTables[i] = (char *) XtMalloc(sizeof(char ) * NMAP);
  1258.    for(j = 0; j < ' '; j++)
  1259.     new->genTermEm.MapTables[i][j] = ' ';
  1260.    for(j = ' '; j < 128; j++)
  1261.     new->genTermEm.MapTables[i][j] = j;
  1262.    for(j = 128; j < NMAP; j++)
  1263.     new->genTermEm.MapTables[i][j] = ' ';
  1264.   }
  1265.  GtSetMapTable(new,new->genTermEm.MapTables[0]);
  1266.  
  1267.  new->genTermEm.StoreArgs = (struct InputArgument *) 
  1268.   XtMalloc(sizeof(struct InputArgument) * new ->genTermEm.NumStoreArgs);
  1269.  for(i = 0; i < new->genTermEm.NumStoreArgs; i++)
  1270.   new->genTermEm.StoreArgs[i].valid = 0;
  1271.  
  1272.  new->genTermEm.InputArgs = (struct InputArgument *)
  1273.   XtMalloc(sizeof(struct InputArgument) * NUMARGS);
  1274.  for(i = 0; i < NUMARGS; i++)
  1275.   new->genTermEm.InputArgs[i].valid = 0;
  1276.  
  1277.  new->genTermEm.Storage = NULL;
  1278.  new->genTermEm.NumInStorage = 0;
  1279.  new->genTermEm.StorageSize = 0;
  1280.  new->genTermEm.InputBlocked = False;
  1281.  new->genTermEm.WidgetLocked = False;
  1282.  new->genTermEm.NeedWakeUp = False;
  1283.  new->genTermEm.SpecialVars.Started = 0;
  1284. }
  1285.  
  1286. /* GtEGetClassParseFile:  This function looks into the class structure to */
  1287. /*  determine if the required parse file has previously been loaded.  It */
  1288. /*  walks the list of cached parse files.  If it finds the required file */
  1289. /*  it sets up the parse table and key table fields in the instance record */
  1290. /*  returns true.  Otherwise it returns false.  */
  1291.  
  1292. static Boolean GtEGetClassParseFile(w)
  1293.  
  1294. GenTermEmWidget w;
  1295.  
  1296. {
  1297.  struct GtEParseFile *files = genTermEmClassRec.genTermEm_class.ParseFiles;
  1298.  struct GtEList *temp;
  1299.  
  1300.  while(files != NULL)
  1301.   {
  1302.    if(strcmp(files->Name,w->genTermEm.ParseFile) == 0)
  1303.     {
  1304.      w->genTermEm.ParseList = files->ParseTables;
  1305.      w->genTermEm.KeyList = files->KeyTables;
  1306.  
  1307.      temp = w->genTermEm.ParseList;
  1308.      while(temp != NULL)
  1309.       {
  1310.        if(strcmp(temp->Name,DEFAULT) == 0)
  1311.     {
  1312.      w->genTermEm.ParseTable = temp->Point.ParseTable;
  1313.      break;
  1314.     }
  1315.        temp = temp->Next;
  1316.       }
  1317.      if(temp == NULL)
  1318.       XtAppError(XtWidgetToApplicationContext(w),
  1319.          "GenTermEm Widget doesn't find default parse table");
  1320.      
  1321.      temp = w->genTermEm.KeyList;
  1322.      while(temp != NULL)
  1323.       {
  1324.        if(strcmp(temp->Name,DEFAULT) == 0)
  1325.     {
  1326.      w->genTermEm.Keys = temp->Point.KeyTable;
  1327.      w->genTermEm.NumKeys = temp->Num;
  1328.      break;
  1329.     }
  1330.        temp = temp->Next;
  1331.       }
  1332.      if(temp == NULL)
  1333.       XtAppError(XtWidgetToApplicationContext(w),
  1334.          "GenTermEm Widget doesn't find default key table"); 
  1335.      return(True);
  1336.     }
  1337.    files = files->Next;
  1338.   }
  1339.  return(False);
  1340. }
  1341.  
  1342. /* GtERealize:  This is the realize method for the widget.  It simply */
  1343. /*  realizes all the superclasses and then, if required, builds the function */
  1344. /*  key widgets.  Next, if there is a Output file descriptor defined we */
  1345. /*  create a callback to executed when ever there is data ready to be read */
  1346. /*  on it. Finally, we execute the translators associated with the StartUp */
  1347. /*  parse table, if there is any. */
  1348.  
  1349. static void GtERealize(w,valueMask,attributes)
  1350.  
  1351. GenTermEmWidget w;
  1352. XtValueMask *valueMask;
  1353. XSetWindowAttributes *attributes;
  1354.  
  1355. {
  1356.  Arg args[20];
  1357.  int n = 0;
  1358.  WidgetClass superclass;
  1359.  
  1360.  superclass = (WidgetClass)coreWidgetClass;
  1361.  (*superclass->core_class.realize)(w,valueMask,attributes);
  1362.  
  1363.  superclass = (WidgetClass)compositeWidgetClass;
  1364.  (*superclass->core_class.realize)(w,valueMask,attributes);
  1365.  
  1366.  superclass = (WidgetClass)genTermWidgetClass;
  1367.  (*superclass->core_class.realize)(w,valueMask,attributes);
  1368.  
  1369.  if(w->genTermEm.ShowKey)
  1370.   GtERealizeFunctionKeys(w);
  1371.  
  1372.  if(w->genTermEm.OutputDescriptor >= 0)
  1373.   w->genTermEm.OutputId = XtAppAddInput(XtWidgetToApplicationContext(w),
  1374.                        w->genTermEm.OutputDescriptor,
  1375.                        XtInputReadMask,
  1376.                        GtEOutputDescriptorCallBack,(caddr_t)w);
  1377.  XtAddCallback(w,XtNlockCallback,GtELockCallback,(caddr_t)w);
  1378.  GtEExecuteParseTable(w,"StartUp",0);
  1379. }
  1380.  
  1381. /* GtERealizeFunctionKeys:  This function creates the widgets which */
  1382. /*  implement the function keys.  At the moment, I use the XmPushButton */
  1383. /*  widget to do this.  I suppose it would be better if I didn't and */
  1384. /*  created my own or, somehow merged it into this widget, but for now this */
  1385. /*  will have to do.  What it does is figure out how big the widget currently*/
  1386. /*  is.  It then requests that the widget resize it self to fit in the */
  1387. /*  function keys and requests a bottom margin be established to put the */
  1388. /*  widgets into.  Finally, it creates the widgets at the correct location */
  1389.  
  1390. static void GtERealizeFunctionKeys(w)
  1391.  
  1392. GenTermEmWidget w;
  1393.  
  1394. {
  1395.  Arg args[20];
  1396.  int n = 0;
  1397.  int i;
  1398.  Dimension Height,OldHeight;
  1399.  Dimension Width;
  1400.  char buffer[1024];
  1401.  
  1402.  if(w->genTermEm.FunctionRealized == FALSE)
  1403.   {
  1404.    XtSetArg(args[n],XtNheight,&Height); n++;
  1405.    XtSetArg(args[n],XtNwidth,&Width); n++;
  1406.    XtGetValues(w,args,n);
  1407.    
  1408.    OldHeight = Height;
  1409.    Height += w->genTermEm.FuncKeyHeight;
  1410.    n = 0;
  1411.    XtSetArg(args[n],XtNheight,Height); n++;
  1412.    XtSetArg(args[n],XtNbottomMargin,w->genTermEm.FuncKeyHeight); n++;
  1413.    XtSetValues(w,args,n);
  1414.    
  1415.    Width = Width/w->genTermEm.NumberFunctionKeys;
  1416.    for(i = 0; i < w->genTermEm.NumberFunctionKeys; i++)
  1417.     {
  1418.      n = 0;
  1419.      XtSetArg(args[n],XtNy,OldHeight); n++;
  1420.      XtSetArg(args[n],XtNx,Width * i); n++;
  1421.      XtSetArg(args[n],XtNheight,w->genTermEm.FuncKeyHeight); n++;
  1422.      XtSetArg(args[n],XtNwidth,Width);n++;
  1423.      if(strlen(w->genTermEm.FKeys[i].Label) > w->genTermEm.FuncLabelWidth)
  1424.       {
  1425.        memcpy(buffer,w->genTermEm.FKeys[i].Label,w->genTermEm.FuncLabelWidth);
  1426.        buffer[w->genTermEm.FuncLabelWidth] = '\n';
  1427.        strcpy(&(buffer[w->genTermEm.FuncLabelWidth + 1]),
  1428.           &(w->genTermEm.FKeys[i].Label[w->genTermEm.FuncLabelWidth]));
  1429.       }
  1430.      else
  1431.       strcpy(buffer,w->genTermEm.FKeys[i].Label);
  1432.      XtSetArg(args[n],XmNlabelString,
  1433.           XmStringCreateLtoR(buffer,XmSTRING_DEFAULT_CHARSET)); n++;
  1434.      XtSetArg(args[n],XmNalignment,XmALIGNMENT_CENTER); n++;
  1435.      XtSetArg(args[n],XmNrecomputeSize,False); n++;
  1436.      XtSetArg(args[n],XmNtraversalOn,False); n++;
  1437.      w->genTermEm.FKeys[i].FuncKey = (Widget) 
  1438.       XmCreatePushButton(w,w->genTermEm.FKeys[i].Label,args,n);
  1439.      XtManageChild(w->genTermEm.FKeys[i].FuncKey);
  1440.      XtAddCallback(w->genTermEm.FKeys[i].FuncKey,XmNactivateCallback,
  1441.            GtEFunctionKeyPress,(caddr_t)i);
  1442.     }
  1443.    w->genTermEm.FunctionRealized = TRUE;
  1444.   }
  1445.  
  1446. }
  1447.  
  1448. /* GtEFunctionKeyPress:  This is a callback routine for the function keys. */
  1449. /*   It is called whenever a function key is selected from the mouse. */
  1450. /*   Depending on what type of function is associated with that function */
  1451. /*   key, it will dispatch the associated string to either the widget, or */
  1452. /*   the managing application or both.  This function can generate a */
  1453. /*   kbdCallback with the reason being GTE_INPUT. */
  1454.  
  1455. static int GtEFunctionKeyPress(button,client_data,call_data)
  1456.  
  1457. Widget button;
  1458. caddr_t client_data;
  1459. caddr_t call_data;
  1460.  
  1461. {
  1462.  GenTermEmWidget w = (GenTermEmWidget) XtParent(button);
  1463.  XmPushButtonCallbackStruct *ReasonCalled = 
  1464.   (XmPushButtonCallbackStruct *)call_data;
  1465.  int num = (int) client_data;
  1466.  GenTermEmCallback ReasonSent;
  1467.  char buffer[1024];
  1468.  
  1469.  ReasonSent.reason = GTE_INPUT;
  1470.  ReasonSent.event = ReasonCalled->event;
  1471.  ReasonSent.string = buffer;
  1472.  ReasonSent.len = 0;
  1473.  
  1474.  if((w->genTermEm.FKeys[num].Type == 0) || (w->genTermEm.FKeys[num].Type == 2))
  1475.   {
  1476.    strcpy(buffer,w->genTermEm.FKeys[num].String);
  1477.    ReasonSent.len = strlen(buffer);
  1478.   }
  1479.  if((w->genTermEm.FKeys[num].Type == 0) || (w->genTermEm.FKeys[num].Type == 1))
  1480.   {
  1481.    GtEOutput(w,w->genTermEm.FKeys[num].String,
  1482.          strlen(w->genTermEm.FKeys[num].String));
  1483.   }
  1484.  if(ReasonSent.len > 0)
  1485.   XtCallCallbacks(w,XtNkbdCallback,(caddr_t) &ReasonSent);
  1486. }
  1487.  
  1488. /*  GtEGeometryManager:  This is the geometry manager method for the widget. */
  1489. /*   As you can see, I doubt this function is really correct but it seems to */
  1490. /*   do roughly what I want.  This section (and GtEResize) needs more work. */
  1491.  
  1492. static XtGeometryResult GtEGeometryManager(w,request,reply)
  1493.  
  1494. GenTermEmWidget w;
  1495. XtWidgetGeometry *request, *reply;
  1496.  
  1497. {
  1498.  return(XtGeometryYes);
  1499. }
  1500.  
  1501. /* GtEInput:  This is the input action handler for the widget.  It is */
  1502. /*  typically called each time there is a key press.  It first calles */
  1503. /*  GtMarginBell to sound the margin bell, if needed.  It then processes */
  1504. /*  the key event.  There are three possible things that can happen.  First, */
  1505. /*  the key is a normal key in which case the kbdCallback is activated and */
  1506. /*  the passed the result from XLookupString.  The second case is that the */
  1507. /*  key is a function key.  In this case, the key press is processed as a */
  1508. /*  normal function key.  Depending on whether it is an input or output key */
  1509. /*  the associated string for the key is processed or passed to the */
  1510. /*  kdbCallback function.  The final case is that the key is in the key */
  1511. /*  mapping table.  In this case the key is translated according to the */
  1512. /*  mapping table and then either processed via GtEOutput or passed to the */
  1513. /*  kbdCallback. */
  1514.  
  1515. static void GtEInput(w,event,x,y)
  1516.  
  1517. GenTermEmWidget w;
  1518. XEvent *event;
  1519. String *x[];
  1520. Cardinal *y;
  1521.  
  1522. {
  1523.  char buffer[1024];
  1524.  GenTermEmCallback reason;
  1525.  int n;
  1526.  KeySym keysym;
  1527.  int i;
  1528.  
  1529.  GtMarginBell(w);
  1530.  
  1531.  reason.reason = GTE_INPUT;
  1532.  reason.event = event;
  1533.  reason.string = buffer;
  1534.  reason.len = 0;
  1535.  
  1536.  n = XLookupString((XKeyEvent *)event,buffer,sizeof(buffer),&keysym,
  1537.            &(w->genTermEm.ComposeStatus));
  1538.  reason.len = n;
  1539.  
  1540.  if(IsFunctionKey(keysym))
  1541.   {
  1542.    i = keysym - XK_F1;
  1543.    if((i >= 0) && (i < w->genTermEm.NumberFunctionKeys))
  1544.     {
  1545.      if((w->genTermEm.FKeys[i].Type == 0) || (w->genTermEm.FKeys[i].Type == 2))
  1546.       {
  1547.        strcpy(buffer,w->genTermEm.FKeys[i].String);
  1548.        reason.len = strlen(buffer);
  1549.       }
  1550.      if((w->genTermEm.FKeys[i].Type == 0) || (w->genTermEm.FKeys[i].Type == 1))
  1551.       {
  1552.        GtEOutput(w,w->genTermEm.FKeys[i].String,
  1553.          strlen(w->genTermEm.FKeys[i].String));
  1554.       }
  1555.     }
  1556.   }
  1557.  else
  1558.   {
  1559.    for(i = 0; i < w->genTermEm.NumKeys; i++)
  1560.     if((keysym == w->genTermEm.Keys[i].sym) && 
  1561.        (event->xkey.state == w->genTermEm.Keys[i].state))
  1562.      {
  1563.       if((w->genTermEm.Keys[i].type == 'I') || 
  1564.      (w->genTermEm.Keys[i].type == 'B'))
  1565.        {
  1566.     memcpy(buffer,w->genTermEm.Keys[i].string,w->genTermEm.Keys[i].len);
  1567.     reason.len = w->genTermEm.Keys[i].len;
  1568.        }
  1569.       if((w->genTermEm.Keys[i].type == 'O') ||
  1570.      (w->genTermEm.Keys[i].type == 'B'))
  1571.        {
  1572.     GtEOutput(w,w->genTermEm.Keys[i].string,w->genTermEm.Keys[i].len);
  1573.     reason.len = 0;
  1574.        }
  1575.       break;
  1576.      }
  1577.   }
  1578.  if(reason.len > 0)
  1579.   XtCallCallbacks(w,XtNkbdCallback,(caddr_t) &reason);
  1580. }
  1581.  
  1582. /* GtEInvokeTranslation:  This is the invokeTranslation action handler */
  1583. /*  function.  It takes the name of a parse table and executes the */
  1584. /*  translations bound to the top of it. */
  1585.  
  1586. static void GtEInvokeTranslation(w,event,names,num)
  1587.  
  1588. GenTermEmWidget w;
  1589. XEvent *event;
  1590. char *names[];
  1591. Cardinal *num;
  1592.  
  1593. {
  1594.  int i;
  1595.  
  1596.  memcpy(&(w->genTermEm.LastEvent),event,sizeof(XEvent));
  1597.  for(i = 0; i < *num; i++)
  1598.   {
  1599.    GtEExecuteParseTable(w,names[i],True);
  1600.   }
  1601. }
  1602.  
  1603. /* GtEOutputAction:  This is the output action handler for the widget.  It */
  1604. /*  will send the given strings to the widget to be displayed on the screen */
  1605.  
  1606. static void GtEOutputAction(w,event,strings,num)
  1607.  
  1608. GenTermEmWidget w;
  1609. XEvent *event;
  1610. char *strings[];
  1611. Cardinal *num;
  1612.  
  1613. {
  1614.  int i;
  1615.  
  1616.  for(i = 0; i < *num; i++)
  1617.   {
  1618.    GtEOutput(w,strings[i],strlen(strings[i]));
  1619.   }
  1620. }
  1621.  
  1622. /* GtEAWaitGraphicsExpose:  This is the graphics exposure wakeup routine. */
  1623. /*  When the widget goes to sleep waiting for a graphics expose it stops */
  1624. /*  processing all input and shuts down its read handler on the output */
  1625. /*  file descriptor.  This function gets the widget processing events again. */
  1626. /*  First it checks to make sure the widget is ready to be woken up.  If it */
  1627. /*  is and there is stored input waiting to be processed, it calls GtEParse */
  1628. /*  to process them.  Finally, if after the reprocessing, the widget is */
  1629. /*  still ready to run, the read handler is once again enabled. Before */
  1630. /*  leaving, it checks to see if the application should be notified that we */
  1631. /*  are once again alive and if it should it call GtEDoWakeUpCallbacks to */
  1632. /*  generate the required callback. */
  1633.  
  1634. static void GtEAWaitGraphicsExpose(w,event,names,num)
  1635.  
  1636. GenTermEmWidget w;
  1637. XEvent *event;
  1638. char *names[];
  1639. Cardinal *num;
  1640.  
  1641. {
  1642.  int len = w->genTermEm.NumInStorage;
  1643.  
  1644.  if((w->genTerm.ExposureCount == 0) && (w->genTermEm.WidgetLocked == False));
  1645.   {
  1646.    w->genTermEm.NumInStorage = 0;
  1647.    if(len > 0)
  1648.     GtEParse(w,w->genTermEm.Storage,len);
  1649.    if((w->genTerm.ExposureCount == 0) && (w->genTermEm.WidgetLocked == False)
  1650.       && (w->genTermEm.InputBlocked == True))
  1651.     {  /* GtEParse might have shut us down again! */
  1652.      if(w->genTermEm.OutputDescriptor >= 0)
  1653.       w->genTermEm.OutputId = XtAppAddInput(XtWidgetToApplicationContext(w),
  1654.                        w->genTermEm.OutputDescriptor,
  1655.                        XtInputReadMask,
  1656.                        GtEOutputDescriptorCallBack,
  1657.                        (caddr_t)w);
  1658.      w->genTermEm.InputBlocked = False;
  1659.      if(w->genTermEm.NeedWakeUp)
  1660.       GtEDoWakeUpCallbacks(w);
  1661.     }
  1662.   }
  1663. }
  1664.  
  1665. /* GtESetWaitForGraphicsExpose:  Whenever the GenTerm widget performs a */
  1666. /*   scroll it uses the XCopyArea function.  However, the region we copy */
  1667. /*   from might not have been available for copying.  If this is the case */
  1668. /*   then a Graphics Expose event will eventually be generated and handled */
  1669. /*   by the GenTerm widget.  However, the GenTermEm widget is sitting in a */
  1670. /*   tight loop processing characters from its input stream.  Therefore it */
  1671. /*   possible for this widget to block the Graphics Expose events which will */
  1672. /*   put us way out of sync and will cause blank regions to be left on the */
  1673. /*   the screen.  To avoid this, GtEParse checks to see if there are any */
  1674. /*   graphics expose events pending.  If there are, this function is called */
  1675. /*   to store the characters which are still to be processed.  The input */
  1676. /*   desciptor is then blocked and the function returns.  This will pass */
  1677. /*   control back to the X event dispatcher which will generate the expose */
  1678. /*   events we need.  GtEAWaitGraphicsExpose will detect the arrival of */
  1679. /*   these events and restart the processing loop. */
  1680.  
  1681. void GtESetWaitForGraphicsExpose(w,string,start,len)
  1682.  
  1683. GenTermEmWidget w;
  1684. char *string;
  1685. int start;
  1686. int len;
  1687.  
  1688. {
  1689.  int size = len - start;
  1690.  
  1691.  if(size > 0)
  1692.   {
  1693.    if(w->genTermEm.StorageSize < size)
  1694.     {
  1695.      w->genTermEm.Storage = XtRealloc(w->genTermEm.Storage,size * 2 *
  1696.                      sizeof(char));
  1697.      w->genTermEm.StorageSize = size * 2;
  1698.     }
  1699.    memcpy(w->genTermEm.Storage,&(string[start]),size);
  1700.    w->genTermEm.NumInStorage = size;
  1701.   }
  1702.  else
  1703.   w->genTermEm.NumInStorage = 0;
  1704.  
  1705.  if((w->genTermEm.InputBlocked == False) && (w->genTermEm.OutputDescriptor >= 0))
  1706.   {
  1707.    w->genTermEm.InputBlocked = True;
  1708.    XtRemoveInput(w->genTermEm.OutputId);
  1709.   }
  1710. }
  1711.  
  1712. /* GtEAddToStorage:  This function adds data to the queue of characters */
  1713. /*  waiting to be processed.  It is called by GtEOutput when ever it is */
  1714. /*  when the widget is locked or waiting for a graphics expose. */
  1715.  
  1716. static void GtEAddToStorage(w,string,len)
  1717.  
  1718. GenTermEmWidget w;
  1719. char *string;
  1720. int len;
  1721.  
  1722. {
  1723.  if(w->genTermEm.NumInStorage + len >= w->genTermEm.StorageSize)
  1724.   {
  1725.    w->genTermEm.StorageSize += 2 + len;
  1726.    w->genTermEm.Storage = XtRealloc(w->genTermEm.Storage,w->genTermEm.StorageSize
  1727.                    * sizeof(char));
  1728.   }
  1729.  memcpy(&(w->genTermEm.Storage[w->genTermEm.NumInStorage]),string,len);
  1730.  w->genTermEm.NumInStorage += len;
  1731. }
  1732.  
  1733. /* GtEOutput:  This is the main output routine for the widget.  It takes a */
  1734. /*  characters string and the len of the character string and displays them */
  1735. /*  in the widget.  It first checks to see if the widget is ready to display */
  1736. /*  any characters.  If it has been locked or is waiting for a graphics */
  1737. /*  expose it simply enqueues the data, makes a note that the caller's */
  1738. /*  request has been delayed  and returns a value of GTE_WAIT.  The calling */
  1739. /*  routine should honour the GTE_WAIT value by not issuing any more calls */
  1740. /*  to GtEOutput until the WakeUpCallback has been activated.   If the */
  1741. /*  caller does not honour this then the widget will be forced to allocate */
  1742. /*  large amount of memory to buffer the requests but no data will be lost. */
  1743. /*  If PreScroll has been asserted the function then performs the prescroll */
  1744. /*  and then, if the widget hasn't locked itself, it calls GtEParse to parse */
  1745. /*  the input and eventually display it.  Finally, if the widget is */
  1746. /*  currently logging its output, it writes a copy of the data to the log */
  1747. /*  file. */
  1748.  
  1749. int GtEOutput(w,string,len)
  1750.  
  1751. GenTermEmWidget w;
  1752. char *string;
  1753. int len;
  1754.  
  1755. {
  1756.  int rval = GTE_DONE;
  1757.  
  1758.  if((w->genTermEm.WidgetLocked) || (w->genTerm.ExposureCount > 0))
  1759.   {
  1760.    GtEAddToStorage(w,string,len);
  1761.    w->genTermEm.NeedWakeUp = True;
  1762.    rval = GTE_WAIT;
  1763.   }
  1764.  else
  1765.   {
  1766.    if(w->genTermEm.PreScroll == TRUE)
  1767.     GtEPreScroll(w,string,len);
  1768.    if(w->genTerm.ExposureCount > 0)
  1769.     {
  1770.      GtEAddToStorage(w,string,len);
  1771.      w->genTermEm.NeedWakeUp = True;
  1772.      rval = GTE_WAIT;
  1773.     }
  1774.    else
  1775.     GtEParse(w,string,len);
  1776.   }
  1777.  if((w->genTermEm.Logging) && (w->genTermEm.LogFileDescriptor >= 0))
  1778.   write(w->genTermEm.LogFileDescriptor,string,len);
  1779.  return(rval);
  1780. }
  1781.  
  1782. /* GtESetValues:  This is the set values method for the widget.  It is called*/
  1783. /*  whenever the user changes on of the resource variables. */
  1784.  
  1785. static Boolean GtESetValues(cur,req,new,args,numargs)
  1786.  
  1787. GenTermEmWidget cur;
  1788. GenTermEmWidget req;
  1789. GenTermEmWidget new;
  1790. ArgList args;
  1791. Cardinal *numargs;
  1792.  
  1793. {
  1794.  Boolean Redraw = False;
  1795.  struct GtEParseFile *temp;
  1796.  int i,j;
  1797.  
  1798.  if((cur->genTermEm.ParseFile != new->genTermEm.ParseFile) &&
  1799.     (strcmp(cur->genTermEm.ParseFile,new->genTermEm.ParseFile) != 0))
  1800.   {
  1801.    /* This is a really nasty thing to change, particularly since GtEParse */
  1802.    /* might still be in the middle of parsing some queued up input.  Still */
  1803.    /* the user is the boss.  */
  1804.    if(!GtEGetClassParseFile(new))
  1805.     {
  1806.      GtELoadParseFile(new);
  1807.      temp = (struct GtEParseFile *)XtMalloc(sizeof(struct GtEParseFile));
  1808.      temp->Name = (char *) XtMalloc(strlen(new->genTermEm.ParseFile)+1);
  1809.      strcpy(temp->Name,new->genTermEm.ParseFile);
  1810.      temp->ParseTables = new->genTermEm.ParseList;
  1811.      temp->KeyTables = new->genTermEm.KeyList;
  1812.      temp->Next = genTermEmClassRec.genTermEm_class.ParseFiles;
  1813.      genTermEmClassRec.genTermEm_class.ParseFiles = temp;
  1814.     }
  1815.    new->genTermEm.CurrentPoint = new->genTermEm.ParseTable;
  1816.   }
  1817.  
  1818.  if(cur->genTermEm.NumberFunctionKeys != new->genTermEm.NumberFunctionKeys)
  1819.   {
  1820.    new->genTermEm.FKeys = (struct FunctionKey *) 
  1821.     XtMalloc(sizeof(struct FunctionKey)* new->genTermEm.NumberFunctionKeys);
  1822.    for(i = 0; i < new->genTermEm.NumberFunctionKeys; i++)
  1823.     {
  1824.      if(i < cur->genTermEm.NumberFunctionKeys)
  1825.       {
  1826.        new->genTermEm.FKeys[i].Label = cur->genTermEm.FKeys[i].Label;
  1827.        new->genTermEm.FKeys[i].String = cur->genTermEm.FKeys[i].String;
  1828.        new->genTermEm.FKeys[i].Type = cur->genTermEm.FKeys[i].Type;
  1829.       }
  1830.      else
  1831.       {
  1832.        new->genTermEm.FKeys[i].Label = (char *) XtMalloc(sizeof(char)*3);
  1833.        sprintf(new->genTermEm.FKeys[i].Label,"F%d",i+1);
  1834.        
  1835.        new->genTermEm.FKeys[i].String = (char *) XtMalloc(sizeof(char) * 3);
  1836.        strcpy(new->genTermEm.FKeys[i].String,new->genTermEm.FKeys[i].Label);
  1837.        
  1838.        new->genTermEm.FKeys[i].Type = 0;
  1839.       }
  1840.     }
  1841.    if(new->genTermEm.FunctionRealized == True)
  1842.     {
  1843.      GtEDestroyFunctionKeys(cur);
  1844.      GtERealizeFunctionKeys(new);
  1845.     }
  1846.    for(i = new->genTermEm.NumberFunctionKeys; 
  1847.        i < cur->genTermEm.NumberFunctionKeys; i++)
  1848.     {
  1849.      XtFree(cur->genTermEm.FKeys[i].Label);
  1850.      XtFree(cur->genTermEm.FKeys[i].String);
  1851.     }
  1852.    XtFree(cur->genTermEm.FKeys);
  1853.   }
  1854.  
  1855.  if((cur->genTermEm.FuncKeyHeight != new->genTermEm.FuncKeyHeight) &&
  1856.     (new->genTermEm.FunctionRealized == True))
  1857.   {
  1858.    GtEDestroyFunctionKeys(new);
  1859.    GtERealizeFunctionKeys(new);
  1860.   }
  1861.  
  1862.  if(cur->genTermEm.ShowKey != new->genTermEm.ShowKey)
  1863.   {
  1864.    if(new->genTermEm.ShowKey)
  1865.     GtERealizeFunctionKeys(new);
  1866.    else
  1867.     GtEDestroyFunctionKeys(new);
  1868.   }
  1869.  
  1870.  if((cur->genTermEm.OutputDescriptor != new->genTermEm.OutputDescriptor) &&
  1871.     (XtIsRealized(new)))
  1872.   {
  1873.    if(cur->genTermEm.OutputDescriptor >= 0)
  1874.     XtRemoveInput(new->genTermEm.OutputId);
  1875.    if(new->genTermEm.OutputDescriptor >= 0)
  1876.     new->genTermEm.OutputId = XtAppAddInput(XtWidgetToApplicationContext(new),
  1877.                        new->genTermEm.OutputDescriptor,
  1878.                        XtInputReadMask,
  1879.                        GtEOutputDescriptorCallBack,
  1880.                        (caddr_t)new);
  1881.   }
  1882.  if(cur->genTermEm.NumMapTables != new->genTermEm.NumMapTables)
  1883.   {
  1884.    new->genTermEm.MapTables = (char **) XtMalloc(sizeof(char *) * 
  1885.                         new->genTermEm.NumMapTables);
  1886.    for(i = 0; i < new->genTermEm.NumMapTables; i++)
  1887.     {
  1888.      if(i < cur->genTermEm.NumMapTables)
  1889.       new->genTermEm.MapTables[i] = cur->genTermEm.MapTables[i];
  1890.      else
  1891.       {
  1892.        new->genTermEm.MapTables[i] = (char *) XtMalloc(sizeof(char ) * NMAP);
  1893.        for(j = 0; j < ' '; j++)
  1894.     new->genTermEm.MapTables[i][j] = ' ';
  1895.        for(j = ' '; j < 128; j++)
  1896.     new->genTermEm.MapTables[i][j] = j;
  1897.        for(j = 128; j < NMAP; j++)
  1898.     new->genTermEm.MapTables[i][j] = ' ';
  1899.       }
  1900.     }
  1901.    for(i = new->genTermEm.NumMapTables; i < cur->genTermEm.NumMapTables; i++)
  1902.     XtFree(cur->genTermEm.MapTables[i]);
  1903.    XtFree(cur->genTermEm.MapTables);
  1904.   }
  1905.  if(cur->genTermEm.NumStoreArgs != new->genTermEm.NumStoreArgs)
  1906.   {
  1907.    new->genTermEm.StoreArgs = (struct InputArgument *) 
  1908.     XtMalloc(sizeof(struct InputArgument) * new ->genTermEm.NumStoreArgs);
  1909.    for(i = 0; i < new->genTermEm.NumStoreArgs; i++)
  1910.     {
  1911.      if(i < cur->genTermEm.NumStoreArgs)
  1912.       {
  1913.        new->genTermEm.StoreArgs[i].string = cur->genTermEm.StoreArgs[i].string;
  1914.        new->genTermEm.StoreArgs[i].length = cur->genTermEm.StoreArgs[i].length;
  1915.        new->genTermEm.StoreArgs[i].valid = cur->genTermEm.StoreArgs[i].valid;
  1916.       }
  1917.      else
  1918.       new->genTermEm.StoreArgs[i].valid = 0;
  1919.     }
  1920.    for(i = new->genTermEm.NumStoreArgs; i < cur->genTermEm.NumStoreArgs; i++)
  1921.     {
  1922.      if(cur->genTermEm.StoreArgs[i].valid & AMALLOCED)
  1923.       XtFree(cur->genTermEm.StoreArgs[i].string);
  1924.     }
  1925.    XtFree(cur->genTermEm.StoreArgs);
  1926.   }
  1927.  
  1928.  return(Redraw);
  1929. }
  1930.  
  1931. /* GtEResize:  This is the resize method for the widget.  It is called */
  1932. /*  whenever the widget has to be resized.  It first make sure the GenTerm */
  1933. /*  widget's resize method is called and then proceeds with itself.  If the */
  1934. /*  function keys are realized it call XtMoveWidget to move them to the new */
  1935. /*  location. */
  1936.  
  1937. static void GtEResize(w)
  1938.  
  1939. GenTermEmWidget w;
  1940. {
  1941.  WidgetClass superclass;
  1942.  Arg args[20];
  1943.  int n,i;
  1944.  Dimension Height,Width;
  1945.  char buffer[1024];
  1946.  
  1947.  superclass = (WidgetClass)genTermWidgetClass;
  1948.  (*superclass->core_class.resize)(w);
  1949.  
  1950.  if(w->genTermEm.FunctionRealized == True)
  1951.   {
  1952.    n = 0;
  1953.    XtSetArg(args[n],XtNheight,&Height); n++;
  1954.    XtSetArg(args[n],XtNwidth,&Width); n++;
  1955.    XtGetValues(w,args,n);
  1956.    
  1957.    Height -= w->genTermEm.FuncKeyHeight;
  1958.    Width = Width/w->genTermEm.NumberFunctionKeys;
  1959.    for(i = 0; i < w->genTermEm.NumberFunctionKeys; i++)
  1960.     {
  1961.      XtMoveWidget(w->genTermEm.FKeys[i].FuncKey,Width * i,Height);
  1962.     }
  1963.   }
  1964. }
  1965.  
  1966. /* GtEDestroy:  This is the destroy method for the widget.  It is called */
  1967. /*  when the widget is being destroyed.  It simply frees all the allocated */
  1968. /*  memory.  */
  1969.  
  1970. static void GtEDestroy(w)
  1971.  
  1972. GenTermEmWidget w;
  1973.  
  1974. {
  1975.  int i;
  1976.  
  1977.  for(i = 0; i < w->genTermEm.NumberFunctionKeys; i++)
  1978.   {
  1979.    XtFree(w->genTermEm.FKeys[i].Label);
  1980.    XtFree(w->genTermEm.FKeys[i].String);
  1981.   }
  1982.  GtEDestroyFunctionKeys(w);
  1983.  XtFree(w->genTermEm.FKeys);
  1984.  
  1985.  for(i = 0; i < w->genTermEm.NumMapTables; i++)
  1986.   {
  1987.    XtFree(w->genTermEm.MapTables[i]);
  1988.   }
  1989.  XtFree(w->genTermEm.MapTables);
  1990.  
  1991.  for(i = 0; i < w->genTermEm.NumStoreArgs; i++)
  1992.   if(w->genTermEm.StoreArgs[i].valid & AMALLOCED)
  1993.    XtFree(w->genTermEm.StoreArgs[i]);
  1994.  XtFree(w->genTermEm.StoreArgs);
  1995.  
  1996.  for(i = 0; i < NUMARGS; i++)
  1997.   if(w->genTermEm.InputArgs[i].valid & AMALLOCED)
  1998.    XtFree(w->genTermEm.InputArgs[i]);
  1999.  XtFree(w->genTermEm.InputArgs);
  2000.  
  2001.  XtFree(w->genTermEm.Storage);
  2002.  if((w->genTermEm.InputBlocked == False) && (w->genTermEm.OutputDescriptor >= 0))
  2003.   {
  2004.    w->genTermEm.InputBlocked = True;
  2005.    XtRemoveInput(w->genTermEm.OutputId);
  2006.   }
  2007. }
  2008.  
  2009. /* GtEDestroyFunctionKeys:  This function removes the function key widgets */
  2010. /*  from the screen and then causes the widget to shrink and removes the */
  2011. /*  bottom margin. */
  2012.  
  2013. static void GtEDestroyFunctionKeys(w)
  2014.  
  2015. GenTermEmWidget(w);
  2016.  
  2017. {
  2018.  int i;
  2019.  Arg args[20];
  2020.  int n = 0;
  2021.  Dimension Height;
  2022.  
  2023.  if(w->genTermEm.FunctionRealized)
  2024.   {
  2025.    w->genTermEm.FunctionRealized = False;
  2026.  
  2027.    for(i = 0; i < w->genTermEm.NumberFunctionKeys; i++)
  2028.     XtDestroyWidget(w->genTermEm.FKeys[i].FuncKey);
  2029.    
  2030.    XtSetArg(args[n],XtNheight,&Height); n++;
  2031.    XtGetValues(w,args,n);
  2032.    
  2033.  
  2034.    Height -= w->genTermEm.FuncKeyHeight;
  2035.    n = 0;
  2036.    XtSetArg(args[n],XtNheight,Height); n++;
  2037.    XtSetArg(args[n],XtNbottomMargin,0); n++;
  2038.    XtSetValues(w,args,n);
  2039.  
  2040.    w->genTermEm.FunctionRealized = FALSE;
  2041.   }
  2042. }
  2043.  
  2044. static void GtEOutputDescriptorCallBack(client_data,source,id)
  2045.  
  2046. XtPointer client_data;
  2047. int *source;
  2048. XtInputId *id;
  2049.  
  2050. {
  2051.  GenTermEmWidget w = (GenTermEmWidget) client_data;
  2052.  char buffer[1024];
  2053.  int nread;
  2054.  
  2055.  while((w->genTerm.ExposureCount <= 0) && (w->genTermEm.WidgetLocked == False) &&
  2056.        ((nread = read(*source,buffer,1024)) > 0))
  2057.   {
  2058.    GtEOutput(w,buffer,nread);
  2059.   }
  2060. }
  2061.  
  2062. /* GtEExecuteParseTable:  This function will execute the translators found */
  2063. /*  at the top of the specified parse table, if any. */
  2064.  
  2065. int GtEExecuteParseTable(w,name,verbose)
  2066.  
  2067. GenTermEmWidget w;
  2068. char *name;
  2069. int verbose;
  2070.  
  2071. {
  2072.  struct GtEList *temp = w->genTermEm.ParseList;
  2073.  struct Translator *Functions;
  2074.  int ReturnVal,k;
  2075.  struct InputArguments *Args;
  2076.  
  2077.  while(temp != NULL)
  2078.   {
  2079.    if(strcmp(name,temp->Name) == 0)
  2080.     break;
  2081.    temp = temp->Next;
  2082.   }
  2083.  if(temp == NULL)
  2084.   {
  2085.    if(verbose)
  2086.     XtAppWarning(XtWidgetToApplicationContext(w),
  2087.          "Invalid Parse Table encountered in GtEExecuteParseTable");
  2088.    return(0);
  2089.   }
  2090.  else
  2091.   {
  2092.    Args = GtEPushArgs(w);
  2093.    Functions = temp->Point.ParseTable->translators;
  2094.     while(Functions != NULL)
  2095.      {
  2096.       ReturnVal = (Functions->func)(w,Functions->arglist);
  2097.       if(ReturnVal == TRANSERROR)
  2098.        break;
  2099.       else if(ReturnVal == TRANSOKAY)
  2100.        Functions = Functions->next;
  2101.       else if(ReturnVal == TRANSREJECT)
  2102.        break;
  2103.       else
  2104.        {
  2105.     while((Functions != NULL) &&(Functions->label != ReturnVal))
  2106.      Functions = Functions->next;
  2107.        }
  2108.      }
  2109.    /* okay, here walk input argument list to free what ever needed */
  2110.    for(k = 0; k < NUMARGS; k++)
  2111.     if(w->genTermEm.InputArgs[k].valid & AMALLOCED)
  2112.      {
  2113.       XtFree(w->genTermEm.InputArgs[k].string);
  2114.       w->genTermEm.InputArgs[k].valid = 0;
  2115.      }
  2116.    GtEPopArgs(w,Args);
  2117.   }
  2118.  return(0);
  2119. }
  2120.  
  2121. /* GtEInsertSelection:  This is the insertSelection action handler.  It */
  2122. /*  merely determines where the selection is coming from and then reqesters */
  2123. /*  the handler to to actually get the selection. */
  2124.  
  2125. static void GtEInsertSelection(w,event,names,num)
  2126.  
  2127. GenTermEmWidget w;
  2128. XEvent *event;
  2129. char *names[];
  2130. Cardinal *num;
  2131.  
  2132. {
  2133.  Atom which = XA_PRIMARY;
  2134.  int i;
  2135.  
  2136.  w->genTermEm.CutBuffer = -1;
  2137.  
  2138.  for(i = 0; i < *num; i++)
  2139.   {
  2140.    if(strcmp(names[i],"SECONDARY") == 0)
  2141.     which = XA_SECONDARY;
  2142.    else if(strncmp(names[i],"CUT_BUFFER",strlen("CUT_BUFFER")) == 0)
  2143.     {
  2144.      w->genTermEm.CutBuffer = names[i][strlen("CUT_BUFFER")] - '0';
  2145.     }
  2146.   }
  2147.  
  2148.  XtGetSelectionValue(w,which,XA_STRING,GtEInsertCallback,NULL,
  2149.              event->xbutton.time);
  2150. }
  2151.  
  2152. /* GtEInsertCallback:  This is the procedure which gets the selection.  If */
  2153. /*  the selection was coming from a cutbuffer then it gets its from there. */
  2154. /*  Once the selection is obtained, it generates a kbdCallback with a reason */
  2155. /*  of GTE_INPUT. */
  2156.  
  2157. static void GtEInsertCallback(w,client_data,selection,type,value,length,format)
  2158.  
  2159. GenTermEmWidget w;
  2160. XtPointer client_data;
  2161. Atom *selection;
  2162. Atom *type;
  2163. XtPointer *value;
  2164. unsigned long *length;
  2165. int *format;
  2166.  
  2167. {
  2168.  GenTermEmCallback reason;
  2169.  
  2170.  if((value == NULL) || ((*value == NULL) && (*length == 0)))
  2171.   {
  2172.    if(w->genTermEm.CutBuffer >= 0)
  2173.     {
  2174.      reason.string = XFetchBuffer(XtDisplay(w),&(reason.len),
  2175.                   w->genTermEm.CutBuffer);
  2176.      if(reason.len > 0)
  2177.       {
  2178.        reason.reason = GTE_INPUT;
  2179.        reason.event = NULL;
  2180.        XtCallCallbacks(w,XtNkbdCallback,(caddr_t)&reason);
  2181.       }
  2182.     }
  2183.   }
  2184.  else
  2185.   {
  2186.    reason.reason = GTE_INPUT;
  2187.    reason.event = NULL;
  2188.    reason.string = (char *)value;
  2189.    reason.len = *length;
  2190.    XtCallCallbacks(w,XtNkbdCallback,(caddr_t)&reason);
  2191.   }
  2192. }
  2193.  
  2194. /* GtELockCallback: This is the lock callback.  It intercepts the underlying */
  2195. /*   GenTerm widget locking itself and records this for our use.  If we are */
  2196. /*   unlocking ourself and there is data in our storage buffer it is */
  2197. /*   processed.  A wakeupCallback can be generated. */
  2198.  
  2199. static void GtELockCallback(w,type,reason)
  2200.  
  2201. GenTermEmWidget w;
  2202. int type;
  2203. GenTermCallback *reason;
  2204.  
  2205. {
  2206.  int len;
  2207.  if(reason->Value)
  2208.   {
  2209.    w->genTermEm.WidgetLocked = True;
  2210.    if((w->genTermEm.InputBlocked == False) && 
  2211.       (w->genTermEm.OutputDescriptor >= 0))
  2212.     {
  2213.      w->genTermEm.InputBlocked = True;
  2214.      XtRemoveInput(w->genTermEm.OutputId);
  2215.     }
  2216.   }
  2217.  else
  2218.   {
  2219.    w->genTermEm.WidgetLocked = False;
  2220.    if(w->genTerm.ExposureCount == 0)
  2221.     {
  2222.      len = w->genTermEm.NumInStorage;
  2223.      w->genTermEm.NumInStorage = 0;
  2224.      if(len > 0)
  2225.       GtEParse(w,w->genTermEm.Storage,len);
  2226.      if((w->genTerm.ExposureCount == 0) && (w->genTermEm.InputBlocked == True))
  2227.       {
  2228.        if(w->genTermEm.OutputDescriptor >= 0)
  2229.     w->genTermEm.OutputId = XtAppAddInput(XtWidgetToApplicationContext(w),
  2230.                          w->genTermEm.OutputDescriptor,
  2231.                          XtInputReadMask,
  2232.                          GtEOutputDescriptorCallBack,
  2233.                          (caddr_t)w);
  2234.        w->genTermEm.InputBlocked = False;
  2235.        if(w->genTermEm.NeedWakeUp)
  2236.     GtEDoWakeUpCallbacks(w);
  2237.       }
  2238.     }
  2239.   }
  2240. }
  2241.  
  2242. /* GtEDoWakeUpCallbacks:  This function envokes the wakeup call back.  A */
  2243. /*  wakeup callback is asserted whenever the widget has completed processing */
  2244. /*  all the queued data after it has asserted GTE_WAIT from GtEOutput. */
  2245.  
  2246. GtEDoWakeUpCallbacks(w)
  2247.  
  2248. GenTermEmWidget w;
  2249.  
  2250. {
  2251.  GenTermEmCallback ReasonSent;
  2252.  
  2253.  ReasonSent.reason = GTE_WAKEUP;
  2254.  
  2255.  XtCallCallbacks(w,XtNwakeUpCallback,(caddr_t)&ReasonSent);
  2256. }
  2257.  
  2258. /* GtEPreScroll:  This function attempts to estimate the amount of lines in */
  2259. /*  a given piece of text.  In reality it can't determine this with out */
  2260. /*  passing it through GtEParse.  However, to implement a jump scroll we need*/
  2261. /*  to be able to estimate it.  It does this by counting the occurance of */
  2262. /*  a specified ScrollChar (typically \n) in the string.  Because escape */
  2263. /*  sequences can make this count invalid we also abort this function if we */
  2264. /*  find the start of a possible escape sequence (ScrollAbortChar). Finally */
  2265. /*  if the amount of scrolling is large enough it moves the screen down and */
  2266. /*  then returns the cursor to its correct position. */
  2267.  
  2268. static void GtEPreScroll(w,string,len)
  2269.  
  2270. GenTermEmWidget w;
  2271. char *string;
  2272. int len;
  2273.  
  2274. {
  2275.  int jump = 0;
  2276.  int i;
  2277.  int rows,cols;
  2278.  int crow,ccol;
  2279.  
  2280.  for(i = 0; i < len; i++)
  2281.   {
  2282.    if(string[i] == w->genTermEm.ScrollAbortChar)
  2283.     return;
  2284.    if(string[i] == w->genTermEm.ScrollChar)
  2285.     jump++;
  2286.   }
  2287.  
  2288.  if(jump > 2)
  2289.   {
  2290.    GtGetScreenSize(w,&rows,&cols);
  2291.    GtGetCursorPosition(w,&crow,&ccol);
  2292.    if(jump > rows)
  2293.     jump = rows - 2;
  2294.    if(jump + crow > rows + 1)
  2295.     {
  2296.      GtNewLine(w,jump);
  2297.      GtCursorUp(w,jump,0);
  2298.     }
  2299.   }
  2300. }
  2301. @EOF
  2302. set `wc -lwc <GenTerm/GenTermEm.c`
  2303. if test $1$2$3 != 1305417241615
  2304. then
  2305.     echo ERROR: wc results of GenTerm/GenTermEm.c are $* should be 1305 4172 41615
  2306. fi
  2307.  
  2308. chmod 644 GenTerm/GenTermEm.c
  2309.  
  2310. echo x - GenTerm/GenTermEm.man
  2311. sed 's/^@//' >GenTerm/GenTermEm.man <<'@EOF'
  2312. @.\" Man page for the GenTermEm Widget -*-nroff-*-
  2313. @.\"
  2314. @.\"  Written by G. Strachan 1992
  2315. @.\"
  2316. @.de KS  \"      Keep start
  2317. @.br
  2318. @.in 0
  2319. @.di KP
  2320. @..
  2321. @.de KE  \"      Keep end
  2322. @.br
  2323. @.di
  2324. @.ne \\n(dnu
  2325. @.nr fI \\n(.u
  2326. @.nf
  2327. @.KP
  2328. @.if \\n(fI .fi
  2329. @.in
  2330. @..
  2331. @.TH GenTermEm 3X
  2332. @.SH NAME
  2333. \fBGenTermEm \- The Generalized terminal emulator widget class.\fP
  2334. @.sp 1
  2335. @.SH SYNOPSIS
  2336. \fB#include "/usr/local/include/GenTermEm.h"\fP
  2337. @.SH DESCRIPTION
  2338. The \fBGenTermEm\fP widget is a generalized terminal emulator widget.
  2339. It inherits all capabilities and resources of the \fBGenTerm\fP widget
  2340. and adds the capability of emulating a specific terminal.  The widget
  2341. does not emulate any one terminal but, instead, can be configured to
  2342. emulate many different types of terminals.  The widget consists of a
  2343. translation table which defines the behavior of each key on the
  2344. keyboard and a parse table which defines the escape sequences the
  2345. terminal supports and the actions they perform.  In addition, the widget
  2346. also supports a set of programmable function keys which can be
  2347. displayed below the terminal screen and a logging capability.
  2348. @.SH CLASSES
  2349. \fBGenTermEm\fP inherits behavior and resources from \fBGenTerm\fP,
  2350. \fBCore\fP and \fBComposite\fP classes.
  2351. @.PP
  2352. The class pointer is \fBgenTermEmWidgetClass\fP
  2353. @.PP
  2354. The class name is \fBGenTermEm\fP
  2355. @.SH "NEW RESOURCES"
  2356. The following table list the resources recognized by the
  2357. \fBGenTermEm\fP widget.  The programmer can also set the resource of
  2358. the inherited classes. To set these resources in the resource
  2359. database, remove the \fBXtN\fP and the \fBXtC\fP prefix of the
  2360. resource name.
  2361. @.sp 1 
  2362. @.KS
  2363. @.sp 1
  2364. @.TS
  2365. center;
  2366. cB sss
  2367. lB lB lB lB
  2368. llll.
  2369. GenTermEm Resource Set
  2370. Name    Class    Type    Default
  2371. _
  2372. XtNdestructiveTab    XtCDestructiveTab    Boolean    True
  2373. XtNescCallback    XtCEscCallback    Callback    Null
  2374. XtNflowCallback    XtCFlowCallback    Callback    Null
  2375. XtNfunctionLabelWidth    XtCFunctionLabelWidth    Int    8
  2376. XtNfunctionSize    XtCFunctionSize    Dimension    39
  2377. XtNlogFile    XtCLogFile    Int    -1
  2378. XtNlogging    XtCLogging    Boolean    False
  2379. XtNname    XtCName    String    term0
  2380. XtNnumberFunctionKeys    XtCNumberFunctionKeys    Int    8
  2381. XtNnumberMapTables    XtCNumberMapTables    Int    1
  2382. XtNnumberStorageArguments    XtCNumberStorageArguments    Int    20
  2383. XtNoutputFile    XtCOutputFile    Int    -1
  2384. XtNparseFile    XtCParseFile    String    ./hpterm.par
  2385. XtNpreScroll    XtCPreScroll    Boolean    False
  2386. XtNscrollAbortChar    XtCScrollAbortChar    Char    ^[
  2387. XtNscrollChar    XtCScrollChar    Char    ^J
  2388. XtNshowFunction    XtCShowFunction    Boolean    False
  2389. XtNwakeUpCallback    XtCWakeUpCallback    Callback    NULL
  2390. @.TE
  2391. @.KE
  2392. @.sp 1
  2393. @.IP "\fBXtNdestructiveTab\fP"
  2394. This resource specifies the behavior of the tab key.  If \fBTrue\fP,
  2395. then striking the tab key causes the cursor to move to the next tab
  2396. stop on the line and erasing any characters is passed.  If \fBFalse\fP
  2397. then the cursor will move to the next tap stop passing over any
  2398. characters.
  2399. @.IP "\fBXtNescCallback\fP"
  2400. This resource specifies the list of callback functions to call when
  2401. ever the widget executes the \fIEscapeCallback\fP input translator
  2402. function.  This allows the calling application to handle specific
  2403. input escape sequences in the input stream.
  2404. @.IP "\fBXtNflowCallback\fP"
  2405. This resource specifies the list of callback functions to call when
  2406. ever the widget executes the \fISetFlow\fP input translator function.
  2407. This allows the calling application to respond to flow control
  2408. requests.
  2409. @.IP "\fBXtNfunctionLabelWidth\fP"
  2410. This resources specifies how many characters wide the function key
  2411. labels should be when they are displayed.
  2412. @.IP "\fBXtNfunctionSize\fP"
  2413. This resource specifies the height of the function key widgets when
  2414. they are displayed.
  2415. @.IP "\fBXtNlogFile\fP"
  2416. This resource specifies the file descriptor for the log file.  If
  2417. logging is enabled, all input and output characters will be written to
  2418. this file.  The file should be opened for writing.
  2419. @.IP "\fBXtNlogging\fP"
  2420. This resource specifies if logging is currently enabled.  If the
  2421. resource is set to \fITrue\fP then all characters either read or
  2422. written will be also written to the file specified by the
  2423. \fBXtNlogFile\fP resource.
  2424. @.IP "\fBXtNname\fP"
  2425. This resource contains the name of the terminal the widget is
  2426. currently emulating.  Currently, this resource is unused and does not
  2427. affect the behavior of the widget.
  2428. @.IP "\fBXtNnumberFunctionKeys\fP"
  2429. This resource specifies how many programmable function keys there are.
  2430. @.IP "\fBXtNnumberMapTables\fP"
  2431. This resource specifies how many output mapping tables can exist
  2432. simultaneously.
  2433. @.IP "\fBXtNnumberStorageArguments\fP"
  2434. This resource specifies how many global variables the input translator
  2435. functions can access.
  2436. @.IP "\fBXtNoutputFile\fP"
  2437. This resource specifies the file descriptor from which it will receive
  2438. input.  The descriptor should be associated with an IPC channel which
  2439. is connected to the output a program which is attached to this
  2440. terminal emulator.  Usually this is a pty but, other file types can be
  2441. used such as pipe, fifo's or sockets can be used.  The widget performs
  2442. only read operations on the descriptor however, the file type
  2443. associated with the descriptor should be suitable for use in the
  2444. \fIXtAppAddInput\fP function.
  2445. @.IP "\fBXtNparseFile\fP"
  2446. This resource specifies the complete path name of the file containing
  2447. the parse table and key tables.  This resource controls what kind of
  2448. terminal the widget is emulating.  If after realization, this
  2449. resource is altered, the widget will reset itself and load the new
  2450. file and thereby change its emulation.
  2451. @.IP "\fBXtNpreScroll\fP"
  2452. This resource specifies whether the widget should perform a prescroll
  2453. or not.  Because of the separation of the widget into a parser widget
  2454. and terminal management widget, a proper smooth scroll can not be
  2455. efficiently implemented.  Therefore, a prescroll is implemented.  If
  2456. this resource is \fITrue\fP, on each block of text, the widget first
  2457. attempts to guess how many lines are required to print the text prior
  2458. to parsing it.  It then requests that many lines from the terminal
  2459. management widget.
  2460. @.IP "\fBXtNscrollAbortChar\fP"
  2461. This resource defines a character which will cause the widget to abort
  2462. calculating the prescroll region.  Typically this resource corresponds
  2463. to the starting character of an escape sequence that would cause the
  2464. cursor to move.  This may cause the prescroll count to be incorrect so
  2465. the widget will abort and process the text block normally.
  2466. @.IP "\fBXtNscrollChar\fP"
  2467. This resource defines the character which causes the cursor to move
  2468. down one line.  It is used for the prescroll calculation only.
  2469. @.IP "\fBXtNshowFunciton\fP"
  2470. This resource specifies whether the widget should display the function
  2471. keys on the screen or not.
  2472. @.IP "\fBXtNwakeUpCallback\fP"
  2473. This resource specifies a list of callback functions to call when ever
  2474. the widget wakes itself up.  The widget goes to sleep when ever
  2475. graphics events are still pending or the \fBGenTerm\fP has locked
  2476. itself.  It wakes up when the graphics expose events are complete or
  2477. the \fBGenTerm\fP widget unlocks itself.  A callback is generated to
  2478. inform the calling application it is now ready to process more
  2479. characters.
  2480. @.sp 1
  2481. @.sp 1
  2482. @.SH "CALLBACK INFORMATION"
  2483. A pointer to the following structure is passed to each callback:
  2484. @.sp .5
  2485. @.nf
  2486. @.ta .25i 1.1i
  2487. \fBtypedef struct\fP
  2488. {
  2489.     \fBint\fP    \fIreason\fP;
  2490.     \fBXEvent\fP    \fI* event\fP;
  2491.     \fBchar\fP    \fI* string\fP;
  2492.     \fBint\fP    \fILen\fP;
  2493.     \fBchar\fP    \fI** escapes\fP;
  2494. } \fBGenTermEmCallback\fP;
  2495. @.fi
  2496. @.sp .5
  2497. @.IP "\fIreason\fP"
  2498. Indicates why the callback was called.
  2499. Possible values are: \fIGTE_INPUT\fP, \fIGTE_ESCAPE\fP,
  2500. \fIGTE_WAKEUP\fP, \fIGTE_XOFF\fP and \fIGTE_XON\fP.
  2501. @.IP "\fIevent\fP"
  2502. Points the the \fBXEvent\fP structure which triggered this event (if
  2503. any event did).
  2504. @.IP "\fIstring\fP"
  2505. If \fBreason\fP equals \fIGTE_INPUT\fP then \fBstring\fP points to the
  2506. characters that were entered by the user.
  2507. @.IP "\fILen\fP"
  2508. If \fBreason\fP equals \fIGTE_INPUT\fP the \fBLen\fP is equal to the
  2509. number of characters that \fBstring\fP points to.
  2510. @.IP "\fIescapes\fP"
  2511. If \fBreason\fP equals \fIGTE_ESCAPE\fP the \fIescapes\fP points to a
  2512. array of null terminated strings.  The final string in the list is
  2513. NULL.  The number and values of the \fIescapes\fP strings  depends on
  2514. the \fBEscapeCallback\fP input translator.
  2515. @.SH "TRANSLATIONS"
  2516. The \fIGenTermEm\fP widget has the following default translations:
  2517. \fB
  2518. @.nf
  2519. @.ta 1.8i
  2520. @.sp 0.5
  2521. <KeyPress>:    input()
  2522. <Expose>:    expose()
  2523. <GraphicsExpose>:    expose() awaitgraphicsexpose()
  2524. <NoExpose>:    noexpose() awaitgraphicsexpose()
  2525. <Btn1Down>:    StartSelection()
  2526. <Btn1Motion>:    ExtendSelection()
  2527. <Btn1Up>:    MakeSelection(PRIMARY,CUT_BUFFER0)
  2528. <Btn2Up>:    InsertSelection(PRIMARY,CUT_BUFFER0)
  2529. @.fi
  2530. \fP
  2531. @.SH "ACTIONS"
  2532. The \fIGenTermEm\fP action routines are:
  2533. @.IP "\fBawaitgraphicsexpose()\fP"
  2534. Determines if all pending graphics expose events have been processed.
  2535. If they have then it wakes the widget up and starts the processing of
  2536. characters.  It may invoke the \fBXtNwakeUpCallback\fP.
  2537. @.IP "\fBinput()\fP"
  2538. Process a key press event.  If the key was a function key then it is
  2539. expanded to its currently programmed value and executed.  If the key
  2540. is defined in the currently active key table then it is converted to
  2541. its appropriate value.  If the key is an \fIoutput\fP key or a
  2542. \fIboth\fP key, then the resultant string is passed through the parser
  2543. to be printed on the screen.  If it is an \fIinput\fP key or a
  2544. \fIboth\fP key then the \fBXtNkbdCallback\fP is invoked with a reason
  2545. of \fIGTE_INPUT\fP.  In the callback structure \fBstring\fP will point
  2546. to translated key value.
  2547. @.IP "\fBInsertSelection(Source)\fP"
  2548. Inserts text from the specified source.  \fBSource\fP and be any of
  2549. \fIPRIMARY\fP, \fISECONDARY\fP or \fICUT_BUFFERn\fP where n is an
  2550. integer from 0 to 7.  You can specify multiple sources in which case
  2551. the action takes the text from the first source that contains text.
  2552. The action then invokes a \fIXtNkbdCallback\fP with a reason of
  2553. \fBGTE_INPUT\fP.
  2554. @.IP "\fBinvokeTranslation(table)\fP"
  2555. Executes a parse table.  The action takes the name of a parse table
  2556. which is defined in the currently loaded parse file and executes any
  2557. input translations that are bound to its first translation rule.
  2558. @.IP "\fBoutput(string)\fP"
  2559. Print the arguments on the screen.  The argument to the action are
  2560. processed through the parser and printed on the widget's screen.
  2561. @.sp 1
  2562. @.SH "THE PARSE FILE"
  2563. The parse file contains all the terminal emulation information the
  2564. widget requires to emulation a specific terminal.  It contains
  2565. translation tables for the key events and the definitions for the
  2566. parser for the output stream.
  2567. @.LP
  2568. The syntax of the parse file is as follows.  Any line starting with a
  2569. \fI#\fP character is considered a comment.  In addition, the \fI^\fP
  2570. character is special.  When encountered the widget reads in the next
  2571. character and clears its seventh bit.  This allows control characters
  2572. to be read in.  Any special characters can be escaped by preceding
  2573. them with the \fI\\\fP character.  The format for the tables are:
  2574. @.sp
  2575. @.nf
  2576. KeyTable(Name)=
  2577. {
  2578. <KeyDefinition>
  2579. }
  2580. }
  2581. ParseTable(Name)=
  2582. {
  2583. <ParseItem>
  2584. }
  2585. @.fi
  2586. @.sp
  2587. Where \fIName\fP is a unique character string identifier.  There can
  2588. be as many key table and parse tables as desired and they can be
  2589. specified in any order.  However, when the widget is first initialized
  2590. it will use the key table whose name is defined as \fIDefault\fP.
  2591. Similarly, the widget will first load the parse table whose name is
  2592. \fIDefault\fP. In
  2593. addition, if any parse table is defined with the identifier
  2594. \fIStartUp\fP and if the first item in the parse table is a null rule,
  2595. then the widget will execute the translator associated with that rule.
  2596. This allows the widget to initialize any global variables it needs.
  2597. @.LP
  2598. \fIKeyDefinition\fPs define the key actions and are listed one per
  2599. line.  The syntax is:
  2600. @.sp
  2601. @.nf
  2602. KeySym(Modifier),Type,String
  2603. @.fi
  2604. @.sp
  2605. \fIKeySym\fP is the name of the X11 key symbol the definition is for.
  2606. It should correspond to the names given in
  2607. \fI/usr/include/X11/keysymdef.h\fP with out the \fIXK_\fP prefix.  The
  2608. \fI(Modifier)\fP is optional.  If specified, it list the modifier that
  2609. is in effect for this definition.  Valid modifiers are:
  2610. \fIShift\fP, \fICaps\fP, \fIControl\fP, \fIMod1\fP, \fIMod\fP,
  2611. \fIMod3\fP, \fIMod4\fP, \fIMod5\fP, \fIButton1\fP, \fIButton2\fP,
  2612. \fIButton3\fP, \fIButton4\fP and \fIButton5\fP.  \fIType\fP specifies
  2613. the type of key this is to become.  If \fIType\fP is equal to \fIO\fP
  2614. then the key is an output only key.  When this key is struck, it will
  2615. be translated and sent through the widget's parser for processing.  It
  2616. will not generate an input event.  If \fIType\fP is equal to \fII\fP,
  2617. then the key is an input only key.  When the key is struck, it will be
  2618. translated and the result will be sent to keyboard callback routines.
  2619. If \fIType\fP is equal to \fIB\fP, then the key is both an input and
  2620. output.  \fIString\fP is the translation string that should be
  2621. substituted for the key.  It is this value that will be sent to the
  2622. parser or the callback routines.  The string continues to the end of
  2623. the line.  Non printable characters can be enbedded via the \fI^\fP
  2624. escape mechanism mentioned above.
  2625. @.LP
  2626. A \fIParseItem\fP define the translation rules for the escape codes
  2627. the terminal supports.  The items are listed one per line and contain
  2628. the grammar for the escape code and the commands the widget should
  2629. execute when the rule is matched. The syntax for the parse item is:
  2630. @.sp
  2631. @.nf
  2632. Rule{Translators}
  2633. @.fi
  2634. @.sp
  2635. A \fIRule\fP consists of a series of characters or special matching
  2636. functions.  Non printable characters can be entered with the \fI^\fP
  2637. escape mechanism.  A special matching function is the name of the a
  2638. function which can scan the input stream and match certain sequences.
  2639. For example, there is a matching function to match a string of
  2640. integers.  The syntax for a matching function is:
  2641. @.sp
  2642. @.nf
  2643. <Name(Args),Num>
  2644. @.fi
  2645. @.sp
  2646. where \fIName\fP is a character string which correspond to the name of
  2647. the function.  \fIArgs\fP is a comma separated list of arguments.  Each
  2648. argument can be either a number, a string enclosed in double quotes or
  2649. a dollar sign (\fI$\fP) followed by a number.  The last specifies a
  2650. positional argument.  When the matching function is executed the value
  2651. of the argument stored in that position will be substituted for the
  2652. argument.  At the end of rule matching, all positional argument values
  2653. are reset.  \fINum\fP is a number which specifies the number of the
  2654. positional argument into which the matched string will be stored.  The
  2655. valid matching functions are:
  2656. @.IP \fBDigits(Default,Seperator,Length)\fP
  2657. This function will match a list of zero or more integer values.
  2658. \fBDefault\fP, an integer value, is the value to return if no digits
  2659. are encountered.  \fBSeperator\fP, a character string, defines the
  2660. single character that separates each integer in the list.
  2661. \fILength\fP, an integer value, is an optional argument.  If it is
  2662. given then it defines the number of digits in each integer.  The
  2663. matching function returns the first matched integer in the specified
  2664. positional argument.  The second matched integer is returned in the
  2665. next argument and so on until the end of the list.  At the end of the
  2666. list, the default value is stored.
  2667. @.IP \fBFloat(IntSize,FracSize)\fP
  2668. This function will match a single floating point number.  It will not
  2669. match a number in exponential format.  \fBIntSize\fP is an optional
  2670. argument and if specified defines the number of digits to match before
  2671. the decimal point.  \fBFracSize\fP is an optional argument and, if
  2672. specified, defines the number of digits to match after the decimal point.
  2673. @.IP \fBInt(Len)\fP
  2674. This function will match a single integer value.  \fBLen\fP is an
  2675. optional value which, if given, defines the number of digits in the
  2676. integer to match.
  2677. @.IP \fBSelect(C1,C2,C3...Cn)\fP
  2678. This function will match either \fIC1\fP or \fIC2\fP \fIC3\fP etc.
  2679. The arguments are character strings whose first character define one
  2680. of the characters to possibly match.
  2681. @.IP \fBString(Len)\fP
  2682. This function will match a string of arbitrary characters of exactly \fBLen\fP
  2683. characters long.
  2684. @.IP \fBUpto(Stop)\fP
  2685. This function will match a string of arbitrary characters upto, and
  2686. including the character given as the first character in \fBStop\fP.
  2687. @.LP
  2688. A \fBTranslators\fP is a semicolon separated list of translation
  2689. functions.  Each translation function has the following syntax:
  2690. @.sp
  2691. @.nf
  2692. Name(Arguments),Label
  2693. @.fi
  2694. @.sp
  2695. where \fBName\fP is a character string which defines the name of the
  2696. function to execute.  \fBArguments\fP is a common separated list of
  2697. arguments.  The arguments have the same form as for the matching
  2698. functions.  The \fB,Label\fP construct is optional and if given
  2699. defines a label for the function.  The \fBLabel\fP is an integer value
  2700. which is used as a branching address.  Valid translation function
  2701. names and the functions they perform are:
  2702. @.IP \fBCarriageReturn()\fP
  2703. Moves the cursor to the leftmost column.
  2704. @.IP \fBCheckModifiers(Modifier,Which,Set)\fP
  2705. Queries the values of the modifiers that were returned with the last
  2706. \fBGetLastButtonEvent\fP translation function.  \fBModifier\fP is the
  2707. number of the positional argument into which the modifier was stored.
  2708. \fBWhich\fP specifies which modifier to test.  It can have a value of
  2709. \fI"Shift"\fP, \fI"Meta"\fP or \fI"Control"\fP.  \fBSet\fP is the
  2710. number of the positional argument into which the result will be
  2711. stored.  If the modifier is set then a one is stored in this variable.
  2712. Otherwise, a zero is stored.
  2713. @.IP \fBClearDisplay(Top,Bottom)\fP
  2714. Clears the screen starting at row \fBTop\fP and ending at row
  2715. \fBBottom\fP.
  2716. @.IP \fBClearLine(Type)\fP
  2717. Clears the current line.  If \fBType\fP is equal to \fI0\fP then the
  2718. entire line is cleared.  If \fBType\fP is equal to \fI1\fP then the
  2719. line is cleared from the cursor to the end of the line.  Finally, if
  2720. \fBType\fP is equal to \fI2\fP the line is cleared from the start to
  2721. the current cursor position.  Any other value causes a warning message
  2722. to be generated.
  2723. @.IP \fBClearMemory(Which)\fP
  2724. Clears the contents of the off screen memory.  If \fBWhich\fP is equal
  2725. to \fI0\fP all the memory is cleared and the screen is blanked.  If
  2726. \fBWhich\fP is equal to \fI1\fP the memory below the current screen
  2727. position if cleared.  If \fBWhich\fP is equal to 2 the memory above
  2728. the current screen position is cleared.
  2729. @.IP \fBDefinePen(Num,ForeRed,ForeGround,ForeBlue,BackRed,BackGreen,BackBlue)\fP
  2730. Defines the foreground and background colours for the specified pen.
  2731. \fBNum\fP is the pen number to change.  It must be within the range of
  2732. 0 to the \fIXtNnumberColor\fP resource.  \fBForeRed\fP,
  2733. \fBForeGreen\fP and \fBForeBlue\fP specify the foreground colour
  2734. triple.  If the resource \fIXtNDefineColor\fP is set to \fBGTRGB\fP
  2735. then they are the red green and blue colours.  If the resource is
  2736. currently \fBGTHSL\fP then these values correspond to the hue
  2737. saturation and luminance.  The values are floating point number
  2738. ranging from zero to one.  Since the widget does not support floating
  2739. point arguments, the values are given as character strings (i.e.
  2740. \fIDefinePen(1,"0.45","1.0","0.3","0.0","0.0","0.0")\fP).
  2741. \fBBackRed\fP, \fBBackGreen\fP and \fBBackBlue\fP specify the
  2742. background colour triple and have the save format and meaning as the
  2743. foreground colours.
  2744. @.IP \fBDeleteCharacters(Num)\fP
  2745. Deletes a number of character from the current line starting at the
  2746. current cursor position.  \fBNum\fP is the number of characters to be
  2747. deleted.  The characters to the right of the deleted ones will be
  2748. pushed left \fBNum\fP spaces.
  2749. @.IP \fBDeleteLines(Num)\fP
  2750. Deletes a number of lines from the screen starting at the current row.
  2751. \fBNum\fP is the number of lines to delete.  Any lines below the
  2752. delete ones will roll up on the screen and any data saved in the off the
  2753. screen memory below the current screen will be scrolled back onto the
  2754. screen.
  2755. @.IP \fBDownLine(Num,Wrap)\fP
  2756. Moves the cursor down \fBNum\fP lines.  \fBWrap\fP is an integer value
  2757. which specifies the behavior of the cursor at the bottom of the screen.
  2758. If \fBWrap\fP is equal to 0 the screen will scroll up the required
  2759. number of lines to keep the cursor on the screen.  If \fBWrap\fP is
  2760. equal to 1 then the cursor will wrap around to the top of the screen.
  2761. Finally, if \fBWrap\fP is equal to 2 then the cursor will stick at the
  2762. bottom of the screen.
  2763. @.IP \fBEmit(String1,String2...)\fP
  2764. Invokes the keyboard callback with the passed strings arguments as the
  2765. data.  One callback will be generated for each argument given.
  2766. \fBString\fP\fIn\fP is the character string to pass to the callback.
  2767. @.IP \fBEscapeCallback(Arg1,Arg2...)\fP
  2768. Invokes the escape callback with the passed strings as the arguments.
  2769. Only one escape callback will be generated per call.  \fBArg\fP\fIn\fP
  2770. is the character string to callback in the \fIn\fP-1 position of the
  2771. escapes array in the callback structure.
  2772. @.IP \fBExecuteFunctionKey(Num)\fP
  2773. Cause the widget to execute a function key.  \fBNum\fP is the number
  2774. of the function key to execute.
  2775. @.IP \fBFetch(From,To)\fP
  2776. Fetches a value from a global variable.  The widget maintains a set of
  2777. global variables that are guaranteed to maintain their value between
  2778. rule executions.  These can be used to store state information for the
  2779. parser.  The variables are referenced by their number just as the
  2780. positional arguments are.  \fBFrom\fP is the number of the global
  2781. variable to fetch the value from.  \fBTo\fP is the number of the
  2782. positional argument into which the value should be stored.
  2783. @.IP \fBGetArg(Pointer,To)\fP
  2784. Implements an indirect reference to a positional argument.
  2785. \fBPointer\fP is the number of the positional argument to read the
  2786. value from.  This value is interpreted as the number of the
  2787. positional argument to return the value of.  \fBTo\fP is the number of
  2788. the positional argument to return the result in.  If the value stored
  2789. in \fBPointer\fP positional argument is not a valid positional
  2790. argument number then a zero is returned.
  2791. @.IP \fBGetBottomText(Where)\fP
  2792. Returns the number of the last nonblank line currently on the screen.
  2793. If all lines contain data then the last visible line is returned.
  2794. \fBWhere\fP is the number of the positional argument to store the
  2795. result in.
  2796. @.IP \fBGetFont(Where)\fP
  2797. Determines which font is currently being used.  It returns 0 is the
  2798. base font is currently being used and 1 if the alternate font is in
  2799. use.  \fBWhere\fP is the number of the positional argument to store
  2800. the result in.
  2801. @.IP \fBGetLine(Row,Column,Where)\fP
  2802. Get the contexts of a line, starting at position \fBRow\fP and
  2803. \fBColumn\fP.  The character string will be stored in the positional
  2804. argument given by \fBWhere\fP.
  2805. @.IP \fBGetLastButton(Button,X,Y,Mods)\fP
  2806. Returns information on the last button press event that the widget
  2807. processed.  \fBButton\fP is the number of the positional argument into
  2808. which the number of the button which was pressed is to be stored.  \fBX\fP
  2809. and \fBY\fP are the number of the positional arguments into which the
  2810. x and y coordinate of the event are to be stored.  \fBMods\fP is the
  2811. number of the positional argument into which the button modifiers are
  2812. to be stored.  Further information on the modifiers can be obtained
  2813. via the \fBCheckModifiers\fP translator function.
  2814. @.IP \fBGetPen(Num)\fP
  2815. Returns the number of the pen that is currently being used.  \fBNum\fP
  2816. is the number of the positional argument to store the pen number in.
  2817. @.IP \fBGetPosition(Row,Column)\fP
  2818. Returns the current cursor position.  \fBRow\fP is the number of the
  2819. positional argument to store the current row in.  \fBColumn\fP is the
  2820. number of the positional argument to store the current column in.
  2821. @.IP \fBGetResource(Name,Where)\fP
  2822. Gets the current value of the specified resource.  \fBName\fP is the
  2823. name of the resource setting to query.  The name should correspond to
  2824. the name in the resource file.  \fBWhere\fP is the number of the
  2825. positional argument to store the result in.  Currently only integer
  2826. valued resources can be properly queried through this function.
  2827. @.IP \fBGetScreenSize(Row,Column)\fP
  2828. Gets the current size of the screen in rows and columns.  \fBRow\fP is
  2829. the number of the positional argument to store the number of rows in.
  2830. \fBColumn\fP is the number of the positional argument to store the
  2831. number of columns in.
  2832. @.IP \fBGetStringLen(String,Where)\fP
  2833. Determines the number of characters in the given string.  \fBString\fP
  2834. is the string to count the characters in.  \fBWhere\fP is the number
  2835. of the positional argument into which the result is to be stored.
  2836. @.IP \fBGetSubString(String,Start,End,Result)\fP
  2837. Extracts the contents of a string and returns the result.
  2838. \fBString\fP is the character string to take the substring from.
  2839. \fBStart\fP and \fBEnd\fP specify the starting and ending positions of
  2840. the string to be extracted.  \fBWhere\fP is the number of the
  2841. positional argument where the substring is to be stored.
  2842. @.IP \fBGetTop(Where)\fP
  2843. Gets the number of the line in the save screen which corresponds to
  2844. the line that is currently at the top of the screen.  \fBWhere\fP is
  2845. the number of the positional argument into which the result is to be
  2846. stored.
  2847. @.IP \fBGetTopOfScrollRegion(Num,Where)\fP
  2848. Finds the top row of a specific scroll region and returns the result.
  2849. \fBNum\fP is the number of the scroll region to find the top of.
  2850. \fBWhere\fP is the number of the positional argument where the result
  2851. is to be stored.  If the scroll region does not exist then the
  2852. function will return 0, the top of the screen.
  2853. @.IP \fBIf(Operand1,Condition,Operand2,Label)\fP
  2854. Test to is if a condition is true and performs a branch operation if
  2855. it is.  \fBOperand1\fP and \fBOperand2\fP are the two values to test.
  2856. \fBCondition\fP is the boolean expression to evaluate.
  2857. \fBCondition\fP can have the following values: \fI"="\fP, \fI">"\fP,
  2858. \fI">="\fP, \fI"<"\fP, \fI"<="\fP or \fI"!="\fP.  \fBLabel\fP is the
  2859. label number to branch to if the result of the operation is true.
  2860. When the branch is taken, the parser does not execute the next
  2861. translation function in the list but instead searches through the
  2862. entire list to find a function whose label equals the specified value.
  2863. If no branch label is found the parser stops executing this list.  It
  2864. is possible to branch back in the list to create loops.
  2865. @.IP \fBIgnore()\fP
  2866. This is a do nothing function.  It simply returns.
  2867. @.IP \fBInsertLines(Num,Where)\fP
  2868. Inserts \fBNum\fP blank lines into the visible screen.  If \fBWhere\fP
  2869. is equal to 1 then the lines are inserted after the current row.  If
  2870. \fBWhere\fP is equal to 0 then the lines are inserted before the
  2871. current row.  All lines below the inserted lines are pushed down
  2872. \fBNum\fP lines.  Any lines pushed off the screen are stored in the
  2873. off screen memory.
  2874. @.IP \fBIntToString(Num,Len,Where)\fP
  2875. Performs an explicit integer to string conversion.  \fBNum\fP is the
  2876. number to convert.  \fBLen\fP is the number of digits the final string
  2877. should have.  The final result will be truncated or padded with
  2878. leading zeroes to make the string the proper length.  \fBWhere\fP is
  2879. the number of the positional argument to store the result in.
  2880. @.IP \fBLoadAttribute(Row,Column)\fP
  2881. Set the current attributes to be the same as the characters associated
  2882. with the character located at position \fBRow\fP and \fBColumn\fP.
  2883. The arguments \fBRow\fP and \fBColumn\fP specify the location of the
  2884. character to load.  If the given location is invalid then the default
  2885. attributes are loaded.
  2886. @.IP \fBLoadMapTable(Num)\fP
  2887. Set the current output mapping table to be map table number \fBNum\fP.
  2888. \fBNum\fP is the number of the map table to load.
  2889. @.IP \fBMath(Operand1,Operation,Operand2,Result)\fP
  2890. Performs a specific mathematical operation and returns the result.
  2891. \fBOperand1\fP and \fBOperand2\fP are the two operands to perform the
  2892. operation on.  \fBOperation\fP is the mathematical operation to
  2893. perform.  The valid operations are : \fI"+"\fP, \fI"-"\fP, \fI"*"\fP,
  2894. \fI"/"\fP, \fI"%"\fP, \fI">"\fP, \fI"<"\fP and \fI"&"\fP.  The first five
  2895. operation correspond to their C language equivalents.  The \fI">"\fP
  2896. and \fI"<"\fP operations are the normal C language shift right
  2897. and left operations.  \fI"&"\fP is a string concatenation operation.
  2898. \fBResult\fP is the number of the positional argument into which the
  2899. result is to be stored.
  2900. @.IP \fBMoveCursor(Row,Column)\fP
  2901. Moves the cursor to the position given by \fBRow\fP and \fBColumn\fP.
  2902. If this position is invalid or is off the visible screen then the
  2903. cursor will be moved to the closest point to the specified point that
  2904. is still on the visible screen.
  2905. @.IP \fBMoveLeft(Num,WrapType,RollType)\fP
  2906. Moves the cursor left \fBNum\fP columns.  \fBWrapType\fP specifies the
  2907. behavior of the cursor when it encounters the leftmost column.  If
  2908. \fBWrapType\fP is equal to \fI0\fP then the cursor sticks at the
  2909. leftmost column.  If \fBWrapType\fP is equal to \fI1\fP then the
  2910. cursor will wrap around to the rightmost column of the previous row.
  2911. If the cursor is at the upper left corner of the screen and
  2912. \fIRollType\fP is equal to \fI0\fP then the cursor moves to the lower
  2913. right corner of the screen.  If \fBRollType\fP is equal to \fI1\fP
  2914. then the screen will be scrolled down and the cursor moved to the
  2915. rightmost column of the previous row.
  2916. @.IP \fBMoveRight(Num,WrapType,RollType)\fP
  2917. Moves the cursor right \fBNum\fP columns.  \fBWrapType\fP specifies
  2918. the behavior of the cursor when it encounters the rightmost column.
  2919. If \fBWrapType\fP is equal to \fI0\fP then the cursor sticks at the
  2920. rightmost column.  If \fBWrapType\fP is equal to \fI1\fP then the
  2921. cursor will wrap around to the leftmost column of the next row.  If
  2922. the cursor is at the lower right corner of the screen and
  2923. \fIRollType\fP is equal to \fI0\fP then the cursor will move the the
  2924. upper left corner of the screen.  If \fBRollType\fP is equal to
  2925. \fI1\fP then the screen will be scrolled up and the cursor moved to
  2926. the leftmost column of the next row.
  2927. @.IP \fBNewLine()\fP
  2928. Moves the cursor down one row.  If the cursor was on the bottom row of
  2929. the screen, the screen will be scrolled up one line.
  2930. @.IP \fBNextTab()\fP
  2931. Moves the cursor to the next tab stop on the current row.  If there
  2932. are no more tab stops on the row then the cursor will move to the end
  2933. of the line.
  2934. @.IP \fBOutputString(String1,String2,Stringn...)\fP
  2935. Prints the passed strings on the screen.  The passed arguments
  2936. \fBString\fP\fIn\fP are the character strings to print out.  Prior to
  2937. printing, the strings are passed through the parser.  The current
  2938. positional arguments are saved prior to parsing the strings and reset
  2939. after.
  2940. @.IP \fBPreviousTab()\fP
  2941. Moves the cursor to the previous tab stop on the current row.  If
  2942. there are no tab stops to the left of the current position the cursor
  2943. will be moved to the leftmost column.
  2944. @.IP \fBProgramKey(Type,Number,Label,String)\fP
  2945. Programs a specific function key.  \fBType\fP determines what kind of
  2946. function key this it.  If \fBType\fP is equal to \fI0\fP then when the key
  2947. is executed, its string sent to the terminal for execution and
  2948. generates a keyboard callback.  If \fBType\fP is equal to \fI1\fP the
  2949. function key is executed locally in the terminal only.  If \fBType\fP
  2950. is equal to \fI2\fP then the key generates a keyboard callback only.
  2951. \fBNum\fP is the number of the function key to program.  \fBLabel\fP
  2952. is the character string that will be printed in the function key label
  2953. widget at the bottom of the screen.  \fBString\fP is the character to
  2954. string to program the key with.
  2955. @.IP \fBProgramMapTable(Num,Start,End,StartVal,EndVal)\fP
  2956. Sets the values for the specified output mapping table.  The mapping
  2957. table defines the font positions for each ascii character.  Initially,
  2958. the mapping table contains a unity translation.  That is to say,
  2959. position \fIi\fP in the table contains a value of \fIi\fP.
  2960. \fBStart\fP and \fBEnd\fP are the starting and ending points of the
  2961. range in the table to perform the programming on.  \fBStartVal\fP and
  2962. \fBEndVal\fP define the values the starting and end points should
  2963. have.  All points in between are assigned a value falling on a
  2964. straight line between \fBStartVal\fP and \fBEndVal\fP.  I.E. the
  2965. function \fIProgramMapTable(1,0,32,0,128)\fP would assign a value of
  2966. \fI0\fP to table position \fI0\fP a value of \fI4\fP to position
  2967. \fI1\fP and so on up to position \fI32\fP which would be assigned a
  2968. value of \fI128\fP.
  2969. @.IP \fBQuit()\fP
  2970. Causes the parser to quit executing the list of translator functions
  2971. and begin parsing the next character in the input stream.
  2972. @.IP \fBReject()\fP
  2973. Causes the parser to reject the matched character sequence.  When a
  2974. sequence is reject it is printed on the screen as it would if it never
  2975. matched a parser sequence.
  2976. @.IP \fBSetBlinkMode(Set)\fP
  2977. If \fBSet\fP is equal to \fIone\fP, the blink attribute is turned on for the
  2978. current attributes.  If \fBSet\fP is equal to \fIzero\fP then the
  2979. blink attribute is turned off.
  2980. @.IP \fBSetField()\fP
  2981. Copies the current attribute setting through out the current field.
  2982. It may also create a new field.  A field is a section of text on the
  2983. screen which have the same attributes.  When text is written on the
  2984. screen it inherits its attributes from the field and not the current
  2985. settings.  If the cursor is positioned at the beginning of a defined
  2986. field, then the attribute is set through out that field.  If the
  2987. cursor position in currently in the middle of a field then the current
  2988. field is truncated to the position immediately to the left of the
  2989. cursor.  A new field is then defined from the current position to the
  2990. end of the previous field.  The current attribute is copied through
  2991. out this field.  Initially, each field contains one field extending
  2992. the entire length of the line.
  2993. @.IP \fBSetFlow(Type)\fP
  2994. Invokes a flow callback. If \fBType\fP is equal to \fI1\fP, the reason
  2995. for the callback will be \fIGTE_XON\fP.  If \fBType\fP is equal to
  2996. \fI0\fP, the reason for the callback will be \fIGTE_XOFF\fP.
  2997. @.IP \fBSetFont(Type)\fP
  2998. Sets the font for the current attribute.  If \fBType\fP is equal
  2999. \fI0\fP the base font will be set.  If \fBType\fP is equal to \fI1\fP
  3000. then the alternate font will be used.
  3001. @.IP \fBSetHalfBrightMode(Flag)\fP
  3002. If \fBFlag\fP is equal to \fI1\fP then the half bright attribute is
  3003. set for the current attributes.  If \fBFlag\fP is equal to \fI0\fP
  3004. then it is cleared.
  3005. @.IP \fBSetInsertMode(Flag)\fP
  3006. If \fBFlag\fP is equal to \fI1\fP then the widget is placed in insert
  3007. mode.  If \fBFlag\fP is equal to \fI0\fP then insert mode is turned
  3008. off.
  3009. @.IP \fBSetInverseVideo(Flag)\fP
  3010. If \fBFlag\fP is equal to \fI1\fP then the inverse video attribute is
  3011. set for the current attributes.  If \fBFlag\fP is equal to \fI0\fP
  3012. then it is cleared.
  3013. @.IP \fBSetKeyTable(Name)\fP
  3014. Loads the specified key table.  \fBName\fP is the name of the key
  3015. table to load as it is specified in the parse file.
  3016. @.IP \fBSetParseTable(Name)\fP
  3017. Sets the current parse table to be the one associated in the parse
  3018. file with the name \fBName\fP.  \fBName\fP is a character string which
  3019. specifies the name of the parse table to load.  If the name is invalid
  3020. then the current parse table remains loaded.  With this function, the
  3021. widget can change the type of terminal it is emulating.
  3022. @.IP \fBSetPen(Num)\fP
  3023. Set the pen number for the current attribute.  \fBNum\fP is the pen
  3024. number to set to.
  3025. @.IP \fBSetResource(Name,Val)\fP
  3026. Set the value of a specific X resource.  \fBName\fP is the name of the
  3027. X resource of the widget to set.  It should correspond to the name
  3028. that would be used in the resource file.  \fBVal\fP is the value to
  3029. set it to.  Currently only integer and boolean valued resources can be
  3030. set with this function.
  3031. @.IP \fBSetScrollRegion(Start,End,Num)\fP
  3032. Defines a scroll region with in the visible screen.  \fBStart\fP and
  3033. \fBEnd\fP are the starting and ending rows of the scroll region.
  3034. \fBNum\fP is the number to assign to the scroll region.  Each scroll
  3035. region should have a unique number.  By convention scroll region
  3036. number zero is the entire visible screen.
  3037. @.IP \fBSetUnderLineMode(Flag)\fP
  3038. If \fBFlag\fP is equal to \fI1\fP then the underline attribute is set
  3039. for the current attributes.  If \fBFlag\fP is equal to \fI0\fP then
  3040. the underline attribute is cleared.
  3041. @.IP \fBSetTab(Col)\fP
  3042. Set a tap stop at the specified column on the current row.  \fBCol\fP
  3043. is the number of the column to set the tab stop on.
  3044. @.IP \fBSetTop(Num)\fP
  3045. Set the top line of the visible screen to correspond to line number
  3046. \fBNum\fP in the save screen.
  3047. @.IP \fBSoundBell()\fP
  3048. Cause the terminal to beep.
  3049. @.IP \fBStore(Val,Where)\fP
  3050. Store the value of argument \fBVal\fP in the global variable whose
  3051. position number if equal to \fBWhere\fP.
  3052. @.IP \fBToAscii(Num,String)\fP
  3053. Returns the ascii equivalent character.  \fBNum\fP is the number to
  3054. convert to ascii.  \fBString\fP is the number of the positional
  3055. argument to return the character in.
  3056. @.IP \fBUpLine(Num,WrapType)\fP
  3057. Moves the cursor up \fBNum\fP lines.  \fBWrapType\fP specifies the
  3058. behavior of the cursor when it encounters the top of the visible
  3059. screen.  If \fBWrapType\fP is equal to \fI0\fP the screen will scroll
  3060. down the required number of lines to keep the cursor on the visible
  3061. screen.  If \fBWrapType\fP is equal to \fI1\fP the cursor will wrap
  3062. around to the bottom of the screen.  If \fBWrapType\fP is equal to \fI2\fP
  3063. then the cursor will stick to the top.
  3064. @.IP \fBUnSetTab(Col)\fP
  3065. Clears a tab stop at a specific column on the current row.  \fBCol\fP
  3066. is the number of the column to set the tab on.
  3067. @.sp 1
  3068. @.SH "EXAMPLE PARSE FILE"
  3069. @.sp
  3070. Below is a simple sample parser file.  It contains key mappings for
  3071. the arrow keys and the home key.  It defines escape sequences for
  3072. newlines, carriage returns and tabs, as well as escapes to move the
  3073. cursor around and perform cursor positioning.
  3074. @.nf
  3075. @.sp 1
  3076. # A Simple example parser
  3077. # A Simple example parser
  3078. KeyTable(Default)=
  3079. {
  3080. Up,I,^[[1A
  3081. Down,I,^[[1B
  3082. Right,I,^[[1C
  3083. Left,I,^[[1D
  3084. Home,O,^[H
  3085. }
  3086. }
  3087. ParseTable(Default)=
  3088. {
  3089. ^J{NewLine()}
  3090. ^M{CarriageReturn()}
  3091. ^G{SoundBell()}
  3092. ^I{NextTab()}
  3093. ^K{DeleteLines(1)}
  3094. ^[[<Int(),1>A{If($1,"<",0,1);UpLine($1,2);Quit();\\
  3095.     Math($1),"*",-1,2),1;DownLine($2,2)}
  3096. ^[[<Int(),1>B{DownLine($1,2)}
  3097. ^[[<Int(),1>C{MoveRight($1,0,0)}
  3098. ^[[<Int(),1>D{MoveLeft($1,0,0)}
  3099. ^[[<Int(),1>;<Int(),2>E{MoveCursor($1,$2)}
  3100. ^[H{MoveCursor(0,0)}
  3101. }
  3102. @.fi
  3103. @.sp
  3104. @.SH "ENTRY POINTS"
  3105. In addition to the normal widget functions, the \fIGenTermEm\fP widget
  3106. also contains the functions which can be called from the application
  3107. program.
  3108. @.ta .2i 1.2i
  3109. @.\"
  3110. @.IP "\fBint GtEOutput(Term,String,Len)\fP"
  3111. @.sp
  3112. @.nf
  3113. \fB\tWidget\tTerm
  3114. \tchar *\tString
  3115. \tint\tLen\fP
  3116. @.fi
  3117. @.sp
  3118. This is the main output routine for the widget.  \fBTerm\fP is the
  3119. widget instance's record.  \fBString\fP is a pointer to a character
  3120. string and \fBLen\fP is the number of characters in the string.  This
  3121. function prints the string on the screen.  The string is passed
  3122. through the parser prior to printing to interprets any escape
  3123. sequences it may contain.  If the screen is currently locked then the
  3124. function will enqueue the string for printing at the next available instance.
  3125. The function returns \fIGTE_DONE\fP if the request completes
  3126. successfully and \fIGTE_WAIT\fP if the widget is currently locked or
  3127. waiting for a graphics expose event.  In the latter case, the
  3128. application program should not call \fBGtEOutput\fP again until it has
  3129. received a wakeup callback.  If the application does not honour this
  3130. request then the widget will be forced to allocate large amounts of
  3131. memory for its input queue which can have negative effects on program
  3132. performance.  If output logging is currently enable, a copy of the
  3133. string will be written into the log file.
  3134. @.sp
  3135. @.SH "RELATED INFORMATION"
  3136. \fBCore(3X)\fP, \fBComposite(3X)\fP, \fBGenTerm(3X)\fP
  3137. @EOF
  3138. set `wc -lwc <GenTerm/GenTermEm.man`
  3139. if test $1$2$3 != 825604339494
  3140. then
  3141.     echo ERROR: wc results of GenTerm/GenTermEm.man are $* should be 825 6043 39494
  3142. fi
  3143.  
  3144. chmod 644 GenTerm/GenTermEm.man
  3145.  
  3146. echo x - GenTerm/LoadParser.c
  3147. cat >GenTerm/LoadParser.c <<'@EOF'
  3148. /* Parse.c : This file contains the section of the terminal emulator parser */
  3149. /*   which loads the parse file. */
  3150. /* History:                                 */
  3151. /*         Written by G. R. Strachan 1992 */
  3152.  
  3153. /*  Copyright Gordon R. Strachan 1992 */
  3154. /*  This code is provided as is, neither the University of Waterloo nor */
  3155. /*  the author is liable for any damage caused by the use or misuse of this */
  3156. /*  code.  */
  3157.  
  3158. /* Permission is granted to copy, use and modify this code provided it is */
  3159. /* not sold for profit and the above copyright remains intact. */
  3160.  
  3161. #include <stdio.h>
  3162. #include <termios.h>
  3163. #include <X11/StringDefs.h>
  3164. #include <X11/IntrinsicP.h>
  3165. #include <X11/Shell.h>
  3166. #include <X11/keysym.h>
  3167. #include <X11/keysymdef.h>
  3168. #include "GenTermEmP.h"
  3169. #include "Parser.h"
  3170.  
  3171. #define BUFSIZ 1024
  3172. #define EOL -2
  3173.  
  3174. struct Buffer
  3175. {
  3176.  int nchar;
  3177.  int pos;
  3178.  int started;
  3179.  int escape;
  3180.  char buffer[BUFSIZ];
  3181.  FILE *File;
  3182. };
  3183.  
  3184. static struct ParseItem *CreatePItem();
  3185. static struct ParseItem *GtELoadParseTable();
  3186. static struct KeyTranslations *LoadKeyTable();
  3187. static int GetNextToken();
  3188. static struct Translator *GetTranslatorToken();
  3189. static struct SpecialItem *GetSpecialToken();
  3190. static struct ArgumentList *BuildArgList();
  3191. static void GetFunctionToken();
  3192. static char *BufferGets();
  3193. static int BufferGetc();
  3194.  
  3195. extern struct FuncDefs Translators[];
  3196.  
  3197. extern struct FuncDefs Specials[];
  3198.  
  3199. GtELoadParseFile(w)
  3200.  
  3201. GenTermEmWidget w;
  3202.  
  3203. {
  3204.  struct Buffer InBuffer;
  3205.  char string[1024];
  3206.  struct GtEList *temp;
  3207.  int i,j;
  3208.  
  3209.  InBuffer.nchar = 0;
  3210.  InBuffer.pos = 0;
  3211.  InBuffer.started = 0;
  3212.  if((InBuffer.File = fopen(w->genTermEm.ParseFile,"r")) == NULL)
  3213.   XtAppError(XtWidgetToApplicationContext(w),
  3214.          "GenTermEm Widget can't find parse Table!");
  3215.  
  3216.  w->genTermEm.ParseList = NULL;
  3217.  w->genTermEm.KeyList = NULL;
  3218.  
  3219.  while(BufferGets(&InBuffer,string,1024) != NULL)
  3220.   {
  3221.    if(strncmp(string,KEYTOKEN,strlen(KEYTOKEN)) == 0)/*start of a key table?*/
  3222.     {
  3223.      temp = (struct GtEList *)XtMalloc(sizeof(struct GtEList));
  3224.      j = i = strlen(KEYTOKEN) + 1;
  3225.      while((string[j++] != ')') && (string[j] != NULL));
  3226.      if(string[j] == NULL)
  3227.       XtAppError(XtWidgetToApplicationContext(w),
  3228.          "GenTermEm Widget finds bad parser file!");
  3229.      string[j-1] = NULL;
  3230.      strcpy(temp->Name,&(string[i]));
  3231.      while((i = BufferGetc(&InBuffer) != (int)'{') && (i != EOF));
  3232.      if(i == EOF)
  3233.       XtAppError(XtWidgetToApplicationContext(w),
  3234.          "GenTermEm Widget finds bad parser file");
  3235.      BufferGets(&InBuffer,string,1024);
  3236.      temp->Point.KeyTable = LoadKeyTable(w,&InBuffer);
  3237.      temp->Num = w->genTermEm.NumKeys;
  3238.      temp->Next = w->genTermEm.KeyList;
  3239.      w->genTermEm.KeyList = temp;
  3240.     }
  3241.    else if(strncmp(string,PARSETOKEN,strlen(PARSETOKEN)) == 0)
  3242.     {
  3243.      temp = (struct GtEList *) XtMalloc(sizeof(struct GtEList));
  3244.      j = i = strlen(PARSETOKEN) + 1;
  3245.      while((string[j++] != ')') && (string[j] != NULL));
  3246.      if(string[j] == NULL)
  3247.       XtAppError(XtWidgetToApplicationContext(w),
  3248.          "GenTermEm Widget finds bad parser file!");
  3249.      string[j-1] = NULL;
  3250.      strcpy(temp->Name,&(string[i]));
  3251.      while((i = BufferGetc(&InBuffer) != (int)'{') && (i != EOF)); 
  3252.      if(i == EOF)
  3253.       XtAppError(XtWidgetToApplicationContext(w),
  3254.          "GenTermEm Widget finds bad parser file");
  3255.      BufferGets(&InBuffer,string,1024);
  3256.      temp->Point.ParseTable = GtELoadParseTable(w,&InBuffer);
  3257.      BufferGets(&InBuffer,string,1024);
  3258.      temp->Next = w->genTermEm.ParseList;
  3259.      w->genTermEm.ParseList = temp;
  3260.     }
  3261.    else
  3262.     XtAppError(XtWidgetToApplicationContext(w),
  3263.            "GenTermEm Widget finds bad parser file");
  3264.   }
  3265.  temp = w->genTermEm.ParseList;
  3266.  while(temp != NULL)
  3267.   {
  3268.    if(strcmp(temp->Name,DEFAULT) == 0)
  3269.     {
  3270.      w->genTermEm.ParseTable = temp->Point.ParseTable;
  3271.      break;
  3272.     }
  3273.    temp = temp->Next;
  3274.   }
  3275.  if(temp == NULL)
  3276.   XtAppError(XtWidgetToApplicationContext(w),
  3277.          "GenTermEm Widget doesn't find default parse table");
  3278.  
  3279.  temp = w->genTermEm.KeyList;
  3280.  while(temp != NULL)
  3281.   {
  3282.    if(strcmp(temp->Name,DEFAULT) == 0)
  3283.     {
  3284.      w->genTermEm.Keys = temp->Point.KeyTable;
  3285.      w->genTermEm.NumKeys = temp->Num;
  3286.      break;
  3287.     }
  3288.    temp = temp->Next;
  3289.   }
  3290.  if(temp == NULL)
  3291.   XtAppError(XtWidgetToApplicationContext(w),
  3292.          "GenTermEm Widget doesn't find default key table"); 
  3293.  
  3294.  fclose(InBuffer.File);
  3295.    
  3296. }
  3297.  
  3298. /* BufferGets:  This function returns the rest of the current line */
  3299.  
  3300. static char *BufferGets(InBuffer,string,len)
  3301.  
  3302. struct Buffer *InBuffer;
  3303. char *string;
  3304. int len;
  3305.  
  3306. {
  3307.  int i,j;
  3308.  char *temp;
  3309.  
  3310.  if(InBuffer->pos >= InBuffer->nchar)
  3311.   {
  3312.    while((temp = fgets(InBuffer->buffer,BUFSIZ,InBuffer->File)) != NULL)
  3313.     if((InBuffer->buffer[0] != '#') &&  (InBuffer->buffer[0] != '\n'))
  3314.      break;
  3315.    if(temp == NULL)
  3316.     return(NULL);
  3317.    InBuffer->nchar = strlen(InBuffer->buffer);
  3318.    InBuffer->pos = 0;
  3319.   }
  3320.  j = 0;
  3321.  i = InBuffer->pos;
  3322.  while(i < InBuffer->nchar)
  3323.   {
  3324.    switch(InBuffer->buffer[i])
  3325.     {
  3326.    case '^':
  3327.     string[j++] = InBuffer->buffer[i+1] & 077;
  3328.      i++;
  3329.      break;
  3330.   case  '\\':
  3331.     if(InBuffer->buffer[i+1] == '\n')
  3332.      {
  3333.       fgets(InBuffer->buffer,BUFSIZ,InBuffer->File);
  3334.       i = InBuffer->pos = 0;
  3335.       InBuffer->nchar = strlen(InBuffer->buffer);
  3336.      }
  3337.     else
  3338.      {
  3339.       string[j++] = InBuffer->buffer[i+1];
  3340.       i++;
  3341.      }
  3342.     break;
  3343.   case ' ':
  3344.   case '\t':
  3345.     break;
  3346.   default:
  3347.     string[j++] = InBuffer->buffer[i];
  3348.     break;
  3349.    }
  3350.    i++;
  3351.    if(j == len)
  3352.     {
  3353.      InBuffer->pos = i;
  3354.      return(string);
  3355.     }
  3356.   }
  3357.  string[j] = NULL;
  3358.  InBuffer->pos = i;
  3359.  return(string);
  3360. }
  3361.  
  3362. static int BufferGetc(InBuffer)
  3363.  
  3364. struct Buffer *InBuffer;
  3365.  
  3366. {
  3367.  int c;
  3368.  char *string;
  3369.  
  3370.  if(InBuffer->pos >= InBuffer->nchar)
  3371.   {
  3372.    while((string = fgets(InBuffer->buffer,BUFSIZ,InBuffer->File)) != NULL)
  3373.     if((InBuffer->buffer[0] != '#') && (InBuffer->buffer[0] != '\n'))
  3374.      break;
  3375.    if(string == NULL)
  3376.     return(EOF);
  3377.    InBuffer->nchar = strlen(InBuffer->buffer);
  3378.    InBuffer->pos = 0;
  3379.   }
  3380.  
  3381.  c = -99;
  3382.  InBuffer->escape = False;
  3383.  while(c == -99)
  3384.   {
  3385.    switch(InBuffer->buffer[InBuffer->pos])
  3386.     {
  3387.    case '^':
  3388.      c = InBuffer->buffer[InBuffer->pos+1] & 077;
  3389.      InBuffer->pos++;
  3390.      break;
  3391.    case  '\\':
  3392.      if(InBuffer->buffer[InBuffer->pos+1] == '\n')
  3393.       {
  3394.        fgets(InBuffer->buffer,BUFSIZ,InBuffer->File);
  3395.        InBuffer->pos = 0;
  3396.        InBuffer->nchar = strlen(InBuffer->buffer);
  3397.       }
  3398.      else
  3399.       {
  3400.        c = InBuffer->buffer[InBuffer->pos+1];
  3401.        InBuffer->escape = True;
  3402.        InBuffer->pos++;
  3403.       }
  3404.      break;
  3405.    case '\n':
  3406.      c = EOL;
  3407.      break;
  3408.    case ' ':
  3409.    case '\t':
  3410.      break;
  3411.    default:
  3412.      c = InBuffer->buffer[InBuffer->pos];
  3413.      break;
  3414.     }
  3415.    InBuffer->pos++;
  3416.   }
  3417.  return((int)c);
  3418. }
  3419.  
  3420. static struct ParseItem *GtELoadParseTable(w,InBuffer)
  3421.  
  3422. GenTermEmWidget w;
  3423. struct Buffer *InBuffer;
  3424.  
  3425. {
  3426.  struct ParseItem *Table;
  3427.  struct ParseItem *NewItem;
  3428.  struct ParseItem *NextItem;
  3429.  int NextToken;
  3430.  char c;
  3431.  int StartLine;
  3432.  struct SpecialItem *special;
  3433.  struct Translator *translator;
  3434.  
  3435.  
  3436.  Table = CreatePItem();
  3437.  NextItem = Table;
  3438.  
  3439.  while(((NextToken=GetNextToken(w,InBuffer,&c,&special,&translator,
  3440.                    &StartLine)) != EOFTOKEN) &&
  3441.        (NextToken != EOTTOKEN))
  3442.   switch(NextToken)
  3443.    {
  3444.   case ENDTOKEN:     /* reset parser to top of table */
  3445.     NextItem = Table;
  3446.     break;
  3447.   case TOKENCHAR:
  3448.     if(NextItem->empty == 0)
  3449.      {
  3450.       NextItem->c = c;
  3451.       NextItem->empty = 1;
  3452.       NextItem->child = CreatePItem();
  3453.       NextItem = NextItem->child;
  3454.      }
  3455.     else
  3456.      {
  3457.       while(NextItem->next != NULL)
  3458.        {
  3459.     if(NextItem->c == c)
  3460.      break;
  3461.     /*if((NextItem->translators != NULL) || (NextItem->special != NULL))
  3462.      XtAppError(XtWidgetToApplicationContext(w),
  3463.             "GenTermEmWidget encounters an ambigous grammar!");*/
  3464.     NextItem = NextItem->next;
  3465.        }
  3466.       if(NextItem->c == c)
  3467.        {
  3468.     if(NextItem->child != NULL)
  3469.      NextItem = NextItem->child;
  3470.     else
  3471.      {
  3472.       if(NextItem->translators != NULL)
  3473.        XtAppError(XtWidgetToApplicationContext(w),
  3474.               "GenTermEmWidget encounters an ambigous grammar!");
  3475.       else
  3476.        {  /* hmmm... can this ever happen? */
  3477.         NextItem->child = CreatePItem();
  3478.         NextItem = NextItem->child;
  3479.        }
  3480.      }
  3481.        }
  3482.       else
  3483.        {
  3484.     NextItem->next = CreatePItem();
  3485.     NextItem->next->c = c;
  3486.     NextItem->next->empty = 1;
  3487.     NextItem->next->child = CreatePItem();
  3488.     NextItem = NextItem->next->child;
  3489.        }
  3490.      }
  3491.     break;
  3492.   case SPECIALCHARTOKEN:
  3493.     if(NextItem->empty != 0)
  3494.      {
  3495. /* here we have a potential problem with my parser design.  I don't want to */
  3496. /* be in the position of running the grammar through a list of special */
  3497. /* matching functions so I have to make sure at any point in the parse table */
  3498. /* there is only one possible special matching function to execute.  But, it */
  3499. /* possible for there to be many branches in the tree after the special match*/
  3500. /* so it is possible to try to insert a special match function where one */
  3501. /* already exists, providing it is the same function.  But, the arguments and*/
  3502. /* storage position of the function may be different.  This is supported */
  3503. /* under my grammar.  For each case, the special matcher must receive the */
  3504. /* same arguments and store its results in the same position.  Here I check */
  3505. /* the position indicator but I don't check the argument list, I simply use */
  3506. /* the first one I find. */
  3507.       if((NextItem->special->func == special->func) &&
  3508.      (NextItem->special->position == special->position))
  3509.        NextItem = NextItem->child;
  3510.       else
  3511.        XtAppError(XtWidgetToApplicationContext(w),
  3512.           "GenTermEmWidget encounters an ambigous grammar!");
  3513.      }
  3514.     else
  3515.      {
  3516.       NextItem->empty = 1;
  3517.       NextItem->special = special;
  3518.       NextItem->child = CreatePItem();
  3519.       NextItem = NextItem->child;
  3520.      }
  3521.     break;
  3522.   case TRANSLATIONTOKEN:
  3523.     if(NextItem->empty != 0)
  3524.      XtAppError(XtWidgetToApplicationContext(w),
  3525.         "GenTermEmWidget encounters an ambigous grammar!");
  3526.     else
  3527.      {
  3528.       NextItem->empty = 1;
  3529.       NextItem->translators = translator;
  3530.       NextItem->child = CreatePItem();
  3531.       NextItem = NextItem->child;
  3532.      }
  3533.    }
  3534.  return(Table);
  3535. }
  3536.  
  3537. static struct KeyTranslations *LoadKeyTable(w,InBuffer)
  3538.  
  3539. GenTermEmWidget w;
  3540. struct Buffer *InBuffer;
  3541.  
  3542. {
  3543.  struct KeyTranslations Keys[1024];
  3544.  struct KeyTranslations *Table;
  3545.  char buffer[1024];
  3546.  char next;
  3547.  int k,j,l;
  3548.  int i = 0;
  3549.  
  3550.  while(BufferGets(InBuffer,buffer,1024)  != NULL)
  3551.   {
  3552.    buffer[strlen(buffer)-1] = NULL;  /* get rid of trailing newline */
  3553.    if(buffer[0] == '}')
  3554.     break;
  3555.    k = -1;
  3556.    while((buffer[++k] != ',') && (buffer[k] != '(') && (buffer[k] != NULL));
  3557.    if(buffer[k] == NULL)
  3558.     XtAppError(XtWidgetToApplicationContext(w),
  3559.            "GenTermEm Widget finds bad key translation table");
  3560.    next = buffer[k];
  3561.    buffer[k] = NULL;
  3562.    Keys[i].sym = XStringToKeysym(buffer);
  3563.    if(Keys[i].sym == NoSymbol)
  3564.     XtAppError(XtWidgetToApplicationContext(w),
  3565.            "GenTermEm Widget finds bad keysym in translation table");
  3566.    Keys[i].state = 0;
  3567.    if(next == '(')   /* are there any modifiers? */
  3568.     {
  3569.      while(next != ')')
  3570.       {
  3571.        j = k+1;
  3572.        while((buffer[++k] != ',') && (buffer[k] != ')') && 
  3573.          (buffer[k] != NULL));
  3574.        if(buffer[k] == NULL)
  3575.     XtAppError(XtWidgetToApplicationContext(w),
  3576.            "GenTermEm Widget find bad modifier in translation table");
  3577.        next = buffer[k];
  3578.        buffer[k] = NULL;
  3579.        for(l = 0; w->genTermEm.Mods[l].Name != NULL; l++)
  3580.     {
  3581.      if(strcmp(w->genTermEm.Mods[l].Name,&(buffer[j])) == 0)
  3582.       {
  3583.        Keys[i].state |= w->genTermEm.Mods[l].Mask;
  3584.        break;
  3585.       }
  3586.     }
  3587.        if(w->genTermEm.Mods[l].Name == NULL)
  3588.     XtAppError(XtWidgetToApplicationContext(w),
  3589.            "GenTermEm Widget finds bad keysym in translation table");
  3590.       }
  3591.      k++;
  3592.      if(buffer[k++] != ',')
  3593.       XtAppError(XtWidgetToApplicationContext(w),
  3594.          "GenTermEm Widget finds bad keysym in translation table");
  3595.     }
  3596.    else
  3597.     {
  3598.      k++;
  3599.      Keys[i].state = 0;
  3600.     }
  3601.    Keys[i].type = buffer[k++];
  3602.    if(buffer[k++] != ',')
  3603.     XtAppError(XtWidgetToApplicationContext(w),
  3604.            "GenTermEm Widget finds bad keytable syntax");
  3605.    Keys[i].string = XtMalloc(strlen(&(buffer[k])+1));
  3606.    j = 0;
  3607.    while(buffer[k] != NULL)
  3608.     {
  3609.      Keys[i].string[j++] = buffer[k++];
  3610.     }
  3611.    Keys[i].len = j;
  3612.    i++;
  3613.   }
  3614.  Table = (struct KeyTranslations *)
  3615.   XtMalloc(sizeof(struct KeyTranslations)*i);
  3616.  for(j = 0; j < i; j++)
  3617.   {
  3618.    Table[j].sym = Keys[j].sym;
  3619.    Table[j].state = Keys[j].state;
  3620.    Table[j].type = Keys[j].type;
  3621.    Table[j].string = Keys[j].string;
  3622.    Table[j].len = Keys[j].len;
  3623.   }
  3624.  w->genTermEm.NumKeys = i;
  3625.  
  3626.  return(Table);
  3627. }
  3628.      
  3629. static struct ParseItem *CreatePItem()
  3630.  
  3631. {
  3632.  struct ParseItem *p;
  3633.  
  3634.  p = (struct ParseItem *) XtMalloc(sizeof(struct ParseItem));
  3635.  p->empty = 0;
  3636.  p->c = NULL;
  3637.  p->next = NULL;
  3638.  p->child = NULL;
  3639.  p->special = NULL;
  3640.  p->translators = NULL;
  3641.  
  3642.  return(p);
  3643. }
  3644.  
  3645. static int GetNextToken(w,InBuffer,c,special,translator,StartLine)
  3646.  
  3647. GenTermEmWidget w;
  3648. struct Buffer *InBuffer;
  3649. char *c;
  3650. struct SpecialItem **special;
  3651. struct Translator **translator;
  3652. int *StartLine;
  3653.  
  3654. {
  3655.  int input;
  3656.  char nextchar;
  3657.  int token = UNKNOWNTOKEN;
  3658.  
  3659.  if((input = BufferGetc(InBuffer)) == EOF)
  3660.   return(EOFTOKEN);
  3661.  
  3662.  nextchar = (char)input;
  3663.  
  3664.  while(token == UNKNOWNTOKEN)
  3665.   {
  3666.    if(InBuffer->escape)
  3667.     {
  3668.      *c = nextchar;
  3669.      token = TOKENCHAR;
  3670.      *StartLine = 0;
  3671.     }
  3672.    else
  3673.     {
  3674.      switch(input)
  3675.       {
  3676.      case '<' :
  3677.       *special = GetSpecialToken(w,InBuffer);
  3678.       *StartLine = 0;
  3679.       token = SPECIALCHARTOKEN;
  3680.       break;
  3681.     case '{' :
  3682.      *translator = GetTranslatorToken(w,InBuffer);
  3683.       *StartLine = 0;
  3684.       token = TRANSLATIONTOKEN;
  3685.       break;
  3686.     case EOL:
  3687.       *StartLine = 1;
  3688.       token = ENDTOKEN;
  3689.       break;
  3690.     case '}':
  3691.       token = EOTTOKEN;
  3692.       break;
  3693. /*    case '\\':
  3694.       *c = BufferGetc(InBuffer);
  3695.       *StartLine = 0;
  3696.       token = TOKENCHAR;
  3697.       break;*/
  3698.     default:
  3699.       *c = nextchar;
  3700.       *StartLine = 0;
  3701.       token = TOKENCHAR;
  3702.       break;
  3703.      }
  3704.     }
  3705.   }
  3706.  return(token);
  3707. }
  3708.  
  3709. static struct Translator *GetTranslatorToken(w,InBuffer)
  3710.  
  3711. GenTermEmWidget w;
  3712. struct Buffer *InBuffer;
  3713.  
  3714. {
  3715.  struct Translator *temp;
  3716.  char TranslationName[1024];
  3717.  int tlen;
  3718.  char Args[1024];
  3719.  int alen;
  3720.  int i = -1;
  3721.  int j;
  3722.  int c;
  3723.  
  3724.  GetFunctionToken(w,InBuffer,TranslationName,&tlen,Args,&alen);
  3725.  
  3726.  temp = (struct Translator *) XtMalloc(sizeof(struct Translator));
  3727.  temp->next = NULL;
  3728.  temp->func = NULL;
  3729.  while(Translators[++i].func != NULL)
  3730.   if(strcmp(Translators[i].name,TranslationName) == 0)
  3731.    {
  3732.     temp->func = Translators[i].func;
  3733.     break;
  3734.    }
  3735.  if(temp->func == NULL)
  3736.   {
  3737.    sprintf(Args,"Error, invalid special function found %s",TranslationName);
  3738.    XtAppError(XtWidgetToApplicationContext(w),Args);
  3739.   }
  3740.  temp->arglist = BuildArgList(Args,alen);
  3741.  if((i = BufferGetc(InBuffer)) == ';')
  3742.   temp->next = GetTranslatorToken(w,InBuffer);
  3743.  else if(i == ',')
  3744.   {
  3745.    j = 0;
  3746.    while(((c = BufferGetc(InBuffer)) != '}') && (c != ';'))
  3747.     {
  3748.      if(c == EOF)
  3749.       XtAppError(XtWidgetToApplicationContext(w),
  3750.          "Unexpected End of File Found");
  3751.      Args[j++] = (char) c;
  3752.     }
  3753.    Args[j] = NULL;
  3754.    if(sscanf(Args,"%d",&(temp->label)) != 1)
  3755.     XtAppError(XtWidgetToApplicationContext(w),"Bad Label Indicator");
  3756.    if(c == ';')
  3757.     temp->next = GetTranslatorToken(w,InBuffer);
  3758.   }
  3759.  else if(i != '}')
  3760.   while(((i = BufferGetc(InBuffer)) != '}') && (i != EOF));
  3761.  return(temp);
  3762. }
  3763.  
  3764. static struct SpecialItem *GetSpecialToken(w,InBuffer)
  3765.  
  3766. GenTermEmWidget w;
  3767. struct Buffer *InBuffer;
  3768.  
  3769. {
  3770.  struct SpecialItem *temp;
  3771.  char SpecialName[1024];
  3772.  int slen;
  3773.  char Args[1024];
  3774.  int alen;
  3775.  int i = -1;
  3776.  int c;
  3777.  
  3778.  GetFunctionToken(w,InBuffer,SpecialName,&slen,Args,&alen);
  3779.  
  3780.  temp = (struct SpecialItem *) XtMalloc(sizeof(struct SpecialItem));
  3781.  temp->func = NULL;
  3782.  while(Specials[++i].func != NULL)
  3783.   if(strcmp(Specials[i].name,SpecialName) == 0)
  3784.    {
  3785.     temp->func = Specials[i].func;
  3786.     break;
  3787.    }
  3788.  if(temp->func == NULL)
  3789.   {
  3790.    sprintf(Args,"Error, invalid special function found %s",SpecialName);
  3791.    XtAppError(XtWidgetToApplicationContext(w),Args);
  3792.   }
  3793.  temp->arglist = BuildArgList(Args,alen);
  3794.  
  3795.  c = BufferGetc(InBuffer);
  3796.  i = 0;
  3797.  if(c == ',')
  3798.   {
  3799.    while((c = BufferGetc(InBuffer)) != '>')
  3800.     {
  3801.      if(c == EOF)
  3802.       XtAppError(XtWidgetToApplicationContext(w),
  3803.          "Unexpected End of File Found");
  3804.      Args[i++] = (char) c;
  3805.     }
  3806.    Args[i] = NULL;
  3807.    if(sscanf(Args,"%d",&(temp->position)) != 1)
  3808.     XtAppError(XtWidgetToApplicationContext(w),"Bad Position Indicator");
  3809.   }
  3810.  else
  3811.   temp->position = 0;     
  3812.  return(temp);
  3813. }
  3814.  
  3815. static void GetFunctionToken(w,InBuffer,FuncName,flen,ArgList,alen)
  3816.  
  3817. GenTermEmWidget w;
  3818. char *FuncName;
  3819. int *flen;
  3820. char *ArgList;
  3821. int *alen;
  3822.  
  3823. {
  3824.  int c;
  3825.  
  3826.  *flen = 0;
  3827.  *alen = 0;
  3828.  
  3829.  while((c = BufferGetc(InBuffer)) != '(')
  3830.   {
  3831.    if(c == EOF)
  3832.     XtAppError(XtWidgetToApplicationContext(w),"Premature end of file found");
  3833.    FuncName[(*flen)++] = (char) c;
  3834.   }
  3835.  FuncName[*flen] = NULL;
  3836.  while((c = BufferGetc(InBuffer)) != ')')
  3837.   {
  3838.    if(c == EOF)
  3839.     XtAppError(XtWidgetToApplicationContext(w),"Premature end of file found");
  3840.    ArgList[(*alen)++] = (char) c;
  3841.   }
  3842.  ArgList[*alen] = NULL;
  3843. }
  3844.  
  3845. static struct ArgumentList *BuildArgList(args,alen)
  3846.  
  3847. char *args;
  3848. int alen;
  3849.  
  3850. {
  3851.  struct Arguments buffer[20];
  3852.  struct ArgumentList *temp;
  3853.  int bcount = 0;
  3854.  int i = 0;
  3855.  int k;
  3856.  
  3857.  while(i < alen)
  3858.   {
  3859.    if(args[i] == '"')     /* start of a string */
  3860.     {
  3861.      i++;
  3862.      buffer[bcount].type = ASTRING;
  3863.      buffer[bcount].string = &(args[i]);
  3864.      k = i;
  3865.      while(args[i] != '"')
  3866.       {
  3867.        if(args[i] == NULL)
  3868.     return(NULL);
  3869.        i++;
  3870.       }
  3871.      buffer[bcount++].n = i-k;
  3872.      i++;
  3873.     }
  3874.    else if(args[i] == '$')   /* positional argument */
  3875.     {
  3876.      buffer[bcount].type = APOSITION;
  3877.      i++;
  3878.      if(sscanf(&(args[i]),"%d",&(buffer[bcount++].n)) != 1)
  3879.       return(NULL);
  3880.      while((i < alen) && (args[i++] != ','));
  3881.     }
  3882.    else if((isdigit(args[i])) ||(args[i] == '-') || (args[i] == '+'))
  3883.     {
  3884.      buffer[bcount].type = AINT;
  3885.      if(sscanf(&(args[i]),"%d",&(buffer[bcount++].n)) != 1)
  3886.       return(NULL);
  3887.      while((i < alen) && (args[i++] != ','));
  3888.     }
  3889.    else if(args[i] == ',')
  3890.     i++;
  3891.    else
  3892.     return(NULL);
  3893.   }
  3894.  
  3895.  temp = (struct ArgumentList *)XtMalloc(sizeof(struct ArgumentList));
  3896.  temp->NumArgs = bcount;
  3897.  
  3898.  temp->args = (struct Arguments *)XtMalloc(sizeof(struct Arguments)*bcount);
  3899.  for(i = 0; i < bcount; i++)
  3900.   {
  3901.    temp->args[i].type = buffer[i].type;
  3902.    if(buffer[i].type == ASTRING)
  3903.     {
  3904.      temp->args[i].string = (char *) XtMalloc(sizeof(char) * buffer[i].n+1);
  3905.      strncpy(temp->args[i].string,buffer[i].string,buffer[i].n);
  3906.     }
  3907.    temp->args[i].n = buffer[i].n;
  3908.   }
  3909.  return(temp);
  3910. }
  3911. @EOF
  3912. set `wc -lwc <GenTerm/LoadParser.c`
  3913. if test $1$2$3 != 763200018601
  3914. then
  3915.     echo ERROR: wc results of GenTerm/LoadParser.c are $* should be 763 2000 18601
  3916. fi
  3917.  
  3918. chmod 644 GenTerm/LoadParser.c
  3919.  
  3920. echo x - GenTerm/Makefile
  3921. cat >GenTerm/Makefile <<'@EOF'
  3922. INCLUDE=-I/usr/include/X11R4 -I/usr/include/Motif1.1 -I/usr/contrib/X11R4
  3923. LIBS=-L/usr/lib/X11R4 -L/usr/lib/Motif1.1 -lXv -lXm -lXt -lXmu -lXext -lX11
  3924. OBJS = GenTerm.o GenTermEm.o Parse.o LoadParser.o Pty.o
  3925. SRC = GenTerm.c GenTermEm.c Parse.c LoadParser.c Pty.c
  3926. CFLAGS=-O $(INCLUDE)
  3927.  
  3928. #all : ctest TAGS
  3929.  
  3930. lib : libTermWidget.a
  3931.  
  3932. libTermWidget.a : $(OBJS)
  3933.     ar -cr libTermWidget.a $(OBJS)
  3934.  
  3935. test : test.o $(OBJS)
  3936.     cc $(CFLAGS) -o test test.o $(OBJS) $(LIBS)
  3937.  
  3938. test.o : test.c
  3939.  
  3940. ctest : ctest.o $(OBJS)
  3941.     cc $(CFLAGS) -o ctest ctest.o $(OBJS) $(LIBS)
  3942.  
  3943. ctest.o : ctest.c
  3944.  
  3945. Pty.o : Pty.c Pty.h
  3946.  
  3947. GenTerm.o : GenTerm.c GenTerm.h GenTermP.h
  3948.  
  3949. GenTermEm.o : GenTermEm.c GenTermEm.h GenTermEmP.h GenTerm.h GenTermP.h
  3950.  
  3951. LoadParser.o : LoadParser.c GenTermEm.h GenTermEmP.h GenTerm.h GenTermP.h Parser.h
  3952.  
  3953. Parse.o : Parse.c GenTermEm.h GenTermEmP.h GenTerm.h GenTermP.h Parser.h
  3954.  
  3955. TAGS : $(SRC)
  3956.     etags $(SRC)
  3957.  
  3958. clean :
  3959.     rm -f *.o core test ctest libTermWidget.a *~
  3960.  
  3961. install :
  3962.     -mkdir $(PARSEDIR)
  3963.     chmod 0555 $(PARSEDIR)
  3964.     cpset hpterm.par $(PARSEDIR) 0444 bin bin
  3965.     cpset xterm.par $(PARSEDIR) 0444 bin bin
  3966.  
  3967. installall :
  3968.     -mkdir $(PARSEDIR)
  3969.     chmod 0555 $(PARSEDIR)
  3970.     cpset hpterm.par $(PARSEDIR) 0444 bin bin
  3971.     cpset xterm.par $(PARSEDIR) 0444 bin bin
  3972.     cpset libTermWidget.a $(LIBDIR) 0444 bin bin
  3973.     cpset GenTerm.man $(MANDIR)/man3/GenTerm.3 0444 bin bin
  3974.     cpset GenTermEm.man $(MANDIR)/man3/GenTermEm.3 0444 bin bin
  3975.     cpset Pty.man $(MANDIR)/man3/Pty.3 0444 bin bin
  3976.     cpset Pty.h $(INCDIR) 0444 bin bin
  3977.     cpset PtyP.h $(INCDIR) 0444 bin bin
  3978.     cpset GenTerm.h $(INCDIR) 0444 bin bin
  3979.     cpset GenTermP.h $(INCDIR) 0444 bin bin
  3980.     cpset GenTermEm.h $(INCDIR) 0444 bin bin
  3981.     cpset GenTermEmP.h $(INCDIR) 0444 bin bin
  3982.  
  3983.  
  3984.  
  3985. @EOF
  3986. set `wc -lwc <GenTerm/Makefile`
  3987. if test $1$2$3 != 632141677
  3988. then
  3989.     echo ERROR: wc results of GenTerm/Makefile are $* should be 63 214 1677
  3990. fi
  3991.  
  3992. chmod 644 GenTerm/Makefile
  3993.  
  3994. echo x - GenTerm/Parser.h
  3995. cat >GenTerm/Parser.h <<'@EOF'
  3996. /* History:                                 */
  3997. /*         Written by G. R. Strachan 1992 */
  3998.  
  3999. /*  Copyright Gordon R. Strachan 1992 */
  4000. /*  This code is provided as is, neither the University of Waterloo nor */
  4001. /*  the author is liable for any damage caused by the use or misuse of this */
  4002. /*  code.  */
  4003.  
  4004. /* Permission is granted to copy, use and modify this code provided it is */
  4005. /* not sold for profit and the above copyright remains intact. */
  4006. #define PARSEFILE "./hpterm.par"
  4007. #define UNKNOWNTOKEN    -1
  4008. #define EOFTOKEN         0
  4009. #define ENDTOKEN         1
  4010. #define TOKENCHAR        2
  4011. #define SPECIALCHARTOKEN 3
  4012. #define TRANSLATIONTOKEN 4
  4013. #define EOTTOKEN         5
  4014.  
  4015. #define ASTRING   1
  4016. #define AINT      2
  4017. #define APOSITION 3
  4018.  
  4019. #define TRANSOKAY   0
  4020. #define TRANSERROR  -1
  4021. #define TRANSREJECT -2
  4022.  
  4023. #define PARSETOKEN "ParseTable"
  4024. #define KEYTOKEN   "KeyTable"
  4025. #define DEFAULT    "Default"
  4026. @EOF
  4027. set `wc -lwc <GenTerm/Parser.h`
  4028. if test $1$2$3 != 30130890
  4029. then
  4030.     echo ERROR: wc results of GenTerm/Parser.h are $* should be 30 130 890
  4031. fi
  4032.  
  4033. chmod 644 GenTerm/Parser.h
  4034.  
  4035. echo x - GenTerm/Pty.h
  4036. cat >GenTerm/Pty.h <<'@EOF'
  4037. /* History:                                 */
  4038. /*         Written by G. R. Strachan 1992 */
  4039.  
  4040. /*  Copyright Gordon R. Strachan 1992 */
  4041. /*  This code is provided as is, neither the University of Waterloo nor */
  4042. /*  the author is liable for any damage caused by the use or misuse of this */
  4043. /*  code.  */
  4044.  
  4045. /* Permission is granted to copy, use and modify this code provided it is */
  4046. /* not sold for profit and the above copyright remains intact. */
  4047. #ifndef _READPtyh
  4048. #define _READPtyh
  4049.  
  4050. #include "GenTermEm.h"
  4051.  
  4052. extern WidgetClass ptyWidgetClass;
  4053.  
  4054. typedef struct _PtyClassRec *PtyWidgetClass;
  4055. typedef struct _PtyRec *PtyWidget;
  4056.  
  4057. #define XtNmasterPtyName       "masterPtyName"
  4058. #define XtNslavePtyName        "slavePtyName"
  4059. #define XtNmasterPtyDescriptor "masterPtyDescriptor"
  4060. #define XtNslavePtyDescriptor  "slavePtyDescriptor"
  4061. #define XtNmasterPtyOpenMode   "masterPtyOpenMode"
  4062. #define XtNslavePtyOpenMode    "slavePtyOpenMode"
  4063. #define XtNttyMode             "ttyMode"
  4064. #define XtNptyCallback         "ptyCallback"
  4065.  
  4066. #define XtCMasterPtyName       "MasterPtyName"
  4067. #define XtCSlavePtyName        "SlavePtyName"
  4068. #define XtCMasterPtyDescriptor "MasterPtyDescriptor"
  4069. #define XtCSlavePtyDescriptor  "SlavePtyDescriptor"
  4070. #define XtCMasterPtyOpenMode   "MasterPtyOpenMode"
  4071. #define XtCSlavePtyOpenMode    "SlavePtyMode"
  4072. #define XtCTtyMode             "TtyMode"
  4073. #define XtCPtyCallback         "PtyCalback"
  4074.  
  4075. #define PTY_OPEN       1
  4076. #define PTY_IOCTL      2
  4077. #define PTY_SLAVEOPEN  3
  4078. #define PTY_SLAVECLOSE 4
  4079.  
  4080. typedef struct ptyCallback
  4081. {
  4082.  int reason;
  4083.  int MasterPtyDescriptor;
  4084.  int SlavePtyDescriptor;
  4085.  struct termios *Termios;
  4086. } PtyCallback;
  4087.  
  4088.  
  4089. #endif _READPtyh
  4090. @EOF
  4091. set `wc -lwc <GenTerm/Pty.h`
  4092. if test $1$2$3 != 531731645
  4093. then
  4094.     echo ERROR: wc results of GenTerm/Pty.h are $* should be 53 173 1645
  4095. fi
  4096.  
  4097. chmod 644 GenTerm/Pty.h
  4098.  
  4099. echo x - GenTerm/PtyP.h
  4100. cat >GenTerm/PtyP.h <<'@EOF'
  4101. /* PtyP.h -- Private definitions for the Pty widget */
  4102. /* History:                                 */
  4103. /*         Written by G. R. Strachan 1992 */
  4104.  
  4105. /*  Copyright Gordon R. Strachan 1992 */
  4106. /*  This code is provided as is, neither the University of Waterloo nor */
  4107. /*  the author is liable for any damage caused by the use or misuse of this */
  4108. /*  code.  */
  4109.  
  4110. /* Permission is granted to copy, use and modify this code provided it is */
  4111. /* not sold for profit and the above copyright remains intact. */
  4112.  
  4113. #ifndef _ReadPtyP
  4114. #define _ReadPtyP
  4115.  
  4116. #include <X11/X.h>
  4117. #include <X11/CoreP.h>
  4118. #include <X11/CompositeP.h>
  4119.  
  4120. #include "Pty.h"
  4121. #include "GenTermEmP.h"
  4122. #include "GenTermP.h"
  4123.  
  4124. #define TTYIMODE 1
  4125. #define TTYOMODE 2
  4126. #define TTYCMODE 3
  4127. #define TTYLMODE 4
  4128. #define TTYCCHAR 5
  4129. #define TTYSPEED 6
  4130. #define TTYSIZE 7
  4131.  
  4132. #define TTYNOW 1
  4133. #define TTYLATER 2
  4134.  
  4135. #define TTYROW 1
  4136. #define TTYCOLUMN 2
  4137.  
  4138. struct TtyMode
  4139. {
  4140.  char *Name;
  4141.  int Invertable;
  4142.  int Type;
  4143.  int When;
  4144.  tcflag_t Mask;
  4145. };
  4146.  
  4147. typedef struct 
  4148. {
  4149.  int dummy;
  4150. } PtyClassPart;
  4151.  
  4152. /* our full class declaration */
  4153.  
  4154. typedef struct _PtyClassRec
  4155. {
  4156.  CoreClassPart core_class;
  4157.  CompositeClassPart composite_class;
  4158.  GenTermClassPart genTerm_class;
  4159.  GenTermEmClassPart genTermEm_class;
  4160.  PtyClassPart pty_class;
  4161. } PtyClassRec;
  4162.  
  4163. /* new fields for our widget record */
  4164.  
  4165. typedef struct
  4166. {
  4167. /* public resources */
  4168.  
  4169.  char *TtyModes;             /* the termio settings */
  4170.  XtCallbackList PtyCallbacks;
  4171.  
  4172. /* public read-only resources */
  4173.  
  4174.  int MasterPtyOpenModes;     /* the arguments to give the open() call */
  4175.  int SlavePtyOpenModes;
  4176.  char *MasterPtyName;        /* the filename of the master Pty */
  4177.  char *SlavePtyName;         /* filename of the slave side of the Pty */
  4178.  int MasterDescriptor;       /* master side file descriptor */
  4179.  int SlaveDescriptor;        /* slave side file descriptor */
  4180.  
  4181. /* private data */
  4182.  
  4183.  XtInputId OutputId;
  4184.  XtInputId ExceptId;
  4185.  char StartChar;
  4186.  Boolean StartAny;
  4187.  Boolean FlowEnabled;
  4188.  Boolean WriteEnabled;
  4189.  char *Storage;
  4190.  int StoreSize;
  4191.  int NumStore;
  4192. } PtyPart;
  4193.  
  4194. /* our full instance record */
  4195.  
  4196. typedef struct _PtyRec
  4197. {
  4198.  CorePart core;
  4199.  CompositePart composite;
  4200.  GenTermPart genTerm;
  4201.  GenTermEmPart genTermEm;
  4202.  PtyPart pty;
  4203. } PtyRec;
  4204.  
  4205. #endif _ReadPtyP
  4206. @EOF
  4207. set `wc -lwc <GenTerm/PtyP.h`
  4208. if test $1$2$3 != 1053092211
  4209. then
  4210.     echo ERROR: wc results of GenTerm/PtyP.h are $* should be 105 309 2211
  4211. fi
  4212.  
  4213. chmod 644 GenTerm/PtyP.h
  4214.  
  4215. echo x - GenTerm/Xmu.h
  4216. cat >GenTerm/Xmu.h <<'@EOF'
  4217. /*
  4218.  * $XConsortium: Xmu.h,v 1.26 89/07/16 14:12:37 jim Exp $
  4219.  *
  4220.  * Copyright 1988 by the Massachusetts Institute of Technology
  4221.  *
  4222.  * Permission to use, copy, modify, and distribute this software and its
  4223.  * documentation for any purpose and without fee is hereby granted, provided 
  4224.  * that the above copyright notice appear in all copies and that both that 
  4225.  * copyright notice and this permission notice appear in supporting 
  4226.  * documentation, and that the name of M.I.T. not be used in advertising
  4227.  * or publicity pertaining to distribution of the software without specific, 
  4228.  * written prior permission. M.I.T. makes no representations about the 
  4229.  * suitability of this software for any purpose.  It is provided "as is"
  4230.  * without express or implied warranty.
  4231.  *
  4232.  * The X Window System is a Trademark of MIT.
  4233.  *
  4234.  * The interfaces described by this header file are for miscellaneous utilities
  4235.  * and are not part of the Xlib standard.
  4236.  */
  4237.  
  4238. #ifndef _XMU_H_
  4239. #define _XMU_H_
  4240.  
  4241. /*
  4242.  * This include file is obsolete and is provided only for compatibility with
  4243.  * MIT Release 3 clients.  Callers should use the appropriate include file.  
  4244.  *
  4245.  * DO NOT ADD ANY NEW INCLUDES OR DEFINITIONS TO THIS FILE!
  4246.  */
  4247. #include <X11/Intrinsic.h>
  4248. #include <X11/Xmu/Atoms.h>        /* _XA_... */
  4249. #include <X11/Xmu/CharSet.h>        /* CopyISOLatin1Lowered */
  4250. #include <X11/Xmu/Converters.h>        /* CvtStringTo... */
  4251. #include <X11/Xmu/Drawing.h>        /* DrawRoundedRect, DrawLogo */
  4252. #include <X11/Xmu/Error.h>        /* PrintDefaultError */
  4253. #include <X11/Xmu/StdSel.h>        /* ConvertStandardSelection */
  4254.  
  4255. #endif /* _XMU_H_ */
  4256.  
  4257. @EOF
  4258. set `wc -lwc <GenTerm/Xmu.h`
  4259. if test $1$2$3 != 402371576
  4260. then
  4261.     echo ERROR: wc results of GenTerm/Xmu.h are $* should be 40 237 1576
  4262. fi
  4263.  
  4264. chmod 444 GenTerm/Xmu.h
  4265.  
  4266. echo x - xcontrol/Makefile
  4267. cat >xcontrol/Makefile <<'@EOF'
  4268. INCLUDE=-I/usr/include/X11R4 -I/usr/include/Motif1.1 -I/usr/contrib/X11R4 -I../GenTerm
  4269. LIBS=-L/usr/lib/X11R4 -L/usr/lib/Motif1.1 -L../GenTerm -lTermWidget -lXv -lXm -lXt -lXmu -lXext -lX11
  4270. OBJS = XControl.o ParseString.o Command.o
  4271. SRC = XControl.c ParseString.c Command.c
  4272. CFLAGS=-O $(INCLUDE)
  4273.  
  4274. all :  XControl TAGS
  4275.  
  4276. XControl : $(OBJS)
  4277.     cc $(CFLAGS) -o XControl $(OBJS)  $(LIBS)
  4278.  
  4279. XControl.o : XControl.c XControl.h
  4280.  
  4281. ParseString.o : ParseString.c XControl.h
  4282.  
  4283. Command.o : Command.c XControl.h
  4284.  
  4285. TAGS : $(SRC)
  4286.     etags $(SRC)
  4287.  
  4288. install :
  4289.     sed -e s%PARSEDIR%$(PARSEDIR)% <XControl.ad >XControl.temp
  4290.     cpset XControl.temp /usr/lib/X11/app-defaults/XControl 0444 bin bin
  4291.     rm XControl.temp
  4292.     sed -e s%PARSEDIR%$(PARSEDIR)% <XVi.ad >XVi.temp
  4293.     cpset XVi.temp /usr/lib/X11/app-defaults/XVi 0444 bin bin
  4294.     cpset XControl $(BINDIR) 0555 bin bin
  4295.     ln -s $(BINDIR)/XControl $(BINDIR)/XVi
  4296.     cpset XControl.man $(MANDIR)/man1/XControl.1 0444 bin bin
  4297.  
  4298. clean :
  4299.     rm -f *.o *.temp a.out core *~ XControl
  4300. @EOF
  4301. set `wc -lwc <xcontrol/Makefile`
  4302. if test $1$2$3 != 32108974
  4303. then
  4304.     echo ERROR: wc results of xcontrol/Makefile are $* should be 32 108 974
  4305. fi
  4306.  
  4307. chmod 644 xcontrol/Makefile
  4308.  
  4309. exit 0
  4310.