Changes for International keyboards on win32 systems.
authorStephen Adams <edu/mit/csail/zurich/adams>
Tue, 20 Jan 1998 18:40:57 +0000 (18:40 +0000)
committerStephen Adams <edu/mit/csail/zurich/adams>
Tue, 20 Jan 1998 18:40:57 +0000 (18:40 +0000)
ntscreen changed to work better with international keyboards.  The
changes peek into the event queue to see how the key presses have been
translated into characters.  Modifiers are also tracked to enable them
to be detected in parallel with keyboard translations (so that
modifier chords like C-M- are detected).

Characters now have 16 bits of character code (instead of 7) to allow
8-bit ISO latin and Unicode characters.  Strings are still based on
8-bit characters.

Runtime changed to allow these `wide' characters to be written and
read e.g. #\<code62834>

Edwin modes changed to treat characters in the range 128-255 as normal
alphabetic characters (to enable accented characters).

v7/src/edwin/calias.scm
v7/src/edwin/modefs.scm
v7/src/microcode/ntscreen.c
v7/src/microcode/ntscreen.h
v7/src/microcode/object.h
v7/src/runtime/char.scm
v8/src/microcode/object.h

index 7be173080a36c58de1bc585f0f52f030108a4e77..be71556842e8515d8ebd3a3bccc26b0f631f4866 100644 (file)
@@ -1,8 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Id: calias.scm,v 1.16 1995/04/13 23:26:00 cph Exp $
+;;;    $Id: calias.scm,v 1.17 1998/01/20 18:40:34 adams Exp $
 ;;;
-;;;    Copyright (c) 1986, 1989-95 Massachusetts Institute of Technology
+;;;    Copyright (c) 1986, 1989-1998 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
   (cond ((char? key)
          (let ((code (char-code key))
                (bits (char-bits key)))
-           (let ((prefix
-                   (lambda (bits suffix)
-                     (if (zero? bits)
-                         suffix
-                         (string-append "M-" suffix)))))
-             (let ((process-code
-                     (lambda (bits)
-                       (cond ((< #x20 code #x7F)
-                              (prefix bits (string (ascii->char code))))
-                             ((= code #x09) (prefix bits "TAB"))
-                             ((= code #x0A) (prefix bits "LFD"))
-                             ((= code #x0D) (prefix bits "RET"))
-                             ((= code #x1B) (prefix bits "ESC"))
-                             ((= code #x20) (prefix bits "SPC"))
-                             ((= code #x7F) (prefix bits "DEL"))
-                             (else
-                               (string-append
-                                 (if (zero? bits) "C-" "C-M-")
-                                 (string
-                                   (ascii->char
-                                     (+ code
-                                        (if (<= #x01 code #x1A)
-                                            #x60
-                                            #x40))))))))))
-               (cond ((< bits 2)
-                      (process-code bits))
-                     ((and handle-prefixes? (< bits 4))
-                      (string-append (if (= 2 bits) "C-^ " "C-z ")
-                                     (process-code 0)))
-                     (else
-                       (char->name (unmap-alias-key key))))))))
-        ((special-key? key)
+          (define (prefix bits suffix)
+            (if (zero? bits)
+                suffix
+                (string-append "M-" suffix)))
+          (define (process-code bits)
+            (cond ((or (< #x20 code #x7F) ; 7-bit ASCII visible characters
+                       (> code #x7F))  ; 8-bit ISO characters
+                   (prefix bits (string (ascii->char code))))
+                  ((= code #x09) (prefix bits "TAB"))
+                  ((= code #x0A) (prefix bits "LFD"))
+                  ((= code #x0D) (prefix bits "RET"))
+                  ((= code #x1B) (prefix bits "ESC"))
+                  ((= code #x20) (prefix bits "SPC"))
+                  ((= code #x7F) (prefix bits "DEL"))
+                  (else
+                   (string-append
+                    (if (zero? bits) "C-" "C-M-")
+                    (string
+                     (ascii->char
+                      (+ code
+                         (if (<= #x01 code #x1A)
+                             #x60      ; C-a .. C-z
+                             #x40)))))))) ; C-@, C-] etc
+          (cond ((< bits 2)            ; no bits or Meta only
+                 (process-code bits))
+                ((and handle-prefixes? (< bits 4))
+                 (string-append (if (= 2 bits) "C-^ " "C-z ")
+                                (process-code 0)))
+                (else
+                 (char->name (unmap-alias-key key))))))
+       ((special-key? key)
          (special-key/name key))
         (else
           (error "emacs-key-name: Unknown key type" key))))
index 909746eec1786a8399de403240f1fe2d7b2876d3..9f7d7b77bfbc0ff2668301dc8e85396650cdcf38 100644 (file)
@@ -1,8 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Id: modefs.scm,v 1.150 1996/04/23 23:09:44 cph Exp $
+;;;    $Id: modefs.scm,v 1.151 1998/01/20 18:40:46 adams Exp $
 ;;;
-;;;    Copyright (c) 1985, 1989-96 Massachusetts Institute of Technology
+;;;    Copyright (c) 1985, 1989-1998 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
@@ -64,7 +64,11 @@ Most other major modes are defined by comparison to this one.")
 (define initial-buffer-name
   "*scheme*")
 
-(define-key 'fundamental char-set:graphic 'self-insert-command)
+;; The extra range allows international keyboards to insert 8-bit characters
+(define char-set:self-insert-keys
+  (char-set-union char-set:graphic (ascii-range->char-set 128 255)))
+
+(define-key 'fundamental char-set:self-insert-keys 'self-insert-command)
 (define-key 'fundamental char-set:numeric 'auto-digit-argument)
 (define-key 'fundamental #\- 'auto-negative-argument)
 (define-key 'fundamental #\rubout 'delete-backward-char)
@@ -74,7 +78,7 @@ Most other major modes are defined by comparison to this one.")
 Like Fundamental mode, but no self-inserting characters.
 Digits and - are bound to prefix argument commands.")
 
-(define-key 'read-only char-set:graphic 'undefined)
+(define-key 'read-only char-set:self-insert-keys 'undefined)
 (define-key 'read-only char-set:numeric 'digit-argument)
 (define-key 'read-only #\- 'negative-argument)
 (define-key 'read-only '(#\c-x #\c-q) 'no-toggle-read-only)
@@ -83,7 +87,7 @@ Digits and - are bound to prefix argument commands.")
   "Major mode for read-only buffers.
 Like Fundamental mode, but no self-inserting characters.")
 
-(define-key 'read-only-noarg char-set:graphic 'undefined)
+(define-key 'read-only-noarg char-set:self-insert-keys 'undefined)
 (define-key 'read-only-noarg '(#\c-x #\c-q) 'no-toggle-read-only)
 \f
 (define-key 'fundamental #\c-space 'set-mark-command)
index 0a60c54ac3460f4552a33dad28e7bf1cb78640d6..3bbb49442821f5fcc65c11af9e3465068c87c7b1 100644 (file)
@@ -1,8 +1,8 @@
 /* -*-C-*-
 
-$Id: ntscreen.c,v 1.31 1997/11/29 04:37:25 cph Exp $
+$Id: ntscreen.c,v 1.32 1998/01/20 18:40:13 adams Exp $
 
-Copyright (c) 1993-97 Massachusetts Institute of Technology
+Copyright (c) 1993-1998 Massachusetts Institute of Technology
 
 This material was developed by the Scheme project at the Massachusetts
 Institute of Technology, Department of Electrical Engineering and
@@ -161,8 +161,11 @@ static BOOL ScrollScreenHorz (HWND, WORD, WORD);
 static BOOL ScrollScreenVert (HWND, WORD, WORD);
 static BOOL SizeScreen (HWND, WORD, WORD);
 static BOOL handle_window_pos_changing (HWND, LPWINDOWPOS);
-static VOID ProcessScreenCharacter (HWND, int, DWORD);
+//static VOID ProcessScreenCharacter (HWND, int, DWORD);
+static VOID reset_modifiers ();
+static void record_modifier_transition (WPARAM, LPARAM, BOOL);
 static BOOL Process_KeyDown (HWND, UINT, WPARAM, LPARAM);
+static BOOL Process_KeyUp   (HWND, UINT, WPARAM, LPARAM);
 static VOID ProcessMouseButton (HWND, UINT, UINT, LONG, BOOL);
 static VOID ProcessCloseMessage (SCREEN);
 static BOOL WriteScreenBlock (HWND, LPSTR, int);
@@ -190,7 +193,7 @@ extern LRESULT ScreenCommand_ChooseFont (HWND, WORD);
 extern LRESULT ScreenCommand_ChooseBackColor (HWND, WORD);
 
 static SCREEN_EVENT * alloc_event (SCREEN, SCREEN_EVENT_TYPE);
-static int GetControlKeyState (void);
+static int  GetModifiers(void);
 
 //void *xmalloc (int size);
 //void xfree (void*);
@@ -679,6 +682,7 @@ ScreenWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
       case WM_SYSKEYDOWN:
       case WM_KEYDOWN:
+         record_modifier_transition (wParam, lParam, TRUE);
          if (IsIconic (hWnd)) goto use_default;
          if (Process_KeyDown (hWnd, uMsg, wParam, lParam))
           goto use_default;
@@ -695,7 +699,12 @@ ScreenWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
       case WM_SYSKEYUP:
       case WM_KEYUP:
+         record_modifier_transition (wParam, lParam, FALSE);
          if (IsIconic (hWnd)) goto use_default;
+         if (Process_KeyUp (hWnd, uMsg, wParam, lParam))
+          goto  use_default;
+        else
+          return  0L;
 #if 1
         return (1L);
 #ifdef WINDOWSLOSES
@@ -720,13 +729,14 @@ ScreenWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
       case WM_SYSCHAR:
       case WM_CHAR:
          if (IsIconic (hWnd)) goto use_default;
-        ProcessScreenCharacter (hWnd,
-                                LOBYTE (LOWORD(wParam)),
-                                (DWORD) lParam);
+//      ProcessScreenCharacter (hWnd,
+//                              LOBYTE (LOWORD(wParam)),
+//                              (DWORD) lParam);
         break ;
 
       case WM_SETFOCUS:
         SetScreenFocus (hWnd);
+         reset_modifiers ();
          goto use_default;
 
       case WM_KILLFOCUS:
@@ -1852,63 +1862,112 @@ flush_typeahead (SCREEN screen)
 }
 \f
 //---------------------------------------------------------------------------
-//
+
+/* Reportedly, GetKeyState ans MapVirtualKey on Windows 95 do not
+actually distinguish between left and right keys as advertized.  We
+track the left and right control and alt keys ourselves.  This is
+necessary for detecting `double meta' key presses on keyboards where
+AltGr is used to get an ordinary character.  For example, on the
+Swiss-French keyboard, @ is obtained from AltGr-2.  To complicate
+things, the AltGr key is represented as having both left control and
+right alt keys pressed.  To generate M-@ on this keyboard we check for
+both alt keys being pressed.  */
+
 //---------------------------------------------------------------------------
 
