aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2000-12-16 03:11:02 +0000
committerChristopher Faylor <me@cgf.cx>2000-12-16 03:11:02 +0000
commit085ec17c5d2dd41d53acaed455fb238116092b32 (patch)
tree07df9122bb752bdd1c27b031368313341af7147d
parent7fbcbc95929b933657d8b69673c42d1dd84408b0 (diff)
downloadnewlib-085ec17c5d2dd41d53acaed455fb238116092b32.zip
newlib-085ec17c5d2dd41d53acaed455fb238116092b32.tar.gz
newlib-085ec17c5d2dd41d53acaed455fb238116092b32.tar.bz2
* fhandler_console.cc (read): Add support for xterm-style mouse event
reporting. (fhandler_console::char_command): Honor mouse events. (fhandler_console::open): Enable mouse input events. (fhandler_console::input_tcsetattr): Ditto. * select.cc (peek_console): Add check for mouse events.
-rw-r--r--winsup/cygwin/ChangeLog9
-rw-r--r--winsup/cygwin/fhandler_console.cc184
-rw-r--r--winsup/cygwin/select.cc4
3 files changed, 159 insertions, 38 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 98e33d6..cf2f6a3 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,12 @@
+Fri Dec 15 18:54:42 2000 Bradley A. Town <townba@pobox.com>
+
+ * fhandler_console.cc (read): Add support for xterm-style mouse event
+ reporting.
+ (fhandler_console::char_command): Honor mouse events.
+ (fhandler_console::open): Enable mouse input events.
+ (fhandler_console::input_tcsetattr): Ditto.
+ * select.cc (peek_console): Add check for mouse events.
+
Fri Dec 15 17:23:17 2000 Christopher Faylor <cgf@cygnus.com>
* path.cc (normalize_posix_path): Calculate path name length overruns
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 22a88ed..6d092f1 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -47,6 +47,8 @@ static struct
const char * get_nonascii_key (INPUT_RECORD&, char *);
+static BOOL use_mouse = FALSE;
+
HANDLE console_shared_h;
static tty_min NO_COPY *shared_console_info = NULL;
@@ -184,7 +186,7 @@ fhandler_console::read (void *pv, size_t buflen)
DWORD nread;
INPUT_RECORD input_rec;
- const char *toadd;
+ const char *toadd = NULL;
if (!ReadConsoleInput (h, &input_rec, 1, &nread))
{
@@ -193,48 +195,142 @@ fhandler_console::read (void *pv, size_t buflen)
return -1; /* seems to be failure */
}
+ /* check the event that occurred */
+ switch (input_rec.EventType)
+ {
+ case KEY_EVENT:
+ if (!input_rec.Event.KeyEvent.bKeyDown)
+ continue;
+
#define ich (input_rec.Event.KeyEvent.uChar.AsciiChar)
#define wch (input_rec.Event.KeyEvent.uChar.UnicodeChar)
- /* check if we're just disposing of this one */
-
- if (input_rec.EventType == WINDOW_BUFFER_SIZE_EVENT)
- {
- kill_pgrp (tc->getpgid (), SIGWINCH);
- continue;
- }
- if (input_rec.EventType != KEY_EVENT ||
- !input_rec.Event.KeyEvent.bKeyDown)
- continue;
+ if (wch == 0 ||
+ /* arrow/function keys */
+ (input_rec.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY))
+ {
+ toadd = get_nonascii_key (input_rec, tmp);
+ if (!toadd)
+ continue;
+ nread = strlen (toadd);
+ }
+ else
+ {
+ tmp[1] = ich;
+ /* Need this check since US code page seems to have a bug when
+ converting a CTRL-U. */
+ if ((unsigned char)ich > 0x7f)
+ OemToCharBuff (tmp + 1, tmp + 1, 1);
+ if (!(input_rec.Event.KeyEvent.dwControlKeyState & LEFT_ALT_PRESSED))
+ toadd = tmp + 1;
+ else
+ {
+ tmp[0] = '\033';
+ tmp[1] = cyg_tolower (tmp[1]);
+ toadd = tmp;
+ nread++;
+ }
+ }
+#undef ich
+#undef wch
+ break;
- if (wch == 0 ||
- /* arrow/function keys */
- (input_rec.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY))
- {
- toadd = get_nonascii_key (input_rec, tmp);
- if (!toadd)
- continue;
- nread = strlen (toadd);
- }
- else
- {
- tmp[1] = ich;
- /* Need this check since US code page seems to have a bug when
- converting a CTRL-U. */
- if ((unsigned char)ich > 0x7f && current_codepage == ansi_cp)
- OemToCharBuff (tmp + 1, tmp + 1, 1);
- if (!(input_rec.Event.KeyEvent.dwControlKeyState & LEFT_ALT_PRESSED))
- toadd = tmp + 1;
- else
+ case MOUSE_EVENT:
+ if (use_mouse)
{
- tmp[0] = '\033';
- tmp[1] = cyg_tolower (tmp[1]);
+ MOUSE_EVENT_RECORD & mouse_event = input_rec.Event.MouseEvent;
+
+ /* Treat the double-click event like a regular button press */
+ if (mouse_event.dwEventFlags == DOUBLE_CLICK)
+ {
+ syscall_printf("mouse: double-click -> click");
+ mouse_event.dwEventFlags = 0;
+ }
+
+ /* Did something other than a click occur? */
+ if (mouse_event.dwEventFlags)
+ continue;
+
+ /* If the mouse event occurred out of the area we can handle,
+ ignore it. */
+ int x = mouse_event.dwMousePosition.X;
+ int y = mouse_event.dwMousePosition.Y;
+ if ((x + ' ' + 1 > 0xFF) || (y + ' ' + 1 > 0xFF))
+ {
+ syscall_printf("mouse: position out of range");
+ continue;
+ }
+
+ /* Ignore unimportant mouse buttons */
+ mouse_event.dwButtonState &= 0x7;
+
+ /* This code assumes Windows never reports multiple button
+ events at the same time. */
+ static DWORD dwLastButtonState = 0;
+ int b = 0;
+ char sz[32];
+ if (mouse_event.dwButtonState == dwLastButtonState)
+ {
+ syscall_printf("mouse: button state unchanged");
+ continue;
+ }
+ else if (mouse_event.dwButtonState < dwLastButtonState)
+ {
+ b = 3;
+ strcpy(sz, "btn up");
+ }
+ else if ((mouse_event.dwButtonState & 1) != (dwLastButtonState & 1))
+ {
+ b = 0;
+ strcpy(sz, "btn1 down");
+ }
+ else if ((mouse_event.dwButtonState & 2) != (dwLastButtonState & 2))
+ {
+ b = 1;
+ strcpy(sz, "btn2 down");
+ }
+ else if ((mouse_event.dwButtonState & 4) != (dwLastButtonState & 4))
+ {
+ b = 2;
+ strcpy(sz, "btn3 down");
+ }
+
+ /* Remember the current button state */
+ dwLastButtonState = mouse_event.dwButtonState;
+
+ static int nModifiers = 0;
+ /* If a button was pressed, remember the modifiers */
+ if (b != 3)
+ {
+ nModifiers = 0;
+ if (mouse_event.dwControlKeyState & SHIFT_PRESSED)
+ nModifiers |= 0x4;
+ if (mouse_event.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED))
+ nModifiers |= 0x8;
+ if (mouse_event.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
+ nModifiers |= 0x10;
+ }
+
+ b |= nModifiers;
+
+ /* We can now create the code. */
+ sprintf(tmp, "\033[M%c%c%c", b + ' ', x + ' ' + 1, y + ' ' + 1);
+ syscall_printf("mouse: %s at (%d,%d)", sz, x, y);
+
toadd = tmp;
- nread++;
+ nread = 6;
}
+ break;
+
+ case WINDOW_BUFFER_SIZE_EVENT:
+ kill_pgrp (tc->getpgid (), SIGWINCH);
+ continue;
+
+ default:
+ continue;
}
- if (line_edit (toadd, nread))
+ if (toadd && line_edit (toadd, nread))
break;
#undef ich
}
@@ -365,7 +461,7 @@ fhandler_console::open (const char *, int flags, mode_t)
set_r_no_interrupt (1); // Handled explicitly in read code
h = CreateFileA ("CONOUT$", GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_WRITE | FILE_SHARE_WRITE, &sec_none,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, &sec_none,
OPEN_EXISTING, 0, 0);
if (h == INVALID_HANDLE_VALUE)
@@ -382,7 +478,7 @@ fhandler_console::open (const char *, int flags, mode_t)
if (GetConsoleMode (get_io_handle (), &cflags))
{
cflags |= ENABLE_PROCESSED_INPUT;
- SetConsoleMode (get_io_handle (), ENABLE_WINDOW_INPUT | cflags);
+ SetConsoleMode (get_io_handle (), ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | cflags);
}
TTYCLEARF (RSTCONS);
@@ -545,7 +641,7 @@ fhandler_console::input_tcsetattr (int, struct termios const *t)
tc->ti.c_lflag = 0;
}
- flags |= ENABLE_WINDOW_INPUT;
+ flags |= ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
int res;
if (flags == oflags)
@@ -903,7 +999,19 @@ fhandler_console::char_command (char c, bool saw_question_mark)
break;
case 'h':
case 'l':
- /* Ignore */
+ if (!saw_question_mark)
+ break;
+ switch (args_[0])
+ {
+ case 1000: /* Mouse support */
+ use_mouse = (c == 'h') ? TRUE : FALSE;
+ syscall_printf("mouse support %sabled", use_mouse ? "en" : "dis");
+ break;
+
+ default: /* Ignore */
+ syscall_printf("unknown h/l command: %d", args_[0]);
+ break;
+ }
break;
case 'J':
switch (args_[0])
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 8331271..168f92c 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -635,6 +635,10 @@ peek_console (select_record *me, int ignra)
{
if (irec.EventType == WINDOW_BUFFER_SIZE_EVENT)
kill_pgrp (fh->tc->getpgid (), SIGWINCH);
+ else if (irec.EventType == MOUSE_EVENT &&
+ (irec.Event.MouseEvent.dwEventFlags == 0 ||
+ irec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK))
+ return me->read_ready = 1;
else if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown == TRUE &&
(irec.Event.KeyEvent.uChar.AsciiChar || get_nonascii_key (irec, tmpbuf)))
return me->read_ready = 1;