1 /****************************************************************************
2 * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
27 ****************************************************************************/
29 /****************************************************************************
30 * Author: Juergen Pfeifer *
32 ****************************************************************************/
34 #include <curses.priv.h>
36 MODULE_ID("$Id: win_driver.c,v 1.1 2009/02/21 15:11:29 juergen Exp $")
38 static bool drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *);
39 static void drv_init(TERMINAL_CONTROL_BLOCK *);
40 static void drv_release(TERMINAL_CONTROL_BLOCK *);
41 static int drv_size(TERMINAL_CONTROL_BLOCK *, int *, int *);
42 static int drv_sgmode(TERMINAL_CONTROL_BLOCK * TCB,
45 static chtype drv_conattr(TERMINAL_CONTROL_BLOCK * TCB);
47 static int drv_mvcur(TERMINAL_CONTROL_BLOCK * TCB,
48 int yold, int xold, int ynew, int xnew);
49 static int drv_mode(TERMINAL_CONTROL_BLOCK * TCB,
50 bool progFlag, bool defFlag);
51 static bool drv_rescol(TERMINAL_CONTROL_BLOCK * TCB);
52 static bool drv_rescolors(TERMINAL_CONTROL_BLOCK * TCB);
53 static void drv_setcolor(TERMINAL_CONTROL_BLOCK * TCB,
56 int (*outc) (SCREEN *, int));
57 static int drv_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB, bool);
58 static void drv_initpair(TERMINAL_CONTROL_BLOCK * TCB,
62 static void drv_initcolor(TERMINAL_CONTROL_BLOCK * TCB,
67 static void drv_do_color(TERMINAL_CONTROL_BLOCK * TCB,
71 int (*outc) (SCREEN *, int));
72 static void drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB);
73 static void drv_setfilter(TERMINAL_CONTROL_BLOCK * TCB);
74 static void drv_hwlabel(TERMINAL_CONTROL_BLOCK * TCB,
77 static void drv_hwlabelOnOff(TERMINAL_CONTROL_BLOCK * TCB,
79 static int drv_doupdate(TERMINAL_CONTROL_BLOCK * TCB);
81 static int drv_defaultcolors(TERMINAL_CONTROL_BLOCK * TCB,
84 static int drv_print(TERMINAL_CONTROL_BLOCK * TCB,
87 /*static int _getsize(TERMINAL_CONTROL_BLOCK*,int *, int *);*/
88 static int drv_setsize(TERMINAL_CONTROL_BLOCK * TCB, int l, int c);
89 static void drv_initacs(TERMINAL_CONTROL_BLOCK * TCB, chtype *, chtype *);
90 static void drv_wrap(SCREEN *);
91 static void drv_screen_init(SCREEN *);
92 static int drv_twait(TERMINAL_CONTROL_BLOCK *,
95 int *EVENTLIST_2nd(_nc_eventlist *));
96 static int drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf);
97 static int drv_nap(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int ms);
98 static int drv_kpad(TERMINAL_CONTROL_BLOCK * TCB, bool);
99 static int drv_keyok(TERMINAL_CONTROL_BLOCK * TCB, int, bool);
100 static bool drv_kyExist(TERMINAL_CONTROL_BLOCK * TCB, int);
102 NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_WIN_DRIVER = {
104 drv_CanHandle, /* CanHandle */
106 drv_release, /* release */
108 drv_sgmode, /* sgmode */
109 drv_conattr, /* conattr */
110 drv_mvcur, /* hwcur */
112 drv_rescol, /* rescol */
113 drv_rescolors, /* rescolors */
114 drv_setcolor, /* color */
115 drv_dobeepflash, /* DoBeepFlash */
116 drv_initpair, /* initpair */
117 drv_initcolor, /* initcolor */
118 drv_do_color, /* docolor */
119 drv_initmouse, /* initmouse */
120 drv_setfilter, /* setfilter */
121 drv_hwlabel, /* hwlabel */
122 drv_hwlabelOnOff, /* hwlabelOnOff */
123 drv_doupdate, /* update */
124 drv_defaultcolors, /* defaultcolors */
125 drv_print, /* print */
126 drv_size, /* getsize */
127 drv_setsize, /* setsize */
128 drv_initacs, /* initacs */
129 drv_screen_init, /* scinit */
130 drv_wrap, /* scexit */
131 drv_twait, /* twait */
135 drv_keyok, /* kyOk */
136 drv_kyExist /* kyExist */
139 #define WINMAGIC NCDRV_MAGIC(NCDRV_WINCONSOLE)
141 #define AssertTCB() assert(TCB!=0 && TCB->magic==WINMAGIC)
142 #define SetSP() assert(TCB->csp!=0); sp = TCB->csp
144 #define GenMap(vKey,key) MAKELONG(key, vKey)
146 static const LONG keylist[] =
148 GenMap(VK_PRIOR, KEY_PPAGE),
149 GenMap(VK_NEXT, KEY_NPAGE),
150 GenMap(VK_END, KEY_END),
151 GenMap(VK_HOME, KEY_HOME),
152 GenMap(VK_LEFT, KEY_LEFT),
153 GenMap(VK_UP, KEY_UP),
154 GenMap(VK_RIGHT, KEY_RIGHT),
155 GenMap(VK_DOWN, KEY_DOWN),
156 GenMap(VK_DELETE, KEY_DC),
157 GenMap(VK_INSERT, KEY_IC)
159 #define N_INI ((int)(sizeof(keylist)/sizeof(keylist[0])))
161 #define MAPSIZE (FKEYS + N_INI)
164 typedef struct props {
165 CONSOLE_SCREEN_BUFFER_INFO SBI;
169 WORD pairs[NUMPAIRS];
172 #define PropOf(TCB) ((Properties*)TCB->prop)
175 _nc_mingw_ioctl(int fd GCC_UNUSED,
176 long int request GCC_UNUSED,
177 struct termios *arg GCC_UNUSED)
181 fprintf(stderr, "TERMINFO currently not supported on Windows.\n");
186 MapColor(bool fore, int color)
188 static const int _cmap[] =
189 {0, 4, 2, 6, 1, 5, 3, 7};
191 if (color < 0 || color > 7)
201 MapAttr(TERMINAL_CONTROL_BLOCK * TCB, WORD res, chtype ch)
210 if (p > 0 && p < NUMPAIRS && TCB != 0 && sp != 0) {
212 a = PropOf(TCB)->pairs[p];
213 res = (res & 0xff00) | a;
218 res = ((res & 0xff00) | (((res & 0x07) << 4) | ((res & 0x70) >> 4)));
221 res = ((res & 0xff00) | (((res & 0x07) << 4) | ((res & 0x70) >> 4))
222 | BACKGROUND_INTENSITY);
225 res |= FOREGROUND_INTENSITY;
228 res |= BACKGROUND_INTENSITY;
234 con_write(TERMINAL_CONTROL_BLOCK * TCB, int y, int x, chtype *str, int n)
245 if (TCB == 0 || InvalidConsoleHandle(TCB->hdl))
250 for (i = 0; i < n; i++) {
252 ci[i].Char.AsciiChar = ChCharOf(ch);
253 ci[i].Attributes = MapAttr(TCB,
254 PropOf(TCB)->SBI.wAttributes,
256 if (ChAttrOf(ch) & A_ALTCHARSET) {
258 ci[i].Char.AsciiChar =
259 ChCharOf(NCURSES_SP_NAME(_nc_acs_char) (sp, ChCharOf(ch)));
268 rec.Left = (short) x;
270 rec.Right = (short) (x + n - 1);
271 rec.Bottom = rec.Top;
273 return WriteConsoleOutput(TCB->hdl, ci, siz, loc, &rec);
276 #define MARK_NOCHANGE(win,row) \
277 win->_line[row].firstchar = _NOCHANGE; \
278 win->_line[row].lastchar = _NOCHANGE
281 drv_doupdate(TERMINAL_CONTROL_BLOCK * TCB)
283 int y, nonempty, n, x0, x1, Width, Height;
289 Width = screen_columns(sp);
290 Height = screen_lines(sp);
291 nonempty = min(Height, sp->_newscr->_maxy + 1);
293 if ((sp->_curscr->_clear || sp->_newscr->_clear)) {
297 for (x = 0; x < Width; x++)
300 for (y = 0; y < nonempty; y++) {
301 con_write(TCB, y, 0, empty, Width);
303 sp->_curscr->_line[y].text,
304 Width * sizeof(chtype));
306 sp->_curscr->_clear = FALSE;
307 sp->_newscr->_clear = FALSE;
308 touchwin(sp->_newscr);
311 for (y = 0; y < nonempty; y++) {
312 x0 = sp->_newscr->_line[y].firstchar;
313 if (x0 != _NOCHANGE) {
314 x1 = sp->_newscr->_line[y].lastchar;
317 memcpy(sp->_curscr->_line[y].text + x0,
318 sp->_newscr->_line[y].text + x0,
323 ((chtype *) sp->_curscr->_line[y].text) + x0, n);
325 /* mark line changed successfully */
326 if (y <= sp->_newscr->_maxy) {
327 MARK_NOCHANGE(sp->_newscr, y);
329 if (y <= sp->_curscr->_maxy) {
330 MARK_NOCHANGE(sp->_curscr, y);
336 /* put everything back in sync */
337 for (y = nonempty; y <= sp->_newscr->_maxy; y++) {
338 MARK_NOCHANGE(sp->_newscr, y);
340 for (y = nonempty; y <= sp->_curscr->_maxy; y++) {
341 MARK_NOCHANGE(sp->_curscr, y);
344 if (!sp->_newscr->_leaveok) {
345 sp->_curscr->_curx = sp->_newscr->_curx;
346 sp->_curscr->_cury = sp->_newscr->_cury;
348 TCB->drv->hwcur(TCB, 0, 0, sp->_curscr->_cury, sp->_curscr->_curx);
350 SetConsoleActiveScreenBuffer(TCB->hdl);
355 drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB,
357 int *errret GCC_UNUSED)
361 TCB->magic = WINMAGIC;
362 if (*tname == 0 || *tname == 0 || strcmp(tname, "unknown") == 0) {
369 drv_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB,
370 bool beepFlag GCC_UNUSED)
382 drv_print(TERMINAL_CONTROL_BLOCK * TCB,
383 char *data GCC_UNUSED,
395 drv_defaultcolors(TERMINAL_CONTROL_BLOCK * TCB,
409 drv_setcolor(TERMINAL_CONTROL_BLOCK * TCB,
412 int (*outc) (SCREEN *, int) GCC_UNUSED)
416 if (TCB && !InvalidConsoleHandle(TCB->hdl)) {
417 WORD a = MapColor(fore, color);
418 a = ((PropOf(TCB)->SBI.wAttributes) & (fore ? 0xfff8 : 0xff8f)) | a;
419 SetConsoleTextAttribute(TCB->hdl, a);
420 GetConsoleScreenBufferInfo(TCB->hdl, &(PropOf(TCB)->SBI));
425 drv_rescol(TERMINAL_CONTROL_BLOCK * TCB)
430 if (TCB && !InvalidConsoleHandle(TCB->hdl)) {
431 WORD a = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN;
432 SetConsoleTextAttribute(TCB->hdl, a);
433 GetConsoleScreenBufferInfo(TCB->hdl, &(PropOf(TCB)->SBI));
440 drv_rescolors(TERMINAL_CONTROL_BLOCK * TCB)
452 drv_size(TERMINAL_CONTROL_BLOCK * TCB, int *Lines, int *Cols)
456 if (TCB == NULL || Lines == NULL || Cols == NULL || InvalidConsoleHandle(TCB->hdl))
459 *Lines = (int) (PropOf(TCB)->SBI.dwSize.Y);
460 *Cols = (int) (PropOf(TCB)->SBI.dwSize.X);
465 drv_setsize(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED,
474 drv_mode(TERMINAL_CONTROL_BLOCK * TCB, bool progFlag, bool defFlag)
477 TERMINAL *_term = (TERMINAL *) TCB;
483 PropOf(TCB)->progMode = progFlag;
484 SetConsoleActiveScreenBuffer(progFlag ? TCB->hdl : TCB->out);
486 if (progFlag) /* prog mode */ {
488 if ((drv_sgmode(TCB, FALSE, &(_term->Nttyb)) == OK)) {
489 _term->Nttyb.c_oflag &= ~OFLAGS_TABS;
493 /* reset_prog_mode */
494 if (drv_sgmode(TCB, TRUE, &(_term->Nttyb)) == OK) {
497 _nc_keypad(sp, TRUE);
498 NC_BUFFERED(sp, TRUE);
503 } else { /* shell mode */
506 if (drv_sgmode(TCB, FALSE, &(_term->Ottyb)) == OK) {
510 /* reset_shell_mode */
512 _nc_keypad(sp, FALSE);
513 NCURSES_SP_NAME(_nc_flush) (sp);
514 NC_BUFFERED(sp, FALSE);
516 code = drv_sgmode(TCB, TRUE, &(_term->Ottyb));
524 drv_screen_init(SCREEN *sp GCC_UNUSED)
529 drv_wrap(SCREEN *sp GCC_UNUSED)
534 rkeycompare(const void *el1, const void *el2)
536 WORD key1 = (LOWORD((*((const LONG *) el1)))) & 0x7fff;
537 WORD key2 = (LOWORD((*((const LONG *) el2)))) & 0x7fff;
539 return ((key1 < key2) ? -1 : ((key1 == key2) ? 0 : 1));
543 keycompare(const void *el1, const void *el2)
545 WORD key1 = HIWORD((*((const LONG *) el1)));
546 WORD key2 = HIWORD((*((const LONG *) el2)));
548 return ((key1 < key2) ? -1 : ((key1 == key2) ? 0 : 1));
552 MapKey(TERMINAL_CONTROL_BLOCK * TCB, WORD vKey)
556 LONG key = GenMap(vKey, 0);
563 (size_t) (N_INI + FKEYS),
567 key = *((LONG *) res);
569 code = (int) (nKey & 0x7fff);
577 drv_release(TERMINAL_CONTROL_BLOCK * TCB)
585 drv_init(TERMINAL_CONTROL_BLOCK * TCB)
590 BOOL b = AllocConsole();
595 b = AttachConsole(ATTACH_PARENT_PROCESS);
597 TCB->inp = GetStdHandle(STD_INPUT_HANDLE);
598 TCB->out = GetStdHandle(STD_OUTPUT_HANDLE);
603 TCB->hdl = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
606 CONSOLE_TEXTMODE_BUFFER,
609 if (!InvalidConsoleHandle(TCB->hdl)) {
610 TCB->prop = typeCalloc(Properties, 1);
611 GetConsoleScreenBufferInfo(TCB->hdl, &(PropOf(TCB)->SBI));
614 TCB->info.initcolor = TRUE;
615 TCB->info.canchange = FALSE;
616 TCB->info.hascolor = TRUE;
617 TCB->info.caninit = TRUE;
619 TCB->info.maxpairs = NUMPAIRS;
620 TCB->info.maxcolors = 8;
621 TCB->info.numlabels = 0;
622 TCB->info.labelwidth = 0;
623 TCB->info.labelheight = 0;
624 TCB->info.nocolorvideo = 1;
625 TCB->info.tabsize = 8;
627 TCB->info.defaultPalette = _nc_cga_palette;
629 for (i = 0; i < (N_INI + FKEYS); i++) {
631 PropOf(TCB)->rmap[i] = PropOf(TCB)->map[i] = keylist[i];
633 PropOf(TCB)->rmap[i] = PropOf(TCB)->map[i] =
634 GenMap((VK_F1 + (i - N_INI)), (KEY_F(1) + (i - N_INI)));
636 qsort(PropOf(TCB)->map,
640 qsort(PropOf(TCB)->rmap,
645 a = MapColor(true, COLOR_WHITE) | MapColor(false, COLOR_BLACK);
646 for (i = 0; i < NUMPAIRS; i++)
647 PropOf(TCB)->pairs[i] = a;
652 drv_initpair(TERMINAL_CONTROL_BLOCK * TCB,
662 if ((pair > 0) && (pair < NUMPAIRS) && (f >= 0) && (f < 8)
663 && (b >= 0) && (b < 8)) {
664 PropOf(TCB)->pairs[pair] = MapColor(true, f) | MapColor(false, b);
669 drv_initcolor(TERMINAL_CONTROL_BLOCK * TCB,
670 short color GCC_UNUSED,
682 drv_do_color(TERMINAL_CONTROL_BLOCK * TCB,
683 short old_pair GCC_UNUSED,
684 short pair GCC_UNUSED,
685 bool reverse GCC_UNUSED,
686 int (*outc) (SCREEN *, int) GCC_UNUSED
696 drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB)
705 drv_mvcur(TERMINAL_CONTROL_BLOCK * TCB,
706 int yold GCC_UNUSED, int xold GCC_UNUSED,
710 if (TCB && !InvalidConsoleHandle(TCB->hdl)) {
714 SetConsoleCursorPosition(TCB->hdl, loc);
721 drv_hwlabel(TERMINAL_CONTROL_BLOCK * TCB,
722 int labnum GCC_UNUSED,
723 char *text GCC_UNUSED)
732 drv_hwlabelOnOff(TERMINAL_CONTROL_BLOCK * TCB,
733 bool OnFlag GCC_UNUSED)
742 drv_conattr(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED)
744 chtype res = A_NORMAL;
745 res |= (A_BOLD | A_DIM | A_REVERSE | A_STANDOUT | A_COLOR);
750 drv_setfilter(TERMINAL_CONTROL_BLOCK * TCB)
759 drv_sgmode(TERMINAL_CONTROL_BLOCK * TCB, bool setFlag, TTY * buf)
767 if (TCB == 0 || buf == NULL)
771 iflag = buf->c_iflag;
772 lflag = buf->c_lflag;
774 GetConsoleMode(TCB->inp, &dwFlag);
777 dwFlag |= ENABLE_LINE_INPUT;
779 dwFlag &= ~ENABLE_LINE_INPUT;
782 dwFlag |= ENABLE_ECHO_INPUT;
784 dwFlag &= ~ENABLE_ECHO_INPUT;
787 dwFlag |= ENABLE_PROCESSED_INPUT;
789 dwFlag &= ~ENABLE_PROCESSED_INPUT;
791 /* we disable that for now to focus on keyboard. */
792 dwFlag &= ~ENABLE_MOUSE_INPUT;
794 buf->c_iflag = iflag;
795 buf->c_lflag = lflag;
796 SetConsoleMode(TCB->inp, dwFlag);
797 TCB->term.Nttyb = *buf;
799 iflag = TCB->term.Nttyb.c_iflag;
800 lflag = TCB->term.Nttyb.c_lflag;
801 GetConsoleMode(TCB->inp, &dwFlag);
803 if (dwFlag & ENABLE_LINE_INPUT)
808 if (dwFlag & ENABLE_ECHO_INPUT)
813 if (dwFlag & ENABLE_PROCESSED_INPUT)
818 TCB->term.Nttyb.c_iflag = iflag;
819 TCB->term.Nttyb.c_lflag = lflag;
821 *buf = TCB->term.Nttyb;
827 drv_initacs(TERMINAL_CONTROL_BLOCK * TCB,
828 chtype *real_map GCC_UNUSED,
829 chtype *fake_map GCC_UNUSED)
837 tdiff(FILETIME fstart, FILETIME fend)
839 ULARGE_INTEGER ustart;
843 ustart.LowPart = fstart.dwLowDateTime;
844 ustart.HighPart = fstart.dwHighDateTime;
845 uend.LowPart = fend.dwLowDateTime;
846 uend.HighPart = fend.dwHighDateTime;
848 diff = (uend.QuadPart - ustart.QuadPart) / 10000;
853 Adjust(int milliseconds, int diff)
855 if (milliseconds == INFINITY)
857 milliseconds -= diff;
858 if (milliseconds < 0)
864 drv_twait(TERMINAL_CONTROL_BLOCK * TCB,
868 EVENTLIST_2nd(_nc_eventlist * evl))
873 DWORD nRead = 0, rc = -1;
878 bool isImmed = (milliseconds == 0);
880 #define CONSUME() ReadConsoleInput(TCB->inp,&inp,1,&nRead)
885 if (milliseconds < 0)
886 milliseconds = INFINITY;
888 memset(&inp, 0, sizeof(inp));
891 GetSystemTimeAsFileTime(&fstart);
892 rc = WaitForSingleObject(TCB->inp, milliseconds);
893 GetSystemTimeAsFileTime(&fend);
894 diff = (int) tdiff(fstart, fend);
895 milliseconds = Adjust(milliseconds, diff);
897 if (!isImmed && milliseconds == 0)
900 if (rc == WAIT_OBJECT_0) {
902 b = GetNumberOfConsoleInputEvents(TCB->inp, &nRead);
903 if (b && nRead > 0) {
904 b = PeekConsoleInput(TCB->inp, &inp, 1, &nRead);
905 if (b && nRead > 0) {
906 switch (inp.EventType) {
908 if (mode & TW_INPUT) {
909 WORD vk = inp.Event.KeyEvent.wVirtualKeyCode;
910 char ch = inp.Event.KeyEvent.uChar.AsciiChar;
912 if (inp.Event.KeyEvent.bKeyDown) {
914 int nKey = MapKey(TCB, vk);
915 if ((nKey < 0) || FALSE == sp->_keypad_on) {
928 if (0 && mode & TW_MOUSE) {
934 SetConsoleActiveScreenBuffer(!PropOf(TCB)->progMode ?
935 TCB->hdl : TCB->out);
943 if (rc != WAIT_TIMEOUT) {
954 *timeleft = milliseconds;
960 drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf)
974 memset(&inp, 0, sizeof(inp));
976 while ((b = ReadConsoleInput(TCB->inp, &inp, 1, &nRead))) {
977 if (b && nRead > 0) {
978 if (inp.EventType == KEY_EVENT) {
979 if (!inp.Event.KeyEvent.bKeyDown)
981 *buf = (int) inp.Event.KeyEvent.uChar.AsciiChar;
982 vk = inp.Event.KeyEvent.wVirtualKeyCode;
983 sc = inp.Event.KeyEvent.wVirtualScanCode;
985 if (sp->_keypad_on) {
986 *buf = MapKey(TCB, vk);
993 } else { /* *buf != 0 */
996 } else if (0 && inp.EventType == MOUSE_EVENT) {
1007 drv_nap(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int ms)
1014 drv_kyExist(TERMINAL_CONTROL_BLOCK * TCB, int keycode)
1020 LONG key = GenMap(0, (WORD) keycode);
1029 (size_t) (N_INI + FKEYS),
1033 key = *((LONG *) res);
1035 if (!(nKey & 0x8000))
1042 drv_kpad(TERMINAL_CONTROL_BLOCK * TCB, bool flag GCC_UNUSED)
1057 drv_keyok(TERMINAL_CONTROL_BLOCK * TCB, int keycode, bool flag)
1064 LONG key = GenMap(0, (WORD) keycode);
1072 (size_t) (N_INI + FKEYS),
1076 key = *((LONG *) res);
1078 nKey = (LOWORD(key)) & 0x7fff;
1081 *(LONG *) res = GenMap(vKey, nKey);