1 /* vms/getch.c: input routines for VMS, integrated with smcurses for VMS
2
3 Copyright (c) 1986-94 Joshua Delahunty, James E. Wilson
4
5 This software may be copied and distributed for educational, research, and
6 not for profit purposes provided that this copyright and statement are
7 included in all such copies. */
8
9 #include <iodef.h>
10 #include <ssdef.h>
11 #include <descrip.h>
12 #include <stdio.h>
13
14 #ifndef TRUE
15 # define TRUE 1
16 # define FALSE 0
17 #endif
18
19 /* the type of keyboard read we're doing */
20 #define FUNC IO$_TTYREADALL|IO$M_NOECHO|IO$M_TRMNOECHO
21
22 static $DESCRIPTOR(chan, "tt:");
23 static char ungotch;
24 static unsigned short int kb_chan = 0; /* channel # */
25 static unsigned short int charwaiting = FALSE,
26 crmode_status = TRUE,
27 echo_status = FALSE;
28
29 /* This code was tested and worked on a VAX 11/785 running VMS 5.2.
30 contributed by Ralph Waters, rwaters@jabba.ess.harris.com. */
31
32 /* Returns 1 is a character has been pressed, 0 otherwise. */
kbhit()33 int kbhit()
34 {
35 /* sys$qiow ( [efn] ,chan ,func [,iosb] [,astadr] [,astprm]
36 [,p1] [,p2] [,p3] [,p4] [,p5] [,p6] ) */
37
38 /* The sys$qiow call with the IO$_SENSEMODE|IO$M_TYPEAHDCNT function
39 will return the following in p1:
40
41 31 24 23 16 15 0
42 ------------|------------|------------------------
43 | reserved | first | number of characters |
44 | | character | in type-ahead buffer |
45 |-----------|------------|-----------------------|
46 | reserved |
47 | |
48 --------------------------------------------------
49 */
50
51 struct qio_return_type {
52 unsigned short int type_ahead_count; /* type-ahead count */
53 unsigned char first_char; /* first character in buffer */
54 unsigned char b_reserved; /* reserved byte */
55 unsigned long int l_reserved; } /* reserved long word */
56 qio_return;
57
58 sys$qiow (0, kb_chan, (IO$_SENSEMODE | IO$M_TYPEAHDCNT), 0, 0, 0,
59 &qio_return, 0, 0, 0, 0, 0);
60 if (qio_return.type_ahead_count > 0)
61 return(1);
62 else
63 return(0);
64 }
65
66 /* Another useful function courtesy of Ralph Waters. */
67 #include <jpidef.h>
68
69 /* Stores the user's login name in the argument buf. */
user_name(buf)70 void user_name(buf)
71 char *buf;
72 {
73 /* sys$getjpiw ( [efn], [pidadr], [prcnam], itmlst [,iosb]
74 [,astadr] [,astprm] */
75
76 long int return_length;
77 struct getjpi_itmlst_type {
78 unsigned short int buffer_length; /* length of return buffer */
79 unsigned short int item_code; /* item code to getjpi about */
80 unsigned long int buffer_address; /* address of return data */
81 unsigned long int return_length_addr; } /*actual size of return data */
82 getjpi_itmlst;
83
84 getjpi_itmlst.buffer_length = 12; /* VMS usernames are 12 chars */
85 getjpi_itmlst.item_code = JPI$_USERNAME;
86 getjpi_itmlst.buffer_address = buf;
87 getjpi_itmlst.return_length_addr = &return_length;
88
89 sys$getjpiw (0, 0, 0, &getjpi_itmlst, 0, 0, 0);
90
91 return;
92 }
93
94 /* After calling this, vms_getch() returns unbuffered single chars. */
vms_crmode()95 void vms_crmode() /* Character-Return MODE */
96 {
97 if(kb_chan == 0)
98 opengetch();
99
100 crmode_status = TRUE;
101 }
102
103 /* After calling this, vms_getch() returns echoed, buffered characters. */
vms_nocrmode()104 void vms_nocrmode() /* NO Character-Return MODE */
105 {
106 if(kb_chan != 0)
107 closegetch();
108
109 crmode_status = FALSE;
110 }
111
112 /* Sets up terminal for getch() calls, returns VMS status code. */
opengetch()113 int opengetch() /* does the actual assignment work */
114 {
115 /* assign channel on keyboard */
116 return(sys$assign(&chan,&kb_chan,0,0));
117 }
118
119 /* Undoes affects of above, returns VMS status code for the operation. */
closegetch()120 int closegetch() /* performs the actual deassignment work */
121 {
122 int rv;
123
124 if(kb_chan != 0) {
125 /* deassign keyboard channel */
126 rv = sys$dassgn(kb_chan);
127 kb_chan = 0;
128 return(rv);
129 }
130 }
131
132 /* Returns an [optionally] unbuffered [non-]echoed input character.
133
134 If crmode_status is not set, then the code returns one character from
135 the buffered input.
136 If crmode_status is set, then the code returns an `ungot' character if
137 one exists, otherwise it tries to read one unbuffered character from the
138 keyboard. If echo_status is set, then the character will be echoed
139 before returning. */
vms_getch()140 char vms_getch()
141 {
142 int rv;
143 char kb_buf; /* buffer for input char */
144
145 if(crmode_status) {
146
147 if(!charwaiting) {
148
149 /* open channel if it hasn't been done already */
150 if (kb_chan == 0)
151 opengetch();
152
153 /* que an i/o request for a character and wait */
154 rv = sys$qiow(0,kb_chan,FUNC,0,0,0,&kb_buf,1,0,0,0,0);
155
156 /* indicate if something is amiss */
157 if(rv != SS$_NORMAL) {
158 printf("?");
159 exit(rv);
160 }
161
162 } else { /* charwaiting */
163
164 kb_buf = ungotch;
165 charwaiting = FALSE;
166 }
167
168 /* massage for getchar() compatibility */
169 if (kb_buf == '\r') kb_buf='\n';
170
171 /* echo char if we're supposed to */
172 if (echo_status) putchar(kb_buf);
173
174 return(kb_buf);
175
176 } else /* nocrmode */
177
178 return(getchar());
179
180 }
181