Copy w32api from trunk
[reactos.git] / rosapps / mc / slang / slos2tty.c
1 /* Copyright (c) 1992, 1995 John E. Davis
2 * All rights reserved.
3 *
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Perl Artistic License.
6 */
7
8 #include "config.h"
9
10 #include <stdio.h>
11
12 #include "slang.h"
13 #include "_slang.h"
14
15 #define INCL_BASE
16 #define INCL_NOPM
17 #define INCL_VIO
18 #define INCL_KBD
19 #define INCL_DOS
20 #if 0
21 # define INCL_DOSSEMAPHORES
22 #endif
23 #ifdef LONG
24 #undef LONG
25 #endif
26 #ifdef VOID
27 #undef VOID
28 #endif
29 #include <os2.h>
30
31 #include <signal.h>
32 #include <process.h>
33
34 KBDINFO initialKbdInfo; /* keyboard info */
35
36 /* Code to read keystrokes in a separate thread */
37
38 typedef struct kbdcodes {
39 UCHAR ascii;
40 UCHAR scan;
41 /* USHORT shift; */
42 } KBDCODES;
43
44 #define BUFFER_LEN 4096
45 static KBDCODES threadKeys[BUFFER_LEN];
46 static int atEnd = 0;
47 static int startBuf;
48 static int endBuf;
49
50 /* Original code used semaphores to control access to threadKeys.
51 * It is expected that the semaphore code will be deleted after 0.97.
52 */
53 #if 0
54
55 #ifdef __os2_16__
56
57 typedef USHORT APIRET;
58 static HSEM Hmtx;
59
60 #define DosRequestMutexSem(hmtx,timeout) DosSemRequest(hmtx,timeout)
61 #define DosReleaseMutexSem(hmtx) DosSemClear(hmtx)
62 #define DosCloseMutexSem(hmtx) DosCloseSem(hmtx)
63
64 #else /* !defined(__os2_16__) */
65
66 static HMTX Hmtx; /* Mutex Semaphore */
67
68 #endif
69
70
71 static APIRET CreateSem(void)
72 {
73 #ifdef __os2_16__
74 char SemName[32];
75 sprintf(SemName, "\\SEM\\jed\\%u", getpid());
76 return ( DosCreateSem (0, &Hmtx, SemName) );
77 #else
78 return ( DosCreateMutexSem (NULL, &Hmtx, 0, 0) );
79 #endif
80 }
81
82 static APIRET RequestSem(void)
83 {
84 return ( DosRequestMutexSem (Hmtx, -1) );
85 }
86
87 static APIRET ReleaseSem(void)
88 {
89 return ( DosReleaseMutexSem (Hmtx) );
90 }
91
92 static APIRET CloseSem(void)
93 {
94 return( DosCloseMutexSem (Hmtx) );
95 }
96
97 #else
98
99 #define CreateSem()
100 #define RequestSem()
101 #define ReleaseSem()
102 #define CloseSem()
103
104 #endif
105
106
107 static void set_kbd(void)
108 {
109 KBDINFO kbdInfo;
110
111 kbdInfo = initialKbdInfo;
112 kbdInfo.fsMask &= ~0x0001; /* not echo on */
113 kbdInfo.fsMask |= 0x0002; /* echo off */
114 kbdInfo.fsMask &= ~0x0008; /* cooked mode off */
115 kbdInfo.fsMask |= 0x0004; /* raw mode */
116 kbdInfo.fsMask &= ~0x0100; /* shift report off */
117 KbdSetStatus(&kbdInfo, 0);
118 }
119
120 static void thread_getkey ()
121 {
122 KBDKEYINFO keyInfo;
123 int n;
124
125 while (!atEnd) { /* at end is a flag */
126 set_kbd();
127 KbdCharIn(&keyInfo, IO_NOWAIT, 0); /* get a character */
128 if (keyInfo.fbStatus & 0x040) { /* found a char process it */
129 if (keyInfo.chChar == SLang_Abort_Char) {
130 if (SLang_Ignore_User_Abort == 0) SLang_Error = USER_BREAK;
131 SLKeyBoard_Quit = 1;
132 }
133 n = (endBuf + 1) % BUFFER_LEN;
134 if (n == startBuf) {
135 DosBeep (500, 20);
136 KbdFlushBuffer(0);
137 continue;
138 }
139 RequestSem();
140 threadKeys [n].ascii = keyInfo.chChar;
141 threadKeys [n].scan = keyInfo.chScan;
142 /* threadKeys [n].shift = keyInfo.fsState; */
143 endBuf = n;
144 ReleaseSem();
145 } else /* no char available*/
146 DosSleep (20);
147 }
148 }
149
150 static void thread_code (void *Args)
151 {
152 (void) Args;
153 startBuf = -1; /* initialize the buffer pointers */
154 endBuf = -1;
155 thread_getkey ();
156 atEnd = 0; /* reset the flag */
157 _endthread();
158 }
159
160
161 /* The code below is in the main thread */
162
163 int SLang_init_tty(int abort_char, int dum2, int dum3)
164 {
165 VIOCURSORINFO cursorInfo, OldcursorInfo;
166
167 (void) dum2; (void) dum3;
168 if (abort_char == -1) abort_char = 3; /* ^C */
169 SLang_Abort_Char = abort_char;
170
171 /* set ^C off */
172 signal (SIGINT, SIG_IGN);
173 signal (SIGBREAK, SIG_IGN);
174
175 /* set up the keyboard */
176
177 initialKbdInfo.cb = sizeof(initialKbdInfo);
178 KbdGetStatus(&initialKbdInfo, 0);
179 set_kbd();
180
181 /* open a semaphore */
182 CreateSem();
183
184 /* start a separate thread to read the keyboard */
185 #if defined(__BORLANDC__)
186 _beginthread (thread_code, 8096, NULL);
187 #else
188 _beginthread (thread_code, NULL, 8096, NULL);
189 #endif
190
191 VioGetCurType (&OldcursorInfo, 0);
192 cursorInfo.yStart = 1;
193 cursorInfo.cEnd = 15;
194 cursorInfo.cx = 1;
195 cursorInfo.attr = 1;
196 if (VioSetCurType (&cursorInfo, 0))
197 VioSetCurType (&OldcursorInfo, 0); /* reset to previous value */
198
199 return 0;
200 }
201
202 void SLang_reset_tty (void)
203 {
204 atEnd = 1; /* set flag and wait until thread ends */
205 while (atEnd) {DosSleep (0);}
206
207 CloseSem();
208
209 /* close the keyboard */
210 KbdSetStatus(&initialKbdInfo, 0); /* restore original state */
211 }
212
213 #define keyWaiting() (endBuf != startBuf)
214
215 /* sleep for *tsecs tenths of a sec waiting for input */
216
217 int SLsys_input_pending(int tsecs)
218 {
219 int count = tsecs * 5;
220
221 if (count)
222 {
223 while(count > 0)
224 {
225 DosSleep(20); /* 20 ms or 1/50 sec */
226 if (keyWaiting ()) break;
227 count--;
228 }
229 return(count);
230 }
231 else return(keyWaiting ());
232 }
233
234 unsigned int SLsys_getkey ()
235 {
236 unsigned int c;
237 unsigned char scan;
238
239 int tsecs = 300;
240
241 if (!keyWaiting())
242 while (!SLsys_input_pending(tsecs));
243
244 /* read codes from buffer */
245 RequestSem();
246 startBuf = (startBuf + 1) % BUFFER_LEN;
247 c = threadKeys [startBuf].ascii;
248 scan = threadKeys [startBuf].scan;
249 ReleaseSem();
250
251 if ((c == 8) && (scan == 0x0e)) c = 127;
252 if (c == 0xE0) c = 0;
253 if (c == 0) SLang_ungetkey (scan);
254 return (c);
255 }
256
257
258 void SLang_set_abort_signal (void (*dum)(int))
259 {
260 (void) dum;
261 }