-#define KEYDATA_ALT_BIT 0x20000000
+#define MOD_LCONTROL 0
+#define MOD_RCONTROL 1
+#define MOD_LMENU 2
+#define MOD_RMENU 3
 
-static int
-GetControlKeyState(void)
+static BOOL modifiers[4] = {FALSE, FALSE, FALSE, FALSE};
+
+static VOID
+reset_modifiers ()
 {
-  return
-    (  (((GetKeyState (VK_MENU)) < 0)     ?     SCREEN_ALT_PRESSED   : 0)
-     | (((GetKeyState (VK_CONTROL)) < 0)  ?     SCREEN_CTRL_PRESSED  : 0)
-     | (((GetKeyState (VK_SHIFT)) < 0)    ?     SCREEN_SHIFT_PRESSED : 0)
-     | (((GetKeyState (VK_NUMLOCK)) & 1)  ?     SCREEN_NUMLOCK_ON    : 0)
-     | (((GetKeyState (VK_SCROLL)) & 1)   ?     SCREEN_SCROLLLOCK_ON : 0)
-     | (((GetKeyState (VK_CAPITAL)) & 1)  ?     SCREEN_CAPSLOCK_ON   : 0));
+  // This is used when we regain focus, since we cannot regenerate the modifier
+  // state.
+  modifiers[0] = modifiers[1] = modifiers[2] = modifiers[3] = FALSE;
 }
 
