(msb--choose-menu): Fix error format string.
[bpt/emacs.git] / src / w32inevt.c
index e41c57e..beeaae6 100644 (file)
@@ -1,21 +1,22 @@
 /* Input event support for Windows NT port of GNU Emacs.
-   Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1995 Free Software Foundation, Inc.
 
-   This file is part of GNU Emacs.
+This file is part of GNU Emacs.
 
-   GNU Emacs is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any later
-   version.
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
 
-   GNU Emacs is distributed in the hope that it will be useful, but WITHOUT
-   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-   more details.
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
 
-   You should have received a copy of the GNU General Public License along
-   with GNU Emacs; see the file COPYING.  If not, write to the Free Software
-   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
 
    Drew Bliss                   01-Oct-93
      Adapted from ntkbd.c by Tim Fleehart
@@ -36,9 +37,6 @@
 /* stdin, from ntterm */
 extern HANDLE keyboard_handle;
 
-/* Indicate mouse motion, from keyboard.c */
-extern int mouse_moved;
-
 /* Info for last mouse motion */
 static COORD movement_pos;
 static DWORD movement_time;
@@ -92,24 +90,67 @@ get_frame (void)
   return selected_frame;
 }
 
-#ifdef MULTI_FRAME
-#define SET_FRAME(o, f) XSET (o, Lisp_Frame, f)
-#else
-#define SET_FRAME(o, f) ((o) = Qnil)
-#endif
-
-/* Translate console modifiers to emacs modifiers.  */
+/* Translate console modifiers to emacs modifiers.  
+   German keyboard support (Kai Morgan Zeise 2/18/95).  */
 static int 
-nt_kbd_mods_to_emacs (DWORD mods)
+win32_kbd_mods_to_emacs (DWORD mods)
 {
-  return ((mods & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) ?
-         meta_modifier : 0) |
-           ((mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) ?
-            ctrl_modifier : 0) |
-              ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) ?
-               shift_modifier : 0);
+  int retval = 0;
+
+  /* If AltGr has been pressed, remove it.  */
+  if ((mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED)) 
+      == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
+    mods &= ~ (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED);
+
+  if (mods & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
+    retval = meta_modifier;
+  
+  if (mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
+    {
+      retval |= ctrl_modifier;
+      if ((mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) 
+         == (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
+       retval |= meta_modifier;
+    }
+
+  if (((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) == SHIFT_PRESSED)
+      || ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) == CAPSLOCK_ON))
+    retval |= shift_modifier;
+
+  return retval;
 }
 
+/* The return code indicates key code size. */
+static int
+win32_kbd_patch_key (KEY_EVENT_RECORD *event)
+{
+  unsigned int key_code = event->wVirtualKeyCode;
+  unsigned int mods = event->dwControlKeyState;
+  BYTE keystate[256];
+  static BYTE ansi_code[4];
+  static int isdead;
+
+  if (isdead == 2)
+    {
+      event->uChar.AsciiChar = ansi_code[2];
+      isdead = 0;
+      return 1;
+    }
+  if (event->uChar.AsciiChar != 0) 
+    return 1;
+  memset (keystate, 0, sizeof (keystate));
+  if (mods & SHIFT_PRESSED) 
+    keystate[VK_SHIFT] = 0x80;
+  if (mods & CAPSLOCK_ON) 
+    keystate[VK_CAPITAL] = 1;
+  isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
+                   keystate, (LPWORD) ansi_code, 0);
+  if (isdead == 0) 
+    return 0;
+  event->uChar.AsciiChar = ansi_code[0];
+  return isdead;
+}
+  
 /* Map virtual key codes into:
    -1 - Ignore this key
    -2 - ASCII char
@@ -121,7 +162,11 @@ nt_kbd_mods_to_emacs (DWORD mods)
 
 static int map_virt_key[256] =
 {
+#ifdef MULE
+  -3,
+#else
   -1,
+#endif
   -1,                 /* VK_LBUTTON */
   -1,                 /* VK_RBUTTON */
   0x69,               /* VK_CANCEL */
@@ -206,7 +251,7 @@ static int map_virt_key[256] =
   0xd5,               /* VK_F24 */
   -1, -1, -1, -1, -1, -1, -1, -1,
   0x7f,               /* VK_NUMLOCK */
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x9f */
+      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x9f */
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xaf */
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb9 */
   -2,                 /* ; */
@@ -216,21 +261,26 @@ static int map_virt_key[256] =
   -2,                 /* . */
   -2,                 /* / */
   -2,                 /* ` */
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xcf */
+      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xcf */
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xda */
-  -2,                 /* [ */
-  -2,                 /* - */
-  -2,                 /* ] */
-  -2,                 /* ' */
-  -1, /* 0xdf */
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xef */
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 0xff */
+                                              -2, -2, -2, -2, -2, /* 0xdf */
+  -2, -2, -2, -2, -2,
+                      -1, /* 0xe5 */
+                          -2, /* oxe6 */
+                              -1, -1, /* 0xe8 */
+                                      -2, -2, -2, -2, -2, -2, -2, /* 0xef */
+  -2, -2, -2, -2, -2, -2,
+                          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 0xff */
 };
 
+/* return code -1 means that event_queue_ptr won't be incremented. 
+   In other word, this event makes two key codes.   (by himi)       */
 static int 
 key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev)
 {
   int map;
+  int key_flag = 0;
+  static BOOL map_virt_key_init_done;
   
   /* Skip key-up events.  */
   if (event->bKeyDown == FALSE)
@@ -241,6 +291,17 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev)
       printf ("Unknown key code %d\n", event->wVirtualKeyCode);
       return 0;
     }
