X-Git-Url: https://ncurses.scripts.mit.edu/?a=blobdiff_plain;ds=sidebyside;f=ncurses%2Fwin32con%2Fwin_driver.c;h=2b159b18316de98df9c7415c3c05b39d6413a65e;hb=f9d358b4f3cf9b44727a0ee5c08f8ca6ae4e3821;hp=78cd8f5089d3c640a5f639f0fbdf64b86137bcbb;hpb=c04d54322f7835ed42e597967d8fa5471025fcac;p=ncurses.git diff --git a/ncurses/win32con/win_driver.c b/ncurses/win32con/win_driver.c index 78cd8f50..2b159b18 100644 --- a/ncurses/win32con/win_driver.c +++ b/ncurses/win32con/win_driver.c @@ -31,9 +31,14 @@ * * ****************************************************************************/ +/* + * TODO - GetMousePos(POINT * result) from ntconio.c + * TODO - implement nodelay + */ + #include -MODULE_ID("$Id: win_driver.c,v 1.5 2010/01/16 22:42:30 tom Exp $") +MODULE_ID("$Id: win_driver.c,v 1.8 2010/04/10 19:42:47 tom Exp $") #define WINMAGIC NCDRV_MAGIC(NCDRV_WINCONSOLE) @@ -105,7 +110,7 @@ MapAttr(TERMINAL_CONTROL_BLOCK * TCB, WORD res, chtype ch) AssertTCB(); SetSP(); - p = PAIR_NUMBER(ch); + p = PairNumber(ch); if (p > 0 && p < NUMPAIRS && TCB != 0 && sp != 0) { WORD a; a = PropOf(TCB)->pairs[p]; @@ -411,8 +416,7 @@ drv_sgmode(TERMINAL_CONTROL_BLOCK * TCB, bool setFlag, TTY * buf) else dwFlag &= ~ENABLE_PROCESSED_INPUT; - /* we disable that for now to focus on keyboard. */ - dwFlag &= ~ENABLE_MOUSE_INPUT; + dwFlag |= ENABLE_MOUSE_INPUT; buf->c_iflag = iflag; buf->c_lflag = lflag; @@ -564,6 +568,8 @@ drv_release(TERMINAL_CONTROL_BLOCK * TCB) static void drv_init(TERMINAL_CONTROL_BLOCK * TCB) { + DWORD num_buttons; + T((T_CALLED("drv_init(%p)"), TCB)); AssertTCB(); @@ -606,6 +612,13 @@ drv_init(TERMINAL_CONTROL_BLOCK * TCB) TCB->info.nocolorvideo = 1; TCB->info.tabsize = 8; + if (GetNumberOfConsoleMouseButtons(&num_buttons)) { + T(("mouse has %ld buttons", num_buttons)); + TCB->info.numbuttons = num_buttons; + } else { + TCB->info.numbuttons = 1; + } + TCB->info.defaultPalette = _nc_cga_palette; for (i = 0; i < (N_INI + FKEYS); i++) { @@ -682,6 +695,30 @@ drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB) AssertTCB(); SetSP(); + + sp->_mouse_type = M_TERM_DRIVER; +} + +static int +drv_testmouse(TERMINAL_CONTROL_BLOCK * TCB, int delay) +{ + int rc = 0; + SCREEN *sp; + + AssertTCB(); + SetSP(); + + if (sp->_drv_mouse_head < sp->_drv_mouse_tail) { + rc = TW_MOUSE; + } else { + rc = TCBOf(sp)->drv->twait(TCBOf(sp), + TWAIT_MASK, + delay, + (int *) 0 + EVENTLIST_2nd(evl)); + } + + return rc; } static int @@ -812,6 +849,50 @@ Adjust(int milliseconds, int diff) return milliseconds; } +#define BUTTON_MASK (FROM_LEFT_1ST_BUTTON_PRESSED | \ + FROM_LEFT_2ND_BUTTON_PRESSED | \ + FROM_LEFT_3RD_BUTTON_PRESSED | \ + FROM_LEFT_4TH_BUTTON_PRESSED | \ + RIGHTMOST_BUTTON_PRESSED) + +static int +decode_mouse(TERMINAL_CONTROL_BLOCK * TCB, int mask) +{ + SCREEN *sp; + int result = 0; + + AssertTCB(); + SetSP(); + + if (mask & FROM_LEFT_1ST_BUTTON_PRESSED) + result |= BUTTON1_PRESSED; + if (mask & FROM_LEFT_2ND_BUTTON_PRESSED) + result |= BUTTON2_PRESSED; + if (mask & FROM_LEFT_3RD_BUTTON_PRESSED) + result |= BUTTON3_PRESSED; + if (mask & FROM_LEFT_4TH_BUTTON_PRESSED) + result |= BUTTON4_PRESSED; + + if (mask & RIGHTMOST_BUTTON_PRESSED) { + switch (TCB->info.numbuttons) { + case 1: + result |= BUTTON1_PRESSED; + break; + case 2: + result |= BUTTON2_PRESSED; + break; + case 3: + result |= BUTTON3_PRESSED; + break; + case 4: + result |= BUTTON4_PRESSED; + break; + } + } + + return result; +} + static int drv_twait(TERMINAL_CONTROL_BLOCK * TCB, int mode, @@ -834,6 +915,9 @@ drv_twait(TERMINAL_CONTROL_BLOCK * TCB, AssertTCB(); SetSP(); + TR(TRACE_IEVENT, ("start twait: %d milliseconds, mode: %d", + milliseconds, mode)); + if (milliseconds < 0) milliseconds = INFINITY; @@ -877,11 +961,15 @@ drv_twait(TERMINAL_CONTROL_BLOCK * TCB, } continue; case MOUSE_EVENT: - if (0 && mode & TW_MOUSE) { + if (decode_mouse(TCB, + (inp.Event.MouseEvent.dwButtonState + & BUTTON_MASK)) == 0) { + CONSUME(); + } else if (mode & TW_MOUSE) { code = TW_MOUSE; goto end; - } else - continue; + } + continue; default: SetConsoleActiveScreenBuffer(!PropOf(TCB)->progMode ? TCB->hdl : TCB->out); @@ -902,12 +990,59 @@ drv_twait(TERMINAL_CONTROL_BLOCK * TCB, } } end: + + TR(TRACE_IEVENT, ("end twait: returned %d (%d), remaining time %d msec", + code, errno, milliseconds)); + if (timeleft) *timeleft = milliseconds; return code; } +static bool +handle_mouse(TERMINAL_CONTROL_BLOCK * TCB, MOUSE_EVENT_RECORD mer) +{ + SCREEN *sp; + MEVENT work; + bool result = FALSE; + + AssertTCB(); + SetSP(); + + sp->_drv_mouse_old_buttons = sp->_drv_mouse_new_buttons; + sp->_drv_mouse_new_buttons = mer.dwButtonState & BUTTON_MASK; + + /* + * We're only interested if the button is pressed or released. + * FIXME: implement continuous event-tracking. + */ + if (sp->_drv_mouse_new_buttons != sp->_drv_mouse_old_buttons) { + + memset(&work, 0, sizeof(work)); + + if (sp->_drv_mouse_new_buttons) { + + work.bstate |= decode_mouse(TCB, sp->_drv_mouse_new_buttons); + + } else { + + /* cf: BUTTON_PRESSED, BUTTON_RELEASED */ + work.bstate |= (decode_mouse(TCB, sp->_drv_mouse_old_buttons) >> 1); + + result = TRUE; + } + + work.x = mer.dwMousePosition.X; + work.y = mer.dwMousePosition.Y; + + sp->_drv_mouse_fifo[sp->_drv_mouse_tail] = work; + sp->_drv_mouse_tail += 1; + } + + return result; +} + static int drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf) { @@ -925,6 +1060,7 @@ drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf) memset(&inp, 0, sizeof(inp)); + T((T_CALLED("drv_read(%p)"), TCB)); while ((b = ReadConsoleInput(TCB->inp, &inp, 1, &nRead))) { if (b && nRead > 0) { if (inp.EventType == KEY_EVENT) { @@ -945,14 +1081,16 @@ drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf) } else { /* *buf != 0 */ break; } - } else if (0 && inp.EventType == MOUSE_EVENT) { - *buf = KEY_MOUSE; - break; + } else if (inp.EventType == MOUSE_EVENT) { + if (handle_mouse(TCB, inp.Event.MouseEvent)) { + *buf = KEY_MOUSE; + break; + } } continue; } } - return n; + returnCode(n); } static int @@ -1054,6 +1192,7 @@ NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_WIN_DRIVER = { drv_initcolor, /* initcolor */ drv_do_color, /* docolor */ drv_initmouse, /* initmouse */ + drv_testmouse, /* testmouse */ drv_setfilter, /* setfilter */ drv_hwlabel, /* hwlabel */ drv_hwlabelOnOff, /* hwlabelOnOff */