1 #ifndef _POSIX_SOURCE
2 #define _POSIX_SOURCE
3 #endif
4 
5 /* Read one character from terminal, interpreting VT100/VT200
6    escape sequences. The program reads from standard input. */
7 
8 /* To put the terminal into 'keypad application mode' send ESC =;
9    to reset, send ESC > */
10 
11 /* DEC keyboards generate the following escape sequences.
12    CSI is either the single character 0x9B or the two
13    characters ESC (0x1B) [ (0x5B). SS3 is the character 0x8F or
14    the two characters ESC (0x1B) O (0x4F).
15 
16    Key		Code generated		Value returned by GRGETC
17    Up arrow	CSI A, SS3 A 			-1
18    Down arrow	CSI B, SS3 B			-2
19    Right arrow	CSI C, SS3 C			-3
20    Left arrow	CSI D, SS3 D			-4
21    Keypad 0	SS3 p				-20
22           1	SS3 q				-21
23           2	SS3 r				-22
24           3	SS3 s				-23
25 	  4	SS3 t				-24
26 	  5	SS3 u				-25
27 	  6	SS3 v				-26
28 	  7	SS3 w				-27
29 	  8	SS3 x				-28
30 	  9	SS3 y				-29
31 	  -	SS3 m				-17
32 	  ,	SS3 l				-16
33 	  .	SS3 n				-18
34    Enter	SS3 M				-8
35    PF1          SS3 P				-11
36    PF2          SS3 Q				-12
37    PF3		SS3 R				-13
38    PF4          SS3 S				-14
39    The following are not implemented yet:
40    Find		CSI 1 ~
41    Insert here	CSI 2 ~
42    Remove	CSI 3 ~
43    Select	CSI 4 ~
44    Prev Screen	CSI 5 ~
45    Next Screen	CSI 6 ~
46    F6		CSI 1 7 ~
47    F7		CSI 1 8 ~
48    F8		CSI 1 9 ~
49    F9		CSI 2 0 ~
50    F10		CSI 2 1 ~
51    F11		CSI 2 3 ~
52    F12		CSI 2 4 ~
53    F13		CSI 2 5 ~
54    F14		CSI 2 6 ~
55    Help		CSI 2 8 ~
56    Do		CSI 2 9 ~
57    F17		CSI 3 1 ~
58    F18		CSI 3 2 ~
59    F19		CSI 3 3 ~
60    F20		CSI 3 4 ~
61 
62    */
63 
64 #include <stdio.h>
65 #include <termios.h>
66 #include <fortran.h>
67 
68 #define CSI (0x9B)
69 #define SS3 (0x8F)
70 #define ESC (0x1B)
71 
GRGETC(int * val)72 void GRGETC(int *val)
73 {
74     static char valid_table[] = {
75 		'A','B','C','D', 'P','Q','R','S',
76 		'p','q','r','s','t','u','v','w','x','y',
77 		'm','l','n', 'M' };
78     static short code_table[] = {
79 		-1,-2,-3,-4, -11,-12,-13,-14,
80 		-20,-21,-22,-23,-24,-25,-26,-27,-28,-29,
81 		-17,-16,-18, -8 };
82     static struct termios term, saveterm;
83     int tmp=0, i;
84     int nextch;
85     static int init=1;
86     static int raw=0;
87     static int save_flags;
88 
89     if (init) {
90 	putchar(ESC);
91 	putchar('=');
92  	init = 0;
93     }
94     if (raw == 0) {
95 	tcgetattr(0, &term);
96 	saveterm = term;
97 	term.c_lflag &= ~( ICANON );
98 	term.c_cc[VMIN] = 1;
99 	tcsetattr(0, TCSADRAIN, &term);
100 	raw = 1;
101     }
102     tcflush(0, TCIOFLUSH);
103     nextch = getchar();
104     if (nextch == ESC) {
105 	nextch = getchar();
106 	if (nextch == '[') nextch = CSI;
107 	if (nextch == 'O') nextch = SS3;
108     }
109     if (nextch == CSI || nextch == SS3) {
110 	nextch = getchar();
111         for (i=0; i<22; i++)
112 	    if (valid_table[i] == nextch) {
113 		nextch = code_table[i];
114 		break;
115 	    }
116     }
117     *val = nextch;
118     /* If a special character was received, stay in CBREAK mode; this
119        is OK for PGPLOT cursor control, but may not be for other
120        applications */
121     if (nextch >= 0) {
122       	tcsetattr(0, TCSADRAIN, &saveterm);
123 	raw = 0;
124     }
125     return;
126 }
127