+
+  /* Patch needed for German keyboard. Ulrich Leodolter (1/11/95).  */
+  if (! map_virt_key_init_done) 
+    {
+      short vk;
+
+      if ((vk = VkKeyScan (0x3c)) >= 0 && vk < 256) map_virt_key[vk] = -2; /* less */
+      if ((vk = VkKeyScan (0x3e)) >= 0 && vk < 256) map_virt_key[vk] = -2; /* greater */
+
+      map_virt_key_init_done = TRUE;
+    }
   
   /* BUGBUG - Ignores the repeat count
      It's questionable whether we want to obey the repeat count anyway
@@ -258,8 +319,28 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev)
     {
       /* ASCII */
       emacs_ev->kind = ascii_keystroke;
-      XSET (emacs_ev->code, Lisp_Int, event->uChar.AsciiChar);
+      key_flag = win32_kbd_patch_key (event); /* 95.7.25 by himi */
+      if (key_flag == 0) 
+       return 0;
+      XSETINT (emacs_ev->code, event->uChar.AsciiChar);
+    }
+#ifdef MULE
+  /* for IME */
+  else if (map == -3)
+    {
+      if ((event->dwControlKeyState & NLS_IME_CONVERSION)
+         && !(event->dwControlKeyState & RIGHT_ALT_PRESSED)
+         && !(event->dwControlKeyState & LEFT_ALT_PRESSED)
+         && !(event->dwControlKeyState & RIGHT_CTRL_PRESSED)
+         && !(event->dwControlKeyState & LEFT_CTRL_PRESSED))
+       {
+         emacs_ev->kind = ascii_keystroke;
+         XSETINT (emacs_ev->code, event->uChar.AsciiChar);
+       }
+      else
+       return 0;
     }
+#endif
   else
     {
       /* non-ASCII */
@@ -269,17 +350,26 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev)
        * the full X keysym values (2nd byte is 0xff).  add it on.
        */
       map |= 0xff00;
-      XSET (emacs_ev->code, Lisp_Int, map);
+      XSETINT (emacs_ev->code, map);
     }
-  SET_FRAME (emacs_ev->frame_or_window, get_frame ());
-  emacs_ev->modifiers = nt_kbd_mods_to_emacs (event->dwControlKeyState);
+/* for Mule 2.2 (Based on Emacs 19.28) */
+#ifdef MULE
+  XSET (emacs_ev->frame_or_window, Lisp_Frame, get_frame ());
+#else
+  XSETFRAME (emacs_ev->frame_or_window, get_frame ());
+#endif
+  emacs_ev->modifiers = win32_kbd_mods_to_emacs (event->dwControlKeyState);
   emacs_ev->timestamp = GetTickCount ();
+  if (key_flag == 2) return -1; /* 95.7.25 by himi */
   return 1;
 }
 
 /* Mouse position hook.  */
 void 
 win32_mouse_position (FRAME_PTR *f,
+#ifndef MULE
+                     int insist,
+#endif
                      Lisp_Object *bar_window,
                      enum scroll_bar_part *part,
                      Lisp_Object *x,
@@ -288,10 +378,14 @@ win32_mouse_position (FRAME_PTR *f,
 {
   BLOCK_INPUT;
   
+#ifndef MULE
+  insist = insist;
+#endif
+
   *f = get_frame ();
   *bar_window = Qnil;
   *part = 0;
-  mouse_moved = 0;
+  selected_frame->mouse_moved = 0;
   
   *x = movement_pos.X;
   *y = movement_pos.Y;
@@ -307,7 +401,7 @@ mouse_moved_to (int x, int y)
   /* If we're in the same place, ignore it */
   if (x != movement_pos.X || y != movement_pos.Y)
     {
-      mouse_moved = 1;
+      selected_frame->mouse_moved = 1;
       movement_pos.X = x;
       movement_pos.Y = y;
       movement_time = GetTickCount ();
@@ -360,7 +454,7 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
   for (i = 0; i < NUM_MOUSE_BUTTONS; i++, mask <<= 1)
     if (but_change & mask)
       {
-       XSET (emacs_ev->code, Lisp_Int, emacs_button_translation[i]);
+       XSETINT (emacs_ev->code, emacs_button_translation[i]);
        break;
       }
 
@@ -371,12 +465,17 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
   
   button_state = event->dwButtonState;
   emacs_ev->timestamp = GetTickCount ();
-  emacs_ev->modifiers = nt_kbd_mods_to_emacs (event->dwControlKeyState) |
+  emacs_ev->modifiers = win32_kbd_mods_to_emacs (event->dwControlKeyState) |
     ((event->dwButtonState & mask) ? down_modifier : up_modifier);
   
-  XFASTINT (emacs_ev->x) = event->dwMousePosition.X;
-  XFASTINT (emacs_ev->y) = event->dwMousePosition.Y;
-  SET_FRAME (emacs_ev->frame_or_window, get_frame ());
+  XSETFASTINT (emacs_ev->x, event->dwMousePosition.X);
+  XSETFASTINT (emacs_ev->y, event->dwMousePosition.Y);
+/* for Mule 2.2 (Based on Emacs 19.28 */
+#ifdef MULE
+  XSET (emacs_ev->frame_or_window, Lisp_Frame, get_frame ());
+#else
+  XSETFRAME (emacs_ev->frame_or_window, get_frame ());
+#endif
   
   return 1;
 }
@@ -424,6 +523,11 @@ win32_read_socket (int sd, struct input_event *bufp, int numchars,
             {
             case KEY_EVENT:
              add = key_event (&queue_ptr->Event.KeyEvent, bufp);
+             if (add == -1) /* 95.7.25 by himi */
+               { 
+                 queue_ptr--;
+                 add = 1;
+               }
              bufp += add;
              ret += add;
              numchars -= add;