-static VOID _fastcall
-make_key_event (SCREEN screen, int ch, int vk_code, DWORD lKeyData)
-{
-  SCREEN_EVENT  *event;
+static BOOL
+test_modifier (int vk)
+{
+  switch (vk) {
+  case VK_LCONTROL:   return  modifiers[MOD_LCONTROL];
+  case VK_RCONTROL:   return  modifiers[MOD_RCONTROL];
+  case VK_LMENU:      return  modifiers[MOD_LMENU];
+  case VK_RMENU:      return  modifiers[MOD_RMENU];
+  default:            return  GetKeyState (vk) < 0;
+  }
+}
 
-  if ((screen->mode_flags & SCREEN_MODE_VK_KEYS) == 0  &&  ch == -1)
+static void
+record_modifier_transition (WPARAM wParam, LPARAM lParam, BOOL updown)
+{
+  int  i;
+  switch (wParam) {
+  default:
     return;
-
-  event = alloc_event (screen, SCREEN_EVENT_TYPE_KEY);
-  if (event) {
-    event->event.key.repeat_count = lKeyData & 0xffff;
-    event->event.key.virtual_keycode = vk_code;
-    event->event.key.virtual_scancode = (lKeyData >> 16) & 0xff;
-    event->event.key.ch = ch;
-    event->event.key.control_key_state = GetControlKeyState();
+  case VK_MENU:
+    i = (lParam & 0x1000000) ? MOD_RMENU : MOD_LMENU;
+    break;
+  case VK_CONTROL:
+    i = (lParam & 0x1000000) ? MOD_RCONTROL : MOD_LCONTROL;
+    break;
   }
+  modifiers[i] = updown;
 }
 
-// We learn which scan codes are for keys that we process ourselves and
-// hence do not want to accept as WM_CHARS from Transalate Message
+static int
+GetPlainModifiers()
+{
+  int mods = 0;
+  if (test_modifier (VK_SHIFT))    mods |= SCREEN_SHIFT_PRESSED;
+  if (test_modifier (VK_CAPITAL))  mods |= SCREEN_CAPSLOCK_ON;
+  if (test_modifier (VK_LCONTROL)) mods |= SCREEN_LEFT_CONTROL_PRESSED;
+  if (test_modifier (VK_RCONTROL)) mods |= SCREEN_RIGHT_CONTROL_PRESSED;
+  if (test_modifier (VK_LMENU))    mods |= SCREEN_LEFT_ALT_PRESSED;
+  if (test_modifier (VK_RMENU))    mods |= SCREEN_RIGHT_ALT_PRESSED;
 
-BOOL scan_codes_to_avoid[256] = {0};
+  if (mods & (SCREEN_RIGHT_ALT_PRESSED | SCREEN_LEFT_ALT_PRESSED))
+    mods |= SCREEN_ALT_PRESSED;
 
-//---------------------------------------------------------------------------
-//  VOID ProcessScreenCharacter (HWND hWnd, int ch, DWORD lKeyData)
-//---------------------------------------------------------------------------
+  if (mods & (SCREEN_RIGHT_CONTROL_PRESSED | SCREEN_LEFT_CONTROL_PRESSED))
+    mods |= SCREEN_CONTROL_PRESSED;
 
-static VOID
-ProcessScreenCharacter (HWND hWnd, int ch, DWORD lKeyData)
+  return  mods;
+}
+
+static int
+GetModifiers(void)
 {
-  // Process a WM_CHAR or WM_SYSCHAR character
-   SCREEN  screen = GETSCREEN (hWnd);
-   
-   if (NULL == screen)
-      return;
-    
+  int mods =
+    GetPlainModifiers() & ~ (SCREEN_ALT_PRESSED | SCREEN_CONTROL_PRESSED);
+
+  // If AltGr pressed, remove it.
+  if (mods & (SCREEN_RIGHT_ALT_PRESSED | SCREEN_LEFT_CONTROL_PRESSED)
+      == (SCREEN_RIGHT_ALT_PRESSED | SCREEN_LEFT_CONTROL_PRESSED))
+    mods &= ~ (SCREEN_RIGHT_ALT_PRESSED | SCREEN_LEFT_CONTROL_PRESSED);
+
+  if (mods & (SCREEN_RIGHT_ALT_PRESSED | SCREEN_LEFT_ALT_PRESSED))
+    mods |= SCREEN_ALT_PRESSED;
+
+  if (mods & (SCREEN_RIGHT_CONTROL_PRESSED | SCREEN_LEFT_CONTROL_PRESSED))
+    mods |= SCREEN_CONTROL_PRESSED;
+
+  return  mods;
+}
+
+static VOID _fastcall
+make_key_event (SCREEN screen, int ch, int vk_code, DWORD lKeyData, int CCstate)
+{
+  SCREEN_EVENT  *event;
+
    // check for bindings:
-   {
+   if (CCstate == 0) {
      int  i;
-     for (i=0; i<screen->n_bindings; i++)
+     for (i = 0; i < screen->n_bindings; i++)
        if (screen->bindings[i].key == ch)
        {
         if (SendMessage (screen->hWnd,
@@ -1921,122 +1980,172 @@ ProcessScreenCharacter (HWND hWnd, int ch, DWORD lKeyData)
        }
    } 
 
-   // exclude characters that TranslateMessage produces but we handle
-   // differently in order to get all those wonderful control-shift-meta
-   // things
+  if ((screen->mode_flags & SCREEN_MODE_VK_KEYS) == 0  &&  ch == -1)
+    return;
 
-   if (scan_codes_to_avoid[(lKeyData >> 16) & 0xff])
-     return;
+  event = alloc_event (screen, SCREEN_EVENT_TYPE_KEY);
+  if (event) {
+    event->event.key.repeat_count = 1;
+    event->event.key.virtual_keycode = vk_code;
+    event->event.key.virtual_scancode = (lKeyData >> 16) & 0xff;
+    event->event.key.ch = ch;
+    event->event.key.control_key_state = CCstate;
 
-   switch (ch) {
-     case -1:
-     return;
-   }
+#if 0
+    {
+      static HWND disp = NULL;
+      static char prevline2[50] = {0};
+      static char prevline1[50] = {0};
+      char line[50], buf[100], name[20];
+      if (disp==NULL)
+       disp = CreateWindowEx(WS_EX_TOPMOST, "STATIC", "", 
+                             WS_VISIBLE | SS_LEFT | SS_NOPREFIX,
+                             0, 0, 130, 20+3*20,
+                             0, 0, ghInstance, 0);
+      if (ch==-1)
+       sprintf(name, "VK_x%02X", vk_code);
+      else if (' ' < ch && ch < ASCII_DEL)
+       sprintf(name, "%c", ch);
+      else if (ch>127)
+       sprintf(name, "code x%02X %c", ch, ch);
+      else if (ch==' ')
+       sprintf(name, "Space");
+      else
+       sprintf(name, "code x%02X", ch);
+      sprintf(line, "%s%s%s%s",
+             (CCstate & SCREEN_ALT_PRESSED) ? "M-" : "",
+             (CCstate & SCREEN_CONTROL_PRESSED) ? "C-" : "",
+             (CCstate & SCREEN_SHIFT_PRESSED) ? "S-" : "",
+             name);
+      sprintf(buf,"%s\r\n%s\r\n%s", prevline2, prevline1, line);
+      strcpy (prevline2, prevline1);
+      strcpy (prevline1, line);
+      SetWindowText (disp, buf);
+    }
+#endif
+  }
+}
 
-   make_key_event (screen, ch, 0, lKeyData);
+static BOOL
+Translate_vk_to_tty_char (SCREEN screen, int vk, LPARAM lParam)
+{
+  // Tranlate to default Emacs-oid key bindings to make console
+  // edwin happy
+  int ch = -1;
+  switch (vk) {
+  case VK_UP:     ch = ASCII_CONTROLIFY('P');   break;
+  case VK_DOWN:   ch = ASCII_CONTROLIFY('N');   break;
+  case VK_LEFT:   ch = ASCII_CONTROLIFY('B');   break;
+  case VK_RIGHT:  ch = ASCII_CONTROLIFY('F');   break;
+  case VK_PRIOR:
+    make_key_event (screen, 'V', 0, lParam, SCREEN_ALT_PRESSED);
+    return  TRUE;
+  case VK_NEXT:   ch = ASCII_CONTROLIFY('V');   break;
+  case VK_DELETE: ch = ASCII_DEL;               break;
+  }
+  if (ch != -1)
+    make_key_event (screen, ch, 0, lParam, 0);
+  return  TRUE;
 }
 
 static BOOL
 Process_KeyDown (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-  // processing for non-ascii VKs
-  // Assume msg = WM_KEYDOWN or WM_SYSKEYDOWN
-  // returns flag to say if DefWindowProc should be called.
   SCREEN  screen = GETSCREEN (hWnd);
-  BOOL  default_ok = TRUE;
   int   scan_code = (lParam >> 16) & 0xff;
+  int   extended_key = (lParam & 0x1000000);
+  int   vk = wParam;
 
-  switch (wParam) {
-    case VK_BACK:
-      make_key_event (screen, ASCII_DEL, 0, lParam);
-      scan_codes_to_avoid[scan_code] = TRUE;
-      return  TRUE;
+  MSG   message;
+  BOOL  found_wm_chars = FALSE;
 
-    case VK_SPACE:
-      make_key_event (screen, ' ', 0, lParam);
-      scan_codes_to_avoid[scan_code] = TRUE;
+  // If Alt is pressed and the key is from the keypad, we are in the middle
+  // of and ALT+numbers sequence.  We will get the char when Alt is released.
+  if (msg == WM_SYSKEYDOWN) {
+    if (VK_NUMPAD0 <= vk && vk <= VK_NUMPAD9)
       return  TRUE;
-
-    case '0':  case '1':  case '2':  case '3':  case '4':
-    case '5':  case '6':  case '7':  case '8':  case '9':
-      // This is very naughty.  We should figure out how to allow the
-      // keyboard to produce the correct  keys according to the keyboard
-      // layout.
-      if (GetKeyState(VK_SHIFT)<0)
-       make_key_event (screen, ")!@#$%^&*("[wParam-'0'], 0, lParam);
-      else
-       make_key_event (screen, wParam, 0, lParam);
-      scan_codes_to_avoid[scan_code] = TRUE;
+    if (!extended_key &&
+       (vk == VK_HOME  || vk == VK_UP    || vk == VK_PRIOR ||
+        vk == VK_LEFT  ||                   vk == VK_RIGHT ||
+        vk == VK_END   || vk == VK_DOWN  || vk == VK_NEXT  ||
+        vk == VK_INSERT))
       return  TRUE;
+  }
 
-    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
-    case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
-    case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
-    case 'V': case 'W': case 'X': case 'Y': case 'Z':
-    {
-      // This is very naughty.  We should figure out how to allow the
-      // keyboard to produce the correct  keys according to the keyboard
-      // layout.
-      int  shift = ((GetKeyState(VK_SHIFT)>>15) ^ GetKeyState(VK_CAPITAL)) & 1;
-      int  control = GetKeyState(VK_CONTROL) < 0;
-      int  alt = GetKeyState(VK_MENU) < 0;
-
-      if (control)
-       make_key_event (screen, wParam-64, 0, lParam);
-      else if (shift)
-       make_key_event (screen, wParam,    0, lParam);
-      else
-       make_key_event (screen, wParam+32, 0, lParam);
-      scan_codes_to_avoid[scan_code] = TRUE;
+  if (vk == VK_LSHIFT   || vk == VK_RSHIFT   || vk == VK_SHIFT ||
+      vk == VK_LMENU    || vk == VK_RMENU    || vk == VK_MENU  ||
+      vk == VK_LCONTROL || vk == VK_RCONTROL || vk == VK_CONTROL ||
+      vk == VK_CAPITAL  || vk == VK_NUMLOCK  || vk == VK_SCROLL) {
+    return  TRUE;
+  }
+
+  while (PeekMessage (&message, hWnd, WM_CHAR, WM_CHAR, PM_REMOVE) ||
+        PeekMessage (&message, hWnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE)) {
+    int mods = GetPlainModifiers();
+    int event_mods = 0;
+    if (vk == VK_BACK && message.wParam == 8)
+      message.wParam = ASCII_DEL;
+    if (vk == VK_SPACE && (mods & SCREEN_CONTROL_PRESSED))
+      event_mods |= SCREEN_CONTROL_PRESSED;
+    if (msg == WM_SYSKEYDOWN ||
+       ((mods & SCREEN_LEFT_ALT_PRESSED) && (mods & SCREEN_RIGHT_ALT_PRESSED)))
+      event_mods |= SCREEN_ALT_PRESSED;
+    make_key_event (screen, message.wParam, 0, lParam, event_mods);
+    found_wm_chars = TRUE;
+  }
+  if (found_wm_chars)
+    return TRUE;
+
+  if (vk == VK_LEFT   || vk == VK_RIGHT  || vk == VK_UP     || vk == VK_DOWN ||
+      vk == VK_HOME   || vk == VK_END    || vk == VK_PRIOR  || vk == VK_NEXT ||
+      vk == VK_INSERT || vk == VK_DELETE || (vk >= VK_F1 && vk <= VK_F24)) {
+    if (screen->mode_flags & SCREEN_MODE_VK_KEYS) {
+      make_key_event (screen, -1, vk, lParam, GetModifiers());
       return  TRUE;
+    } else {
+      return  Translate_vk_to_tty_char (screen, vk, lParam);
     }
+  }
 
-    case VK_F1:
-    case VK_F2:
-    case VK_F3:
-    case VK_F4:
-    case VK_F5:
-    case VK_F6:
-    case VK_F7:
-    case VK_F8:
-    case VK_F9:
-    case VK_F10:
-    case VK_F11:
-    case VK_F12:
-    case VK_UP:
-    case VK_DOWN:
-    case VK_LEFT:
-    case VK_RIGHT:
-    case VK_INSERT:
-    case VK_DELETE:
-    case VK_HOME:
-    case VK_END:
-    case VK_PRIOR:
-    case VK_NEXT:
-      if (screen->mode_flags & SCREEN_MODE_VK_KEYS)
-       make_key_event (screen, -1, wParam, lParam);
-      else {
-       int ch;
-       switch (wParam) {
-         // Tranlate to default Emacs-oid key bindings to make console
-         // edwin happy
-         default:        ch = -1;       break;
-         case VK_UP:     ch = ASCII_CONTROLIFY('P');   break;
-         case VK_DOWN:   ch = ASCII_CONTROLIFY('N');   break;
-         case VK_LEFT:   ch = ASCII_CONTROLIFY('B');   break;
-         case VK_RIGHT:  ch = ASCII_CONTROLIFY('F');   break;
-         case VK_PRIOR:  ch = ASCII_METAFY('V');       break;
-         case VK_NEXT:   ch = ASCII_CONTROLIFY('V');   break;
-         case VK_DELETE: ch = ASCII_DEL;               break;
-       }
-       if (ch != -1)
-         make_key_event (screen, ch, 0, lParam);
-      }
-      return  TRUE;
+  // At this point the keypress didnt generate a character because it
+  // doesn't understand the combination of modifiers, or the character
+  // could be a dead character.
 
-    default:
-      return  TRUE;
+  if (PeekMessage (&message, hWnd, WM_DEADCHAR, WM_DEADCHAR, PM_REMOVE) ||
+      PeekMessage (&message, hWnd, WM_SYSDEADCHAR, WM_SYSDEADCHAR, PM_REMOVE)) {
+    return  TRUE;
+  }
+
+  if (('A' <= vk && vk <= 'Z') ||
+      ('0' <= vk && vk <= '9') ||
+      (vk == VK_SPACE)) {
+    make_key_event (screen, vk, 0, lParam, GetPlainModifiers());
+    return  TRUE;
+  }
+
+  return  TRUE;
+}
+
+static BOOL
+Process_KeyUp (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+  SCREEN  screen = GETSCREEN (hWnd);
+  int   vk = wParam;
+
+  // Releasing ALT might give us an ALT+numbers character.
+  if (vk == VK_MENU) {
+    MSG   message;
+    BOOL  found_wm_chars = FALSE;
+    while (PeekMessage (&message, hWnd, WM_CHAR, WM_CHAR, PM_REMOVE) ||
+          PeekMessage (&message, hWnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE)) {
+      make_key_event (screen, message.wParam, 0, lParam, 0);
+      found_wm_chars = TRUE;
     }
+    if (found_wm_chars)
+      return  TRUE;
+    return  FALSE;    // Don't activate the system menu!
+  }
+  return  TRUE;
 }
 
 static VOID
@@ -2049,7 +2158,7 @@ ProcessCloseMessage (SCREEN screen)
 
 static VOID
 ProcessMouseButton (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
-                   BOOL up)
+                    BOOL up)
 {
   SCREEN screen = GETSCREEN (hWnd) ;
   SCREEN_EVENT * event ;
index 84640622cb543595293a2d7f5144cb962a04df59..33d7ec194b2f019af24cc10b30b9ffa397f07ec4 100644 (file)
@@ -1,8 +1,8 @@
 /* -*-C-*-
 
-$Id: ntscreen.h,v 1.15 1997/05/17 06:59:56 cph Exp $
+$Id: ntscreen.h,v 1.16 1998/01/20 18:39:45 adams Exp $
 
-Copyright (c) 1993-97 Massachusetts Institute of Technology
+Copyright (c) 1993-1998 Massachusetts Institute of Technology
 
 This material was developed by the Scheme project at the Massachusetts
 Institute of Technology, Department of Electrical Engineering and
@@ -92,25 +92,19 @@ typedef struct {
   int  key_down : 1;
 } SCREEN_KEY_EVENT_RECORD;
 
-// control_key_state flags
-
-//#define SCREEN_RIGHT_ALT_PRESSED     0x0001 // the right alt key is pressed.
-//#define SCREEN_LEFT_ALT_PRESSED      0x0002 // the left alt key is pressed.
-//#define SCREEN_RIGHT_CTRL_PRESSED    0x0004 // the right ctrl key is pressed.
-//#define SCREEN_LEFT_CTRL_PRESSED     0x0008 // the left ctrl key is pressed.
-//#define SCREEN_SHIFT_PRESSED         0x0010 // the shift key is pressed.
-//#define SCREEN_NUMLOCK_ON            0x0020 // the numlock light is on.
-//#define SCREEN_SCROLLLOCK_ON         0x0040 // the scrolllock light is on.
-//#define SCREEN_CAPSLOCK_ON           0x0080 // the capslock light is on.
-//#define SCREEN_ENHANCED_KEY          0x0100 // the key is enhanced.
-//#define SCREEN_ALT_KEY_PRESSED       0x0200 // Any alt key pressed
-
-#define SCREEN_ALT_PRESSED       0x0001 // An alt key is pressed.
-#define SCREEN_CTRL_PRESSED      0x0002 // a ctrl key is pressed.
-#define SCREEN_SHIFT_PRESSED     0x0004 // a shift key is pressed.
-#define SCREEN_NUMLOCK_ON        0x0020 // the numlock light is on.
-#define SCREEN_SCROLLLOCK_ON     0x0040 // the scrolllock light is on.
-#define SCREEN_CAPSLOCK_ON       0x0080 // the capslock light is on.
+// control_key_state flags.  Only used for effective modifiers (i.e.
+// not set when already incorporated into a character translation.
+
+#define SCREEN_ALT_PRESSED            0x0001 // An Alt key is pressed.
+#define SCREEN_CONTROL_PRESSED        0x0002 // a Ctrl key is pressed.
+#define SCREEN_SHIFT_PRESSED          0x0004 // a Shift key is pressed.
+#define SCREEN_CAPSLOCK_ON            0x0008
+#define SCREEN_LEFT_CONTROL_PRESSED   0x0010
+#define SCREEN_RIGHT_CONTROL_PRESSED  0x0020
+#define SCREEN_LEFT_ALT_PRESSED       0x0040
+#define SCREEN_RIGHT_ALT_PRESSED      0x0080
+#define SCREEN_NUMLOCK_ON             0x0100
+
 
 #define SCREEN_ANY_ALT_KEY_MASK             SCREEN_ALT_PRESSED
 
index dbbb297a72b32072812d42d25ee898dce94b07ca..97d3dceac8b5f1c798358d608478bde63785ef71 100644 (file)
@@ -1,8 +1,8 @@
 /* -*-C-*-
 
-$Id: object.h,v 9.47 1997/07/15 22:06:24 adams Exp $
+$Id: object.h,v 9.48 1998/01/20 18:40:57 adams Exp $
 
-Copyright (c) 1987-95 Massachusetts Institute of Technology
+Copyright (c) 1987-1998 Massachusetts Institute of Technology
 
 This material was developed by the Scheme project at the Massachusetts
 Institute of Technology, Department of Electrical Engineering and
@@ -355,9 +355,9 @@ extern SCHEME_OBJECT * memory_base;
 /* Character Operations */
 
 #define ASCII_LENGTH CHAR_BIT  /* CHAR_BIT in config.h - 8 for unix  */
-#define CODE_LENGTH 7
+#define CODE_LENGTH 16
 #define BITS_LENGTH 5
-#define MIT_ASCII_LENGTH 12
+#define MIT_ASCII_LENGTH 21
 
 #define CHAR_BITS_META                 01
 #define CHAR_BITS_CONTROL      02
index b107b972cdb95eb7a864fda0021f5ba11e7263b8..112c8b934c97907b7db32616ec0005e24670d8aa 100644 (file)
@@ -1,8 +1,8 @@
 #| -*-Scheme-*-
 
-$Id: char.scm,v 14.7 1997/10/15 03:20:42 adams Exp $
+$Id: char.scm,v 14.8 1998/01/20 18:40:24 adams Exp $
 
-Copyright (c) 1988-97 Massachusetts Institute of Technology
+Copyright (c) 1988-1998 Massachusetts Institute of Technology
 
 This material was developed by the Scheme project at the Massachusetts
 Institute of Technology, Department of Electrical Engineering and
@@ -38,7 +38,8 @@ MIT in each case. |#
 (declare (usual-integrations))
 \f
 (define-primitives
-  char? make-char char-code char-bits char->integer integer->char char->ascii
+  (char? 1)
+  make-char char-code char-bits char->integer integer->char char->ascii
   char-ascii? ascii->char char-upcase char-downcase)
 
 (define-integrable char-code-limit #x80)
@@ -169,8 +170,15 @@ MIT in each case. |#
   (if (substring-ci=? string start end "Newline" 0 7)
       (char-code char:newline)
       (or (-map-> named-codes string start end)
+         (numeric-name->code string start end)
          (error "Unknown character name" (substring string start end)))))
 
+(define (numeric-name->code string start end)
+  (and (> (- end start) 6)
+       (substring-ci=? string start (+ start 5) "<code" 0 5)
+       (substring-ci=? string (- end 1)  end    ">" 0 1)
+       (string->number (substring string (+ start 5) (- end 1)) 10)))
+
 (define (char->name char #!optional slashify?)
   (if (default-object? slashify?) (set! slashify? false))
   (define (loop weight bits)
@@ -187,16 +195,16 @@ MIT in each case. |#
                  ((char-graphic? base-char)
                   (string base-char))
                  (else
-                  (string-append "<code "
-                                 (write-to-string code)
+                  (string-append "<code"
+                                 (number->string code 10)
                                  ">")))))
        (let ((qr (integer-divide bits 2)))
          (let ((rest (loop (fix:* weight 2) (integer-divide-quotient qr))))
            (if (fix:= 0 (integer-divide-remainder qr))
                rest
                (string-append (or (<-map- named-bits weight)
-                                  (string-append "<bit "
-                                                 (write-to-string weight)
+                                  (string-append "<bits-"
+                                                 (number->string weight 10)
                                                  ">"))
                               "-"
                               rest))))))
index a66aabdbae838a9d3f7bbb07a1fb437d5aad7035..c471510b6991d219a68c7a9721d40ef164353fe5 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: object.h,v 9.47 1995/09/18 22:32:56 cph Exp $
+$Id: object.h,v 9.48 1998/01/20 18:39:35 adams Exp $
 
 Copyright (c) 1987-95 Massachusetts Institute of Technology
 
@@ -386,9 +386,9 @@ extern SCHEME_OBJECT * memory_base;
 /* Character Operations */
 
 #define ASCII_LENGTH CHAR_BIT  /* CHAR_BIT in config.h - 8 for unix  */
-#define CODE_LENGTH 7
+#define CODE_LENGTH 16
 #define BITS_LENGTH 5
-#define MIT_ASCII_LENGTH 12
+#define MIT_ASCII_LENGTH 21
 
 #define CHAR_BITS_META                 01
 #define CHAR_BITS_CONTROL      02