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