home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / VILE327.ZIP / VILE327.TAR / vile3.27 / vmsvt.c < prev    next >
C/C++ Source or Header  |  1992-12-14  |  10KB  |  442 lines

  1. /*
  2.  *  Advanced VMS terminal driver
  3.  *
  4.  *  Knows about any terminal defined in SMGTERMS.TXT and TERMTABLE.TXT
  5.  *  located in SYS$SYSTEM.
  6.  *
  7.  *  Author:  Curtis Smith
  8.  *  Last Updated: 07/14/87
  9.  *
  10.  * $Log: vmsvt.c,v $
  11.  * Revision 1.3  1992/08/20  23:40:48  foxharp
  12.  * typo fixes -- thanks, eric
  13.  *
  14.  * Revision 1.2  1991/08/07  12:35:07  pgf
  15.  * added RCS log messages
  16.  *
  17.  * revision 1.1
  18.  * date: 1990/09/21 10:26:19;
  19.  * initial vile RCS revision
  20.  */
  21.  
  22. #include    <stdio.h>        /* Standard I/O package        */
  23. #include    "estruct.h"        /* Emacs' structures        */
  24. #include    "edef.h"        /* Emacs' definitions        */
  25.  
  26. #if    VMSVT
  27.  
  28. #include     <descrip.h>        /* Descriptor definitions    */
  29.  
  30. /*  These would normally come from iodef.h and ttdef.h  */
  31. #define IO$_SENSEMODE    0x27        /* Sense mode of terminal    */
  32. #define TT$_UNKNOWN    0x00        /* Unknown terminal        */
  33.  
  34. /** Forward references **/
  35. int vmsopen(), ttclose(), vmskopen(), vmskclose(), ttgetc(), ttputc();
  36. int ttflush(), vmsmove(), vmseeol(), vmseeop(), vmsbeep(), vmsrev();
  37. int vmscres();
  38. extern int eolexist, revexist;
  39. extern char sres[];
  40.  
  41. #if COLOR
  42. int vmsfcol(), vmsbcol();
  43. #endif
  44.  
  45. /** SMG stuff **/
  46. static char * begin_reverse, * end_reverse, * erase_to_end_line;
  47. static char * erase_whole_display;
  48. static int termtype;
  49.  
  50. #define SMG$K_BEGIN_REVERSE        0x1bf
  51. #define SMG$K_END_REVERSE        0x1d6
  52. #define SMG$K_SET_CURSOR_ABS        0x23a
  53. #define SMG$K_ERASE_WHOLE_DISPLAY    0x1da
  54. #define SMG$K_ERASE_TO_END_LINE        0x1d9
  55.  
  56.  
  57. /* Dispatch table. All hard fields just point into the terminal I/O code. */
  58. TERM    term    = {
  59.     24 - 1,                /* Max number of rows allowable */
  60.     /* Filled in */ - 1,        /* Current number of rows used    */
  61.     132,                /* Max number of columns    */
  62.     /* Filled in */ 0,        /* Current number of columns    */
  63.     64,                /* Min margin for extended lines*/
  64.     8,                /* Size of scroll region    */
  65.     100,                /* # times thru update to pause */
  66.     vmsopen,            /* Open terminal at the start    */
  67.     ttclose,            /* Close terminal at end    */
  68.     vmskopen,            /* Open keyboard        */
  69.     vmskclose,            /* Close keyboard        */
  70.     ttgetc,                /* Get character from keyboard    */
  71.     ttputc,                /* Put character to display    */
  72.     ttflush,            /* Flush output buffers        */
  73.     vmsmove,            /* Move cursor, origin 0    */
  74.     vmseeol,            /* Erase to end of line        */
  75.     vmseeop,            /* Erase to end of page        */
  76.     vmsbeep,            /* Beep                */
  77.     vmsrev,                /* Set reverse video state    */
  78.     vmscres                /* Change screen resolution    */
  79. #if    COLOR
  80.     , vmsfcol,            /* Set forground color        */
  81.     vmsbcol                /* Set background color        */
  82. #endif
  83. };
  84.  
  85. /***
  86.  *  ttputs  -  Send a string to ttputc
  87.  *
  88.  *  Nothing returned
  89.  ***/
  90. ttputs(string)
  91. char * string;                /* String to write        */
  92. {
  93.     if (string)
  94.         while (*string != '\0')
  95.             ttputc(*string++);
  96. }
  97.  
  98.  
  99. /***
  100.  *  vmsmove  -  Move the cursor (0 origin)
  101.  *
  102.  *  Nothing returned
  103.  ***/
  104. vmsmove(row, col)
  105. int row;                /* Row position            */
  106. int col;                /* Column position        */
  107. {
  108.     char buffer[32];
  109.     int ret_length;
  110.     static int request_code = SMG$K_SET_CURSOR_ABS;
  111.     static int max_buffer_length = sizeof(buffer);
  112.     static int arg_list[3] = { 2 };
  113.     register char * cp;
  114.     
  115.     register int i;
  116.  
  117.     /* Set the arguments into the arg_list array
  118.      * SMG assumes the row/column positions are 1 based (boo!)
  119.      */
  120.     arg_list[1] = row + 1;
  121.     arg_list[2] = col + 1;
  122.  
  123.     if ((smg$get_term_data(        /* Get terminal data        */
  124.         &termtype,        /* Terminal table address    */
  125.         &request_code,        /* Request code            */
  126.         &max_buffer_length,    /* Maximum buffer length    */
  127.         &ret_length,        /* Return length        */
  128.         buffer,            /* Capability data buffer    */
  129.         arg_list)        /* Argument list array        */
  130.  
  131.     /* We'll know soon enough if this doesn't work        */
  132.             & 1) == 0) {
  133.                 ttputs("OOPS");
  134.                 return;
  135.             }
  136.  
  137.     /* Send out resulting sequence                */
  138.     i = ret_length;
  139.     cp = buffer;
  140.     while (i-- > 0)
  141.         ttputc(*cp++);
  142. }
  143.  
  144.  
  145. /***
  146.  *  vmsrev  -  Set the reverse video status
  147.  *
  148.  *  Nothing returned
  149.  ***/
  150. vmsrev(status)
  151. int status;                /* TRUE if setting reverse    */
  152. {
  153.     if (status)
  154.         ttputs(begin_reverse);
  155.     else 
  156.         ttputs(end_reverse);
  157. }
  158.  
  159. /***
  160.  *  vmscres  -  Change screen resolution (which it doesn't)
  161.  *
  162.  *  Nothing returned
  163.  ***/
  164. vmscres()
  165. {
  166.     /* But it could.  For vt100/vt200s, one could switch from
  167.     80 and 132 columns modes */
  168. }
  169.  
  170.  
  171. #if    COLOR
  172. /***
  173.  *  vmsfcol  -  Set the foreground color (not implemented)
  174.  *
  175.  *  Nothing returned
  176.  ***/
  177. vmsfcol()
  178. {
  179. }
  180.  
  181. /***
  182.  *  vmsbcol  -  Set the background color (not implemented)
  183.  *
  184.  *  Nothing returned
  185.  ***/
  186. vmsbcol()
  187. {
  188. }
  189. #endif
  190.  
  191. /***
  192.  *  vmseeol  -  Erase to end of line
  193.  *
  194.  *  Nothing returned
  195.  ***/
  196. vmseeol()
  197. {
  198.     ttputs(erase_to_end_line);
  199. }
  200.  
  201.  
  202. /***
  203.  *  vmseeop  -  Erase to end of page (clear screen)
  204.  *
  205.  *  Nothing returned
  206.  ***/
  207. vmseeop()
  208. {
  209.     ttputs(erase_whole_display);
  210. }
  211.  
  212.  
  213. /***
  214.  *  vmsbeep  -  Ring the bell
  215.  *
  216.  *  Nothing returned
  217.  ***/
  218. vmsbeep()
  219. {
  220.     ttputc('\007');
  221. }
  222.  
  223.  
  224. /***
  225.  *  vmsgetstr  -  Get an SMG string capability by name
  226.  *
  227.  *  Returns:    Escape sequence
  228.  *        NULL    No escape sequence available
  229.  ***/ 
  230. char * vmsgetstr(request_code)
  231. int request_code;            /* Request code            */
  232. {
  233.     register char * result;
  234.     static char seq_storage[1024];
  235.     static char * buffer = seq_storage;
  236.     static int arg_list[2] = { 1, 1 };
  237.     int max_buffer_length, ret_length;
  238.  
  239.     /*  Precompute buffer length */
  240.     
  241.     max_buffer_length = (seq_storage + sizeof(seq_storage)) - buffer;
  242.  
  243.     /* Get terminal commands sequence from master table */
  244.  
  245.     if ((smg$get_term_data(    /* Get terminal data        */
  246.         &termtype,    /* Terminal table address    */
  247.         &request_code,    /* Request code            */
  248.         &max_buffer_length,/* Maximum buffer length    */
  249.         &ret_length,    /* Return length        */
  250.         buffer,        /* Capability data buffer    */
  251.         arg_list)    /* Argument list array        */
  252.  
  253.     /* If this doesn't work, try again with no arguments */
  254.     
  255.         & 1) == 0 && 
  256.  
  257.         (smg$get_term_data(    /* Get terminal data        */
  258.             &termtype,    /* Terminal table address    */
  259.             &request_code,    /* Request code            */
  260.             &max_buffer_length,/* Maximum buffer length    */
  261.             &ret_length,    /* Return length        */
  262.             buffer)        /* Capability data buffer    */
  263.  
  264.     /* Return NULL pointer if capability is not available */
  265.     
  266.             & 1) == 0)
  267.                 return NULL;
  268.  
  269.     /* Check for empty result */
  270.     if (ret_length == 0)
  271.         return NULL;
  272.     
  273.     /* Save current position so we can return it to caller */
  274.  
  275.     result = buffer;
  276.  
  277.     /* NIL terminate the sequence for return */
  278.     
  279.     buffer[ret_length] = 0;
  280.  
  281.     /* Advance buffer */
  282.  
  283.     buffer += ret_length + 1;
  284.  
  285.     /* Return capability to user */
  286.     return result;
  287. }
  288.  
  289.  
  290. /** I/O information block definitions **/
  291. struct iosb {            /* I/O status block            */
  292.     short    i_cond;        /* Condition value            */
  293.     short    i_xfer;        /* Transfer count            */
  294.     long    i_info;        /* Device information            */
  295. };
  296. struct termchar {        /* Terminal characteristics        */
  297.     char    t_class;    /* Terminal class            */
  298.     char    t_type;        /* Terminal type            */
  299.     short    t_width;    /* Terminal width in characters        */
  300.     long    t_mandl;    /* Terminal's mode and length        */
  301.     long    t_extend;    /* Extended terminal characteristics    */
  302. };
  303. static struct termchar tc;    /* Terminal characteristics        */
  304.  
  305. /***
  306.  *  vmsgtty - Get terminal type from system control block
  307.  *
  308.  *  Nothing returned
  309.  ***/
  310. vmsgtty()
  311. {
  312.     short fd;
  313.     int status;
  314.     struct iosb iostatus;
  315.     $DESCRIPTOR(devnam, "SYS$INPUT");
  316.  
  317.     /* Assign input to a channel */
  318.     status = sys$assign(&devnam, &fd, 0, 0);
  319.     if ((status & 1) == 0)
  320.         exit (status);
  321.  
  322.     /* Get terminal characteristics */
  323.     status = sys$qiow(        /* Queue and wait        */
  324.         0,            /* Wait on event flag zero    */
  325.         fd,            /* Channel to input terminal    */
  326.         IO$_SENSEMODE,        /* Get current characteristic    */
  327.         &iostatus,        /* Status after operation    */
  328.         0, 0,            /* No AST service        */
  329.         &tc,            /* Terminal characteristics buf */
  330.         sizeof(tc),        /* Size of the buffer        */
  331.         0, 0, 0, 0);        /* P3-P6 unused            */
  332.  
  333.     /* De-assign the input device */
  334.     if ((sys$dassgn(fd) & 1) == 0)
  335.         exit(status);
  336.  
  337.     /* Jump out if bad status */
  338.     if ((status & 1) == 0)
  339.         exit(status);
  340.     if ((iostatus.i_cond & 1) == 0)
  341.         exit(iostatus.i_cond);
  342. }
  343.  
  344.  
  345. /***
  346.  *  vmsopen  -  Get terminal type and open terminal
  347.  *
  348.  *  Nothing returned
  349.  ***/
  350. vmsopen()
  351. {
  352.     /* Get terminal type */
  353.     vmsgtty();
  354.     if (tc.t_type == TT$_UNKNOWN) {
  355.         printf("Terminal type is unknown!\n");
  356.         printf("Try set your terminal type with SET TERMINAL/INQUIRE\n");
  357.         printf("Or get help on SET TERMINAL/DEVICE_TYPE\n");
  358.         exit(3);
  359.     }
  360.  
  361.     /* Access the system terminal definition table for the        */
  362.     /* information of the terminal type returned by IO$_SENSEMODE    */
  363.     if ((smg$init_term_table_by_type(&tc.t_type, &termtype) & 1) == 0)
  364.         return -1;
  365.         
  366.     /* Set sizes */
  367.     term.t_nrow = ((unsigned int) tc.t_mandl >> 24) - 1;
  368.     term.t_ncol = tc.t_width;
  369.  
  370.     /* Get some capabilities */
  371.     begin_reverse = vmsgetstr(SMG$K_BEGIN_REVERSE);
  372.     end_reverse = vmsgetstr(SMG$K_END_REVERSE);
  373.     revexist = begin_reverse != NULL && end_reverse != NULL;
  374.     erase_to_end_line = vmsgetstr(SMG$K_ERASE_TO_END_LINE);
  375.     eolexist = erase_whole_display != NULL;
  376.     erase_whole_display = vmsgetstr(SMG$K_ERASE_WHOLE_DISPLAY);
  377.  
  378.     /* Set resolution */
  379.     strcpy(sres, "NORMAL");
  380.  
  381.     /* Open terminal I/O drivers */
  382.     ttopen();
  383. }
  384.  
  385.  
  386. /***
  387.  *  vmskopen  -  Open keyboard (not used)
  388.  *
  389.  *  Nothing returned
  390.  ***/
  391. vmskopen()
  392. {
  393. }
  394.  
  395.  
  396. /***
  397.  *  vmskclose  -  Close keyboard (not used)
  398.  *
  399.  *  Nothing returned
  400.  ***/
  401. vmskclose()
  402. {
  403. }
  404.  
  405.  
  406. /***
  407.  *  fnclabel  -  Label function keys (not used)
  408.  *
  409.  *  Nothing returned
  410.  ***/
  411. #if    FLABEL
  412. fnclabel(f, n)        /* label a function key */
  413. int f,n;    /* default flag, numeric argument [unused] */
  414. {
  415.     /* on machines with no function keys...don't bother */
  416.     return(TRUE);
  417. }
  418. #endif
  419.  
  420.  
  421. /***
  422.  *  spal  -  Set palette type  (Are you kidding?)
  423.  *
  424.  *  Nothing returned
  425.  ***/
  426. spal()
  427. {
  428. }
  429.  
  430. #else
  431.  
  432. /***
  433.  *  hellovms  -  Avoid error because of empty module
  434.  *
  435.  *  Nothing returned
  436.  ***/
  437. hellovms()
  438. {
  439. }
  440.  
  441. #endif
  442.