home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / memacs400_src.lzh / MEMACS400 / SRC / smg.c < prev    next >
Text File  |  1996-04-25  |  28KB  |  958 lines

  1. /*
  2.  *  SMG terminal driver for VMS.
  3.  *
  4.  *  Consults the system's terminal tables for both DEC terminals,
  5.  *  foreign and user defined terminals.
  6.  *
  7.  *  Author:  Curtis Smith
  8.  *  Update history:
  9.  *    14-Jul-1987, first revision.
  10.  *    02-Jan-1988, by J. A. Lomicka: Code addition for interpreting
  11.  *        LK201 function keys, application keypad and cursor
  12.  *        position reports.
  13.  *    09-Apr-1988, second revision.
  14.  *        Major changes:
  15.  *        1) H files removed; replaced with globalvalues.
  16.  *        2) Terminal now left in ECHO mode. Read call
  17.  *        disables echo.
  18.  *        3) TYPAHD macro now performs correctly.
  19.  *        4) $sres variable now accepts NORMAL and WIDE.
  20.  *        5) Writes to screen now use QIO without waiting.
  21.  *        This gives a slight increase in performance.
  22.  *        Had to make some QIOW a different event flag number.
  23.  *        6) Function keys, special keys and arrow keys
  24.  *        are now bound using the following table:
  25.  *            FNN-DOWN            FNS-E1
  26.  *            FNB-LEFT            FNC-E2
  27.  *            FNF-RIGHT            FND-E3
  28.  *            FNP-UP                FN@-E4
  29.  *            FN^1-PF1            FNZ-E5
  30.  *            FN^2-PF2            FNV-E6
  31.  *            FN^3-PF3
  32.  *            FN^4-PF4
  33.  *
  34.  *            A-0 thru A-9: Keypad 0 thru 9
  35.  *            A-E: Enter
  36.  *            A-., A-, : Keypad . and ,
  37.  *
  38.  *            FN1 thru FN0 : Function keys 1 thru 10
  39.  *            S-FN1 thru S-FN0 : Function keys 11 thru 20
  40.  *            
  41.  *        See ebind.h for key bindings.
  42.  *    2-dec-88 Curtis Smith
  43.  *    - These have been rebound to the new machine independant bindings
  44.  *    27-March-1989    J.A.Lomicka    Separate VMS.C from SMG.C,
  45.  *                    This file is now SMG.C, and only
  46.  *                    contains the SMG stuff.
  47.  *
  48.  *
  49.  *    17-jul-89 : mike ward
  50.  *        Modifications for proper operation of special keys. Basically,
  51.  *        the changes are to deal with key values as ints rather rather
  52.  *        than characters so that when a character sequence is recognized
  53.  *        as a special key, the approriate value can be substituted for
  54.  *        the sequence directly (in inbuf).
  55.  *
  56.  *        1)    Use "int" rather than "char" to declare inbuf[],
  57.  *            *inbuft, and *inbufh since keys use more than 8-bits
  58.  *        2)    Change the parameter declaration "char ch" to "int ch"
  59.  *            in smgqin since we queue key values (not characters)
  60.  *        3)     Change calls "smgqin(ch)" to "smgqin((unsigned char)ch)"
  61.  *            in cook since we don't want sign extension
  62.  *        4)    Remove call "smgqin(0)" in cook. Instead of queuing
  63.  *            a sequence of chars to represent the key value, just
  64.  *            queue the final value instead - much cleaner.
  65.  *        5)    Change the declaration from "char ch" to "int ch" in
  66.  *            smggetc since ch now holds a key value rather than a
  67.  *            character.
  68.  *    11-dec-89:    Kevin A. Mitchell
  69.  *        Don't restore numeric keypad if the user had it set that way
  70.  *        in DCL.
  71.  */
  72.  
  73. /** Standard include files **/
  74. #include <stdio.h>            /* Standard I/O package        */
  75. #include "estruct.h"            /* Emacs' structures        */
  76.  
  77. /*
  78.     Empty routine make some compilers happy when SMG is not defined,
  79.     and is also used as a noop routine in the terminal dispatch table.
  80. */
  81. smg_noop()
  82. {
  83. }
  84.  
  85. #if    SMG
  86.  
  87. #include "eproto.h"
  88. #include "edef.h"            /* Emacs' definitions        */
  89. #include "elang.h"
  90. #include smgdef
  91. #include ssdef
  92. #include descrip
  93. #include ttdef
  94. #include tt2def
  95.  
  96. /*
  97.     SMG constants from $$smgtrmptrdef
  98. */
  99. #define    SMG$K_ADVANCED_VIDEO        1
  100. #define    SMG$K_ANSI_CRT            2
  101. #define    SMG$K_AUTO_MARGIN        3
  102. #define    SMG$K_BACKSPACE            4
  103. #define    SMG$K_BLOCK_MODE        5
  104. #define    SMG$K_DEC_CRT            6
  105. #define    SMG$K_EDIT            7
  106. #define    SMG$K_EIGHT_BIT            8
  107. #define    SMG$K_FULLDUP            9
  108. #define    SMG$K_IGNORE_NEWLINE        10
  109. #define    SMG$K_INSERT_MODE_NULLS        11
  110. #define    SMG$K_LOWERCASE            12
  111. #define    SMG$K_NO_ERASE            13
  112. #define    SMG$K_NO_SCROLL            14
  113. #define    SMG$K_OVERSTRIKE        15
  114. #define    SMG$K_PRINTER_PORT        16
  115. #define    SMG$K_REGIS            17
  116. #define    SMG$K_SCOPE            18
  117. #define    SMG$K_SIXEL_GRAPHICS        19
  118. #define    SMG$K_SOFT_CHARACTERS        20
  119. #define    SMG$K_PHYSICAL_TABS        21
  120. #define    SMG$K_PHYSICAL_FF        22
  121. #define    SMG$K_UNDERLINE            23
  122. #define    SMG$K_CURSOR_REPORT_ANSI    24
  123. #define    SMG$K_DEC_CRT_2            25
  124. #define    SMG$K_DEC_CRT_3            26
  125. #define    SMG$K_SET_CURSOR_COL_ROW    27
  126. #define    SMG$K_PRIVATE_BOO_1        211
  127. #define    SMG$K_PRIVATE_BOO_2        212
  128. #define    SMG$K_PRIVATE_BOO_3        213
  129. #define    SMG$K_PRIVATE_BOO_4        214
  130. #define    SMG$K_PRIVATE_BOO_5        215
  131. #define    SMG$K_PRIVATE_BOO_6        216
  132. #define    SMG$K_PRIVATE_BOO_7        217
  133. #define    SMG$K_PRIVATE_BOO_8        218
  134. #define    SMG$K_PRIVATE_BOO_9        219
  135. #define    SMG$K_PRIVATE_BOO_10        220
  136. #define    SMG$K_MAX_BOOLEAN_CODE        220
  137. #define    SMG$K_COLUMNS            221
  138. #define    SMG$K_CR_FILL            222
  139. #define    SMG$K_FRAME            223
  140. #define    SMG$K_LF_FILL            224
  141. #define    SMG$K_NUMBER_FN_KEYS        225
  142. #define    SMG$K_ROWS            226
  143. #define    SMG$K_VMS_TERMINAL_NUMBER    227
  144. #define    SMG$K_WIDE_SCREEN_COLUMNS    228
  145. #define    SMG$K_PRIVATE_NUM_1        431
  146. #define    SMG$K_PRIVATE_NUM_2        432
  147. #define    SMG$K_PRIVATE_NUM_3        433
  148. #define    SMG$K_PRIVATE_NUM_4        434
  149. #define    SMG$K_PRIVATE_NUM_5        435
  150. #define    SMG$K_PRIVATE_NUM_6        436
  151. #define    SMG$K_PRIVATE_NUM_7        437
  152. #define    SMG$K_PRIVATE_NUM_8        438
  153. #define    SMG$K_PRIVATE_NUM_9        439
  154. #define    SMG$K_PRIVATE_NUM_10        440
  155. #define    SMG$K_MAX_NUMERIC_CODE        440
  156. #define    SMG$K_BEGIN_ALTERNATE_CHAR    441
  157. #define    SMG$K_BEGIN_BLINK        442
  158. #define    SMG$K_BEGIN_BOLD        443
  159. #define    SMG$K_BEGIN_DELETE_MODE        444
  160. #define    SMG$K_BEGIN_INSERT_MODE        445
  161. #define    SMG$K_BEGIN_LINE_DRAWING_CHAR    446
  162. #define    SMG$K_BEGIN_REVERSE        447
  163. #define    SMG$K_BEGIN_UNDERSCORE        448
  164. #define    SMG$K_BOTTOM_T_CHAR        449
  165. #define    SMG$K_CLEAR_TAB            450
  166. #define    SMG$K_CROSS_CHAR        451
  167. #define    SMG$K_CURSOR_DOWN        452
  168. #define    SMG$K_CURSOR_LEFT        453
  169. #define    SMG$K_CURSOR_RIGHT        454
  170. #define    SMG$K_CURSOR_UP            455
  171. #define    SMG$K_DARK_SCREEN        456
  172. #define    SMG$K_DELETE_CHAR        457
  173. #define    SMG$K_DELETE_LINE        458
  174. #define    SMG$K_DEVICE_ATTRIBUTES        459
  175. #define    SMG$K_DOUBLE_HIGH_BOTTOM    460
  176. #define    SMG$K_DOUBLE_HIGH_TOP        461
  177. #define    SMG$K_DOUBLE_WIDE        462
  178. #define    SMG$K_DUPLICATE            463
  179. #define    SMG$K_END_ALTERNATE_CHAR    464
  180. #define    SMG$K_END_BLINK            465
  181. #define    SMG$K_END_BOLD            466
  182. #define    SMG$K_END_DELETE_MODE        467
  183. #define    SMG$K_END_INSERT_MODE        468
  184. #define    SMG$K_END_LINE_DRAWING_CHAR    469
  185. #define    SMG$K_END_REVERSE        470
  186. #define    SMG$K_END_UNDERSCORE        471
  187. #define    SMG$K_ERASE_TO_END_DISPLAY    472
  188. #define    SMG$K_ERASE_TO_END_LINE        473
  189. #define    SMG$K_ERASE_WHOLE_DISPLAY    474
  190. #define    SMG$K_ERASE_WHOLE_LINE        475
  191. #define    SMG$K_HOME            476
  192. #define    SMG$K_HORIZONTAL_BAR        477
  193. #define    SMG$K_INIT_STRING        478
  194. #define    SMG$K_INSERT_CHAR        479
  195. #define    SMG$K_INSERT_LINE        480
  196. #define    SMG$K_INSERT_PAD        481
  197. #define    SMG$K_KEY_0            482
  198. #define    SMG$K_KEY_1            483
  199. #define    SMG$K_KEY_2            484
  200. #define    SMG$K_KEY_3            485
  201. #define    SMG$K_KEY_4            486
  202. #define    SMG$K_KEY_5            487
  203. #define    SMG$K_KEY_6            488
  204. #define    SMG$K_KEY_7            489
  205. #define    SMG$K_KEY_8            490
  206. #define    SMG$K_KEY_9            491
  207. #define    SMG$K_KEY_BACKSPACE        492
  208. #define    SMG$K_KEY_COMMA            493
  209. #define    SMG$K_KEY_DOWN_ARROW        494
  210. #define    SMG$K_KEY_E1            495
  211. #define    SMG$K_KEY_E2            496
  212. #define    SMG$K_KEY_E3            497
  213. #define    SMG$K_KEY_E4            498
  214. #define    SMG$K_KEY_E5            499
  215. #define    SMG$K_KEY_E6            500
  216. #define    SMG$K_KEY_ENTER            501
  217. #define    SMG$K_KEY_F1            502
  218. #define    SMG$K_KEY_F2            503
  219. #define    SMG$K_KEY_F3            504
  220. #define    SMG$K_KEY_F4            505
  221. #define    SMG$K_KEY_F5            506
  222. #define    SMG$K_KEY_F6            507
  223. #define    SMG$K_KEY_F7            508
  224. #define    SMG$K_KEY_F8            509
  225. #define    SMG$K_KEY_F9            510
  226. #define    SMG$K_KEY_F10            511
  227. #define    SMG$K_KEY_F11            512
  228. #define    SMG$K_KEY_F12            513
  229. #define    SMG$K_KEY_F13            514
  230. #define    SMG$K_KEY_F14            515
  231. #define    SMG$K_KEY_F15            516
  232. #define    SMG$K_KEY_F16            517
  233. #define    SMG$K_KEY_F17            518
  234. #define    SMG$K_KEY_F18            519
  235. #define    SMG$K_KEY_F19            520
  236. #define    SMG$K_KEY_F20            521
  237. #define    SMG$K_KEY_LEFT_ARROW        522
  238. #define    SMG$K_KEY_MINUS            523
  239. #define    SMG$K_KEY_PERIOD        524
  240. #define    SMG$K_KEY_PF1            525
  241. #define    SMG$K_KEY_PF2            526
  242. #define    SMG$K_KEY_PF3            527
  243. #define    SMG$K_KEY_PF4            528
  244. #define    SMG$K_KEY_RIGHT_ARROW        529
  245. #define    SMG$K_KEY_UP_ARROW        530
  246. #define    SMG$K_LABEL_F1            531
  247. #define    SMG$K_LABEL_F2            532
  248. #define    SMG$K_LABEL_F3            533
  249. #define    SMG$K_LABEL_F4            534
  250. #define    SMG$K_LABEL_F5            535
  251. #define    SMG$K_LABEL_F6            536
  252. #define    SMG$K_LABEL_F7            537
  253. #define    SMG$K_LABEL_F8            538
  254. #define    SMG$K_LABEL_F9            539
  255. #define    SMG$K_LABEL_F10            540
  256. #define    SMG$K_LABEL_F11            541
  257. #define    SMG$K_LABEL_F12            542
  258. #define    SMG$K_LABEL_F13            543
  259. #define    SMG$K_LABEL_F14            544
  260. #define    SMG$K_LABEL_F15            545
  261. #define    SMG$K_LABEL_F16            546
  262. #define    SMG$K_LABEL_F17            547
  263. #define    SMG$K_LABEL_F18            548
  264. #define    SMG$K_LABEL_F19            549
  265. #define    SMG$K_LABEL_F20            550
  266. #define    SMG$K_LEFT_T_CHAR        551
  267. #define    SMG$K_LIGHT_SCREEN        552
  268. #define    SMG$K_LOWER_LEFT_CORNER        553
  269. #define    SMG$K_LOWER_RIGHT_CORNER    554
  270. #define    SMG$K_NAME            555
  271. #define    SMG$K_NEWLINE_CHAR        556
  272. #define    SMG$K_PAD_CHAR            557
  273. #define    SMG$K_RESTORE_CURSOR        558
  274. #define    SMG$K_RIGHT_T_CHAR        559
  275. #define    SMG$K_SAVE_CURSOR        560
  276. #define    SMG$K_SCROLL_FORWARD        561
  277. #define    SMG$K_SCROLL_REVERSE        562
  278. #define    SMG$K_SEL_ERASE_TO_END_DISPLAY    563
  279. #define    SMG$K_SEL_ERASE_TO_END_LINE    564
  280. #define    SMG$K_SEL_ERASE_WHOLE_DISPLAY    565
  281. #define    SMG$K_SEL_ERASE_WHOLE_LINE    566
  282. #define    SMG$K_SET_APPLICATION_KEYPAD    567
  283. #define    SMG$K_SET_CHAR_NOT_SEL_ERASE    568
  284. #define    SMG$K_SET_CHAR_SEL_ERASE    569
  285. #define    SMG$K_SET_CURSOR_ABS        570
  286. #define    SMG$K_SET_NUMERIC_KEYPAD    571
  287. #define    SMG$K_SET_SCROLL_REGION        572
  288. #define    SMG$K_SET_TAB            573
  289. #define    SMG$K_SINGLE_HIGH        574
  290. #define    SMG$K_TAB_CHAR            575
  291. #define    SMG$K_TOP_T_CHAR        576
  292. #define    SMG$K_UNDERLINE_CHAR        577
  293. #define    SMG$K_UPPER_LEFT_CORNER        578
  294. #define    SMG$K_UPPER_RIGHT_CORNER    579
  295. #define    SMG$K_VERTICAL_BAR        580
  296. #define    SMG$K_WIDTH_NARROW        581
  297. #define    SMG$K_WIDTH_WIDE        582
  298. #define    SMG$K_CURSOR_POSITION_REPORT    583
  299. #define    SMG$K_REQUEST_CURSOR_POSITION    584
  300. #define    SMG$K_CR_GRAPHIC        585
  301. #define    SMG$K_FF_GRAPHIC        586
  302. #define    SMG$K_LF_GRAPHIC        587
  303. #define    SMG$K_HT_GRAPHIC        588
  304. #define    SMG$K_VT_GRAPHIC        589
  305. #define    SMG$K_TRUNCATION_ICON        590
  306. #define    SMG$K_CURSOR_NEXT_LINE        591
  307. #define    SMG$K_CURSOR_PRECEDING_LINE    592
  308. #define    SMG$K_INDEX            593
  309. #define    SMG$K_REVERSE_INDEX        594
  310. #define    SMG$K_BEGIN_NORMAL_RENDITION    595
  311. #define    SMG$K_BEGIN_AUTOWRAP_MODE    596
  312. #define    SMG$K_END_AUTOWRAP_MODE        597
  313. #define    SMG$K_BEGIN_AUTOREPEAT_MODE    598
  314. #define    SMG$K_END_AUTOREPEAT_MODE    599
  315. #define    SMG$K_SET_ORIGIN_RELATIVE    600
  316. #define    SMG$K_SET_ORIGIN_ABSOLUTE    601
  317. #define    SMG$K_ERASE_LINE_TO_CURSOR    602
  318. #define    SMG$K_NEXT_LINE            603
  319. #define    SMG$K_BEGIN_AUTOPRINT_MODE    604
  320. #define    SMG$K_END_AUTOPRINT_MODE    605
  321. #define    SMG$K_PRINT_SCREEN        606
  322. #define    SMG$K_SET_CURSOR_ON        607
  323. #define    SMG$K_SET_CURSOR_OFF        608
  324. #define    SMG$K_SET_PRINTER_OUTPUT    609
  325. #define    SMG$K_SET_SCREEN_OUTPUT        610
  326. #define    SMG$K_ERASE_DISPLAY_TO_CURSOR    611
  327. #define    SMG$K_REQUEST_PRINTER_STATUS    612
  328. #define    SMG$K_PRINTER_READY        613
  329. #define    SMG$K_PRINTER_NOT_READY        614
  330. #define    SMG$K_NO_PRINTER        615
  331. #define    SMG$K_SET_JUMP_SCROLL        616
  332. #define    SMG$K_SET_SMOOTH_SCROLL        617
  333. #define    SMG$K_ERROR_ICON        618
  334. #define    SMG$K_PAGE_LENGTH        619
  335. #define    SMG$K_PRIVATE_STR_1        651
  336. #define    SMG$K_PRIVATE_STR_2        652
  337. #define    SMG$K_PRIVATE_STR_3        653
  338. #define    SMG$K_PRIVATE_STR_4        654
  339. #define    SMG$K_PRIVATE_STR_5        655
  340. #define    SMG$K_PRIVATE_STR_6        656
  341. #define    SMG$K_PRIVATE_STR_7        657
  342. #define    SMG$K_PRIVATE_STR_8        658
  343. #define    SMG$K_PRIVATE_STR_9        659
  344. #define    SMG$K_PRIVATE_STR_10        660
  345. #define    SMG$K_MAX_STRING_CODE        660
  346. #define    SMG$K_BEGIN_USER1        661
  347. #define    SMG$K_BEGIN_USER2        662
  348. #define    SMG$K_BEGIN_USER3        663
  349. #define    SMG$K_BEGIN_USER4        664
  350. #define    SMG$K_BEGIN_USER5        665
  351. #define    SMG$K_BEGIN_USER6        666
  352. #define    SMG$K_BEGIN_USER7        667
  353. #define    SMG$K_BEGIN_USER8        668
  354. #define    SMG$K_END_USER1            669
  355. #define    SMG$K_END_USER2            670
  356. #define    SMG$K_END_USER3            671
  357. #define    SMG$K_END_USER4            672
  358. #define    SMG$K_END_USER5            673
  359. #define    SMG$K_END_USER6            674
  360. #define    SMG$K_END_USER7            675
  361. #define    SMG$K_END_USER8            676
  362. #define    SMG$K_BLACK_SCREEN        677
  363. #define    SMG$K_BLUE_SCREEN        678
  364. #define    SMG$K_CYAN_SCREEN        679
  365. #define    SMG$K_MAGENTA_SCREEN        680
  366. #define    SMG$K_GREEN_SCREEN        681
  367. #define    SMG$K_RED_SCREEN        682
  368. #define    SMG$K_WHITE_SCREEN        683
  369. #define    SMG$K_YELLOW_SCREEN        684
  370. #define    SMG$K_USER1_SCREEN        685
  371. #define    SMG$K_USER2_SCREEN        686
  372. #define    SMG$K_BEGIN_STATUS_LINE        687
  373. #define    SMG$K_END_STATUS_LINE        688
  374. #define    SMG$K_BEGIN_LOCATOR        689
  375. #define    SMG$K_END_LOCATOR        690
  376. #define    SMG$K_KEY_FIRST_DOWN        691
  377. #define    SMG$K_KEY_SECOND_DOWN        692
  378. #define    SMG$K_KEY_THIRD_DOWN        693
  379. #define    SMG$K_KEY_FOURTH_DOWN        694
  380. #define    SMG$K_KEY_FIRST_UP        695
  381. #define    SMG$K_KEY_SECOND_UP        696
  382. #define    SMG$K_KEY_THIRD_UP        697
  383. #define    SMG$K_KEY_FOURTH_UP        698
  384. #define    SMG$K_MAX_STRING2_CODE        880
  385.  
  386. /*
  387.     Parts of VMS.C that we'll want to access here
  388. */
  389. extern struct dsc$descriptor_s *descptr();
  390. extern struct dsc$descriptor_s *descrp();
  391. #define DESCPTR( s)    descrp( s, sizeof(s)-1)
  392. /*
  393.     These two structures, along with ttdef.h, are good for manipulating
  394.     terminal characteristics.
  395. */
  396. typedef struct
  397.     {/* Terminal characteristics buffer */
  398.     unsigned char class, type;
  399.     unsigned short width;
  400.     unsigned tt1 : 24;
  401.     unsigned char page;
  402.     unsigned long tt2;
  403.     } TTCHAR;
  404. extern NOSHARE TTCHAR orgchar;            /* Original characteristics */
  405. /*
  406.     test macro is used to signal errors from system services
  407. */
  408. #define test( s) {int st; st = (s); if( (st&1)==0) LIB$SIGNAL( st);}
  409. #define FAILURE( s) (!(s&1))
  410. #define SUCCESS( s) (s&1)
  411.  
  412.  
  413.  
  414. /** Values to manage the screen **/
  415. static int termtype;            /* Handle to pass to SMG    */
  416. #if    KEYPAD
  417. static char * applic_keypad;        /* Put keypad in application mode.*/
  418. static char * numeric_keypad;        /* Put keypad in numeric mode.    */
  419. #endif
  420. static char * begin_reverse;        /* Begin reverse video        */
  421. static char * end_reverse;        /* End reverse video        */
  422. static char * begin_mouse;        /* Begin using mouse        */
  423. static char * end_mouse;        /* End using mouse        */
  424. static char * erase_to_end_line;    /* Erase to end of line        */
  425. static char * erase_whole_display;    /* Erase whole display        */
  426. static char * width_narrow;        /* Set narrow size screen    */
  427. static char * width_wide;        /* Set wide size screen        */
  428. static int narrow_char;            /* Number of characters narrow    */
  429. static int wide_char;            /* Number of characters wide    */
  430. static int inbuf[64];            /* Input buffer            */
  431. static int * inbufh = inbuf;        /* Head of input buffer        */
  432. static int * inbuft = inbuf;        /* Tail of input buffer        */
  433.  
  434.  
  435. /* Forward references.          */
  436. extern int PASCAL NEAR smgmove();
  437. extern int PASCAL NEAR smgeeol();
  438. extern int PASCAL NEAR smgeeop();
  439. extern int PASCAL NEAR smgbeep();
  440. extern int PASCAL NEAR smgopen();
  441. extern int PASCAL NEAR smgrev();
  442. extern int PASCAL NEAR smgcres();
  443. extern int PASCAL NEAR smgparm();
  444. extern int PASCAL NEAR smggetc();
  445. extern int PASCAL NEAR smgclose();
  446.  
  447. /** Terminal dispatch table **/
  448. NOSHARE TERM term = {
  449.     72-1,                /* Max number of rows allowable */
  450.     0,                /* Current number of rows used    */
  451.     256,                /* Max number of columns    */
  452.     0,                /* Current number of columns    */
  453.     0, 0,                /* x/y origin of screen        */
  454.     64,                /* Min margin for extended lines*/
  455.     8,                /* Size of scroll region    */
  456.     100,                /* # times thru update to pause */
  457.     smgopen,            /* Open terminal at the start    */
  458.     smgclose,            /* Close terminal at end    */
  459.     smg_noop,            /* Open keyboard        */
  460.     smg_noop,            /* Close keyboard        */
  461.     smggetc,            /* Get character from keyboard    */
  462.     ttputc,                /* Put character to display    */
  463.     ttflush,            /* Flush output buffers        */
  464.     smgmove,            /* Move cursor, origin 0    */
  465.     smgeeol,            /* Erase to end of line        */
  466.     smgeeop,            /* Erase to end of page        */
  467.     smgeeop,            /* Erase to end of screen    */
  468.     smgbeep,            /* Beep                */
  469.     smgrev,                /* Set reverse video state    */
  470.     smgcres                /* Change screen resolution    */
  471. #if COLOR
  472.     ,
  473.     smg_noop,            /* Set forground color        */
  474.     smg_noop            /* Set background color        */
  475. #endif /* COLOR */
  476. };
  477.  
  478. /***
  479.  *  smgmove  -  Move the cursor (0 origin)
  480.  *
  481.  *  smgmove calls to the SMG run-time library to produce a character
  482.  *  sequence to position the cursor.  If the sequence cannot be made,
  483.  *  a string "OOPS" is produced instead, much like the termcap library
  484.  *  under UNIX.  In the case of "OOPS", the user will soon know that
  485.  *  his terminal entry is incorrect.
  486.  *
  487.  *  Nothing returned.
  488.  ***/
  489. smgmove(int row, int column)
  490. {
  491.     char buffer[32];
  492.     int rlen, status;
  493.     
  494.     static int code = SMG$K_SET_CURSOR_ABS;
  495.     static int len = sizeof(buffer);
  496.     static int arg[3] = { 2 };
  497.  
  498.     /* SMG assumes the row/column positions    are 1 based. */
  499.     arg[1] = row + 1;
  500.     arg[2] = column + 1;
  501.  
  502.     /* Call to SMG for the sequence */
  503.     status = SMG$GET_TERM_DATA(&termtype, &code, &len, &rlen, buffer, arg);
  504.     if (SUCCESS(status)) {
  505.         buffer[rlen] = '\0';
  506.         smgputs(buffer);
  507.     } else
  508.         smgputs("OOPS");
  509. }
  510.  
  511. /***
  512.  *  smgcres  -  Change screen resolution
  513.  *
  514.  *  smgcres changes the screen resolution of the current window.
  515.  *  Allowable sizes are NORMAL and WIDE.
  516.  *
  517.  *  Nothing returned
  518.  ***/
  519. smgcres(char *value)
  520. {
  521.     int width;
  522.  
  523.     /* Skip if not supported */
  524.     if (width_wide == NULL || width_narrow == NULL)
  525.         return;
  526.  
  527.     /* Check value */
  528.     if (strcmp(value, "WIDE") == 0) {
  529.         width = wide_char;
  530.         smgputs(width_wide);
  531.     } else if (strcmp(value, "NORMAL") == 0) {
  532.         width = narrow_char;
  533.         smgputs(width_narrow);
  534.     }
  535.  
  536.     /* Change width */
  537.     orgchar.width = width;
  538.     newwidth(TRUE, width);
  539.  
  540.     /* Set resolution variable */
  541.     strcpy(sres, value);
  542. }
  543.  
  544. /***
  545.  *  smgrev  -  Set the reverse video status
  546.  *
  547.  *  smgrev either sets or resets the reverse video state, based on the
  548.  *  boolean argument.  This function is only called if the revexist
  549.  *  boolean variable is set to TRUE.  Otherwise there is no reverse
  550.  *  video available.
  551.  *
  552.  *  Nothing returned.
  553.  ***/
  554. smgrev(int status)
  555. {
  556.     smgputs(status ? begin_reverse : end_reverse);
  557. }
  558.  
  559. /***
  560.  *  smgeeol  -  Erase to end of line
  561.  *
  562.  *  When this function is called, the lines worth of text after the
  563.  *  cursor is erased.  This function is only called if the eolexist
  564.  *  boolean variable is set to TRUE.  Otherwise the display manager
  565.  *  will produce enough spaces to erase the line.
  566.  *
  567.  *  Nothing returned.
  568.  ***/
  569. smgeeol()
  570. {
  571.     smgputs(erase_to_end_line);
  572. }
  573.  
  574. /***
  575.  *  smgeeop  -  Erase to end of page (clear screen)
  576.  *
  577.  *  smgeeop really should be called smgclear because it really should
  578.  *  be an erase screen function.  When called, this routine will send
  579.  *  the erase entire screen sequence to the output.
  580.  *
  581.  *  Nothing returned.
  582.  ***/
  583. smgeeop()
  584. {
  585.     smgputs(erase_whole_display);
  586. }
  587.  
  588. /***
  589.  *  smgbeep  -  Ring the bell
  590.  *
  591.  *  smgbeep send a bell character to the output.  It might be possible
  592.  *  in the future to include the NOISY definition and attempt to flash
  593.  *  the screen, perhaps using LIGHT_SCREEN and DARK_SCREEN.
  594.  *
  595.  *  Nothing returned.
  596.  ***/
  597. smgbeep()
  598. {
  599.     ttputc('\007');
  600. }
  601.  
  602. /***
  603.  *  smggetstr  -  Get an SMG string capability by name
  604.  *
  605.  *  smggetstr attempts to obtain the escape sequence for a particular
  606.  *  job from the SMG library.  Most sequences do not require a parameter
  607.  *  with the sequence, others do.  In order to obtain the definition
  608.  *  without knowing ahead of time whether ornot the definition has a
  609.  *  parameter, we call SMG once with a parameter and if that fails, we
  610.  *  try again without one.  If both attempts fail, we will return the
  611.  *  NULL string.
  612.  *
  613.  *  Storage for the sequence comes from a local pool.
  614.  *
  615.  *  Returns:    Escape sequence
  616.  *        NULL    No escape sequence available
  617.  ***/ 
  618. char * smggetstr(int code)    /* Request code            */
  619. {
  620.     char * result;
  621.     int rlen, status;
  622.     
  623.     static char seq[1024];
  624.     static char * buffer = seq;
  625.     static int len = sizeof(seq);
  626.     static int arg[2] = { 1, 1 };
  627.  
  628.     /* Get sequence with one parameter */
  629.     status = SMG$GET_TERM_DATA(&termtype, &code, &len, &rlen, buffer, arg);
  630.     if (FAILURE(status)) {
  631.         /* Try again with zero parameters */
  632.         status = SMG$GET_TERM_DATA(&termtype, &code, &len, &rlen, buffer);
  633.         if (FAILURE(status))
  634.             return NULL;
  635.     }
  636.  
  637.     /* Check for empty result */
  638.     if (rlen == 0)
  639.         return NULL;
  640.     
  641.     /* Save current position so we can return it to caller */
  642.     result = buffer;
  643.     buffer[rlen++] = '\0';
  644.     buffer += rlen;
  645.  
  646.     /* Return capability to user */
  647.     return result;
  648. }
  649.  
  650. /***
  651.  *  smggetnum  -  Get numerical constant from SMG
  652.  *
  653.  *  smggetnum attempts to get a numerical constant from the SMG package.
  654.  *  If the constant cannot be found, -1 is returned.
  655.  *
  656.  *  code - SMG code
  657.  ***/
  658. int smggetnum(int code)
  659. {
  660.     int status, result;
  661.  
  662.     /* Call SMG for code translation */
  663.     status = SMG$GET_NUMERIC_DATA(&termtype, &code, &result);
  664.     return FAILURE(status) ? -1 : result;
  665. }
  666.  
  667. /***
  668.  *  smgaddkey - translate the SMG code to the escape sequence, and
  669.  *  add it to the list of keys.
  670.  ***/
  671. int smgaddkey(int code, int fn)
  672. {
  673.     return (addkey(smggetstr(code), fn));
  674. }
  675.  
  676. /***
  677.  *  smgcap  -  Get capabilities from VMS's SMG library
  678.  *
  679.  *  smgcap retrives all the necessary capabilities from the SMG
  680.  *  library to operate MicroEMACS.  If an insufficent number of
  681.  *  capabilities are found for the particular terminal, an error
  682.  *  status is returned.
  683.  *
  684.  *  Returns:    0 if okay, <>0 if error
  685.  ***/
  686. int smgcap()
  687. {
  688.     char * set_cursor_abs;
  689.     int status;
  690.     
  691.     /* Start SMG package */
  692.     status = SMG$INIT_TERM_TABLE_BY_TYPE( &orgchar.type, &termtype);
  693.     if (FAILURE(status)) {
  694.         printf(TEXT189);
  695. /*                     "Cannot find entry for terminal type.\n" */
  696.         printf(TEXT190);
  697. /*                     "Check terminal type with \"SHOW TERMINAL\" or\n" */
  698.         printf(TEXT191);
  699. /*                     "try setting with \"SET TERMINAL/INQUIRE\"\n" */
  700.         return 1;
  701.     }
  702.         
  703.     /* Get reverse video */
  704.     begin_reverse = smggetstr(SMG$K_BEGIN_REVERSE);
  705.     end_reverse = smggetstr(SMG$K_END_REVERSE);
  706. #if    KEYPAD
  707.     applic_keypad = smggetstr(SMG$K_SET_APPLICATION_KEYPAD);
  708.     numeric_keypad = smggetstr(SMG$K_SET_NUMERIC_KEYPAD);
  709. #endif
  710.     begin_mouse = smggetstr(SMG$K_BEGIN_LOCATOR);
  711.     end_mouse = smggetstr(SMG$K_END_LOCATOR);
  712.     revexist = begin_reverse != NULL && end_reverse != NULL;
  713.     
  714.     /* Get erase to end of line */
  715.     erase_to_end_line = smggetstr(SMG$K_ERASE_TO_END_LINE);
  716.     eolexist = erase_to_end_line != NULL;
  717.     
  718.     /* Get more neat stuff */
  719.     erase_whole_display = smggetstr(SMG$K_ERASE_WHOLE_DISPLAY);
  720.     width_wide = smggetstr(SMG$K_WIDTH_WIDE);
  721.     width_narrow = smggetstr(SMG$K_WIDTH_NARROW);
  722.     narrow_char = smggetnum(SMG$K_COLUMNS);
  723.     wide_char = smggetnum(SMG$K_WIDE_SCREEN_COLUMNS);
  724.     set_cursor_abs = smggetstr(SMG$K_SET_CURSOR_ABS);
  725.  
  726.     /* Disable resolution if unreasonable */
  727.     if (narrow_char < 10 || wide_char < 10) {
  728.         width_wide = width_narrow = NULL;
  729.         strcpy(sres, "NORMAL");
  730.     } else
  731.         /* Kludge resolution */
  732.         strcpy(sres, orgchar.width == wide_char ? "WIDE" : "NORMAL");
  733.  
  734.     /* Check for minimal operations */
  735.     if (set_cursor_abs == NULL || erase_whole_display == NULL) {
  736.         printf(TEXT192);
  737. /*                     "The terminal type does not have enough power to run\n" */
  738.         printf(TEXT193);
  739. /*                     "MicroEMACS.  Try a different terminal or check\n" */
  740.         printf(TEXT194);
  741. /*                     "type with \"SHOW TERMINAL\".\n" */
  742.         return 1;
  743.     }
  744.     
  745.     /* Add function keys to keymapping table */
  746.     smgaddkey(SMG$K_KEY_DOWN_ARROW,        SPEC | 'N');
  747.     smgaddkey(SMG$K_KEY_LEFT_ARROW,        SPEC | 'B');
  748.     smgaddkey(SMG$K_KEY_RIGHT_ARROW,    SPEC | 'F');
  749.     smgaddkey(SMG$K_KEY_UP_ARROW,        SPEC | 'P');
  750.  
  751.     smgaddkey(SMG$K_KEY_PF1,    CTRL | SPEC | '1');
  752.     smgaddkey(SMG$K_KEY_PF2,    CTRL | SPEC | '2');
  753.     smgaddkey(SMG$K_KEY_PF3,    CTRL | SPEC | '3');
  754.     smgaddkey(SMG$K_KEY_PF4,    CTRL | SPEC | '4');
  755.  
  756.     smgaddkey(SMG$K_KEY_0,        ALTD | '0');
  757.     smgaddkey(SMG$K_KEY_1,        ALTD | '1');
  758.     smgaddkey(SMG$K_KEY_2,        ALTD | '2');
  759.     smgaddkey(SMG$K_KEY_3,        ALTD | '3');
  760.     smgaddkey(SMG$K_KEY_4,        ALTD | '4');
  761.     smgaddkey(SMG$K_KEY_5,        ALTD | '5');
  762.     smgaddkey(SMG$K_KEY_6,        ALTD | '6');
  763.     smgaddkey(SMG$K_KEY_7,        ALTD | '7');
  764.     smgaddkey(SMG$K_KEY_8,        ALTD | '8');
  765.     smgaddkey(SMG$K_KEY_9,        ALTD | '9');
  766.     smgaddkey(SMG$K_KEY_PERIOD,    ALTD | '.');
  767.     smgaddkey(SMG$K_KEY_ENTER,     ALTD | 'E');
  768.     smgaddkey(SMG$K_KEY_COMMA,     ALTD | ',');
  769.     smgaddkey(SMG$K_KEY_MINUS,     ALTD | '-');
  770.  
  771.     smgaddkey(SMG$K_KEY_F1,        SPEC | '1');
  772.     smgaddkey(SMG$K_KEY_F2,        SPEC | '2');
  773.     smgaddkey(SMG$K_KEY_F3,        SPEC | '3');
  774.     smgaddkey(SMG$K_KEY_F4,        SPEC | '4');
  775.     smgaddkey(SMG$K_KEY_F5,        SPEC | '5');
  776.     smgaddkey(SMG$K_KEY_F6,        SPEC | '6');
  777.     smgaddkey(SMG$K_KEY_F7,        SPEC | '7');
  778.     smgaddkey(SMG$K_KEY_F8,        SPEC | '8');
  779.     smgaddkey(SMG$K_KEY_F9,        SPEC | '9');
  780.     smgaddkey(SMG$K_KEY_F10,    SPEC | '0');
  781.     smgaddkey(SMG$K_KEY_F11,    SHFT | SPEC | '1');
  782.     smgaddkey(SMG$K_KEY_F12,    SHFT | SPEC | '2');
  783.     smgaddkey(SMG$K_KEY_F13,    SHFT | SPEC | '3');
  784.     smgaddkey(SMG$K_KEY_F14,    SHFT | SPEC | '4');
  785.     smgaddkey(SMG$K_KEY_F15,    SHFT | SPEC | '5');
  786.     smgaddkey(SMG$K_KEY_F16,    SHFT | SPEC | '6');
  787.     smgaddkey(SMG$K_KEY_F17,    SHFT | SPEC | '7');
  788.     smgaddkey(SMG$K_KEY_F18,    SHFT | SPEC | '8');
  789.     smgaddkey(SMG$K_KEY_F19,    SHFT | SPEC | '9');
  790.     smgaddkey(SMG$K_KEY_F20,    SHFT | SPEC | '0');
  791.  
  792.     smgaddkey(SMG$K_KEY_E1,        SPEC | 'S');
  793.     smgaddkey(SMG$K_KEY_E2,        SPEC | 'C');
  794.     smgaddkey(SMG$K_KEY_E3,        SPEC | 'D');
  795.     smgaddkey(SMG$K_KEY_E4,        SPEC | '@');
  796.     smgaddkey(SMG$K_KEY_E5,        SPEC | 'Z');
  797.     smgaddkey(SMG$K_KEY_E6,        SPEC | 'V');
  798.  
  799.     smgaddkey(SMG$K_KEY_FIRST_DOWN,        MOUS | 'a');
  800.     smgaddkey(SMG$K_KEY_FIRST_UP,        MOUS | 'b');
  801.     smgaddkey(SMG$K_KEY_SECOND_DOWN,    MOUS | 'c');
  802.     smgaddkey(SMG$K_KEY_SECOND_UP,        MOUS | 'd');
  803.     smgaddkey(SMG$K_KEY_THIRD_DOWN,        MOUS | 'e');
  804.     smgaddkey(SMG$K_KEY_THIRD_UP,        MOUS | 'f');
  805.     smgaddkey(SMG$K_KEY_FOURTH_DOWN,    MOUS | 'g');
  806.     smgaddkey(SMG$K_KEY_FOURTH_UP,        MOUS | 'h');
  807.     /* Everything okay */
  808.     return 0;
  809. }
  810.  
  811. /***
  812.  *  smgopen  -  Get terminal type and open terminal
  813.  *
  814.  *  Nothing returned
  815.  ***/
  816. smgopen()
  817. {
  818.     static int first_time = 1;
  819.     
  820.     /* Open channel to terminal (also sets sizes in TERM structure) */
  821.     ttopen();
  822.  
  823.     /* Get SMG */
  824.     if (first_time)
  825.     {
  826.         first_time = 0;
  827.         if (smgcap())
  828.             meexit( 1);
  829.     }
  830.  
  831. #if    KEYPAD
  832.     smgputs(applic_keypad);
  833. #endif
  834. #ifdef NEVER
  835.     smgputs( begin_mouse);
  836. #endif
  837. }
  838.  
  839. smgclose()
  840. {
  841. #ifdef NEVER
  842.     smgputs( end_mouse);
  843. #endif
  844. #if    KEYPAD
  845.     if ((orgchar.tt2 & TT2$M_APP_KEYPAD)==0)
  846.         smgputs(numeric_keypad);
  847. #endif
  848.     ttclose();
  849. }
  850.  
  851. /***
  852.  *  smgputs  -  Send a string to ttputc
  853.  *
  854.  *  smgputs is a short-cut routine to handle sending a string of characters
  855.  *  to the character output routine.  A check is made for a NULL string,
  856.  *  while is considered valid.  A NULL string will produce no output.
  857.  *
  858.  *  Nothing returned.
  859.  ***/
  860. smgputs(string)
  861. char * string;                /* String to write        */
  862. {
  863.     if (string)
  864.         while (*string)
  865.             ttputc(*string++);
  866. }
  867.  
  868. /***
  869.  *  qin  -  Queue character for input
  870.  *
  871.  *  qin queues the character into the input buffer for later
  872.  *  reading.  This routine will mostly be used by mouse support
  873.  *  and other escape sequence processing.
  874.  *
  875.  *  Nothing returned.
  876.  *
  877.  *  ch  - (Extended) character to add
  878.  ***/
  879. qin(int ch)
  880. {
  881.     /* Check for overflow */
  882.     if (inbuft == &inbuf[sizeof(inbuf)]) {
  883.         
  884.         /* Annoy user */
  885.         smgbeep();
  886.         return;
  887.     }
  888.     
  889.     /* Add character */
  890.     *inbuft++ = ch;
  891. }
  892.  
  893. /***
  894.  *  smggetc  -  Get a character
  895.  *
  896.  *  smggetc obtains input from the character input queue.  If the queue
  897.  *  is empty, a call to cook() is called to fill the input queue.
  898.  *
  899.  *  Returns:    character
  900.  ***/
  901. int smggetc()
  902. {
  903.     int ch;
  904.  
  905.     /* Loop until character found */
  906.     while (1) {
  907.     
  908.         /* Get input from buffer, if available */
  909.         if (inbufh != inbuft) {
  910.             ch = *inbufh++;
  911.             if (inbufh == inbuft)
  912.                 inbufh = inbuft = inbuf;
  913.             break;
  914.         } else
  915.     
  916.             /* Fill input buffer */
  917.             cook();
  918.     }
  919.     
  920.     /* Return next character */
  921.     return (int) ch;
  922. }
  923.  
  924. /***
  925.  *  spal  -  Set palette type
  926.  *
  927.  *  spal sets the palette colors for the 8 colors available.  Currently,
  928.  *  there is nothing here, but some DEC terminals, (VT240 and VT340) have
  929.  *  a color palette which is available under the graphics modes.
  930.  *  Further, a foreign terminal could also change color registers.
  931.  *
  932.  *  Nothing returned
  933.  ***/
  934. spal()
  935. {
  936.     /* Nothing */
  937. }
  938.  
  939. #if FLABEL
  940. /***
  941.  *  fnclabel  -  Label function keys
  942.  *
  943.  *  Currently, smg does not have function key labeling.
  944.  *
  945.  *  Returns:    status.
  946.  *
  947.  *  flag - TRUE if default
  948.  *  n    - Numerical argument
  949.  ***/
  950. int fnclabel(int flag, int n)
  951. {
  952.     /* On machines with no function keys...don't bother */
  953.     return TRUE;
  954. }
  955. #endif /* FLABEL */
  956.  
  957. #endif    /* End of SMG terminal type */
  958.