This is the mail archive of the
cygwin@cygwin.com
mailing list for the Cygwin project.
Re: "Application key pad mode" in cygwin console
- From: Fabien PERRIOLLAT <Fabien dot Perriollat at cern dot ch>
- To: cygwin at cygwin dot com
- Date: Mon, 08 Jul 2002 12:02:21 +0200
- Subject: Re: "Application key pad mode" in cygwin console
- Organization: CERN
- References: <3CACCDA6.CDCE45E9@cern.ch> <20020404222702.GA4161@redhat.com>
Christopher Faylor,
I just completed a patch to cygwin1.dll to provide the application keyboard
modes.
The patches are in the files :
fhandler_console.cc
fhandler_termios.cc
select.cc
fhandler.h
tty.h
shared_info,h
These patches was done in the Cygwin version 10 03.11.0.0
And I have a short and simple test program to exercise the new facility.
I attache a file which is the output of diif processing for the modified
files.
Could you tel me to how I must send this patch, and what is the procedure.
Fabien PERRIOLLAT
Christopher Faylor wrote:
> On Fri, Apr 05, 2002 at 12:03:18AM +0200, Fabien Perriollat wrote:
> >I am porting a Unix package to Cygwin environment.
> >This package use the capability offered by xterm but also by linux
> >console to set the numerical key pad in "Application mode" (by sending
> >an escape sequence string).
> >This facility seem to be not available, and a quick look into the file
> >fhandler_console.cc and into winuser.h show me that "NUMPADxx" key
> >outside VK_NUMPAD5 is not handle. but only the "Numeric key pad mode"
> >is handle.
> >
> >Do you have any plan to provide the cygwin console with this facility
> >similar to xterm and or linux console,
>
> No plans, but you're welcome to submit a patch.
>
> >our could you provide me with any alternated way to have a similar
> >result.
>
> Have you tried 'rxvt'?
>
> If you don't have it installed currently, rerun setup.exe to install it.
>
> cgf
--
====================================================================
Fabien Perriollat office 10 2-001 http://home.cern.ch/perrioll/
Beam Diagnostics mailto:Fabien.Perriollat@cern.ch
Division PS, CERN Phone (+41 22) 767 5044 (+41) 79 201 0561
CH-1211 Geneva 23 Fax (+41 22) 767 9145
====================================================================
==============================================================================
Cygwin version 10 03.11.0.0
differences in /src/winsup/cygwin files :
fhandler_console.cc
fhandler_termios.cc
select.cc
fhandler.h
tty.h
shared_info.h
as produced by 'diff -bE -C 2 new_file ref_file
introduced to provide keypad mode control (DECPAM, DECPNM control sequences)
and cursor key mode (DECCKM control sequences)
Fabien PERRIOLLAT, CERN Geneva, Switzerland
Fabien.Perriollat@cern.ch
June 2002
==============================================================================
*** fhandler_console_ref.cc Wed Jun 12 16:07:04 2002
--- fhandler_console.cc Wed Jun 19 14:47:29 2002
***************
*** 93,97 ****
#define use_tty ISSTATE (myself, PID_USETTY)
! const char * get_nonascii_key (INPUT_RECORD&, char *);
static tty_min NO_COPY *shared_console_info = NULL;
--- 93,97 ----
#define use_tty ISSTATE (myself, PID_USETTY)
! const char * get_nonascii_key (INPUT_RECORD&, char *, BOOL, BOOL);
static tty_min NO_COPY *shared_console_info = NULL;
***************
*** 204,207 ****
--- 204,209 ----
int ch;
+ int vkc;
+
set_input_state ();
***************
*** 227,230 ****
--- 229,233 ----
{
int bgres;
+ int remove_echo = FALSE;
if ((bgres = bg_check (SIGTTIN)) <= bg_eof)
return bgres;
***************
*** 294,305 ****
#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
if (wch == 0 ||
/* arrow/function keys */
! (input_rec.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY))
{
! toadd = get_nonascii_key (input_rec, tmp);
if (!toadd)
continue;
nread = strlen (toadd);
}
else
--- 297,311 ----
#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
+ vkc = input_rec.Event.KeyEvent.wVirtualKeyCode;
if (wch == 0 ||
/* arrow/function keys */
! (input_rec.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY) ||
! ((vkc == VK_MULTIPLY) || (vkc == VK_SUBTRACT) || (vkc == VK_ADD) ) )
{
! toadd = get_nonascii_key (input_rec, tmp, tc->application_keypad_mode, tc->application_cursor_mode);
if (!toadd)
continue;
nread = strlen (toadd);
+ remove_echo = (*toadd == '\033'); /* no echo of escape sequence */
}
else
***************
*** 436,440 ****
if (toadd)
{
! int res = line_edit (toadd, nread);
if (res < 0)
goto sig_exit;
--- 442,446 ----
if (toadd)
{
! int res = line_edit (toadd, nread, 0, remove_echo);
if (res < 0)
goto sig_exit;
***************
*** 659,662 ****
--- 665,671 ----
fhc->raw_win32_keyboard_mode = raw_win32_keyboard_mode;
+ fhc->tc->application_keypad_mode = tc->application_keypad_mode;
+ fhc->tc->application_cursor_mode = tc->application_cursor_mode;
+
return 0;
}
***************
*** 1034,1038 ****
/*18 19 1A 1B 1C 1D 1E 1F */ NOR, NOR, ERR, ESC, ERR, ERR, ERR, ERR,
/* ! " # $ % & ' */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
! /*() * + , - . / */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
/*0 1 2 3 4 5 6 7 */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
/*8 9 : ; < = > ? */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
--- 1043,1047 ----
/*18 19 1A 1B 1C 1D 1E 1F */ NOR, NOR, ERR, ESC, ERR, ERR, ERR, ERR,
/* ! " # $ % & ' */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
! /*( ) * + , - . / */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
/*0 1 2 3 4 5 6 7 */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
/*8 9 : ; < = > ? */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
***************
*** 1176,1179 ****
--- 1185,1195 ----
switch (args_[0])
{
+ bool set_flg;
+
+ case 1: /* Cursor Key mode */
+ set_flg = (c == 'h');
+ tc->application_cursor_mode = set_flg;
+ break;
+
case 47: /* Save/Restore screen */
if (c == 'h') /* save */
***************
*** 1493,1496 ****
--- 1509,1513 ----
debug_printf ("%x, %d", vsrc, len);
+
while (src < end)
{
***************
*** 1544,1548 ****
--- 1561,1577 ----
}
else if (*src == 'R')
+ {
state_ = normal;
+ }
+ else if (*src == '=')
+ {
+ tc->application_keypad_mode = TRUE;
+ state_ = normal;
+ }
+ else if (*src == '>')
+ {
+ tc->application_keypad_mode = FALSE;
+ state_ = normal;
+ }
else
{
***************
*** 1633,1640 ****
}
! 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"}},
--- 1662,1671 ----
}
! typedef struct {
int vk;
! const char *val[4]; /* for NORMAL, SHIFT, CTRL and ALT modifier case */
! } KEY_TABLE;
!
! static KEY_TABLE keytable[] NO_COPY = {
/* NORMAL */ /* SHIFT */ /* CTRL */ /* ALT */
{VK_LEFT, {"\033[D", "\033[D", "\033[D", "\033\033[D"}},
***************
*** 1662,1671 ****
{VK_NUMPAD5, {"\033[G", NULL, NULL, NULL}},
{VK_CLEAR, {"\033[G", NULL, NULL, NULL}},
! {'6', {NULL, NULL, "\036", NULL}},
{0, {"", NULL, NULL, NULL}}
};
const char *
! get_nonascii_key (INPUT_RECORD& input_rec, char *tmp)
{
#define NORMAL 0
--- 1693,1762 ----
{VK_NUMPAD5, {"\033[G", NULL, NULL, NULL}},
{VK_CLEAR, {"\033[G", NULL, NULL, NULL}},
! {'6', { NULL, NULL, "\036", NULL}},
{0, {"", NULL, NULL, NULL}}
};
+ /* WARNING :
+ * 1 - the order of these arrays are very much sensitive
+ * VK_xxx must be in numerical order, and it is assumed that some
+ * values are contigous.
+ * 2 - VK_APPS (0X5D) is also an enhanced key.
+ */
+
+ static KEY_TABLE numkeytable[] NO_COPY = {
+ /* NORMAL SHIFT CTRL ALT */
+ {VK_RETURN, {"\033OM", "\r", NULL, NULL}},
+
+ {VK_NUMPAD0, {"\033Op", "0", "\033Op", "\033Op"}},
+ {VK_NUMPAD1, {"\033Oq", "1", "\033Oq", "\033Oq"}},
+ {VK_NUMPAD2, {"\033Or", "2", "\033Or", "\033Or"}},
+ {VK_NUMPAD3, {"\033Os", "3", "\033Os", "\033Os"}},
+ {VK_NUMPAD4, {"\033Ot", "4", "\033Ot", "\033Ot"}},
+ {VK_NUMPAD5, {"\033Ou", "5", "\033Ou", "\033Ou"}},
+ {VK_NUMPAD6, {"\033Ov", "6", "\033Ov", "\033Ov"}},
+ {VK_NUMPAD7, {"\033Ow", "7", "\033Ow", "\033Ow"}},
+ {VK_NUMPAD8, {"\033Ox", "8", "\033Ox", "\033Ox"}},
+ {VK_NUMPAD9, {"\033Oy", "9", "\033Oy", "\033Oy"}},
+
+ {VK_MULTIPLY, {"\033Oj", "*", NULL, NULL}},
+ {VK_ADD, {"\033Ok", "+", NULL, NULL}},
+ {VK_SEPARATOR,{"\033Ol", "'", NULL, NULL}},
+ {VK_SUBTRACT, {"\033Om", "-", NULL, NULL}},
+ {VK_DECIMAL, {"\033On", ".", NULL, NULL}},
+ {VK_DIVIDE, {"\033Oo", "/", NULL, NULL}},
+
+ {0, {NULL, NULL, NULL, NULL}}
+ };
+
+ static KEY_TABLE applcursortable [] NO_COPY = {
+ /* NORMAL SHIFT CTRL ALT */
+ {VK_LEFT, {"\033OD", "\033OD", "\033OD", "\033OD"}}, /* VK_LEFT 37 */
+ {VK_UP, {"\033OA", "\033OA", "\033OA", "\033OA"}}, /* VK_UP 38 */
+ {VK_RIGHT, {"\033OC", "\033OC", "\033OC", "\033OC"}}, /* VK_RIGHT 39 */
+ {VK_DOWN, {"\033OB", "\033OB", "\033OB", "\033OB"}}, /* VK_DOWN 40 */
+ {0, { NULL, NULL, NULL, }}
+ };
+
+ static struct {
+ int kc;
+ int mkc;
+ } numkeytranst[] NO_COPY = {
+ {VK_LEFT, VK_NUMPAD4},
+ {VK_RIGHT, VK_NUMPAD6},
+ {VK_UP, VK_NUMPAD8},
+ {VK_DOWN, VK_NUMPAD2},
+ {VK_PRIOR, VK_NUMPAD9},
+ {VK_NEXT, VK_NUMPAD3},
+ {VK_HOME, VK_NUMPAD7},
+ {VK_END, VK_NUMPAD1},
+ {VK_INSERT, VK_NUMPAD0},
+ {VK_DELETE, VK_DECIMAL},
+ {VK_CLEAR, VK_NUMPAD5},
+ {0, 0}
+ };
+
+
const char *
! get_nonascii_key (INPUT_RECORD& input_rec, char *tmp, BOOL keypad_mode, BOOL cursor_mode)
{
#define NORMAL 0
***************
*** 1673,1700 ****
#define CONTROL 2
#define ALT 3
int modifier_index = NORMAL;
! if (input_rec.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)
modifier_index = SHIFT;
! else 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;
! 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.uChar.AsciiChar)
! {
! tmp[0] = input_rec.Event.KeyEvent.uChar.AsciiChar;
! tmp[1] = '\0';
return tmp;
}
return NULL;
}
void
fhandler_console::init (HANDLE f, DWORD a, mode_t bin)
--- 1764,1886 ----
#define CONTROL 2
#define ALT 3
+
+ int v_keycode, kc;
+ int kstate;
+ int i;
+ char ascii;
+
int modifier_index = NORMAL;
+ BOOL enhanced = FALSE;
+ BOOL num_key = FALSE; /* a key from numeric key pad */
+ BOOL ext_key = FALSE; /* a key from extended key pad */
+ BOOL numlock = FALSE;
+ BOOL shift = FALSE;
+
+ kstate = input_rec.Event.KeyEvent.dwControlKeyState;
+ v_keycode = input_rec.Event.KeyEvent.wVirtualKeyCode;
+ enhanced = input_rec.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY;
+ numlock = kstate & NUMLOCK_ON;
+ shift = kstate & SHIFT_PRESSED;
+ tmp[0] = ascii = input_rec.Event.KeyEvent.uChar.AsciiChar;
+ tmp[1] = '\0';
! if ( shift )
modifier_index = SHIFT;
! else if ( kstate & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) )
modifier_index = CONTROL;
! else if (kstate & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) )
modifier_index = ALT;
! if ( keypad_mode ) {
! /* check for numeric or extended keypad */
! if ( enhanced ) {
! num_key = ((v_keycode == VK_RETURN) || (v_keycode == VK_DIVIDE));
! ext_key = ! num_key;
! } else {
! switch (v_keycode) {
! case VK_MULTIPLY :
! case VK_SUBTRACT :
! case VK_ADD :
! num_key = TRUE;
! break;
! default :
! if ( v_keycode < VK_NUMPAD0 ) {
! for (i = 0; (kc = numkeytranst[i].kc) != 0; i++) {
! if ( kc == v_keycode ) {
! v_keycode = numkeytranst[i].mkc;
! num_key = TRUE;
! break;
! }
! }
! } else num_key = (v_keycode <= VK_DIVIDE);
! }
! }
! if ( num_key ) {
! if ( !numlock && !shift ) {
! /* get answer from translation table */
! ascii = '\0';
! } else if ( numlock && shift ) {
! /* cancel the numlock effect */
! ascii = '\0';
! modifier_index = NORMAL;
! }
! }
!
! if ( ascii ) {
! /* return the ascii code */
return tmp;
}
+
+ if ( num_key ) {
+ /* a numeric key pad */
+ if ( v_keycode == VK_RETURN ) {
+ return numkeytable[0].val[modifier_index];
+ } else if ( ((i = v_keycode - VK_NUMPAD0) >= 0) && (i <= (VK_DIVIDE - VK_NUMPAD0)) ) {
+ return numkeytable[i+1].val[modifier_index];
+ }
+ }
+ }
+
+
+ if ( cursor_mode && ((v_keycode >= VK_LEFT) && (v_keycode <= VK_DOWN)) ) {
+ return applcursortable[v_keycode - VK_LEFT].val[modifier_index];
+ }
+
+ /* other key (function or extended key pad) */
+ for (i = 0; keytable[i].vk; i++) {
+ if (v_keycode == keytable[i].vk)
+ return keytable[i].val[modifier_index];
+ }
+
+ if ( !keypad_mode && ascii )
+ return tmp;
+
return NULL;
}
+ /* check_keyevent : return true if something will be returned
+ * by a read to the console input (used by 'peek_console'
+ * in select.cc file
+ * Must be call only on KEY_EVENT, and when bKeyDown is true
+ */
+ bool
+ check_keyevent (fhandler_console *fh, INPUT_RECORD& input_rec)
+ {
+ int vkc;
+ char tmpbuf[17];
+ const char *toadd;
+
+ vkc = input_rec.Event.KeyEvent.wVirtualKeyCode;
+ if ( (input_rec.Event.KeyEvent.uChar.AsciiChar == '\0') ||
+ (input_rec.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY) ||
+ ((vkc == VK_MULTIPLY) || (vkc == VK_SUBTRACT) || (vkc == VK_ADD))
+ ) {
+ toadd = get_nonascii_key (input_rec, tmpbuf, fh->tc->application_keypad_mode, fh->tc->application_cursor_mode);
+ return (toadd != NULL);
+ }
+ return true; /* a valid ascii char */
+ }
+
void
fhandler_console::init (HANDLE f, DWORD a, mode_t bin)
*** fhandler_termios_ref.cc Thu Jun 13 17:54:40 2002
--- fhandler_termios.cc Wed Jun 19 14:22:41 2002
***************
*** 61,64 ****
--- 61,66 ----
tc->pgid = myself->pgid;
TTYSETF (INITIALIZED);
+
+ tc->application_keypad_mode = tc->application_cursor_mode = FALSE;
}
}
*** select_ref.cc Wed Jun 12 15:45:24 2002
--- select.cc Wed Jun 12 15:31:04 2002
***************
*** 622,626 ****
peek_console (select_record *me, bool)
{
! extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *);
fhandler_console *fh = (fhandler_console *)me->fh;
--- 622,626 ----
peek_console (select_record *me, bool)
{
! extern bool check_keyevent (fhandler_console *, INPUT_RECORD& input_rec);
fhandler_console *fh = (fhandler_console *)me->fh;
***************
*** 643,647 ****
DWORD events_read;
HANDLE h;
- char tmpbuf[17];
set_handle_or_return_if_not_open (h, me);
--- 643,646 ----
***************
*** 662,667 ****
return me->read_ready = true;
}
! else if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown == true &&
! (irec.Event.KeyEvent.uChar.AsciiChar || get_nonascii_key (irec, tmpbuf)))
return me->read_ready = true;
--- 661,666 ----
return me->read_ready = true;
}
! else if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown
! && (check_keyevent (fh, irec)))
return me->read_ready = true;
*** fhandler_ref.h Fri May 24 07:44:10 2002
--- fhandler.h Thu Jun 20 14:34:06 2002
***************
*** 652,656 ****
}
HANDLE& get_output_handle () { return output_handle; }
! int line_edit (const char *rptr, int nread, int always_accept = 0);
void set_output_handle (HANDLE h) { output_handle = h; }
void tcinit (tty_min *this_tc, int force = FALSE);
--- 652,656 ----
}
HANDLE& get_output_handle () { return output_handle; }
! int line_edit (const char *rptr, int nread, int always_accept = 0, int remove_echo = 0);
void set_output_handle (HANDLE h) { output_handle = h; }
void tcinit (tty_min *this_tc, int force = FALSE);
*** tty_ref.h Tue Mar 5 19:03:32 2002
--- tty.h Wed Jun 19 10:04:48 2002
***************
*** 67,70 ****
--- 67,74 ----
struct winsize winsize;
+ /* cursor and keypad mode (0 : normal (FALSE) or != 0 : application (TRUE)) */
+ int application_keypad_mode;
+ int application_cursor_mode;
+
/* ioctl requests buffer */
int cmd;
*** shared_info_ref.h Thu Jun 20 15:08:59 2002
--- shared_info.h Thu Jun 20 15:08:01 2002
***************
*** 140,144 ****
#define SHARED_VERSION_MAGIC CYGWIN_VERSION_MAGIC (SHARED_MAGIC, SHARED_VERSION)
! #define SHARED_INFO_CB 47112
#define CURR_SHARED_MAGIC 0x88e
--- 140,146 ----
#define SHARED_VERSION_MAGIC CYGWIN_VERSION_MAGIC (SHARED_MAGIC, SHARED_VERSION)
! /* #define SHARED_INFO_CB 47112 */
! /* tty_min class was extented with 2 int for keypad and cursor mode. F.P. June 2002 */
! #define SHARED_INFO_CB 48136
#define CURR_SHARED_MAGIC 0x88e
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/