slos2tty.c 5.2 KB

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