delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2002/07/08/06:02:47

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
X-Authentication-Warning: smtp3.cern.ch: Host pspc7715.cern.ch [137.138.169.144] claimed to be cern.ch
Message-ID: <3D29632C.8E5DCB70@cern.ch>
Date: Mon, 08 Jul 2002 12:02:21 +0200
From: Fabien PERRIOLLAT <Fabien DOT Perriollat AT cern DOT ch>
Organization: CERN
X-Accept-Language: en,fr
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Re: "Application key pad mode" in cygwin console
References: <3CACCDA6 DOT CDCE45E9 AT cern DOT ch> <20020404222702 DOT GA4161 AT redhat DOT com>

--------------3AAAD96027EE3530F39772F0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

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 DOT Perriollat AT cern DOT ch
Division PS, CERN      Phone (+41 22) 767 5044   (+41) 79 201 0561
CH-1211 Geneva 23      Fax   (+41 22) 767 9145
====================================================================


--------------3AAAD96027EE3530F39772F0
Content-Type: text/plain; charset=us-ascii;
 name="cygwin_diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="cygwin_diff"

==============================================================================

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 DOT Perriollat AT cern DOT 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


--------------3AAAD96027EE3530F39772F0
Content-Type: text/plain; charset=us-ascii

--
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/
--------------3AAAD96027EE3530F39772F0--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019