1 /* Copyright (c) 1992, 1995 John E. Davis
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Perl Artistic License.
21 # define INCL_DOSSEMAPHORES
34 KBDINFO initialKbdInfo
; /* keyboard info */
36 /* Code to read keystrokes in a separate thread */
38 typedef struct kbdcodes
{
44 #define BUFFER_LEN 4096
45 static KBDCODES threadKeys
[BUFFER_LEN
];
50 /* Original code used semaphores to control access to threadKeys.
51 * It is expected that the semaphore code will be deleted after 0.97.
57 typedef USHORT APIRET
;
60 #define DosRequestMutexSem(hmtx,timeout) DosSemRequest(hmtx,timeout)
61 #define DosReleaseMutexSem(hmtx) DosSemClear(hmtx)
62 #define DosCloseMutexSem(hmtx) DosCloseSem(hmtx)
64 #else /* !defined(__os2_16__) */
66 static HMTX Hmtx
; /* Mutex Semaphore */
71 static APIRET
CreateSem(void)
75 sprintf(SemName
, "\\SEM\\jed\\%u", getpid());
76 return ( DosCreateSem (0, &Hmtx
, SemName
) );
78 return ( DosCreateMutexSem (NULL
, &Hmtx
, 0, 0) );
82 static APIRET
RequestSem(void)
84 return ( DosRequestMutexSem (Hmtx
, -1) );
87 static APIRET
ReleaseSem(void)
89 return ( DosReleaseMutexSem (Hmtx
) );
92 static APIRET
CloseSem(void)
94 return( DosCloseMutexSem (Hmtx
) );
107 static void set_kbd(void)
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);
120 static void thread_getkey ()
125 while (!atEnd
) { /* at end is a flag */
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
;
133 n
= (endBuf
+ 1) % BUFFER_LEN
;
140 threadKeys
[n
].ascii
= keyInfo
.chChar
;
141 threadKeys
[n
].scan
= keyInfo
.chScan
;
142 /* threadKeys [n].shift = keyInfo.fsState; */
145 } else /* no char available*/
150 static void thread_code (void *Args
)
153 startBuf
= -1; /* initialize the buffer pointers */
156 atEnd
= 0; /* reset the flag */
161 /* The code below is in the main thread */
163 int SLang_init_tty(int abort_char
, int dum2
, int dum3
)
165 VIOCURSORINFO cursorInfo
, OldcursorInfo
;
167 (void) dum2
; (void) dum3
;
168 if (abort_char
== -1) abort_char
= 3; /* ^C */
169 SLang_Abort_Char
= abort_char
;
172 signal (SIGINT
, SIG_IGN
);
173 signal (SIGBREAK
, SIG_IGN
);
175 /* set up the keyboard */
177 initialKbdInfo
.cb
= sizeof(initialKbdInfo
);
178 KbdGetStatus(&initialKbdInfo
, 0);
181 /* open a semaphore */
184 /* start a separate thread to read the keyboard */
185 #if defined(__BORLANDC__)
186 _beginthread (thread_code
, 8096, NULL
);
188 _beginthread (thread_code
, NULL
, 8096, NULL
);
191 VioGetCurType (&OldcursorInfo
, 0);
192 cursorInfo
.yStart
= 1;
193 cursorInfo
.cEnd
= 15;
196 if (VioSetCurType (&cursorInfo
, 0))
197 VioSetCurType (&OldcursorInfo
, 0); /* reset to previous value */
202 void SLang_reset_tty (void)
204 atEnd
= 1; /* set flag and wait until thread ends */
205 while (atEnd
) {DosSleep (0);}
209 /* close the keyboard */
210 KbdSetStatus(&initialKbdInfo
, 0); /* restore original state */
213 #define keyWaiting() (endBuf != startBuf)
215 /* sleep for *tsecs tenths of a sec waiting for input */
217 int SLsys_input_pending(int tsecs
)
219 int count
= tsecs
* 5;
225 DosSleep(20); /* 20 ms or 1/50 sec */
226 if (keyWaiting ()) break;
231 else return(keyWaiting ());
234 unsigned int SLsys_getkey ()
242 while (!SLsys_input_pending(tsecs
));
244 /* read codes from buffer */
246 startBuf
= (startBuf
+ 1) % BUFFER_LEN
;
247 c
= threadKeys
[startBuf
].ascii
;
248 scan
= threadKeys
[startBuf
].scan
;
251 if ((c
== 8) && (scan
== 0x0e)) c
= 127;
252 if (c
== 0xE0) c
= 0;
253 if (c
== 0) SLang_ungetkey (scan
);
258 void SLang_set_abort_signal (void (*dum
)(int))