1 /****************************************************************************
2 * Copyright (c) 1998-2010,2012 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 *
31 ****************************************************************************/
34 * TODO - GetMousePos(POINT * result) from ntconio.c
35 * TODO - implement nodelay
38 #include <curses.priv.h>
39 #define CUR my_term.type.
41 MODULE_ID("$Id: win_driver.c,v 1.11 2012/02/18 20:28:25 tom Exp $")
43 #define WINMAGIC NCDRV_MAGIC(NCDRV_WINCONSOLE)
45 #define AssertTCB() assert(TCB!=0 && TCB->magic==WINMAGIC)
46 #define SetSP() assert(TCB->csp!=0); sp = TCB->csp; (void) sp
48 #define GenMap(vKey,key) MAKELONG(key, vKey)
50 static const LONG keylist[] =
52 GenMap(VK_PRIOR, KEY_PPAGE),
53 GenMap(VK_NEXT, KEY_NPAGE),
54 GenMap(VK_END, KEY_END),
55 GenMap(VK_HOME, KEY_HOME),
56 GenMap(VK_LEFT, KEY_LEFT),
57 GenMap(VK_UP, KEY_UP),
58 GenMap(VK_RIGHT, KEY_RIGHT),
59 GenMap(VK_DOWN, KEY_DOWN),
60 GenMap(VK_DELETE, KEY_DC),
61 GenMap(VK_INSERT, KEY_IC)
63 #define N_INI ((int)(sizeof(keylist)/sizeof(keylist[0])))
65 #define MAPSIZE (FKEYS + N_INI)
68 typedef struct props {
69 CONSOLE_SCREEN_BUFFER_INFO SBI;
76 #define PropOf(TCB) ((Properties*)TCB->prop)
79 _nc_mingw_ioctl(int fd GCC_UNUSED,
80 long int request GCC_UNUSED,
81 struct termios *arg GCC_UNUSED)
85 fprintf(stderr, "TERMINFO currently not supported on Windows.\n");
90 MapColor(bool fore, int color)
92 static const int _cmap[] =
93 {0, 4, 2, 6, 1, 5, 3, 7};
95 if (color < 0 || color > 7)
105 MapAttr(TERMINAL_CONTROL_BLOCK * TCB, WORD res, chtype ch)
114 if (p > 0 && p < NUMPAIRS && TCB != 0 && sp != 0) {
116 a = PropOf(TCB)->pairs[p];
117 res = (res & 0xff00) | a;
122 res = ((res & 0xff00) | (((res & 0x07) << 4) | ((res & 0x70) >> 4)));
125 res = ((res & 0xff00) | (((res & 0x07) << 4) | ((res & 0x70) >> 4))
126 | BACKGROUND_INTENSITY);
129 res |= FOREGROUND_INTENSITY;
132 res |= BACKGROUND_INTENSITY;
138 con_write(TERMINAL_CONTROL_BLOCK * TCB, int y, int x, chtype *str, int n)
149 if (TCB == 0 || InvalidConsoleHandle(TCB->hdl))
154 for (i = 0; i < n; i++) {
156 ci[i].Char.AsciiChar = ChCharOf(ch);
157 ci[i].Attributes = MapAttr(TCB,
158 PropOf(TCB)->SBI.wAttributes,
160 if (ChAttrOf(ch) & A_ALTCHARSET) {
162 ci[i].Char.AsciiChar =
163 ChCharOf(NCURSES_SP_NAME(_nc_acs_char) (sp, ChCharOf(ch)));
172 rec.Left = (short) x;
174 rec.Right = (short) (x + n - 1);
175 rec.Bottom = rec.Top;
177 return WriteConsoleOutput(TCB->hdl, ci, siz, loc, &rec);
180 #define MARK_NOCHANGE(win,row) \
181 win->_line[row].firstchar = _NOCHANGE; \
182 win->_line[row].lastchar = _NOCHANGE
185 drv_doupdate(TERMINAL_CONTROL_BLOCK * TCB)
187 int y, nonempty, n, x0, x1, Width, Height;
193 Width = screen_columns(sp);
194 Height = screen_lines(sp);
195 nonempty = min(Height, NewScreen(sp)->_maxy + 1);
197 if ((CurScreen(sp)->_clear || NewScreen(sp)->_clear)) {
201 for (x = 0; x < Width; x++)
204 for (y = 0; y < nonempty; y++) {
205 con_write(TCB, y, 0, empty, Width);
207 CurScreen(sp)->_line[y].text,
208 Width * sizeof(chtype));
210 CurScreen(sp)->_clear = FALSE;
211 NewScreen(sp)->_clear = FALSE;
212 touchwin(NewScreen(sp));
215 for (y = 0; y < nonempty; y++) {
216 x0 = NewScreen(sp)->_line[y].firstchar;
217 if (x0 != _NOCHANGE) {
218 x1 = NewScreen(sp)->_line[y].lastchar;
221 memcpy(CurScreen(sp)->_line[y].text + x0,
222 NewScreen(sp)->_line[y].text + x0,
227 ((chtype *) CurScreen(sp)->_line[y].text) + x0, n);
229 /* mark line changed successfully */
230 if (y <= NewScreen(sp)->_maxy) {
231 MARK_NOCHANGE(NewScreen(sp), y);
233 if (y <= CurScreen(sp)->_maxy) {
234 MARK_NOCHANGE(CurScreen(sp), y);
240 /* put everything back in sync */
241 for (y = nonempty; y <= NewScreen(sp)->_maxy; y++) {
242 MARK_NOCHANGE(NewScreen(sp), y);
244 for (y = nonempty; y <= CurScreen(sp)->_maxy; y++) {
245 MARK_NOCHANGE(CurScreen(sp), y);
248 if (!NewScreen(sp)->_leaveok) {
249 CurScreen(sp)->_curx = NewScreen(sp)->_curx;
250 CurScreen(sp)->_cury = NewScreen(sp)->_cury;
252 TCB->drv->hwcur(TCB, 0, 0, CurScreen(sp)->_cury, CurScreen(sp)->_curx);
254 SetConsoleActiveScreenBuffer(TCB->hdl);
259 drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB,
261 int *errret GCC_UNUSED)
265 T((T_CALLED("win32con::drv_CanHandle(%p)"), TCB));
270 TCB->magic = WINMAGIC;
271 if (*tname == 0 || *tname == 0) {
278 #if (USE_DATABASE || USE_TERMCAP)
279 status = _nc_setup_tinfo(tname, &my_term.type);
283 if (status != TGETENT_YES) {
284 const TERMTYPE *fallback = _nc_fallback(tname);
287 my_term.type = *fallback;
288 status = TGETENT_YES;
289 } else if (!strcmp(tname, "unknown")) {
293 if (status == TGETENT_YES) {
294 if (generic_type || hard_copy)
300 if ((TCB->term.type.Booleans) == 0) {
301 _nc_init_entry(&(TCB->term.type));
309 drv_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB,
310 int beepFlag GCC_UNUSED)
322 drv_print(TERMINAL_CONTROL_BLOCK * TCB,
323 char *data GCC_UNUSED,
335 drv_defaultcolors(TERMINAL_CONTROL_BLOCK * TCB,
349 drv_setcolor(TERMINAL_CONTROL_BLOCK * TCB,
352 int (*outc) (SCREEN *, int) GCC_UNUSED)
356 if (TCB && !InvalidConsoleHandle(TCB->hdl)) {
357 WORD a = MapColor(fore, color);
358 a = ((PropOf(TCB)->SBI.wAttributes) & (fore ? 0xfff8 : 0xff8f)) | a;
359 SetConsoleTextAttribute(TCB->hdl, a);
360 GetConsoleScreenBufferInfo(TCB->hdl, &(PropOf(TCB)->SBI));
365 drv_rescol(TERMINAL_CONTROL_BLOCK * TCB)
370 if (TCB && !InvalidConsoleHandle(TCB->hdl)) {
371 WORD a = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN;
372 SetConsoleTextAttribute(TCB->hdl, a);
373 GetConsoleScreenBufferInfo(TCB->hdl, &(PropOf(TCB)->SBI));
380 drv_rescolors(TERMINAL_CONTROL_BLOCK * TCB)
392 drv_size(TERMINAL_CONTROL_BLOCK * TCB, int *Lines, int *Cols)
396 if (TCB == NULL || Lines == NULL || Cols == NULL || InvalidConsoleHandle(TCB->hdl))
399 *Lines = (int) (PropOf(TCB)->SBI.dwSize.Y);
400 *Cols = (int) (PropOf(TCB)->SBI.dwSize.X);
405 drv_setsize(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED,
414 drv_sgmode(TERMINAL_CONTROL_BLOCK * TCB, int setFlag, TTY * buf)
422 if (TCB == 0 || buf == NULL)
426 iflag = buf->c_iflag;
427 lflag = buf->c_lflag;
429 GetConsoleMode(TCB->inp, &dwFlag);
432 dwFlag |= ENABLE_LINE_INPUT;
434 dwFlag &= ~ENABLE_LINE_INPUT;
437 dwFlag |= ENABLE_ECHO_INPUT;
439 dwFlag &= ~ENABLE_ECHO_INPUT;
442 dwFlag |= ENABLE_PROCESSED_INPUT;
444 dwFlag &= ~ENABLE_PROCESSED_INPUT;
446 dwFlag |= ENABLE_MOUSE_INPUT;
448 buf->c_iflag = iflag;
449 buf->c_lflag = lflag;
450 SetConsoleMode(TCB->inp, dwFlag);
451 TCB->term.Nttyb = *buf;
453 iflag = TCB->term.Nttyb.c_iflag;
454 lflag = TCB->term.Nttyb.c_lflag;
455 GetConsoleMode(TCB->inp, &dwFlag);
457 if (dwFlag & ENABLE_LINE_INPUT)
462 if (dwFlag & ENABLE_ECHO_INPUT)
467 if (dwFlag & ENABLE_PROCESSED_INPUT)
472 TCB->term.Nttyb.c_iflag = iflag;
473 TCB->term.Nttyb.c_lflag = lflag;
475 *buf = TCB->term.Nttyb;
481 drv_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag)
484 TERMINAL *_term = (TERMINAL *) TCB;
490 PropOf(TCB)->progMode = progFlag;
491 SetConsoleActiveScreenBuffer(progFlag ? TCB->hdl : TCB->out);
493 if (progFlag) /* prog mode */ {
495 if ((drv_sgmode(TCB, FALSE, &(_term->Nttyb)) == OK)) {
496 _term->Nttyb.c_oflag &= ~OFLAGS_TABS;
500 /* reset_prog_mode */
501 if (drv_sgmode(TCB, TRUE, &(_term->Nttyb)) == OK) {
504 _nc_keypad(sp, TRUE);
505 NC_BUFFERED(sp, TRUE);
510 } else { /* shell mode */
513 if (drv_sgmode(TCB, FALSE, &(_term->Ottyb)) == OK) {
517 /* reset_shell_mode */
519 _nc_keypad(sp, FALSE);
520 NCURSES_SP_NAME(_nc_flush) (sp);
521 NC_BUFFERED(sp, FALSE);
523 code = drv_sgmode(TCB, TRUE, &(_term->Ottyb));
531 drv_screen_init(SCREEN *sp GCC_UNUSED)
536 drv_wrap(SCREEN *sp GCC_UNUSED)
541 rkeycompare(const void *el1, const void *el2)
543 WORD key1 = (LOWORD((*((const LONG *) el1)))) & 0x7fff;
544 WORD key2 = (LOWORD((*((const LONG *) el2)))) & 0x7fff;
546 return ((key1 < key2) ? -1 : ((key1 == key2) ? 0 : 1));
550 keycompare(const void *el1, const void *el2)
552 WORD key1 = HIWORD((*((const LONG *) el1)));
553 WORD key2 = HIWORD((*((const LONG *) el2)));
555 return ((key1 < key2) ? -1 : ((key1 == key2) ? 0 : 1));
559 MapKey(TERMINAL_CONTROL_BLOCK * TCB, WORD vKey)
563 LONG key = GenMap(vKey, 0);
570 (size_t) (N_INI + FKEYS),
574 key = *((LONG *) res);
576 code = (int) (nKey & 0x7fff);
584 drv_release(TERMINAL_CONTROL_BLOCK * TCB)
586 T((T_CALLED("win32con::drv_release(%p)"), TCB));
596 drv_init(TERMINAL_CONTROL_BLOCK * TCB)
600 T((T_CALLED("win32con::drv_init(%p)"), TCB));
605 BOOL b = AllocConsole();
610 b = AttachConsole(ATTACH_PARENT_PROCESS);
612 TCB->inp = GetStdHandle(STD_INPUT_HANDLE);
613 TCB->out = GetStdHandle(STD_OUTPUT_HANDLE);
618 TCB->hdl = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
621 CONSOLE_TEXTMODE_BUFFER,
624 if (!InvalidConsoleHandle(TCB->hdl)) {
625 TCB->prop = typeCalloc(Properties, 1);
626 GetConsoleScreenBufferInfo(TCB->hdl, &(PropOf(TCB)->SBI));
629 TCB->info.initcolor = TRUE;
630 TCB->info.canchange = FALSE;
631 TCB->info.hascolor = TRUE;
632 TCB->info.caninit = TRUE;
634 TCB->info.maxpairs = NUMPAIRS;
635 TCB->info.maxcolors = 8;
636 TCB->info.numlabels = 0;
637 TCB->info.labelwidth = 0;
638 TCB->info.labelheight = 0;
639 TCB->info.nocolorvideo = 1;
640 TCB->info.tabsize = 8;
642 if (GetNumberOfConsoleMouseButtons(&num_buttons)) {
643 T(("mouse has %ld buttons", num_buttons));
644 TCB->info.numbuttons = num_buttons;
646 TCB->info.numbuttons = 1;
649 TCB->info.defaultPalette = _nc_cga_palette;
651 for (i = 0; i < (N_INI + FKEYS); i++) {
653 PropOf(TCB)->rmap[i] = PropOf(TCB)->map[i] = keylist[i];
655 PropOf(TCB)->rmap[i] = PropOf(TCB)->map[i] =
656 GenMap((VK_F1 + (i - N_INI)), (KEY_F(1) + (i - N_INI)));
658 qsort(PropOf(TCB)->map,
662 qsort(PropOf(TCB)->rmap,
667 a = MapColor(true, COLOR_WHITE) | MapColor(false, COLOR_BLACK);
668 for (i = 0; i < NUMPAIRS; i++)
669 PropOf(TCB)->pairs[i] = a;
675 drv_initpair(TERMINAL_CONTROL_BLOCK * TCB,
685 if ((pair > 0) && (pair < NUMPAIRS) && (f >= 0) && (f < 8)
686 && (b >= 0) && (b < 8)) {
687 PropOf(TCB)->pairs[pair] = MapColor(true, f) | MapColor(false, b);
692 drv_initcolor(TERMINAL_CONTROL_BLOCK * TCB,
693 int color GCC_UNUSED,
705 drv_do_color(TERMINAL_CONTROL_BLOCK * TCB,
706 int old_pair GCC_UNUSED,
708 int reverse GCC_UNUSED,
709 int (*outc) (SCREEN *, int) GCC_UNUSED
719 drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB)
726 sp->_mouse_type = M_TERM_DRIVER;
730 drv_testmouse(TERMINAL_CONTROL_BLOCK * TCB, int delay)
738 if (sp->_drv_mouse_head < sp->_drv_mouse_tail) {
741 rc = TCBOf(sp)->drv->twait(TCBOf(sp),
752 drv_mvcur(TERMINAL_CONTROL_BLOCK * TCB,
753 int yold GCC_UNUSED, int xold GCC_UNUSED,
757 if (TCB && !InvalidConsoleHandle(TCB->hdl)) {
761 SetConsoleCursorPosition(TCB->hdl, loc);
768 drv_hwlabel(TERMINAL_CONTROL_BLOCK * TCB,
769 int labnum GCC_UNUSED,
770 char *text GCC_UNUSED)
779 drv_hwlabelOnOff(TERMINAL_CONTROL_BLOCK * TCB,
780 int OnFlag GCC_UNUSED)
789 drv_conattr(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED)
791 chtype res = A_NORMAL;
792 res |= (A_BOLD | A_DIM | A_REVERSE | A_STANDOUT | A_COLOR);
797 drv_setfilter(TERMINAL_CONTROL_BLOCK * TCB)
806 drv_initacs(TERMINAL_CONTROL_BLOCK * TCB,
807 chtype *real_map GCC_UNUSED,
808 chtype *fake_map GCC_UNUSED)
810 #define DATA(a,b) { a, b }
815 DATA('a', 0xb1), /* ACS_CKBOARD */
816 DATA('f', 0xf8), /* ACS_DEGREE */
817 DATA('g', 0xf1), /* ACS_PLMINUS */
818 DATA('j', 0xd9), /* ACS_LRCORNER */
819 DATA('l', 0xda), /* ACS_ULCORNER */
820 DATA('k', 0xbf), /* ACS_URCORNER */
821 DATA('m', 0xc0), /* ACS_LLCORNER */
822 DATA('n', 0xc5), /* ACS_PLUS */
823 DATA('q', 0xc4), /* ACS_HLINE */
824 DATA('t', 0xc3), /* ACS_LTEE */
825 DATA('u', 0xb4), /* ACS_RTEE */
826 DATA('v', 0xc1), /* ACS_BTEE */
827 DATA('w', 0xc2), /* ACS_TTEE */
828 DATA('x', 0xb3), /* ACS_VLINE */
829 DATA('y', 0xf3), /* ACS_LEQUAL */
830 DATA('z', 0xf2), /* ACS_GEQUAL */
831 DATA('0', 0xdb), /* ACS_BLOCK */
832 DATA('{', 0xe3), /* ACS_PI */
833 DATA('}', 0x9c), /* ACS_STERLING */
834 DATA(',', 0xae), /* ACS_LARROW */
835 DATA('+', 0xaf), /* ACS_RARROW */
836 DATA('~', 0xf9), /* ACS_BULLET */
845 for (n = 0; n < SIZEOF(table); ++n) {
846 real_map[table[n].acs_code] = table[n].use_code | A_ALTCHARSET;
848 sp->_screen_acs_map[table[n].acs_code] = TRUE;
853 tdiff(FILETIME fstart, FILETIME fend)
855 ULARGE_INTEGER ustart;
859 ustart.LowPart = fstart.dwLowDateTime;
860 ustart.HighPart = fstart.dwHighDateTime;
861 uend.LowPart = fend.dwLowDateTime;
862 uend.HighPart = fend.dwHighDateTime;
864 diff = (uend.QuadPart - ustart.QuadPart) / 10000;
869 Adjust(int milliseconds, int diff)
871 if (milliseconds == INFINITY)
873 milliseconds -= diff;
874 if (milliseconds < 0)
879 #define BUTTON_MASK (FROM_LEFT_1ST_BUTTON_PRESSED | \
880 FROM_LEFT_2ND_BUTTON_PRESSED | \
881 FROM_LEFT_3RD_BUTTON_PRESSED | \
882 FROM_LEFT_4TH_BUTTON_PRESSED | \
883 RIGHTMOST_BUTTON_PRESSED)
886 decode_mouse(TERMINAL_CONTROL_BLOCK * TCB, int mask)
894 if (mask & FROM_LEFT_1ST_BUTTON_PRESSED)
895 result |= BUTTON1_PRESSED;
896 if (mask & FROM_LEFT_2ND_BUTTON_PRESSED)
897 result |= BUTTON2_PRESSED;
898 if (mask & FROM_LEFT_3RD_BUTTON_PRESSED)
899 result |= BUTTON3_PRESSED;
900 if (mask & FROM_LEFT_4TH_BUTTON_PRESSED)
901 result |= BUTTON4_PRESSED;
903 if (mask & RIGHTMOST_BUTTON_PRESSED) {
904 switch (TCB->info.numbuttons) {
906 result |= BUTTON1_PRESSED;
909 result |= BUTTON2_PRESSED;
912 result |= BUTTON3_PRESSED;
915 result |= BUTTON4_PRESSED;
924 drv_twait(TERMINAL_CONTROL_BLOCK * TCB,
928 EVENTLIST_2nd(_nc_eventlist * evl))
931 INPUT_RECORD inp_rec;
933 DWORD nRead = 0, rc = -1;
938 bool isImmed = (milliseconds == 0);
940 #define CONSUME() ReadConsoleInput(TCB->inp,&inp_rec,1,&nRead)
945 TR(TRACE_IEVENT, ("start twait: %d milliseconds, mode: %d",
946 milliseconds, mode));
948 if (milliseconds < 0)
949 milliseconds = INFINITY;
951 memset(&inp_rec, 0, sizeof(inp_rec));
954 GetSystemTimeAsFileTime(&fstart);
955 rc = WaitForSingleObject(TCB->inp, milliseconds);
956 GetSystemTimeAsFileTime(&fend);
957 diff = (int) tdiff(fstart, fend);
958 milliseconds = Adjust(milliseconds, diff);
960 if (!isImmed && milliseconds == 0)
963 if (rc == WAIT_OBJECT_0) {
965 b = GetNumberOfConsoleInputEvents(TCB->inp, &nRead);
966 if (b && nRead > 0) {
967 b = PeekConsoleInput(TCB->inp, &inp_rec, 1, &nRead);
968 if (b && nRead > 0) {
969 switch (inp_rec.EventType) {
971 if (mode & TW_INPUT) {
972 WORD vk = inp_rec.Event.KeyEvent.wVirtualKeyCode;
973 char ch = inp_rec.Event.KeyEvent.uChar.AsciiChar;
975 if (inp_rec.Event.KeyEvent.bKeyDown) {
977 int nKey = MapKey(TCB, vk);
978 if ((nKey < 0) || FALSE == sp->_keypad_on) {
991 if (decode_mouse(TCB,
992 (inp_rec.Event.MouseEvent.dwButtonState
993 & BUTTON_MASK)) == 0) {
995 } else if (mode & TW_MOUSE) {
1001 SetConsoleActiveScreenBuffer(!PropOf(TCB)->progMode ?
1002 TCB->hdl : TCB->out);
1010 if (rc != WAIT_TIMEOUT) {
1021 TR(TRACE_IEVENT, ("end twait: returned %d (%d), remaining time %d msec",
1022 code, errno, milliseconds));
1025 *timeleft = milliseconds;
1031 handle_mouse(TERMINAL_CONTROL_BLOCK * TCB, MOUSE_EVENT_RECORD mer)
1035 bool result = FALSE;
1040 sp->_drv_mouse_old_buttons = sp->_drv_mouse_new_buttons;
1041 sp->_drv_mouse_new_buttons = mer.dwButtonState & BUTTON_MASK;
1044 * We're only interested if the button is pressed or released.
1045 * FIXME: implement continuous event-tracking.
1047 if (sp->_drv_mouse_new_buttons != sp->_drv_mouse_old_buttons) {
1049 memset(&work, 0, sizeof(work));
1051 if (sp->_drv_mouse_new_buttons) {
1053 work.bstate |= decode_mouse(TCB, sp->_drv_mouse_new_buttons);
1057 /* cf: BUTTON_PRESSED, BUTTON_RELEASED */
1058 work.bstate |= (decode_mouse(TCB, sp->_drv_mouse_old_buttons) >> 1);
1063 work.x = mer.dwMousePosition.X;
1064 work.y = mer.dwMousePosition.Y;
1066 sp->_drv_mouse_fifo[sp->_drv_mouse_tail] = work;
1067 sp->_drv_mouse_tail += 1;
1074 drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf)
1078 INPUT_RECORD inp_rec;
1087 memset(&inp_rec, 0, sizeof(inp_rec));
1089 T((T_CALLED("win32con::drv_read(%p)"), TCB));
1090 while ((b = ReadConsoleInput(TCB->inp, &inp_rec, 1, &nRead))) {
1091 if (b && nRead > 0) {
1092 if (inp_rec.EventType == KEY_EVENT) {
1093 if (!inp_rec.Event.KeyEvent.bKeyDown)
1095 *buf = (int) inp_rec.Event.KeyEvent.uChar.AsciiChar;
1096 vk = inp_rec.Event.KeyEvent.wVirtualKeyCode;
1098 if (sp->_keypad_on) {
1099 *buf = MapKey(TCB, vk);
1106 } else { /* *buf != 0 */
1109 } else if (inp_rec.EventType == MOUSE_EVENT) {
1110 if (handle_mouse(TCB, inp_rec.Event.MouseEvent)) {
1122 drv_nap(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int ms)
1129 drv_kyExist(TERMINAL_CONTROL_BLOCK * TCB, int keycode)
1135 LONG key = GenMap(0, (WORD) keycode);
1144 (size_t) (N_INI + FKEYS),
1148 key = *((LONG *) res);
1150 if (!(nKey & 0x8000))
1157 drv_kpad(TERMINAL_CONTROL_BLOCK * TCB, int flag GCC_UNUSED)
1172 drv_keyok(TERMINAL_CONTROL_BLOCK * TCB, int keycode, int flag)
1179 LONG key = GenMap(0, (WORD) keycode);
1187 (size_t) (N_INI + FKEYS),
1191 key = *((LONG *) res);
1193 nKey = (LOWORD(key)) & 0x7fff;
1196 *(LONG *) res = GenMap(vKey, nKey);
1202 NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_WIN_DRIVER = {
1204 drv_CanHandle, /* CanHandle */
1205 drv_init, /* init */
1206 drv_release, /* release */
1207 drv_size, /* size */
1208 drv_sgmode, /* sgmode */
1209 drv_conattr, /* conattr */
1210 drv_mvcur, /* hwcur */
1211 drv_mode, /* mode */
1212 drv_rescol, /* rescol */
1213 drv_rescolors, /* rescolors */
1214 drv_setcolor, /* color */
1215 drv_dobeepflash, /* DoBeepFlash */
1216 drv_initpair, /* initpair */
1217 drv_initcolor, /* initcolor */
1218 drv_do_color, /* docolor */
1219 drv_initmouse, /* initmouse */
1220 drv_testmouse, /* testmouse */
1221 drv_setfilter, /* setfilter */
1222 drv_hwlabel, /* hwlabel */
1223 drv_hwlabelOnOff, /* hwlabelOnOff */
1224 drv_doupdate, /* update */
1225 drv_defaultcolors, /* defaultcolors */
1226 drv_print, /* print */
1227 drv_size, /* getsize */
1228 drv_setsize, /* setsize */
1229 drv_initacs, /* initacs */
1230 drv_screen_init, /* scinit */
1231 drv_wrap, /* scexit */
1232 drv_twait, /* twait */
1233 drv_read, /* read */
1235 drv_kpad, /* kpad */
1236 drv_keyok, /* kyOk */
1237 drv_kyExist /* kyExist */