console enhancements: mouse events

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

console enhancements: mouse events

by Thomas Wolff-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,
About enhancements of cygwin console features, I've now worked out a
patch which does the following:

* Implement additional mouse reporting modes 1002 and 1003 as known
  from xterm and mintty; they report mouse move events.
* Add detection and reporting of mouse scroll events to mouse reporting
  mode 1000.
  Note: This works on my home PC (Windows XP Home) but it's not effective
  on my work PC (Windows XP Professional) where the mouse wheel scrolls the
  Windows console (which it doesn't on the other machine); I don't know
  how to disable or configure this.
* Enforce consistence between select() and read() about whether mouse
  reporting input is available by moving all checks into the common
  function mouse_aware.
* Add mouse focus reporting mode 1004 as known from xterm and mintty.
* As a separate change, where I added the initialization of the additional
  reporting modes, I also added and fixed some screen attribute modes as
  known from the Linux console (and xterm):
  - ESC[22m disable bold, ESC[28m disable invisible, ESC[25m disable blinking
  - ESC[2m dim as usual on other terminals, instead of ESC[9m

Some other console issues (not covered by this patch) are probably better
discussed on cygwin-developers but maybe I can mention them here already:
* Maybe the escape sequences of shifted function keys should be modified
  to comply with those of the Linux console?
* I would like to fix some key assignments:
  - Control-(Shift-)6 inputs Control-^ which is not proper on international
    keyboards if Shift-6 is not "^", Control-^ (the key) does not input
    Control-^ (the character) on the other hand; the same glitch
    occurs in the pure Windows console, however.
    Unfortunately, with the functions being used it is not possible to
    detect that shifted key "^" was hit together with Control; only
    keycodes/scancodes are available when Control/Shift/Alt are used. So
    I don't know whether this can easily be fixed. It works in mintty but
    I think mintty uses different Windows functions.
  - Pressing something like Alt-ö on a German keyboard leaves an illegal UTF-8
    sequence (the second byte of the respective sequence) in input, apparently
    because Alt-0xC3 is handled somehow. Don't know, though, whether this is
    a cygwin console issue or maybe a readline issue.
* I intended to implement cursor position reports and noticed that their
  request ESC[6n is already handled in the code; it does not work, however,
  so I started to debug it:
  The readahead buffer is used (also used for UTF-8 bytes) but after the
  buffer has been filled with the reporting sequence it appears to be empty
  (logged ralen in put_readahead, get_readahead and elsewhere where it is
  modified). First puzzled by the trace output, my assumption is that
  the readahead buffer of stdout is being filled (while handling the
  request) but the readahead buffer of stdin is checked and should have
  been filled instead (so this can never have worked).
  I don't know, however, how to access the other buffer while handling
  within stdout because I'm not familiar with the fhandler design. Could
  someone please give a hint or fix this?
* VT100 graphics mode should be added as suggested by Andy.

Kind regards,
Thomas



diff -rup cygwin-1.7.0-63-orig/winsup/cygwin/ChangeLog cygwin-1.7.0-63/winsup/cygwin/ChangeLog
--- cygwin-1.7.0-63-orig/winsup/cygwin/ChangeLog 2009-11-03 14:58:50.000000000 +0100
+++ cygwin-1.7.0-63/winsup/cygwin/ChangeLog 2009-11-04 12:55:52.227074000 +0100
@@ -1,3 +1,27 @@
+2009-11-04  Thomas Wolff  <towo@...>
+
+ * fhandler.h (use_mouse): Enable additional mouse modes (bool->int).
+ (mouse_aware): Move enhanced function into fhandler_console.cc.
+ * fhandler_console.cc (read): Detect and handle mouse wheel scrolling
+ and mouse movement events. Use mouse_aware as a guard and only
+ condition for mouse reporting in order to enforce consistence
+ with select(). Add focus reports.
+ (mouse_aware) Enable detection of additional mouse events for select.
+ Tune function to precisely match actual reporting criteria.
+ Move adjustment of mouse position (by window scroll offset)
+ here to avoid duplicate code.
+ (char_command): Initialization of enhanced mouse reporting modes.
+ Initialization of focus reports.
+ * select.cc (peek_console): Use modified mouse_aware() for more
+ general detection of mouse events. Also check for focus reports.
+
+2009-11-04  Thomas Wolff  <towo@...>
+
+ * fhandler_console.cc (char_command): Fix code to select dim mode
+ to usual 2 (not leaving previous 9 for compatibility because it
+ doesn't work anyway); also add entries for mode 22 (normal, not bold)
+ 28 (visible, not invisible), 25 (not blinking).
+
 2009-11-03  Corinna Vinschen  <corinna@...>
 
  * security.cc (alloc_sd): Re-introduce setting the SE_DACL_PROTECTED
diff -rup cygwin-1.7.0-63-orig/winsup/cygwin/fhandler.h cygwin-1.7.0-63/winsup/cygwin/fhandler.h
--- cygwin-1.7.0-63-orig/winsup/cygwin/fhandler.h 2009-10-20 10:16:40.000000000 +0200
+++ cygwin-1.7.0-63/winsup/cygwin/fhandler.h 2009-11-04 12:45:39.688539000 +0100
@@ -925,11 +925,15 @@ class dev_console
     } info;
 
   COORD dwLastCursorPosition;
-  DWORD dwLastButtonState;
+  COORD dwMousePosition; /* scroll-adjusted coord of mouse event */
+  COORD dwLastMousePosition; /* scroll-adjusted coord of previous mouse event */
+  DWORD dwLastButtonState; /* (not noting mouse wheel events) */
+  int last_button_code; /* transformed mouse report button code */
   int nModifiers;
 
   bool insert_mode;
-  bool use_mouse;
+  int use_mouse;
+  bool use_focus;
   bool raw_win32_keyboard_mode;
 
   inline UINT get_console_cp ();
@@ -1001,7 +1005,11 @@ class fhandler_console: public fhandler_
 
   int ioctl (unsigned int cmd, void *);
   int init (HANDLE, DWORD, mode_t);
-  bool mouse_aware () {return dev_state->use_mouse;}
+  bool mouse_aware (MOUSE_EVENT_RECORD& mouse_event);
+  bool focus_aware ()
+    {
+      return dev_state->use_focus;
+    }
 
   select_record *select_read (select_stuff *);
   select_record *select_write (select_stuff *);
diff -rup cygwin-1.7.0-63-orig/winsup/cygwin/fhandler_console.cc cygwin-1.7.0-63/winsup/cygwin/fhandler_console.cc
--- cygwin-1.7.0-63-orig/winsup/cygwin/fhandler_console.cc 2009-10-03 14:28:04.000000000 +0200
+++ cygwin-1.7.0-63/winsup/cygwin/fhandler_console.cc 2009-11-04 14:48:31.197074200 +0100
@@ -100,6 +100,10 @@ fhandler_console::get_tty_stuff (int fla
       dev_state->scroll_region.Bottom = -1;
       dev_state->dwLastCursorPosition.X = -1;
       dev_state->dwLastCursorPosition.Y = -1;
+      dev_state->dwLastMousePosition.X = -1;
+      dev_state->dwLastMousePosition.Y = -1;
+      dev_state->dwLastButtonState = 0; /* none pressed */
+      dev_state->last_button_code = 3; /* released */
       dev_state->underline_color = FOREGROUND_GREEN | FOREGROUND_BLUE;
       dev_state->dim_color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
       dev_state->meta_mask = LEFT_ALT_PRESSED;
@@ -206,6 +210,45 @@ fhandler_console::send_winch_maybe ()
     }
 }
 
+/* Check whether a mouse event is to be reported as an escape sequence */
+bool
+fhandler_console::mouse_aware (MOUSE_EVENT_RECORD& mouse_event)
+{
+  if (! dev_state->use_mouse)
+    return 0;
+
+  /* Adjust mouse position by window scroll buffer offset
+     and remember adjusted position in state for use by read() */
+  CONSOLE_SCREEN_BUFFER_INFO now;
+  if (GetConsoleScreenBufferInfo (get_output_handle (), &now))
+    {
+      dev_state->dwMousePosition.X = mouse_event.dwMousePosition.X - now.srWindow.Left;
+      dev_state->dwMousePosition.Y = mouse_event.dwMousePosition.Y - now.srWindow.Top;
+    }
+  else
+    {
+      /* Cannot adjust position by window scroll buffer offset */
+      return 0;
+    }
+
+  /* Check whether adjusted mouse position can be reported */
+  if (dev_state->dwMousePosition.X > 0xFF - ' ' - 1
+      || dev_state->dwMousePosition.Y > 0xFF - ' ' - 1)
+    {
+      /* Mouse position out of reporting range */
+      return 0;
+    }
+
+  return ((mouse_event.dwEventFlags == 0 || mouse_event.dwEventFlags == DOUBLE_CLICK)
+  && mouse_event.dwButtonState != dev_state->dwLastButtonState)
+ || mouse_event.dwEventFlags == MOUSE_WHEELED
+ || (mouse_event.dwEventFlags == MOUSE_MOVED
+     && (dev_state->dwMousePosition.X != dev_state->dwLastMousePosition.X
+         || dev_state->dwMousePosition.Y != dev_state->dwLastMousePosition.Y)
+     && ((dev_state->use_mouse >= 2 && mouse_event.dwButtonState)
+         || dev_state->use_mouse >= 3));
+}
+
 void __stdcall
 fhandler_console::read (void *pv, size_t& buflen)
 {
@@ -400,10 +443,18 @@ fhandler_console::read (void *pv, size_t
   break;
 
  case MOUSE_EVENT:
-  send_winch_maybe ();
-  if (dev_state->use_mouse)
+ send_winch_maybe ();
+ {
+  MOUSE_EVENT_RECORD& mouse_event = input_rec.Event.MouseEvent;
+  /* As a unique guard for mouse report generation,
+     call mouse_aware() which is common with select(), so the result
+     of select() and the actual read() will be consistent on the
+     issue of whether input (i.e. a mouse escape sequence) will
+     be available or not */
+  if (mouse_aware (mouse_event))
     {
-      MOUSE_EVENT_RECORD& mouse_event = input_rec.Event.MouseEvent;
+      /* Note: Reported mouse position was already retrieved by
+         mouse_aware() and adjusted by window scroll buffer offset */
 
       /* Treat the double-click event like a regular button press */
       if (mouse_event.dwEventFlags == DOUBLE_CLICK)
@@ -412,95 +463,106 @@ fhandler_console::read (void *pv, size_t
   mouse_event.dwEventFlags = 0;
  }
 
-      /* Did something other than a click occur? */
-      if (mouse_event.dwEventFlags)
- continue;
-
-      /* Retrieve reported mouse position */
-      int x = mouse_event.dwMousePosition.X;
-      int y = mouse_event.dwMousePosition.Y;
-
-      /* Adjust mouse position by scroll buffer offset */
-      CONSOLE_SCREEN_BUFFER_INFO now;
-      if (GetConsoleScreenBufferInfo (get_output_handle (), &now))
- {
-  y -= now.srWindow.Top;
-  x -= now.srWindow.Left;
- }
-      else
- {
-  syscall_printf ("mouse: cannot adjust position by scroll buffer offset");
-  continue;
- }
-
-      /* If the mouse event occurred out of the area we can handle,
- ignore it. */
-      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. */
       int b = 0;
       char sz[32];
-      if (mouse_event.dwButtonState == dev_state->dwLastButtonState)
- {
-  syscall_printf ("mouse: button state unchanged");
-  continue;
- }
-      else if (mouse_event.dwButtonState < dev_state->dwLastButtonState)
- {
-  b = 3;
-  strcpy (sz, "btn up");
- }
-      else if ((mouse_event.dwButtonState & 1) != (dev_state->dwLastButtonState & 1))
- {
-  b = 0;
-  strcpy (sz, "btn1 down");
- }
-      else if ((mouse_event.dwButtonState & 2) != (dev_state->dwLastButtonState & 2))
+
+      if (mouse_event.dwEventFlags == MOUSE_WHEELED)
  {
-  b = 2;
-  strcpy (sz, "btn2 down");
+  if (mouse_event.dwButtonState & 0xFF800000)
+    {
+      b = 0x41;
+      strcpy (sz, "wheel down");
+    }
+  else
+    {
+      b = 0x40;
+      strcpy (sz, "wheel up");
+    }
  }
-      else if ((mouse_event.dwButtonState & 4) != (dev_state->dwLastButtonState & 4))
+      else
  {
-  b = 1;
-  strcpy (sz, "btn3 down");
- }
+  /* Ignore unimportant mouse buttons */
+  mouse_event.dwButtonState &= 0x7;
 
-      /* Remember the current button state */
-      dev_state->dwLastButtonState = mouse_event.dwButtonState;
-
-      /* If a button was pressed, remember the modifiers */
-      if (b != 3)
- {
-  dev_state->nModifiers = 0;
-  if (mouse_event.dwControlKeyState & SHIFT_PRESSED)
-    dev_state->nModifiers |= 0x4;
-  if (mouse_event.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED))
-    dev_state->nModifiers |= 0x8;
-  if (mouse_event.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
-    dev_state->nModifiers |= 0x10;
- }
+  if (mouse_event.dwEventFlags == MOUSE_MOVED)
+    {
+      b = dev_state->last_button_code;
+    }
+  else if (mouse_event.dwButtonState < dev_state->dwLastButtonState)
+    {
+      b = 3;
+      strcpy (sz, "btn up");
+    }
+  else if ((mouse_event.dwButtonState & 1) != (dev_state->dwLastButtonState & 1))
+    {
+      b = 0;
+      strcpy (sz, "btn1 down");
+    }
+  else if ((mouse_event.dwButtonState & 2) != (dev_state->dwLastButtonState & 2))
+    {
+      b = 2;
+      strcpy (sz, "btn2 down");
+    }
+  else if ((mouse_event.dwButtonState & 4) != (dev_state->dwLastButtonState & 4))
+    {
+      b = 1;
+      strcpy (sz, "btn3 down");
+    }
+
+  dev_state->last_button_code = b;
+
+  if (mouse_event.dwEventFlags == MOUSE_MOVED)
+    {
+      b += 32;
+      strcpy (sz, "move");
+    }
+  else
+    {
+      /* Remember the modified button state */
+      dev_state->dwLastButtonState = mouse_event.dwButtonState;
+    }
+        }
+
+      /* Remember mouse position */
+      dev_state->dwLastMousePosition.X = dev_state->dwMousePosition.X;
+      dev_state->dwLastMousePosition.Y = dev_state->dwMousePosition.Y;
+
+      /* Remember the modifiers */
+      dev_state->nModifiers = 0;
+      if (mouse_event.dwControlKeyState & SHIFT_PRESSED)
+  dev_state->nModifiers |= 0x4;
+      if (mouse_event.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED))
+  dev_state->nModifiers |= 0x8;
+      if (mouse_event.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
+  dev_state->nModifiers |= 0x10;
 
+      /* Indicate the modifiers */
       b |= dev_state->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);
+      sprintf (tmp, "\033[M%c%c%c", b + ' ', dev_state->dwMousePosition.X + ' ' + 1, dev_state->dwMousePosition.Y + ' ' + 1);
+      syscall_printf ("mouse: %s at (%d,%d)", sz, dev_state->dwMousePosition.X, dev_state->dwMousePosition.Y);
 
       toadd = tmp;
       nread = 6;
     }
-  break;
+ }
+ break;
 
  case FOCUS_EVENT:
+  if (dev_state->use_focus) {
+    if (input_rec.Event.FocusEvent.bSetFocus)
+      sprintf (tmp, "\033[I");
+    else
+      sprintf (tmp, "\033[O");
+
+    toadd = tmp;
+    nread = 3;
+  }
+  break;
+
  case WINDOW_BUFFER_SIZE_EVENT:
   send_winch_maybe ();
   /* fall through */
@@ -1136,7 +1198,10 @@ fhandler_console::char_command (char c)
      case 1:    /* bold */
        dev_state->intensity = INTENSITY_BOLD;
        break;
-     case 4:
+     case 2:    /* dim */
+       dev_state->intensity = INTENSITY_DIM;
+       break;
+     case 4:    /* underlined */
        dev_state->underline = 1;
        break;
      case 5:    /* blink mode */
@@ -1148,18 +1213,22 @@ fhandler_console::char_command (char c)
      case 8:    /* invisible */
        dev_state->intensity = INTENSITY_INVISIBLE;
        break;
-     case 9:    /* dim */
-       dev_state->intensity = INTENSITY_DIM;
-       break;
      case 10:   /* end alternate charset */
        dev_state->alternate_charset_active = false;
        break;
      case 11:   /* start alternate charset */
        dev_state->alternate_charset_active = true;
        break;
+     case 22:
+     case 28:
+       dev_state->intensity = INTENSITY_NORMAL;
+       break;
      case 24:
        dev_state->underline = false;
        break;
+     case 25:
+       dev_state->blink = false;
+       break;
      case 27:
        dev_state->reverse = false;
        break;
@@ -1275,9 +1344,24 @@ fhandler_console::char_command (char c)
     }
   break;
 
- case 1000: /* Mouse support */
-  dev_state->use_mouse = (c == 'h') ? true : false;
-  syscall_printf ("mouse support %sabled", dev_state->use_mouse ? "en" : "dis");
+ case 1000: /* Mouse tracking */
+  dev_state->use_mouse = (c == 'h') ? 1 : 0;
+  syscall_printf ("mouse support set to mode %d", dev_state->use_mouse);
+  break;
+
+ case 1002: /* Mouse button event tracking */
+  dev_state->use_mouse = (c == 'h') ? 2 : 0;
+  syscall_printf ("mouse support set to mode %d", dev_state->use_mouse);
+  break;
+
+ case 1003: /* Mouse any event tracking */
+  dev_state->use_mouse = (c == 'h') ? 3 : 0;
+  syscall_printf ("mouse support set to mode %d", dev_state->use_mouse);
+  break;
+
+ case 1004: /* Focus in/out event reporting */
+  dev_state->use_focus = (c == 'h') ? true : false;
+  syscall_printf ("focus reporting set to %d", dev_state->use_focus);
   break;
 
  case 2000: /* Raw keyboard mode */
diff -rup cygwin-1.7.0-63-orig/winsup/cygwin/select.cc cygwin-1.7.0-63/winsup/cygwin/select.cc
--- cygwin-1.7.0-63-orig/winsup/cygwin/select.cc 2009-10-03 14:28:04.000000000 +0200
+++ cygwin-1.7.0-63/winsup/cygwin/select.cc 2009-10-24 02:30:14.000000000 +0200
@@ -823,9 +823,9 @@ peek_console (select_record *me, bool)
  else
   {
     if (irec.EventType == MOUSE_EVENT
- && fh->mouse_aware ()
- && (irec.Event.MouseEvent.dwEventFlags == 0
-    || irec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK))
+ && fh->mouse_aware (irec.Event.MouseEvent))
+ return me->read_ready = true;
+    if (irec.EventType == FOCUS_EVENT && fh->focus_aware ())
  return me->read_ready = true;
   }
 

Re: console enhancements: mouse events

by Corinna Vinschen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Nov  6 09:20, Thomas Wolff wrote:
> Hi,
> About enhancements of cygwin console features, I've now worked out a
> patch which does the following:

Thanks for the patch, it looks like a nice addition.

However, there's the problem of the copyright assignment.  As described
on the http://cygwin.com/contrib.html page, in the "Before you get
started" section, we can't take non-trivial patches without have a
signed copyright assignment form (http://cygwin.com/assign.txt) in place.

Usually it takes the time to snail-mail the assignment to California,
plus 3 or 4 days.  Sorry for the hassle, but it's legally necessary.

A few comments:

> * Implement additional mouse reporting modes 1002 and 1003 as known
>   from xterm and mintty; they report mouse move events.
> * Add detection and reporting of mouse scroll events to mouse reporting
>   mode 1000.
>   Note: This works on my home PC (Windows XP Home) but it's not effective
>   on my work PC (Windows XP Professional) where the mouse wheel scrolls the
>   Windows console (which it doesn't on the other machine); I don't know
>   how to disable or configure this.

Open the console properties dialog and disable QuickEdit.

> * Enforce consistence between select() and read() about whether mouse
>   reporting input is available by moving all checks into the common
>   function mouse_aware.
> * Add mouse focus reporting mode 1004 as known from xterm and mintty.
> * As a separate change, where I added the initialization of the additional
>   reporting modes, I also added and fixed some screen attribute modes as
>   known from the Linux console (and xterm):
>   - ESC[22m disable bold, ESC[28m disable invisible, ESC[25m disable blinking
>   - ESC[2m dim as usual on other terminals, instead of ESC[9m

For backward compatibility, I'd prefer if ESC[9m would still do the same.
As long as ESC[9m isn't desparately needed for something else...

> Some other console issues (not covered by this patch) are probably better
> discussed on cygwin-developers but maybe I can mention them here already:
> * Maybe the escape sequences of shifted function keys should be modified
>   to comply with those of the Linux console?

Aren't they compatible with xterm?  I don't think it's a terrible good
idea to change that.

> * I would like to fix some key assignments:
>   - Control-(Shift-)6 inputs Control-^ which is not proper on international
>     keyboards if Shift-6 is not "^", Control-^ (the key) does not input
>     Control-^ (the character) on the other hand; the same glitch
>     occurs in the pure Windows console, however.
>     Unfortunately, with the functions being used it is not possible to
>     detect that shifted key "^" was hit together with Control; only
>     keycodes/scancodes are available when Control/Shift/Alt are used. So
>     I don't know whether this can easily be fixed. It works in mintty but
>     I think mintty uses different Windows functions.

How do you enter any of the control chars ^^, ^\, ^[, ^], ^_ anyway?
In a CMD window using an english keyboard I can just enter any of them
using the control char,  C+S+6 = ^^, C+\ = ^\, C+[ = ^[, C+] = ^],
and C+S+- = ^_.  Same in a cygwin console.  The reason is that these
sequences return their ASCII value in the INPUT_RECORD in
Event.KeyEvent.uChar.

Except for one of them, this doesn't work with a german keyboard and
german keyboard layout.  In this case, the respective keysequences
C+^, C+AltGr+sz, C+AG+8, C+AG+9 return nothing at all.  Only the
C+S+- key returns ^_, as expected.

>   - Pressing something like Alt-ö on a German keyboard leaves an illegal UTF-8
>     sequence (the second byte of the respective sequence) in input, apparently
>     because Alt-0xC3 is handled somehow. Don't know, though, whether this is
>     a cygwin console issue or maybe a readline issue.

Alt is converted to a leading ESC.  I don't know how to fix that for
non-ASCII chars, yet.

> * I intended to implement cursor position reports and noticed that their
>   request ESC[6n is already handled in the code; it does not work, however,
>   so I started to debug it:

This needs some more debugging, I guess.


Thanks,
Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

Re: console enhancements: mouse events

by Andy Koppe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/11/6 Thomas Wolff:

> * I would like to fix some key assignments:
>  - Control-(Shift-)6 inputs Control-^ which is not proper on international
>    keyboards if Shift-6 is not "^", Control-^ (the key) does not input
>    Control-^ (the character) on the other hand; the same glitch
>    occurs in the pure Windows console, however.
>    Unfortunately, with the functions being used it is not possible to
>    detect that shifted key "^" was hit together with Control; only
>    keycodes/scancodes are available when Control/Shift/Alt are used. So
>    I don't know whether this can easily be fixed. It works in mintty but
>    I think mintty uses different Windows functions.

Mintty roughly does the following for Ctrl(+Shift)+symbol combinations:
- obtain the keymap using GetKeyboardState()
- set the state of the Ctrl key to released
- invoke ToUnicode() to get the character code according to the keyboard layout
- if the character code is one of [\]_^? send the corresponding control code
- otherwise, set the state of both Ctrl and Alt to pressed (this is
equivalent to AltGr), and try ToUnicode() again

The last step means that e.g. Ctrl+9 on a German keyboard will send
^]. The proper combination would be Ctrl+AltGr+9, but since
AltGr==Ctrl+Alt, that can't be distinguished from AltGr+9 without
Ctrl. (Well, not without somewhat dodgy trickery anyway.)

Btw, ^[, ^], and ^\ are actually available as Ctrl+ü, Ctrl+plus, and
Ctrl+# in the German keyboard layout, but those combinations make no
sense unless you're familiar with the US layout. It's similar with
many, but by no means all, other layouts. (Microsoft's Keyboard Layout
Creator is a good way to inspect different layouts.)

>  - Pressing something like Alt-ö on a German keyboard leaves an illegal UTF-8
>    sequence (the second byte of the respective sequence) in input, apparently
>    because Alt-0xC3 is handled somehow. Don't know, though, whether this is
>    a cygwin console issue or maybe a readline issue.

Readline issue. It's fine in zsh.

Andy

Re: console enhancements: mouse events

by Corinna Vinschen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Nov  6 21:55, Andy Koppe wrote:

> 2009/11/6 Thomas Wolff:
> > * I would like to fix some key assignments:
> >  - Control-(Shift-)6 inputs Control-^ which is not proper on international
> >    keyboards if Shift-6 is not "^", Control-^ (the key) does not input
> >    Control-^ (the character) on the other hand; the same glitch
> >    occurs in the pure Windows console, however.
> >    Unfortunately, with the functions being used it is not possible to
> >    detect that shifted key "^" was hit together with Control; only
> >    keycodes/scancodes are available when Control/Shift/Alt are used. So
> >    I don't know whether this can easily be fixed. It works in mintty but
> >    I think mintty uses different Windows functions.
>
> Mintty roughly does the following for Ctrl(+Shift)+symbol combinations:
> - obtain the keymap using GetKeyboardState()
> - set the state of the Ctrl key to released
> - invoke ToUnicode() to get the character code according to the keyboard layout
> - if the character code is one of [\]_^? send the corresponding control code
> - otherwise, set the state of both Ctrl and Alt to pressed (this is
> equivalent to AltGr), and try ToUnicode() again
>
> The last step means that e.g. Ctrl+9 on a German keyboard will send
> ^]. The proper combination would be Ctrl+AltGr+9, but since
> AltGr==Ctrl+Alt, that can't be distinguished from AltGr+9 without
> Ctrl. (Well, not without somewhat dodgy trickery anyway.)

How does that work for ^^?  The ^ key is a deadkey on the german keyboard
layout, so the actual char value is only generated after pressing the key
twice.  Just curious.

> Btw, ^[, ^], and ^\ are actually available as Ctrl+ü, Ctrl+plus, and
> Ctrl+# in the German keyboard layout, but those combinations make no
> sense unless you're familiar with the US layout.

Indeed.


Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

Re: console enhancements: mouse events

by Andy Koppe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/11/7 Corinna Vinschen:

>> Mintty roughly does the following for Ctrl(+Shift)+symbol combinations:
>> - obtain the keymap using GetKeyboardState()
>> - set the state of the Ctrl key to released
>> - invoke ToUnicode() to get the character code according to the keyboard layout
>> - if the character code is one of [\]_^? send the corresponding control code
>> - otherwise, set the state of both Ctrl and Alt to pressed (this is
>> equivalent to AltGr), and try ToUnicode() again
>>
>> The last step means that e.g. Ctrl+9 on a German keyboard will send
>> ^]. The proper combination would be Ctrl+AltGr+9, but since
>> AltGr==Ctrl+Alt, that can't be distinguished from AltGr+9 without
>> Ctrl. (Well, not without somewhat dodgy trickery anyway.)
>
> How does that work for ^^?  The ^ key is a deadkey on the german keyboard
> layout, so the actual char value is only generated after pressing the key
> twice.  Just curious.

ToUnicode actually delivers the ^ character right away when pressing
the key, but with return value -1 to signify that it's a dead key and
that the next key will be modified accordingly. So for Ctrl+^, mintty
sends ^^ right away and then clears the dead key state using a trick
picked up from http://blogs.msdn.com/michkap/archive/2006/04/06/569632.aspx:
feed VK_DECIMALs into ToUnicode until it stops returning dead-key
characters.

(Yep, it's a terrible API for an unintuitive feature. See also
http://blogs.msdn.com/michkap/archive/2005/01/19/355870.aspx)

Andy

Re: console enhancements: mouse events

by Thomas Wolff-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Corinna Vinschen schrieb:

> On Nov  6 09:20, Thomas Wolff wrote:
>  
>> Hi,
>> About enhancements of cygwin console features, I've now worked out a
>> patch which does the following:
>>    
>
> Thanks for the patch, it looks like a nice addition.
>
> However, there's the problem of the copyright assignment.  As described
> on the http://cygwin.com/contrib.html page, in the "Before you get
> started" section, we can't take non-trivial patches without have a
> signed copyright assignment form (http://cygwin.com/assign.txt) in place.
>  
It's in the envelope.

> A few comments:
>
>  
>> * Implement additional mouse reporting modes 1002 and 1003 as known
>>   from xterm and mintty; they report mouse move events.
>> * Add detection and reporting of mouse scroll events to mouse reporting
>>   mode 1000.
>>   Note: This works on my home PC (Windows XP Home) but it's not effective
>>   on my work PC (Windows XP Professional) where the mouse wheel scrolls the
>>   Windows console (which it doesn't on the other machine); I don't know
>>   how to disable or configure this.
>>    
> Open the console properties dialog and disable QuickEdit.
>  
I had checked the properties and nothing worked. QuickEdit enabled would
disable mouse control for applications altogether; it is disabled so
mouse click and move events can be processed but the mouse wheel still
scrolls the window instead, on that machine.

>> * Enforce consistence between select() and read() about whether mouse
>>   reporting input is available by moving all checks into the common
>>   function mouse_aware.
>> * Add mouse focus reporting mode 1004 as known from xterm and mintty.
>> * As a separate change, where I added the initialization of the additional
>>   reporting modes, I also added and fixed some screen attribute modes as
>>   known from the Linux console (and xterm):
>>   - ESC[22m disable bold, ESC[28m disable invisible, ESC[25m disable blinking
>>   - ESC[2m dim as usual on other terminals, instead of ESC[9m
>>    
> For backward compatibility, I'd prefer if ESC[9m would still do the same.
> As long as ESC[9m isn't desparately needed for something else...
>  
I thought there might be this objection as it is in theory an
incompatible change but it's not in practice since dim mode doesn't work
anyway; so I think this change towards the standard assignment should be
done before someone in the future may fix dim mode to work after which
it would actually be an incompatible change.

>> * Maybe the escape sequences of shifted function keys should be modified
>>   to comply with those of the Linux console?
>>    
> Aren't they compatible with xterm?  I don't think it's a terrible good
> idea to change that.
>  
No, they are not:

Linux console
F1..F12         ^[[[A ^[[[B ^[[[C ^[[[D ^[[[E ^[[17~ ^[[18~ ^[[19~
^[[20~ ^[[21~ ^[[23~ ^[[24~
shift-F1..F8    ^[[25~ ^[[26~ ^[[28~ ^[[29~ ^[[31~ ^[[32~ ^[[33~ ^[[34~

cygwin console
F1..F12         ^[[[A ^[[[B ^[[[C ^[[[D ^[[[E ^[[17~ ^[[18~ ^[[19~
^[[20~ ^[[21~ ^[[23~ ^[[24~
shift-F1..F10   ^[[23~ ^[[24~ ^[[25~ ^[[26~ ^[[28~ ^[[29~ ^[[31~ ^[[32~
^[[33~ ^[[34~

xterm, mintty
F1..F12         ^[OP ^[OQ ^[OR ^[OS ^[[15~ ^[[17~ ^[[18~ ^[[19~ ^[[20~
^[[21~ ^[[23~ ^[[24~
shift-F1..F12   ^[[1;2P ^[[1;2Q ^[[1;2R ^[[1;2S ^[[15;2~ ^[[17;2~
^[[18;2~ ^[[19;2~ ^[[20;2~ ^[[21;2~ ^[[23;2~ ^[[24;2~

Note the shift by 2 in the shifted F-keys from Linux console to cygwin
console which is quite confusing for any application that might want to
use them. Modified F-keys are indicated in a generic way by xterm and
mintty which is much more obvious for unique mapping to the keys and
which can be detected by applications in a generic way as well.
Furthermore, xterm and mintty also support Control- and Alt-modified
F-keys and combinations of the modifiers.
So if your preference would be to follow xterm here anyway, I would
welcome this change and provide a patch; I think this change can be done
without compatibility trouble in "mainstream applications" since the
shifted F-keys are not listed in the cygwin terminfo entry.

>> * I would like to fix some key assignments:
>>   - Control-(Shift-)6 inputs Control-^ which is not proper on international
>>     keyboards if Shift-6 is not "^", Control-^ (the key) does not input
>>     Control-^ (the character) on the other hand; the same glitch
>>     occurs in the pure Windows console, however.
>>     Unfortunately, with the functions being used it is not possible to
>>     detect that shifted key "^" was hit together with Control; only
>>     keycodes/scancodes are available when Control/Shift/Alt are used. So
>>     I don't know whether this can easily be fixed. It works in mintty but
>>     I think mintty uses different Windows functions.
>>    
> How do you enter any of the control chars ^^, ^\, ^[, ^], ^_ anyway?
> In a CMD window using an english keyboard I can just enter any of them
> using the control char,  C+S+6 = ^^, C+\ = ^\, C+[ = ^[, C+] = ^],
> and C+S+- = ^_.  Same in a cygwin console.  The reason is that these
> sequences return their ASCII value in the INPUT_RECORD in
> Event.KeyEvent.uChar.
>
> Except for one of them, this doesn't work with a german keyboard and
> german keyboard layout.  In this case, the respective keysequences
> C+^, C+AltGr+sz, C+AG+8, C+AG+9 return nothing at all.  Only the
> C+S+- key returns ^_, as expected.
>  
Thanks Andy for pointing to the part of mintty code handling this.
However, the whole function there looks too complex for a quick
copy-paste-patch. Maybe later... or Andy might like to factor out the
mapping part in a way directly reusable for the cygwin console? (Or
should it be left as is because it's "just the console"...?)

>>   - Pressing something like Alt-ö on a German keyboard leaves an illegal UTF-8
>>     sequence (the second byte of the respective sequence) in input, apparently
>>     because Alt-0xC3 is handled somehow. Don't know, though, whether this is
>>     a cygwin console issue or maybe a readline issue.
>>    
> Alt is converted to a leading ESC.  I don't know how to fix that for
> non-ASCII chars, yet.
>  
For non-ASCII it works fine, thanks to Andy for clarifying; I could have
checked this myself, even within bash, by simply typing Control-V Alt-ö.
It does not work however, even for ASCII characters, for characters
produced with AltGr, e.g. Alt-AltGr-Q where AltGr-Q is @ (German
keyboard). Andy got this to work in mintty (I think with some other
subtle trick after I challenged him for it IIRC); it does not work in
xterm either.

>> * I intended to implement cursor position reports and noticed that their
>>   request ESC[6n is already handled in the code; it does not work, however,
>>   so I started to debug it:
>>    
> This needs some more debugging, I guess.
>  
Do you have an opinion about my theory that the wrong read-ahead buffer
is being filled here (stdout vs. stdin)? If so, I still have no clue how
to proceed; maybe you'd kindly give a hint how to access the stdin
buffer / stdin fhandler?

Thanks,
Thomas

Re: console enhancements: mouse events

by Andy Koppe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thomas Wolff:
>>>  Note: This works on my home PC (Windows XP Home) but it's not effective
>>>  on my work PC (Windows XP Professional) where the mouse wheel scrolls the
>>>  Windows console (which it doesn't on the other machine); I don't know  how
>>> to disable or configure this.

I've come across a similar issue in mintty: on some machines, if the
scrollbar is enabled, mousewheel events never reach the window's event
loop. I never really got to the bottom of it, but I think it's to do
with mouse drivers: some appear to send mousewheel events straight to
a window's scrollbar if there is one, no matter where in the window
the mouse is positioned.

>> [Ctrl+AltGr+key stuff]

> Thanks Andy for pointing to the part of mintty code handling this. However,
> the whole function there looks too complex for a quick copy-paste-patch.

Nested functions, big switches, and even a couple of gotos, that
function has it all. ;)

> Maybe later... or Andy might like to factor out the mapping part in a way
> directly reusable for the cygwin console?

Erm, no. The crucial subfunction there is undead_keycode().

> It
> does not work however, even for ASCII characters, for characters produced
> with AltGr, e.g. Alt-AltGr-Q where AltGr-Q is @ (German keyboard). Andy got
> this to work in mintty (I think with some other subtle trick after I
> challenged him for it IIRC); it does not work in xterm either.

You can tell whether both Alt and AltGr are down by checking VK_LMENU
and VK_RMENU.

Andy

Re: console enhancements: mouse events

by Corinna Vinschen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Nov  8 23:02, towo@... wrote:
> Corinna Vinschen schrieb:
> >signed copyright assignment form (http://cygwin.com/assign.txt) in place.
> It's in the envelope.

Cool.

> >Open the console properties dialog and disable QuickEdit.
> I had checked the properties and nothing worked. QuickEdit enabled
> would disable mouse control for applications altogether; it is
> disabled so mouse click and move events can be processed but the
> mouse wheel still scrolls the window instead, on that machine.

Weird.  It works for me.  Andy seems to be right about drivers.  

> >For backward compatibility, I'd prefer if ESC[9m would still do the same.
> >As long as ESC[9m isn't desparately needed for something else...
> I thought there might be this objection as it is in theory an
> incompatible change but it's not in practice since dim mode doesn't
> work anyway; so I think this change towards the standard assignment
> should be done before someone in the future may fix dim mode to work
> after which it would actually be an incompatible change.
>
> >>* Maybe the escape sequences of shifted function keys should be
> >>modified   to comply with those of the Linux console?
> >Aren't they compatible with xterm?  I don't think it's a terrible good
> >idea to change that.
> No, they are not:
>
> Linux console
> F1..F12         ^[[[A ^[[[B ^[[[C ^[[[D ^[[[E ^[[17~ ^[[18~ ^[[19~
> ^[[20~ ^[[21~ ^[[23~ ^[[24~
> shift-F1..F8    ^[[25~ ^[[26~ ^[[28~ ^[[29~ ^[[31~ ^[[32~ ^[[33~ ^[[34~
>
> cygwin console
> F1..F12         ^[[[A ^[[[B ^[[[C ^[[[D ^[[[E ^[[17~ ^[[18~ ^[[19~
> ^[[20~ ^[[21~ ^[[23~ ^[[24~
> shift-F1..F10   ^[[23~ ^[[24~ ^[[25~ ^[[26~ ^[[28~ ^[[29~ ^[[31~
> ^[[32~ ^[[33~ ^[[34~
> [...]
>  Furthermore, xterm and mintty also support
> Control- and Alt-modified F-keys and combinations of the modifiers.
> So if your preference would be to follow xterm here anyway, I would
> welcome this change and provide a patch; I think this change can be
> done without compatibility trouble in "mainstream applications"
> since the shifted F-keys are not listed in the cygwin terminfo
> entry.

Ooookey, if they aren't listed in terminfo anyway, I have no problems
to change them.  But we should stick to following the Linux console,
I guess.

> >Except for one of them, this doesn't work with a german keyboard and
> >german keyboard layout.  In this case, the respective keysequences
> >C+^, C+AltGr+sz, C+AG+8, C+AG+9 return nothing at all.  Only the
> >C+S+- key returns ^_, as expected.
> Thanks Andy for pointing to the part of mintty code handling this.
> However, the whole function there looks too complex for a quick
> copy-paste-patch. Maybe later...

No copy-paste, please.  Mintty is under GPL, so we can't just take
the code, unless Andy gives us explicit permission to do so.

> or Andy might like to factor out
> the mapping part in a way directly reusable for the cygwin console?
> (Or should it be left as is because it's "just the console"...?)

Well, it works in some way.  I played around with ToUnicode over the
weekend, and I didn't get it working as expected.  Take, for instance,
this (simplified):

  if (input_rec.Event.KeyEvent.dwControlKeyState
      & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
    {
      GetKeyboardState (state);
      state[VK_CONTROL] = state[VK_LCONTROL] = state[VK_RCONTROL] = 0;
      if (ToUnicode (input_rec.Event.KeyEvent.wVirtualKeyCode,
                     input_rec.Event.KeyEvent.wVirtualScanCode,
                     state, wcbuf, 8, 0) > 0)
      switch (wcbuf[0])
          {
          case L'[' ... L'_':
            got_one = true;
            break;
          [...]
          }
      [...]

When I pressed Strg-^ on a german keyboard layout (left of the "1"
key), I constantly got Ctrl-\ instead of Ctrl-^.  Weird.

> >>  - Pressing something like Alt-ö on a German keyboard leaves an
> >>illegal UTF-8     sequence (the second byte of the respective
> >>sequence) in input, apparently     because Alt-0xC3 is handled
> >>somehow. Don't know, though, whether this is     a cygwin
> >>console issue or maybe a readline issue.
> >Alt is converted to a leading ESC.  I don't know how to fix that for
> >non-ASCII chars, yet.
> For non-ASCII it works fine, thanks to Andy for clarifying; I could

Erm... sorry, but do we really talk about the same?  If you press
Alt-ö, the console generates the sequence ESC 0xc3 0xb6.  That's not
desired so I'm contemplating the idea to skip the keypress if the
resulting multibyte char is > 1 byte.  This restricts ESC-somekey
either to explicit function key sequences (ESC-[-foo, etc), or
to just two byte sequences like ESC-A, ESC-0, ESC-;, etc.

> have checked this myself, even within bash, by simply typing
> Control-V Alt-ö. It does not work however, even for ASCII
> characters, for characters produced with AltGr, e.g. Alt-AltGr-Q
> where AltGr-Q is @ (German keyboard). Andy got this to work in
> mintty (I think with some other subtle trick after I challenged him
> for it IIRC); it does not work in xterm either.

That's potentially too tricky for the current code.  And, whatever
super-duper change we make to this essential console code in future,
let's wait until after 1.7.1, please.

> >>* I intended to implement cursor position reports and noticed
> >>that their   request ESC[6n is already handled in the code; it
> >>does not work, however,   so I started to debug it:
> >This needs some more debugging, I guess.
> Do you have an opinion about my theory that the wrong read-ahead
> buffer is being filled here (stdout vs. stdin)? If so, I still have
> no clue how to proceed; maybe you'd kindly give a hint how to access
> the stdin buffer / stdin fhandler?

I have no opinion yet, since I don't know this part of the code good
enough.  IIUC you think that the readahead buffer of the wrong
fhandle_console is filled, the one connected with stdout, not the
one connected with stdin, right?


Corinna


--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

Re: console enhancements: mouse events

by Christopher Faylor-8 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Nov 09, 2009 at 02:35:51PM +0100, Corinna Vinschen wrote:
>On Nov 8 23:02, towo@... wrote:
>>Corinna Vinschen schrieb:
>Ooookey, if they aren't listed in terminfo anyway, I have no problems
>to change them.  But we should stick to following the Linux console, I
>guess.

I agree.  I'm surprised that we've had the function keys wrong all these
years.

>>>>* I intended to implement cursor position reports and noticed that
>>>>their request ESC[6n is already handled in the code; it does not work,
>>>>however, so I started to debug it:
>>>This needs some more debugging, I guess.
>>Do you have an opinion about my theory that the wrong read-ahead buffer
>>is being filled here (stdout vs.  stdin)?  If so, I still have no clue
>>how to proceed; maybe you'd kindly give a hint how to access the stdin
>>buffer / stdin fhandler?
>
>I have no opinion yet, since I don't know this part of the code good
>enough.  IIUC you think that the readahead buffer of the wrong
>fhandle_console is filled, the one connected with stdout, not the one
>connected with stdin, right?

I'm still struggling to understand what a "stdout read-ahead buffer"
might be.  Could you point to the place in the code where you see the
problem?

cgf

Re: console enhancements: mouse events

by Corinna Vinschen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Nov  9 09:54, Christopher Faylor wrote:

> On Mon, Nov 09, 2009 at 02:35:51PM +0100, Corinna Vinschen wrote:
> >On Nov 8 23:02, towo@... wrote:
> >>Corinna Vinschen schrieb:
> >Ooookey, if they aren't listed in terminfo anyway, I have no problems
> >to change them.  But we should stick to following the Linux console, I
> >guess.
>
> I agree.  I'm surprised that we've had the function keys wrong all these
> years.
>
> >>>>* I intended to implement cursor position reports and noticed that
> >>>>their request ESC[6n is already handled in the code; it does not work,
> >>>>however, so I started to debug it:
> >>>This needs some more debugging, I guess.
> >>Do you have an opinion about my theory that the wrong read-ahead buffer
> >>is being filled here (stdout vs.  stdin)?  If so, I still have no clue
> >>how to proceed; maybe you'd kindly give a hint how to access the stdin
> >>buffer / stdin fhandler?
> >
> >I have no opinion yet, since I don't know this part of the code good
> >enough.  IIUC you think that the readahead buffer of the wrong
> >fhandle_console is filled, the one connected with stdout, not the one
> >connected with stdin, right?
>
> I'm still struggling to understand what a "stdout read-ahead buffer"
> might be.  Could you point to the place in the code where you see the
> problem?

As far as I understand it:

  Application writes ESC [ 6 n to stdout which is connected to one
  fhandler_console.  Cygwin creates the reply and copies it into the
  readahead buffer of this very fhandler_console.  But that's not the
  same fhandler_console which is connected to stdin, which is the
  fhandler the application reads the reply from.  So the reply never
  makes it to the application.


Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

Re: console enhancements: mouse events

by Thomas Wolff-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Corinna Vinschen schrieb:

> On Nov  9 09:54, Christopher Faylor wrote:
>  
>> On Mon, Nov 09, 2009 at 02:35:51PM +0100, Corinna Vinschen wrote:
>>    
>>> On Nov 8 23:02, towo@... wrote:
>>>      
>>>> Corinna Vinschen schrieb:
>>>>        
>>> Ooookey, if they aren't listed in terminfo anyway, I have no problems
>>> to change them.  But we should stick to following the Linux console, I
>>> guess.
>>>      
>> I agree.  I'm surprised that we've had the function keys wrong all these
>> years.
>>
>>    
>>>>>> * I intended to implement cursor position reports and noticed that
>>>>>> their request ESC[6n is already handled in the code; it does not work,
>>>>>> however, so I started to debug it:
>>>>>>            
>>>>> This needs some more debugging, I guess.
>>>>>          
>>>> Do you have an opinion about my theory that the wrong read-ahead buffer
>>>> is being filled here (stdout vs.  stdin)?  If so, I still have no clue
>>>> how to proceed; maybe you'd kindly give a hint how to access the stdin
>>>> buffer / stdin fhandler?
>>>>        
>>> I have no opinion yet, since I don't know this part of the code good
>>> enough.  IIUC you think that the readahead buffer of the wrong
>>> fhandle_console is filled, the one connected with stdout, not the one
>>> connected with stdin, right?
>>>      
>> I'm still struggling to understand what a "stdout read-ahead buffer"
>> might be.  Could you point to the place in the code where you see the
>> problem?
>>    
>
> As far as I understand it:
>
>   Application writes ESC [ 6 n to stdout which is connected to one
>   fhandler_console.  Cygwin creates the reply and copies it into the
>  
Yes, see fhandler_console::char_command, case 'n', small_sprintf, then
puts_readahead (buf);
>   readahead buffer of this very fhandler_console.
Yes, I traced ralen and raixput in fhandler_base::put_readahead (in
fhandler.cc) and could watch the buffer being filled with e.g. 7 bytes.
>   But that's not the
>   same fhandler_console which is connected to stdin, which is the
>   fhandler the application reads the reply from.
I also traced ralen and raixget in fhandler_base::get_readahead and saw
the buffer empty immediately after the filling with 7 bytes;
I had also traced other places where ralen could be reset, with no
occurrence logged between the two traces mentioned.
>   So the reply never
>   makes it to the application.
>  
Thomas

Re: console enhancements: mouse events

by Thomas Wolff-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Corinna Vinschen schrieb:

>>>>  - Pressing something like Alt-ö on a German keyboard leaves an
>>>> illegal UTF-8     sequence (the second byte of the respective
>>>> sequence) in input, apparently     because Alt-0xC3 is handled
>>>> somehow. Don't know, though, whether this is     a cygwin
>>>> console issue or maybe a readline issue.
>>>>        
>>> Alt is converted to a leading ESC.  I don't know how to fix that for
>>> non-ASCII chars, yet.
>>>      
>> For non-ASCII it works fine, thanks to Andy for clarifying; I could
>>    
>
> Erm... sorry, but do we really talk about the same?  If you press
> Alt-ö, the console generates the sequence ESC 0xc3 0xb6.  That's not
> desired so I'm contemplating the idea to skip the keypress if the
> resulting multibyte char is > 1 byte.  This restricts ESC-somekey
> either to explicit function key sequences (ESC-[-foo, etc), or
> to just two byte sequences like ESC-A, ESC-0, ESC-;, etc.
>  
I had not expected you to take action on this issue so soon:
> - Don't create ESC sequences for ALT-key keypresses if key translates
>   into a multibyte sequence.  This avoids stray bytes in input when
>   pressing for instance ALT-ö (Umlaut-o) under UTF-8.
>  
- especially given:
> ...  And, whatever
> super-duper change we make to this essential console code in future,
> let's wait until after 1.7.1, please.
>  
Actually, I think this is the wrong change. I'm sorry I came up with
this confusion because I didn't test sufficiently, but as I said in my
second mail
> For non-ASCII it works fine,
and contemplating again
> If you press Alt-ö, the console generates the sequence ESC 0xc3 0xb6.
I think this is absolutely the right thing to generate - after all, what
else should be expected here?
The "stray bytes" are created in bash/readline, the previous behavior of
cygwin console in this case was perfect, I'd suggest to revert, please.

Thomas

Re: console enhancements: mouse events

by Corinna Vinschen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Nov 10 17:47, Thomas Wolff wrote:
> Corinna Vinschen schrieb:
> I had not expected you to take action on this issue so soon:
> >- Don't create ESC sequences for ALT-key keypresses if key translates
> >  into a multibyte sequence.  This avoids stray bytes in input when
> >  pressing for instance ALT-ö (Umlaut-o) under UTF-8.

I applied the change already an hour before your mail from yesterday.
It makes a lot of sense to subscribe to the cygwin-cvs mailing list,
since you see immediately what has happened in the repository.

> - especially given:
> >...  And, whatever
> >super-duper change we make to this essential console code in future,
> >let's wait until after 1.7.1, please.

Well, it wasn't exactly a super-duper change, rather something I thought
of as a bugfix.

> Actually, I think this is the wrong change. I'm sorry I came up with
> this confusion because I didn't test sufficiently, but as I said in
> my second mail
> >For non-ASCII it works fine,
> and contemplating again
> >If you press Alt-ö, the console generates the sequence ESC 0xc3 0xb6.
> I think this is absolutely the right thing to generate - after all,
> what else should be expected here?
> The "stray bytes" are created in bash/readline, the previous
> behavior of cygwin console in this case was perfect, I'd suggest to
> revert, please.

I was just going to refuse your request, when I had this really spooky
idea of actually *testing* this in an xterm running under Linux.  And,
what shall I say?  Xterm creates the same ESC 0xc3 0xb6 sequence when
pressing Alt-ö.  I'll revert the change.  Note to self: "Testing doesn't
hurt".


Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

Re: console enhancements: mouse events

by Thomas Wolff-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Corinna Vinschen wrote:

>>>> * Maybe the escape sequences of shifted function keys should be
>>>> modified   to comply with those of the Linux console?
>>>>        
>>> Aren't they compatible with xterm?  I don't think it's a terrible good
>>> idea to change that.
>>>      
>> No, they are not:
>>
>> Linux console
>> F1..F12         ^[[[A ^[[[B ^[[[C ^[[[D ^[[[E ^[[17~ ^[[18~ ^[[19~
>> ^[[20~ ^[[21~ ^[[23~ ^[[24~
>> shift-F1..F8    ^[[25~ ^[[26~ ^[[28~ ^[[29~ ^[[31~ ^[[32~ ^[[33~ ^[[34~
>>
>> cygwin console
>> F1..F12         ^[[[A ^[[[B ^[[[C ^[[[D ^[[[E ^[[17~ ^[[18~ ^[[19~
>> ^[[20~ ^[[21~ ^[[23~ ^[[24~
>> shift-F1..F10   ^[[23~ ^[[24~ ^[[25~ ^[[26~ ^[[28~ ^[[29~ ^[[31~
>> ^[[32~ ^[[33~ ^[[34~
>> [...]
>>  Furthermore, xterm and mintty also support
>> Control- and Alt-modified F-keys and combinations of the modifiers.
>> So if your preference would be to follow xterm here anyway, I would
>> welcome this change and provide a patch; I think this change can be
>> done without compatibility trouble in "mainstream applications"
>> since the shifted F-keys are not listed in the cygwin terminfo
>> entry.
>>    
> Ooookey, if they aren't listed in terminfo anyway, I have no problems
> to change them.  But we should stick to following the Linux console,
> I guess.
>  
Well, cygwin console is actually following rxvt and VT220 here (which I
should have included in my survey for completeness), while Linux console
is deviating from VT220, so there is at least some kind of consistence
in the cygwin console. (Contemplating that rxvt and VT220 are both
abandonware...)
If you don't like my suggestion to switch to the unanbigous sequences of
xterm and mintty (still my favorite), I'll not pursue this issue further
because I don't want to be blamed for potential confusion of a
"shift-by-2" change. It would still be an option to fill the unmapped
combinations (esp. with Ctrl and Alt), in that case probably in the
style of rxvt.


About the Alt-AltGr issue (which is orthogonal to the previous
Alt-non-ASCII issue):
>> ... e.g. Alt-AltGr-Q where AltGr-Q is @ (German keyboard).
>> ...; it does not work in xterm either.
>>    
(which isn't quite true; it works with the resource metaSendsEscape: true)

- I found a very simple patch, just one additional line (the third below):
              meta = (control_key_state & ALT_PRESSED) != 0
                     && ((control_key_state & CTRL_PRESSED) == 0
                         || (control_key_state & ALT_PRESSED) == ALT_PRESSED
                         || (wch <= 0x1f || wch == 0x7f));

and Alt-AltGr-Q delivers ESC @ as expected (German keyboard, AltGr-Q = @).

> That's potentially too tricky for the current code.  And, whatever
> super-duper change we make to this essential console code in future,
> let's wait until after 1.7.1, please.
>  
Thanks Andy for previous hints that enabled me find the solution,
otherwise it would have been too tricky; the actual solution isn't.
Changes about the basic Ctrl-key layout for international keyboards are
more super-duper apparently and will have to wait.

Thomas

Re: console enhancements: mouse events

by Corinna Vinschen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Tom,

On Nov  8 23:02, towo@... wrote:

> Corinna Vinschen schrieb:
> >On Nov  6 09:20, Thomas Wolff wrote:
> >>Hi,
> >>About enhancements of cygwin console features, I've now worked
> >>out a patch which does the following:
> >
> >Thanks for the patch, it looks like a nice addition.
> >
> >However, there's the problem of the copyright assignment.  As described
> >on the http://cygwin.com/contrib.html page, in the "Before you get
> >started" section, we can't take non-trivial patches without have a
> >signed copyright assignment form (http://cygwin.com/assign.txt) in place.
> It's in the envelope.

Your copyright assignment has been countersigned and we're ready to
go.  Could you please resend the latest version of your patch so we
can have another look into it?


Thanks,
Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

Re: console enhancements: mouse events

by Christopher Faylor-8 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Nov 19, 2009 at 04:26:32PM +0100, Corinna Vinschen wrote:

>Tom,
>
>On Nov  8 23:02, towo@... wrote:
>> Corinna Vinschen schrieb:
>> >On Nov  6 09:20, Thomas Wolff wrote:
>> >>Hi,
>> >>About enhancements of cygwin console features, I've now worked
>> >>out a patch which does the following:
>> >
>> >Thanks for the patch, it looks like a nice addition.
>> >
>> >However, there's the problem of the copyright assignment.  As described
>> >on the http://cygwin.com/contrib.html page, in the "Before you get
>> >started" section, we can't take non-trivial patches without have a
>> >signed copyright assignment form (http://cygwin.com/assign.txt) in place.
>> It's in the envelope.
>
>Your copyright assignment has been countersigned and we're ready to
>go.  Could you please resend the latest version of your patch so we
>can have another look into it?

Can we hold of on applying this until after 1.7 is released?

cgf

Re: console enhancements: mouse events

by Corinna Vinschen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Nov 19 11:00, Christopher Faylor wrote:

> On Thu, Nov 19, 2009 at 04:26:32PM +0100, Corinna Vinschen wrote:
> >Tom,
> >
> >On Nov  8 23:02, towo@... wrote:
> >> Corinna Vinschen schrieb:
> >> >On Nov  6 09:20, Thomas Wolff wrote:
> >> >>Hi,
> >> >>About enhancements of cygwin console features, I've now worked
> >> >>out a patch which does the following:
> >> >
> >> >Thanks for the patch, it looks like a nice addition.
> >> >
> >> >However, there's the problem of the copyright assignment.  As described
> >> >on the http://cygwin.com/contrib.html page, in the "Before you get
> >> >started" section, we can't take non-trivial patches without have a
> >> >signed copyright assignment form (http://cygwin.com/assign.txt) in place.
> >> It's in the envelope.
> >
> >Your copyright assignment has been countersigned and we're ready to
> >go.  Could you please resend the latest version of your patch so we
> >can have another look into it?
>
> Can we hold of on applying this until after 1.7 is released?

Yeah, maybe we really should do that for now.  Except for the
ESC9m -> ESC2m change, maybe...


Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

Re: console enhancements: mouse events etc

by Thomas Wolff-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Corinna Vinschen wrote:
> Could you please resend the latest version of your patch so we
> can have another look into it?
This is my updated and extended patch for a number of console enhancements.
> Christopher Faylor wrote:
>  
>> Can we hold of on applying this until after 1.7 is released?
>>    
Sure, feel free to apply when suitable. I just happened to work on it
around this time...
> Yeah, maybe we really should do that for now.  Except for the
> ESC9m -> ESC2m change, maybe...
>  
If you want a subset of the features sooner than others, I may split the
patch.


------------------------------------------------------------------------

The patch contains the following enhancements, all intended to increase
compatibility with xterm and mintty (or rxvt in the case of modified
function keys as it was desired to stay compatible with the linux console):

* Additional event reporting as described before:
  - Report mouse wheel scrolling in mode 1000.
  - Report mouse movement in new modes 1002 and 1003.
  - Report focus events in new mode 1004.
* Add and fix a few rarely used screen attributes as described before.
* Enable ESC prefixing for Alt-AltGr keys, so that e.g. Alt-@ works on
keyboards where @ is AltGr-q.
* Extend escape sequences for modified function keys to indicate all
combinations of Ctrl, Shift, Alt, using the rxvt codes.
* Extend escape sequences for modified keypad keys to indicate all
combinations of Ctrl, Shift, Alt, following the xterm/mintty convention
for Ctrl and Shift, and the rxvt/linux convention for Alt, to reach
maximum compatibility.
  Note that Alt handling interfers with the Windows-style Alt-numeric
character input method but it did so before already, so I didn't break
anything. However, if that method is desired to work, I would modify my
patch accordingly.
* Add VT100 graphics mode. It remaps small ASCII letters to line drawing
graphics and is enabled / disabled in either of two ways:
        \033(0 jklmntuvwx \033(B
        \016 jklmntuvwx \017
  where the latter mode would normally be enabled with \033)0 but this
is not required by my implementation (nor by mlterm); if guarding it by
the enabling sequence is desired, I can easily add that.
* Fix cursor position reports and terminal status reports to work. Add
"Secondary Device Attribute" report option to the latter.
  I implemented this with an additional static readahead buffer local to
fhandler_console because the fhandler_base object buffer did not work as
I described before.
  Side remark: While implementing this, I noticed that cygwin creates 37
fhandler_console objects which I think is quite weird and probably not
intended. Stdin is associated with object # 7 and stdout is always
associated with the last one. Whenever bash redirects output to stderr,
3 new objects are created.

There is only one feature missing now which I may try to implement later:
* Fix control-character mappings (for non-letter controls) on
international keyboards.

Thomas

diff -rup cygwin-1.7.0-68.orig/winsup/cygwin/ChangeLog cygwin-1.7.0-68/winsup/cygwin/ChangeLog
--- cygwin-1.7.0-68.orig/winsup/cygwin/ChangeLog 2009-12-04 16:53:56.000000000 +0100
+++ cygwin-1.7.0-68/winsup/cygwin/ChangeLog 2009-12-05 14:02:42.000000000 +0100
@@ -1,3 +1,76 @@
+2009-12-04  Thomas Wolff  <towo@...>
+
+ * fhandler_console.cc (write): Detect ">" while parsing ESC [
+ sequences to distinguish specific requests.
+ (char_command): Distinguish Secondary from Primary Device Attribute
+ request to report more details about cygwin console terminal version.
+ * fhandler.h: Flag to note ">" in ESC [ sequences.
+
+2009-12-04  Thomas Wolff  <towo@...>
+
+ * fhandler_console.cc (c_rabuf, c_puts_readahead, c_peek_readahead,
+ c_get_readahead_into_buffer): Static readahead buffer specific
+ for fhandler_console (independent from fhandler_base buffer)
+ to fix terminal status requests / escape sequence reporting.
+ (read): Check c_rabuf to deliver status report strings.
+ * select.cc (peek_console): Check peek_c_readahead() to detect
+ console terminal reports.
+
+2009-12-04  Thomas Wolff  <towo@...>
+
+ * fhandler_console.cc (read): Allow combined Alt-AltGr modifiers
+ to also produce an ESC prefix like a plain Alt modifier, e.g. to make
+ Alt-@ work on a keyboard where @ is AltGr-q.
+
+2009-12-04  Thomas Wolff  <towo@...>
+
+ * fhandler_console.cc (get_nonascii_key): Generate ESC prefix
+ for Alt modifier generically for function keys and keypad keys.
+ (keytable): Add escape sequences for remaining modified function keys as
+ a compatible extension using rxvt escape codes.
+ Also distinguish keypad keys modified with Ctrl, Shift, Ctrl-Shift using
+ xterm-style modifier coding.
+
+2009-12-04  Thomas Wolff  <towo@...>
+
+ * fhandler_console.cc (__vt100_conv): Table to transform small ASCII
+ letters to line drawing graphics for use in VT100 graphics mode.
+ (write_console): Check for VT100 graphics mode and transform wide
+ characters in ASCII small letter range to corresponding graphics.
+ (write_normal): Check for SO/SI control characters to
+ enable/disable VT100 graphics mode.
+ (base_chars): Enable SO/SI control characters for detection.
+ (write): Check for ESC ( 0 / ESC ( B escape sequences to
+ enable/disable VT100 graphics mode.
+ * fhandler.h: New flag vt100_graphics_mode_active, state value
+ gotparen to parse ESC ( escape sequences.
+
+2009-12-04  Thomas Wolff  <towo@...>
+
+ * fhandler_console.cc (read): Detect and handle mouse wheel scrolling
+ events (for completion of mouse reporting mode 1000) and mouse
+ movement events (for additional mouse reporting modes 1002 and 1003).
+ Use mouse_aware() as a guard and only condition for mouse
+ reporting in order to enforce consistence of read() and select().
+ Add focus reports (for additional focus reporting mode 1004).
+ (mouse_aware): Enable detection of additional mouse events for select.
+ Tune function to precisely match actual reporting criteria.
+ Move adjustment of mouse position (by window scroll offset)
+ here to avoid duplicate code.
+ (char_command): Initialization of enhanced mouse reporting modes.
+ Initialization of focus reports.
+ * fhandler.h (use_mouse): Flag for additional mouse modes (bool->int).
+ (mouse_aware): Move enhanced function into fhandler_console.cc.
+ * select.cc (peek_console): Use modified mouse_aware() for more
+ general detection of mouse events. Also check for focus reports.
+
+2009-12-04  Thomas Wolff  <towo@...>
+
+ * fhandler_console.cc (char_command): Fix code to select dim mode
+ to usual 2 (not leaving previous 9 for compatibility because it
+ doesn't work anyway); also add entries for mode 22 (normal, not bold)
+ 28 (visible, not invisible), 25 (not blinking).
+
 2009-12-02  Corinna Vinschen  <corinna@...>
 
  * fhandler_socket.cc (send_internal): Don't split datagram messages
diff -rup cygwin-1.7.0-68.orig/winsup/cygwin/fhandler.h cygwin-1.7.0-68/winsup/cygwin/fhandler.h
--- cygwin-1.7.0-68.orig/winsup/cygwin/fhandler.h 2009-11-19 09:55:58.000000000 +0100
+++ cygwin-1.7.0-68/winsup/cygwin/fhandler.h 2009-12-04 17:45:02.000000000 +0100
@@ -889,6 +889,8 @@ enum ansi_intensity
 #define gotcommand 5
 #define gettitle 6
 #define eattitle 7
+#define gotparen 8
+#define gotrparen 9
 #define MAXARGS 10
 
 class dev_console
@@ -904,6 +906,8 @@ class dev_console
   int nargs_;
   unsigned rarg;
   bool saw_question_mark;
+  bool saw_greater_than_sign;
+  bool vt100_graphics_mode_active;
   bool alternate_charset_active;
   bool metabit;
 
@@ -936,11 +940,15 @@ class dev_console
     } info;
 
   COORD dwLastCursorPosition;
-  DWORD dwLastButtonState;
+  COORD dwMousePosition; /* scroll-adjusted coord of mouse event */
+  COORD dwLastMousePosition; /* scroll-adjusted coord of previous mouse event */
+  DWORD dwLastButtonState; /* (not noting mouse wheel events) */
+  int last_button_code; /* transformed mouse report button code */
   int nModifiers;
 
   bool insert_mode;
-  bool use_mouse;
+  int use_mouse;
+  bool use_focus;
   bool raw_win32_keyboard_mode;
 
   inline UINT get_console_cp ();
@@ -1012,7 +1020,8 @@ class fhandler_console: public fhandler_
 
   int ioctl (unsigned int cmd, void *);
   int init (HANDLE, DWORD, mode_t);
-  bool mouse_aware () {return dev_state->use_mouse;}
+  bool mouse_aware (MOUSE_EVENT_RECORD& mouse_event);
+  bool focus_aware () {return dev_state->use_focus;}
 
   select_record *select_read (select_stuff *);
   select_record *select_write (select_stuff *);
diff -rup cygwin-1.7.0-68.orig/winsup/cygwin/fhandler_console.cc cygwin-1.7.0-68/winsup/cygwin/fhandler_console.cc
--- cygwin-1.7.0-68.orig/winsup/cygwin/fhandler_console.cc 2009-11-19 09:55:58.000000000 +0100
+++ cygwin-1.7.0-68/winsup/cygwin/fhandler_console.cc 2009-12-04 18:03:56.000000000 +0100
@@ -100,6 +100,10 @@ fhandler_console::get_tty_stuff (int fla
       dev_state->scroll_region.Bottom = -1;
       dev_state->dwLastCursorPosition.X = -1;
       dev_state->dwLastCursorPosition.Y = -1;
+      dev_state->dwLastMousePosition.X = -1;
+      dev_state->dwLastMousePosition.Y = -1;
+      dev_state->dwLastButtonState = 0; /* none pressed */
+      dev_state->last_button_code = 3; /* released */
       dev_state->underline_color = FOREGROUND_GREEN | FOREGROUND_BLUE;
       dev_state->dim_color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
       dev_state->meta_mask = LEFT_ALT_PRESSED;
@@ -206,6 +210,78 @@ fhandler_console::send_winch_maybe ()
     }
 }
 
+/* Check whether a mouse event is to be reported as an escape sequence */
+bool
+fhandler_console::mouse_aware (MOUSE_EVENT_RECORD& mouse_event)
+{
+  if (! dev_state->use_mouse)
+    return 0;
+
+  /* Adjust mouse position by window scroll buffer offset
+     and remember adjusted position in state for use by read() */
+  CONSOLE_SCREEN_BUFFER_INFO now;
+  if (GetConsoleScreenBufferInfo (get_output_handle (), &now))
+    {
+      dev_state->dwMousePosition.X = mouse_event.dwMousePosition.X - now.srWindow.Left;
+      dev_state->dwMousePosition.Y = mouse_event.dwMousePosition.Y - now.srWindow.Top;
+    }
+  else
+    {
+      /* Cannot adjust position by window scroll buffer offset */
+      return 0;
+    }
+
+  /* Check whether adjusted mouse position can be reported */
+  if (dev_state->dwMousePosition.X > 0xFF - ' ' - 1
+      || dev_state->dwMousePosition.Y > 0xFF - ' ' - 1)
+    {
+      /* Mouse position out of reporting range */
+      return 0;
+    }
+
+  return ((mouse_event.dwEventFlags == 0 || mouse_event.dwEventFlags == DOUBLE_CLICK)
+  && mouse_event.dwButtonState != dev_state->dwLastButtonState)
+ || mouse_event.dwEventFlags == MOUSE_WHEELED
+ || (mouse_event.dwEventFlags == MOUSE_MOVED
+     && (dev_state->dwMousePosition.X != dev_state->dwLastMousePosition.X
+         || dev_state->dwMousePosition.Y != dev_state->dwLastMousePosition.Y)
+     && ((dev_state->use_mouse >= 2 && mouse_event.dwButtonState)
+         || dev_state->use_mouse >= 3));
+}
+
+static char c_rabuf[40];
+static char * c_rabufpoi = 0;
+
+static void
+c_puts_readahead (char *buf)
+{
+  strcpy (c_rabuf, buf);
+  c_rabufpoi = c_rabuf;
+}
+
+static int
+c_get_readahead_into_buffer (char *buf, size_t buflen)
+{
+  int copied_chars = 0;
+
+  while (buflen && c_rabufpoi && *c_rabufpoi)
+    {
+ buf[copied_chars++] = (unsigned char) (*c_rabufpoi++ & 0xff);
+ buflen--;
+    }
+
+  return copied_chars;
+}
+
+int
+c_peek_readahead ()
+{
+  if (c_rabufpoi)
+    return (unsigned char) *c_rabufpoi;
+  else
+    return -1;
+}
+
 void __stdcall
 fhandler_console::read (void *pv, size_t& buflen)
 {
@@ -216,7 +292,11 @@ fhandler_console::read (void *pv, size_t
   int ch;
   set_input_state ();
 
-  int copied_chars = get_readahead_into_buffer (buf, buflen);
+  int copied_chars = c_get_readahead_into_buffer (buf, buflen);
+  if (!copied_chars)
+    {
+      copied_chars = get_readahead_into_buffer (buf, buflen);
+    }
 
   if (copied_chars)
     {
@@ -362,9 +442,12 @@ fhandler_console::read (void *pv, size_t
       /* Determine if the keystroke is modified by META.  The tricky
  part is to distinguish whether the right Alt key should be
  recognized as Alt, or as AltGr. */
-      bool meta;
-      meta = (control_key_state & ALT_PRESSED) != 0
+      bool meta =
+     /* Alt but not AltGr (= left ctrl + right alt)? */
+     (control_key_state & ALT_PRESSED) != 0
      && ((control_key_state & CTRL_PRESSED) == 0
+    /* but also allow Alt-AltGr: */
+ || (control_key_state & ALT_PRESSED) == ALT_PRESSED
  || (wch <= 0x1f || wch == 0x7f));
       if (!meta)
  {
@@ -400,10 +483,18 @@ fhandler_console::read (void *pv, size_t
   break;
 
  case MOUSE_EVENT:
-  send_winch_maybe ();
-  if (dev_state->use_mouse)
+ send_winch_maybe ();
+ {
+  MOUSE_EVENT_RECORD& mouse_event = input_rec.Event.MouseEvent;
+  /* As a unique guard for mouse report generation,
+     call mouse_aware() which is common with select(), so the result
+     of select() and the actual read() will be consistent on the
+     issue of whether input (i.e. a mouse escape sequence) will
+     be available or not */
+  if (mouse_aware (mouse_event))
     {
-      MOUSE_EVENT_RECORD& mouse_event = input_rec.Event.MouseEvent;
+      /* Note: Reported mouse position was already retrieved by
+         mouse_aware() and adjusted by window scroll buffer offset */
 
       /* Treat the double-click event like a regular button press */
       if (mouse_event.dwEventFlags == DOUBLE_CLICK)
@@ -412,95 +503,106 @@ fhandler_console::read (void *pv, size_t
   mouse_event.dwEventFlags = 0;
  }
 
-      /* Did something other than a click occur? */
-      if (mouse_event.dwEventFlags)
- continue;
-
-      /* Retrieve reported mouse position */
-      int x = mouse_event.dwMousePosition.X;
-      int y = mouse_event.dwMousePosition.Y;
-
-      /* Adjust mouse position by scroll buffer offset */
-      CONSOLE_SCREEN_BUFFER_INFO now;
-      if (GetConsoleScreenBufferInfo (get_output_handle (), &now))
- {
-  y -= now.srWindow.Top;
-  x -= now.srWindow.Left;
- }
-      else
- {
-  syscall_printf ("mouse: cannot adjust position by scroll buffer offset");
-  continue;
- }
-
-      /* If the mouse event occurred out of the area we can handle,
- ignore it. */
-      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. */
       int b = 0;
       char sz[32];
-      if (mouse_event.dwButtonState == dev_state->dwLastButtonState)
- {
-  syscall_printf ("mouse: button state unchanged");
-  continue;
- }
-      else if (mouse_event.dwButtonState < dev_state->dwLastButtonState)
- {
-  b = 3;
-  strcpy (sz, "btn up");
- }
-      else if ((mouse_event.dwButtonState & 1) != (dev_state->dwLastButtonState & 1))
- {
-  b = 0;
-  strcpy (sz, "btn1 down");
- }
-      else if ((mouse_event.dwButtonState & 2) != (dev_state->dwLastButtonState & 2))
+
+      if (mouse_event.dwEventFlags == MOUSE_WHEELED)
  {
-  b = 2;
-  strcpy (sz, "btn2 down");
+  if (mouse_event.dwButtonState & 0xFF800000)
+    {
+      b = 0x41;
+      strcpy (sz, "wheel down");
+    }
+  else
+    {
+      b = 0x40;
+      strcpy (sz, "wheel up");
+    }
  }
-      else if ((mouse_event.dwButtonState & 4) != (dev_state->dwLastButtonState & 4))
+      else
  {
-  b = 1;
-  strcpy (sz, "btn3 down");
- }
-
-      /* Remember the current button state */
-      dev_state->dwLastButtonState = mouse_event.dwButtonState;
+  /* Ignore unimportant mouse buttons */
+  mouse_event.dwButtonState &= 0x7;
 
-      /* If a button was pressed, remember the modifiers */
-      if (b != 3)
- {
-  dev_state->nModifiers = 0;
-  if (mouse_event.dwControlKeyState & SHIFT_PRESSED)
-    dev_state->nModifiers |= 0x4;
-  if (mouse_event.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED))
-    dev_state->nModifiers |= 0x8;
-  if (mouse_event.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
-    dev_state->nModifiers |= 0x10;
- }
+  if (mouse_event.dwEventFlags == MOUSE_MOVED)
+    {
+      b = dev_state->last_button_code;
+    }
+  else if (mouse_event.dwButtonState < dev_state->dwLastButtonState)
+    {
+      b = 3;
+      strcpy (sz, "btn up");
+    }
+  else if ((mouse_event.dwButtonState & 1) != (dev_state->dwLastButtonState & 1))
+    {
+      b = 0;
+      strcpy (sz, "btn1 down");
+    }
+  else if ((mouse_event.dwButtonState & 2) != (dev_state->dwLastButtonState & 2))
+    {
+      b = 2;
+      strcpy (sz, "btn2 down");
+    }
+  else if ((mouse_event.dwButtonState & 4) != (dev_state->dwLastButtonState & 4))
+    {
+      b = 1;
+      strcpy (sz, "btn3 down");
+    }
+
+  dev_state->last_button_code = b;
+
+  if (mouse_event.dwEventFlags == MOUSE_MOVED)
+    {
+      b += 32;
+      strcpy (sz, "move");
+    }
+  else
+    {
+      /* Remember the modified button state */
+      dev_state->dwLastButtonState = mouse_event.dwButtonState;
+    }
+        }
+
+      /* Remember mouse position */
+      dev_state->dwLastMousePosition.X = dev_state->dwMousePosition.X;
+      dev_state->dwLastMousePosition.Y = dev_state->dwMousePosition.Y;
+
+      /* Remember the modifiers */
+      dev_state->nModifiers = 0;
+      if (mouse_event.dwControlKeyState & SHIFT_PRESSED)
+  dev_state->nModifiers |= 0x4;
+      if (mouse_event.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED))
+  dev_state->nModifiers |= 0x8;
+      if (mouse_event.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
+  dev_state->nModifiers |= 0x10;
 
+      /* Indicate the modifiers */
       b |= dev_state->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);
+      sprintf (tmp, "\033[M%c%c%c", b + ' ', dev_state->dwMousePosition.X + ' ' + 1, dev_state->dwMousePosition.Y + ' ' + 1);
+      syscall_printf ("mouse: %s at (%d,%d)", sz, dev_state->dwMousePosition.X, dev_state->dwMousePosition.Y);
 
       toadd = tmp;
       nread = 6;
     }
-  break;
+ }
+ break;
 
  case FOCUS_EVENT:
+  if (dev_state->use_focus) {
+    if (input_rec.Event.FocusEvent.bSetFocus)
+      sprintf (tmp, "\033[I");
+    else
+      sprintf (tmp, "\033[O");
+
+    toadd = tmp;
+    nread = 3;
+  }
+  break;
+
  case WINDOW_BUFFER_SIZE_EVENT:
   send_winch_maybe ();
   /* fall through */
@@ -1051,9 +1153,53 @@ fhandler_console::cursor_get (int *x, in
   *x = dev_state->info.dwCursorPosition.X;
 }
 
+static wchar_t __vt100_conv [31] = {
+/* VT100 line drawing graphics mode maps
+ `abcdefghijklmnopqrstuvwxyz{|}~
+   to
+ ◆▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·
+*/
+ 0x25C6 /* ◆ */,
+ 0x2592 /* ▒ */,
+ 0x2409 /* ␉ */,
+ 0x240C /* ␌ */,
+ 0x240D /* ␍ */,
+ 0x240A /* ␊ */,
+ 0x00B0 /* ° */,
+ 0x00B1 /* ± */,
+ 0x2424 /* ␤ */,
+ 0x240B /* ␋ */,
+ 0x2518 /* ┘ */,
+ 0x2510 /* ┐ */,
+ 0x250C /* ┌ */,
+ 0x2514 /* └ */,
+ 0x253C /* ┼ */,
+ 0x23BA /* ⎺ */,
+ 0x23BB /* ⎻ */,
+ 0x2500 /* ─ */,
+ 0x23BC /* ⎼ */,
+ 0x23BD /* ⎽ */,
+ 0x251C /* ├ */,
+ 0x2524 /* ┤ */,
+ 0x2534 /* ┴ */,
+ 0x252C /* ┬ */,
+ 0x2502 /* │ */,
+ 0x2264 /* ≤ */,
+ 0x2265 /* ≥ */,
+ 0x03C0 /* π */,
+ 0x2260 /* ≠ */,
+ 0x00A3 /* £ */,
+ 0x00B7 /* · */,
+};
+
 inline
 bool fhandler_console::write_console (PWCHAR buf, DWORD len, DWORD& done)
 {
+  if (dev_state->vt100_graphics_mode_active)
+    for (DWORD i = 0; i < len; i ++)
+      if (buf[i] >= (unsigned char) '`' && buf[i] <= (unsigned char) '~')
+        buf[i] = __vt100_conv[buf[i] - (unsigned char) '`'];
+
   while (len > 0)
     {
       DWORD nbytes = len > MAX_WRITE_CHARS ? MAX_WRITE_CHARS : len;
@@ -1082,11 +1228,13 @@ bool fhandler_console::write_console (PW
 #define TAB 8 /* We should't let the console deal with these */
 #define CR 13
 #define LF 10
+#define SO 14
+#define SI 15
 
 static const char base_chars[256] =
 {
 /*00 01 02 03 04 05 06 07 */ IGN, ERR, ERR, NOR, NOR, NOR, NOR, BEL,
-/*08 09 0A 0B 0C 0D 0E 0F */ BAK, TAB, DWN, ERR, ERR, CR,  ERR, IGN,
+/*08 09 0A 0B 0C 0D 0E 0F */ BAK, TAB, DWN, ERR, ERR, CR,  SO,  SI,
 /*10 11 12 13 14 15 16 17 */ NOR, NOR, ERR, ERR, ERR, ERR, ERR, ERR,
 /*18 19 1A 1B 1C 1D 1E 1F */ NOR, NOR, ERR, ESC, ERR, ERR, ERR, ERR,
 /*   !  "  #  $  %  &  '  */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
@@ -1136,7 +1284,10 @@ fhandler_console::char_command (char c)
      case 1:    /* bold */
        dev_state->intensity = INTENSITY_BOLD;
        break;
-     case 4:
+     case 2:    /* dim */
+       dev_state->intensity = INTENSITY_DIM;
+       break;
+     case 4:    /* underlined */
        dev_state->underline = 1;
        break;
      case 5:    /* blink mode */
@@ -1148,18 +1299,22 @@ fhandler_console::char_command (char c)
      case 8:    /* invisible */
        dev_state->intensity = INTENSITY_INVISIBLE;
        break;
-     case 9:    /* dim */
-       dev_state->intensity = INTENSITY_DIM;
-       break;
      case 10:   /* end alternate charset */
        dev_state->alternate_charset_active = false;
        break;
      case 11:   /* start alternate charset */
        dev_state->alternate_charset_active = true;
        break;
+     case 22:
+     case 28:
+       dev_state->intensity = INTENSITY_NORMAL;
+       break;
      case 24:
        dev_state->underline = false;
        break;
+     case 25:
+       dev_state->blink = false;
+       break;
      case 27:
        dev_state->reverse = false;
        break;
@@ -1275,9 +1430,24 @@ fhandler_console::char_command (char c)
     }
   break;
 
- case 1000: /* Mouse support */
-  dev_state->use_mouse = (c == 'h') ? true : false;
-  syscall_printf ("mouse support %sabled", dev_state->use_mouse ? "en" : "dis");
+ case 1000: /* Mouse tracking */
+  dev_state->use_mouse = (c == 'h') ? 1 : 0;
+  syscall_printf ("mouse support set to mode %d", dev_state->use_mouse);
+  break;
+
+ case 1002: /* Mouse button event tracking */
+  dev_state->use_mouse = (c == 'h') ? 2 : 0;
+  syscall_printf ("mouse support set to mode %d", dev_state->use_mouse);
+  break;
+
+ case 1003: /* Mouse any event tracking */
+  dev_state->use_mouse = (c == 'h') ? 3 : 0;
+  syscall_printf ("mouse support set to mode %d", dev_state->use_mouse);
+  break;
+
+ case 1004: /* Focus in/out event reporting */
+  dev_state->use_focus = (c == 'h') ? true : false;
+  syscall_printf ("focus reporting set to %d", dev_state->use_focus);
   break;
 
  case 2000: /* Raw keyboard mode */
@@ -1413,8 +1583,11 @@ fhandler_console::char_command (char c)
  WriteFile (get_output_handle (), &dev_state->args_[0], 1, (DWORD *) &x, 0);
       break;
     case 'c': /* u9 - Terminal enquire string */
-      strcpy (buf, "\033[?6c");
-      puts_readahead (buf);
+      if (dev_state->saw_greater_than_sign)
+ __small_sprintf (buf, "\033[>67;%d%02d;0c", CYGWIN_VERSION_DLL_MAJOR, CYGWIN_VERSION_DLL_MINOR);
+      else
+ strcpy (buf, "\033[?6c");
+      c_puts_readahead (buf);
       break;
     case 'n':
       switch (dev_state->args_[0])
@@ -1424,7 +1597,7 @@ fhandler_console::char_command (char c)
   y -= dev_state->info.winTop;
   /* x -= dev_state->info.winLeft; // not available yet */
   __small_sprintf (buf, "\033[%d;%dR", y + 1, x + 1);
-  puts_readahead (buf);
+  c_puts_readahead (buf);
   break;
     default:
   goto bad_escape;
@@ -1589,6 +1762,12 @@ fhandler_console::write_normal (const un
       int x, y;
       switch (base_chars[*found])
  {
+ case SO:
+  dev_state->vt100_graphics_mode_active = true;
+  break;
+ case SI:
+  dev_state->vt100_graphics_mode_active = false;
+  break;
  case BEL:
   beep ();
   break;
@@ -1679,45 +1858,54 @@ fhandler_console::write (const void *vsr
     return -1;
   break;
  case gotesc:
-  if (*src == '[')
+  if (*src == '[') /* CSI Control Sequence Introducer */
     {
       dev_state->state_ = gotsquare;
       dev_state->saw_question_mark = false;
+      dev_state->saw_greater_than_sign = false;
       for (dev_state->nargs_ = 0; dev_state->nargs_ < MAXARGS; dev_state->nargs_++)
  dev_state->args_[dev_state->nargs_] = 0;
       dev_state->nargs_ = 0;
     }
-  else if (*src == ']')
+  else if (*src == ']') /* OSC Operating System Command */
     {
       dev_state->rarg = 0;
       dev_state->my_title_buf[0] = '\0';
       dev_state->state_ = gotrsquare;
     }
-  else if (*src == 'M') /* Reverse Index */
+  else if (*src == '(') /* Designate G0 character set */
+    {
+      dev_state->state_ = gotparen;
+    }
+  else if (*src == ')') /* Designate G1 character set */
+    {
+      dev_state->state_ = gotrparen;
+    }
+  else if (*src == 'M') /* Reverse Index (scroll down) */
     {
       dev_state->fillin_info (get_output_handle ());
       scroll_screen (0, 0, -1, -1, 0, dev_state->info.winTop + 1);
       dev_state->state_ = normal;
     }
-  else if (*src == 'c') /* Reset Linux terminal */
+  else if (*src == 'c') /* RIS Full Reset */
     {
       dev_state->set_default_attr ();
       clear_screen (0, 0, -1, -1);
       cursor_set (true, 0, 0);
       dev_state->state_ = normal;
     }
-  else if (*src == '8') /* Restore cursor position */
+  else if (*src == '8') /* DECRC Restore cursor position */
     {
       cursor_set (true, dev_state->savex, dev_state->savey);
       dev_state->state_ = normal;
     }
-  else if (*src == '7') /* Save cursor position */
+  else if (*src == '7') /* DECSC Save cursor position */
     {
       cursor_get (&dev_state->savex, &dev_state->savey);
       dev_state->savey -= dev_state->info.winTop;
       dev_state->state_ = normal;
     }
-  else if (*src == 'R')
+  else if (*src == 'R') /* ? */
       dev_state->state_ = normal;
   else
     {
@@ -1791,12 +1979,31 @@ fhandler_console::write (const void *vsr
     {
       if (*src == '?')
  dev_state->saw_question_mark = true;
+      else if (*src == '>')
+ dev_state->saw_greater_than_sign = true;
       /* ignore any extra chars between [ and first arg or command */
       src++;
     }
   else
     dev_state->state_ = gotarg1;
   break;
+ case gotparen:
+  if (*src == '0')
+    dev_state->vt100_graphics_mode_active = true;
+  else
+    dev_state->vt100_graphics_mode_active = false;
+  dev_state->state_ = normal;
+  src++;
+  break;
+ case gotrparen:
+  /* This is not strictly needed, ^N/^O can just always be enabled */
+  if (*src == '0')
+    /*dev_state->vt100_graphics_mode_SOSI_enabled = true*/;
+  else
+    /*dev_state->vt100_graphics_mode_SOSI_enabled = false*/;
+  dev_state->state_ = normal;
+  src++;
+  break;
  }
     }
 
@@ -1809,33 +2016,39 @@ static struct {
   int vk;
   const char *val[4];
 } keytable[] NO_COPY = {
-       /* NORMAL */    /* SHIFT */     /* CTRL */     /* ALT */
-  {VK_LEFT, {"\033[D", "\033[D", "\033[D", "\033\033[D"}},
-  {VK_RIGHT, {"\033[C", "\033[C", "\033[C", "\033\033[C"}},
-  {VK_UP, {"\033[A", "\033[A", "\033[A", "\033\033[A"}},
-  {VK_DOWN, {"\033[B", "\033[B", "\033[B", "\033\033[B"}},
-  {VK_PRIOR, {"\033[5~", "\033[5~", "\033[5~", "\033\033[5~"}},
-  {VK_NEXT, {"\033[6~", "\033[6~", "\033[6~", "\033\033[6~"}},
-  {VK_HOME, {"\033[1~", "\033[1~", "\033[1~", "\033\033[1~"}},
-  {VK_END, {"\033[4~", "\033[4~", "\033[4~", "\033\033[4~"}},
-  {VK_INSERT, {"\033[2~", "\033[2~", "\033[2~", "\033\033[2~"}},
-  {VK_DELETE, {"\033[3~", "\033[3~", "\033[3~", "\033\033[3~"}},
-  {VK_F1, {"\033[[A", "\033[23~", NULL, NULL}},
-  {VK_F2, {"\033[[B", "\033[24~", NULL, NULL}},
-  {VK_F3, {"\033[[C", "\033[25~", NULL, NULL}},
-  {VK_F4, {"\033[[D", "\033[26~", NULL, NULL}},
-  {VK_F5, {"\033[[E", "\033[28~", NULL, NULL}},
-  {VK_F6, {"\033[17~", "\033[29~", "\036", NULL}},
-  {VK_F7, {"\033[18~", "\033[31~", NULL, NULL}},
-  {VK_F8, {"\033[19~", "\033[32~", NULL, NULL}},
-  {VK_F9, {"\033[20~", "\033[33~", NULL, NULL}},
-  {VK_F10, {"\033[21~", "\033[34~", NULL, NULL}},
-  {VK_F11, {"\033[23~", NULL, NULL, NULL}},
-  {VK_F12, {"\033[24~", NULL, NULL, NULL}},
-  {VK_NUMPAD5, {"\033[G", NULL, NULL, NULL}},
-  {VK_CLEAR, {"\033[G", NULL, NULL, NULL}},
+       /* NORMAL */    /* SHIFT */     /* CTRL */     /* CTRL-SHIFT */
+  /* Unmodified and Alt-modified keypad keys comply with linux console
+     SHIFT, CTRL, CTRL-SHIFT modifiers comply with xterm modifier usage */
+  {VK_NUMPAD5, {"\033[G", "\033[1;2G", "\033[1;5G", "\033[1;6G"}},
+  {VK_CLEAR, {"\033[G", "\033[1;2G", "\033[1;5G", "\033[1;6G"}},
+  {VK_LEFT, {"\033[D", "\033[1;2D", "\033[1;5D", "\033[1;6D"}},
+  {VK_RIGHT, {"\033[C", "\033[1;2C", "\033[1;5C", "\033[1;6C"}},
+  {VK_UP, {"\033[A", "\033[1;2A", "\033[1;5A", "\033[1;6A"}},
+  {VK_DOWN, {"\033[B", "\033[1;2B", "\033[1;5B", "\033[1;6B"}},
+  {VK_PRIOR, {"\033[5~", "\033[5;2~", "\033[5;5~", "\033[5;6~"}},
+  {VK_NEXT, {"\033[6~", "\033[6;2~", "\033[6;5~", "\033[6;6~"}},
+  {VK_HOME, {"\033[1~", "\033[1;2~", "\033[1;5~", "\033[1;6~"}},
+  {VK_END, {"\033[4~", "\033[4;2~", "\033[4;5~", "\033[4;6~"}},
+  {VK_INSERT, {"\033[2~", "\033[2;2~", "\033[2;5~", "\033[2;6~"}},
+  {VK_DELETE, {"\033[3~", "\033[3;2~", "\033[3;5~", "\033[3;6~"}},
+  /* F1...F12, SHIFT-F1...SHIFT-F10 comply with linux console
+     F6...F12, and all modified F-keys comply with rxvt (compatible extension) */
+  {VK_F1, {"\033[[A", "\033[23~", "\033[11^", "\033[23^"}},
+  {VK_F2, {"\033[[B", "\033[24~", "\033[12^", "\033[24^"}},
+  {VK_F3, {"\033[[C", "\033[25~", "\033[13^", "\033[25^"}},
+  {VK_F4, {"\033[[D", "\033[26~", "\033[14^", "\033[26^"}},
+  {VK_F5, {"\033[[E", "\033[28~", "\033[15^", "\033[28^"}},
+  {VK_F6, {"\033[17~", "\033[29~", "\033[17^", "\033[29^"}},
+  {VK_F7, {"\033[18~", "\033[31~", "\033[18^", "\033[31^"}},
+  {VK_F8, {"\033[19~", "\033[32~", "\033[19^", "\033[32^"}},
+  {VK_F9, {"\033[20~", "\033[33~", "\033[20^", "\033[33^"}},
+  {VK_F10, {"\033[21~", "\033[34~", "\033[21^", "\033[34^"}},
+  {VK_F11, {"\033[23~", "\033[23$", "\033[23^", "\033[23@"}},
+  {VK_F12, {"\033[24~", "\033[24$", "\033[24^", "\033[24@"}},
+  /* CTRL-6 complies with Windows cmd console but should be fixed */
   {'6', {NULL, NULL, "\036", NULL}},
-  {0, {"", NULL, NULL, NULL}}
+  /* Table end marker */
+  {0}
 };
 
 const char *
@@ -1844,21 +2057,29 @@ get_nonascii_key (INPUT_RECORD& input_re
 #define NORMAL  0
 #define SHIFT 1
 #define CONTROL 2
-#define ALT 3
-  int modifier_index = NORMAL;
+/*#define CONTROLSHIFT 3*/
 
+  int modifier_index = NORMAL;
   if (input_rec.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)
     modifier_index = SHIFT;
-  else if (input_rec.Event.KeyEvent.dwControlKeyState &
+  if (input_rec.Event.KeyEvent.dwControlKeyState &
  (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
-    modifier_index = CONTROL;
-  else if (input_rec.Event.KeyEvent.dwControlKeyState &
- (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
-    modifier_index = ALT;
+    modifier_index += CONTROL;
 
   for (int i = 0; keytable[i].vk; i++)
     if (input_rec.Event.KeyEvent.wVirtualKeyCode == keytable[i].vk)
-      return keytable[i].val[modifier_index];
+      {
+        if ((input_rec.Event.KeyEvent.dwControlKeyState &
+ (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
+    && keytable[i].val[modifier_index] != NULL)
+          { /* Generic ESC prefixing if Alt is pressed */
+    tmp[0] = '\033';
+    strcpy (tmp + 1, keytable[i].val[modifier_index]);
+    return tmp;
+          }
+        else
+          return keytable[i].val[modifier_index];
+      }
 
   if (input_rec.Event.KeyEvent.uChar.AsciiChar)
     {
diff -rup cygwin-1.7.0-68.orig/winsup/cygwin/select.cc cygwin-1.7.0-68/winsup/cygwin/select.cc
--- cygwin-1.7.0-68.orig/winsup/cygwin/select.cc 2009-10-03 14:28:06.000000000 +0200
+++ cygwin-1.7.0-68/winsup/cygwin/select.cc 2009-12-04 18:36:06.000000000 +0100
@@ -781,6 +781,7 @@ fhandler_fifo::select_except (select_stu
 static int
 peek_console (select_record *me, bool)
 {
+  extern int c_peek_readahead ();
   extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *);
   fhandler_console *fh = (fhandler_console *) me->fh;
 
@@ -815,6 +816,8 @@ peek_console (select_record *me, bool)
  fh->send_winch_maybe ();
  if (irec.EventType == KEY_EVENT)
   {
+    if (c_peek_readahead () >= 0)
+      return me->read_ready = true;
     if (irec.Event.KeyEvent.bKeyDown
  && (irec.Event.KeyEvent.uChar.AsciiChar
     || get_nonascii_key (irec, tmpbuf)))
@@ -823,9 +826,9 @@ peek_console (select_record *me, bool)
  else
   {
     if (irec.EventType == MOUSE_EVENT
- && fh->mouse_aware ()
- && (irec.Event.MouseEvent.dwEventFlags == 0
-    || irec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK))
+ && fh->mouse_aware (irec.Event.MouseEvent))
+ return me->read_ready = true;
+    if (irec.EventType == FOCUS_EVENT && fh->focus_aware ())
  return me->read_ready = true;
   }
 

Re: console enhancements: mouse events etc

by Corinna Vinschen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Tom,

On Dec  6 20:24, Thomas Wolff wrote:

> Corinna Vinschen wrote:
> >Could you please resend the latest version of your patch so we
> >can have another look into it?
> This is my updated and extended patch for a number of console enhancements.
> >Christopher Faylor wrote:
> >>Can we hold of on applying this until after 1.7 is released?
> Sure, feel free to apply when suitable. I just happened to work on
> it around this time...
> >Yeah, maybe we really should do that for now.  Except for the
> >ESC9m -> ESC2m change, maybe...
> If you want a subset of the features sooner than others, I may split
> the patch.

Thanks for the offer.  It would be nice if you could split up the patch
in the chunks which you're referring to in your ChangeLog entries.  It
makes it less hard to follow the individual bits.


Thanks,
Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

Re: console enhancements: mouse events etc

by Thomas Wolff-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Corinna Vinschen wrote:
> Hi Tom,
>  
Hi Cori,

> On Dec  6 20:24, Thomas Wolff wrote:
>  
>> This is my updated and extended patch for a number of console enhancements.
>>    
>> ...
>>    
>> If you want a subset of the features sooner than others, I may split
>> the patch.
>>    
> Thanks for the offer.  It would be nice if you could split up the patch
> in the chunks which you're referring to in your ChangeLog entries.  It
> makes it less hard to follow the individual bits.
Sure, although I had hoped I could at least combine a few modifications
to reduce fiddling around...
Also, since it's always cumbersome to update a patch to a new target
version, would you be willing to apply some of the features still to the
current release, 1.7.0-68?
I would provide those first.
My proposal:

Patch 1 (1.7.0-68):
* Additional event reporting as described before.
* Add and fix a few rarely used screen attributes as described before.
* Enable ESC prefixing for Alt-AltGr keys, so that e.g. Alt-@ works on
keyboards where @ is AltGr-q (a one-liner).
But if you prefer, I'll make it 3 patches.

Patch 2 (maybe 1.7.0-68, or later, as you like):
* Extend escape sequences for modified function keys to indicate all
combinations of Ctrl, Shift, Alt, using the rxvt codes.
* Extend escape sequences for modified keypad keys to indicate all
combinations of Ctrl, Shift, Alt, following the xterm/mintty convention
for Ctrl and Shift, and the rxvt/linux convention for Alt, to reach
maximum compatibility.
  Note that Alt handling interfers with the Windows-style Alt-numeric
character input method but it did so before already, so I didn't break
anything. However, if that method is desired to work, I would modify my
patch accordingly.

Patch 3 (maybe 1.7.0-68, or later, as you like):
* Add VT100 graphics mode. It remaps small ASCII letters to line drawing
graphics and is enabled / disabled in either of two ways:
* Add "Secondary Device Attribute" report option to terminal status reports.
I would like to leave the second in here because both include an update
of escape sequence parsing. It's in preparation of patch 4.

Patch 4 (to be postponed as there's still some trouble with it):
* Fix cursor position reports and terminal status reports to work.

Patch 5 (later, to be investigated):
* Fix control-character mappings (for non-letter controls) on
international keyboards.

Kind regards,
Thomas
< Prev | 1 - 2 | Next >