home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / e20313sr.zip / emacs / 20.3.1 / src / w32inevt.c < prev    next >
C/C++ Source or Header  |  1999-07-31  |  18KB  |  624 lines

  1. /* Input event support for Emacs on the Microsoft W32 API.
  2.    Copyright (C) 1992, 1993, 1995 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU Emacs.
  5.  
  6. GNU Emacs is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU Emacs is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Emacs; see the file COPYING.  If not, write to
  18. the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. Boston, MA 02111-1307, USA.
  20.  
  21.    Drew Bliss                   01-Oct-93
  22.      Adapted from ntkbd.c by Tim Fleehart
  23. */
  24.  
  25.  
  26. #include "config.h"
  27.  
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <windows.h>
  31.  
  32. #include "lisp.h"
  33. #include "frame.h"
  34. #include "blockinput.h"
  35. #include "termhooks.h"
  36.  
  37. /* stdin, from ntterm */
  38. extern HANDLE keyboard_handle;
  39.  
  40. /* Info for last mouse motion */
  41. static COORD movement_pos;
  42. static DWORD movement_time;
  43.  
  44. /* from keyboard.c */
  45. extern void reinvoke_input_signal (void);
  46.  
  47. /* from dispnew.c */
  48. extern int change_frame_size (FRAME_PTR, int, int, int, int);
  49.  
  50. /* from w32fns.c */
  51. extern Lisp_Object Vw32_alt_is_meta;
  52.  
  53. /* from w32term */
  54. extern Lisp_Object Vw32_capslock_is_shiftlock;
  55. extern Lisp_Object Vw32_recognize_altgr;
  56.  
  57. /* Event queue */
  58. #define EVENT_QUEUE_SIZE 50
  59. static INPUT_RECORD event_queue[EVENT_QUEUE_SIZE];
  60. static INPUT_RECORD *queue_ptr = event_queue, *queue_end = event_queue;
  61.  
  62. static int 
  63. fill_queue (BOOL block)
  64. {
  65.   BOOL rc;
  66.   DWORD events_waiting;
  67.   
  68.   if (queue_ptr < queue_end)
  69.     return queue_end-queue_ptr;
  70.   
  71.   if (!block)
  72.     {
  73.       /* Check to see if there are some events to read before we try
  74.      because we can't block.  */
  75.       if (!GetNumberOfConsoleInputEvents (keyboard_handle, &events_waiting))
  76.     return -1;
  77.       if (events_waiting == 0)
  78.     return 0;
  79.     }
  80.   
  81.   rc = ReadConsoleInput (keyboard_handle, event_queue, EVENT_QUEUE_SIZE,
  82.              &events_waiting);
  83.   if (!rc)
  84.     return -1;
  85.   queue_ptr = event_queue;
  86.   queue_end = event_queue + events_waiting;
  87.   return (int) events_waiting;
  88. }
  89.  
  90. /* In a generic, multi-frame world this should take a console handle
  91.    and return the frame for it
  92.  
  93.    Right now, there's only one frame so return it.  */
  94. static FRAME_PTR 
  95. get_frame (void)
  96. {
  97.   return selected_frame;
  98. }
  99.  
  100. /* Translate console modifiers to emacs modifiers.  
  101.    German keyboard support (Kai Morgan Zeise 2/18/95).  */
  102. int
  103. w32_kbd_mods_to_emacs (DWORD mods, WORD key)
  104. {
  105.   int retval = 0;
  106.  
  107.   /* If we recognize right-alt and left-ctrl as AltGr, and it has been
  108.      pressed, remove the modifiers.  */
  109.   if (!NILP (Vw32_recognize_altgr) 
  110.       && (mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED)) 
  111.       == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
  112.     mods &= ~ (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED);
  113.  
  114.   if (mods & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
  115.     retval = ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier);
  116.   
  117.   if (mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
  118.     {
  119.       retval |= ctrl_modifier;
  120.       if ((mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) 
  121.       == (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
  122.     retval |= meta_modifier;
  123.     }
  124.  
  125.   /* Just in case someone wanted the original behaviour, make it
  126.      optional by setting w32-capslock-is-shiftlock to t.  */
  127.   if (NILP (Vw32_capslock_is_shiftlock) &&
  128. #if 1
  129.       ( (key == VK_BACK) ||
  130.     (key == VK_TAB) ||
  131.     (key == VK_CLEAR) ||
  132.     (key == VK_RETURN) ||
  133.     (key == VK_ESCAPE) ||
  134.     ( (key >= VK_SPACE) && (key <= VK_HELP)) ||
  135.     ( (key >= VK_NUMPAD0) && (key <= VK_F24))
  136.     )
  137. #else
  138.       /* Perhaps easier to say which keys we *do* always want affected
  139.      by capslock.  Not sure how this affects "alphabetic" keyboard
  140.      input in non-English languages though - what virtual key codes
  141.      are returned for accented letters, for instance?  */
  142.       !( (key >= '0' && key <= '9') || (key >= 'A' && key <= 'Z') )
  143. #endif
  144.       )
  145.     {
  146.       if ( (mods & SHIFT_PRESSED) == SHIFT_PRESSED)
  147.     retval |= shift_modifier;
  148.     }
  149.   else
  150.     {
  151.   if (((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) == SHIFT_PRESSED)
  152.       || ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) == CAPSLOCK_ON))
  153.     retval |= shift_modifier;
  154.     }
  155.  
  156.   return retval;
  157. }
  158.  
  159. /* The return code indicates key code size. */
  160. int
  161. w32_kbd_patch_key (KEY_EVENT_RECORD *event)
  162. {
  163.   unsigned int key_code = event->wVirtualKeyCode;
  164.   unsigned int mods = event->dwControlKeyState;
  165.   BYTE keystate[256];
  166.   static BYTE ansi_code[4];
  167.   static int isdead = 0;
  168.  
  169.   if (isdead == 2)
  170.     {
  171.       event->uChar.AsciiChar = ansi_code[2];
  172.       isdead = 0;
  173.       return 1;
  174.     }
  175.   if (event->uChar.AsciiChar != 0) 
  176.     return 1;
  177.  
  178.   memset (keystate, 0, sizeof (keystate));
  179.   if (mods & SHIFT_PRESSED) 
  180.     keystate[VK_SHIFT] = 0x80;
  181.   if (mods & CAPSLOCK_ON) 
  182.     keystate[VK_CAPITAL] = 1;
  183.   /* If we recognize right-alt and left-ctrl as AltGr, set the key
  184.      states accordingly before invoking ToAscii.  */
  185.   if (!NILP (Vw32_recognize_altgr)
  186.       && (mods & LEFT_CTRL_PRESSED) && (mods & RIGHT_ALT_PRESSED))
  187.     {
  188.       keystate[VK_CONTROL] = 0x80;
  189.       keystate[VK_LCONTROL] = 0x80;
  190.       keystate[VK_MENU] = 0x80;
  191.       keystate[VK_RMENU] = 0x80;
  192.     }
  193.  
  194.   isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
  195.             keystate, (LPWORD) ansi_code, 0);
  196.   if (isdead == 0) 
  197.     return 0;
  198.   event->uChar.AsciiChar = ansi_code[0];
  199.   return isdead;
  200. }
  201.  
  202. /* Map virtual key codes into:
  203.    -1 - Ignore this key
  204.    -2 - ASCII char
  205.    Other - Map non-ASCII keys into X keysyms so that they are looked up
  206.    correctly in keyboard.c
  207.  
  208.    Return, escape and tab are mapped to ASCII rather than coming back
  209.    as non-ASCII to be more compatible with old-style keyboard support.  */
  210.  
  211. static int map_virt_key[256] =
  212. {
  213. #ifdef MULE
  214.   -3,
  215. #else
  216.   -1,
  217. #endif
  218.   -1,                 /* VK_LBUTTON */
  219.   -1,                 /* VK_RBUTTON */
  220.   0x69,               /* VK_CANCEL */
  221.   -1,                 /* VK_MBUTTON */
  222.   -1, -1, -1,
  223.   8,                  /* VK_BACK */
  224.   -2,                 /* VK_TAB */
  225.   -1, -1,
  226.   11,                 /* VK_CLEAR */
  227.   -2,                 /* VK_RETURN */
  228.   -1, -1,
  229.   -1,                 /* VK_SHIFT */
  230.   -1,                 /* VK_CONTROL */
  231.   -1,                 /* VK_MENU */
  232.   0x13,               /* VK_PAUSE */
  233.   -1,                 /* VK_CAPITAL */
  234.   -1, -1, -1, -1, -1, -1,
  235.   -2,                 /* VK_ESCAPE */
  236.   -1, -1, -1, -1,
  237.   -2,                 /* VK_SPACE */
  238.   0x55,               /* VK_PRIOR */
  239.   0x56,               /* VK_NEXT */
  240.   0x57,               /* VK_END */
  241.   0x50,               /* VK_HOME */
  242.   0x51,               /* VK_LEFT */
  243.   0x52,               /* VK_UP */
  244.   0x53,               /* VK_RIGHT */
  245.   0x54,               /* VK_DOWN */
  246.   0x60,               /* VK_SELECT */
  247.   0x61,               /* VK_PRINT */
  248.   0x62,               /* VK_EXECUTE */
  249.   -1,                 /* VK_SNAPSHOT */
  250.   0x63,               /* VK_INSERT */
  251.   0xff,               /* VK_DELETE */
  252.   0x6a,               /* VK_HELP */
  253.   -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,     /* 0 - 9 */
  254.   -1, -1, -1, -1, -1, -1, -1,
  255.   -2, -2, -2, -2, -2, -2, -2, -2,             /* A - Z */
  256.   -2, -2, -2, -2, -2, -2, -2, -2,
  257.   -2, -2, -2, -2, -2, -2, -2, -2,
  258.   -2, -2,
  259.   -1, -1, -1, -1, -1,
  260.   0xb0,               /* VK_NUMPAD0 */
  261.   0xb1,               /* VK_NUMPAD1 */
  262.   0xb2,               /* VK_NUMPAD2 */
  263.   0xb3,               /* VK_NUMPAD3 */
  264.   0xb4,               /* VK_NUMPAD4 */
  265.   0xb5,               /* VK_NUMPAD5 */
  266.   0xb6,               /* VK_NUMPAD6 */
  267.   0xb7,               /* VK_NUMPAD7 */
  268.   0xb8,               /* VK_NUMPAD8 */
  269.   0xb9,               /* VK_NUMPAD9 */
  270.   0xaa,               /* VK_MULTIPLY */
  271.   0xab,               /* VK_ADD */
  272.   0xac,               /* VK_SEPARATOR */
  273.   0xad,               /* VK_SUBTRACT */
  274.   0xae,               /* VK_DECIMAL */
  275.   0xaf,               /* VK_DIVIDE */
  276.   0xbe,               /* VK_F1 */
  277.   0xbf,               /* VK_F2 */
  278.   0xc0,               /* VK_F3 */
  279.   0xc1,               /* VK_F4 */
  280.   0xc2,               /* VK_F5 */
  281.   0xc3,               /* VK_F6 */
  282.   0xc4,               /* VK_F7 */
  283.   0xc5,               /* VK_F8 */
  284.   0xc6,               /* VK_F9 */
  285.   0xc7,               /* VK_F10 */
  286.   0xc8,               /* VK_F11 */
  287.   0xc9,               /* VK_F12 */
  288.   0xca,               /* VK_F13 */
  289.   0xcb,               /* VK_F14 */
  290.   0xcc,               /* VK_F15 */
  291.   0xcd,               /* VK_F16 */
  292.   0xce,               /* VK_F17 */
  293.   0xcf,               /* VK_F18 */
  294.   0xd0,               /* VK_F19 */
  295.   0xd1,               /* VK_F20 */
  296.   0xd2,               /* VK_F21 */
  297.   0xd3,               /* VK_F22 */
  298.   0xd4,               /* VK_F23 */
  299.   0xd5,               /* VK_F24 */
  300.   -1, -1, -1, -1, -1, -1, -1, -1,
  301.   0x7f,               /* VK_NUMLOCK */
  302.       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x9f */
  303.   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xaf */
  304.   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb9 */
  305.   -2,                 /* ; */
  306.   -2,                 /* = */
  307.   -2,                 /* , */
  308.   -2,                 /* \ */
  309.   -2,                 /* . */
  310.   -2,                 /* / */
  311.   -2,                 /* ` */
  312.       -2, /* 0xc1: on Brazilian keyboards, this is the /(?) key. */
  313.           -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xcf */
  314.   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xda */
  315.                                               -2, -2, -2, -2, -2, /* 0xdf */
  316.   -2, -2, -2, -2, -2,
  317.                       -1, /* 0xe5 */
  318.                           -2, /* oxe6 */
  319.                               -1, -1, /* 0xe8 */
  320.                                       -2, -2, -2, -2, -2, -2, -2, /* 0xef */
  321.   -2, -2, -2, -2, -2, -2,
  322.                           -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 0xff */
  323. };
  324.  
  325. /* return code -1 means that event_queue_ptr won't be incremented. 
  326.    In other word, this event makes two key codes.   (by himi)       */
  327. int 
  328. key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead)
  329. {
  330.   int map;
  331.   int key_flag = 0;
  332.   static BOOL map_virt_key_init_done;
  333.  
  334.   *isdead = 0;
  335.   
  336.   /* Skip key-up events.  */
  337.   if (!event->bKeyDown)
  338.     return 0;
  339.   
  340.   if (event->wVirtualKeyCode > 0xff)
  341.     {
  342.       printf ("Unknown key code %d\n", event->wVirtualKeyCode);
  343.       return 0;
  344.     }
  345.  
  346.   /* Patch needed for German keyboard. Ulrich Leodolter (1/11/95).  */
  347.   if (! map_virt_key_init_done) 
  348.     {
  349.       short vk;
  350.  
  351.       if ((vk = VkKeyScan (0x3c)) >= 0 && vk < 256) map_virt_key[vk] = -2; /* less */
  352.       if ((vk = VkKeyScan (0x3e)) >= 0 && vk < 256) map_virt_key[vk] = -2; /* greater */
  353.  
  354.       map_virt_key_init_done = TRUE;
  355.     }
  356.   
  357.   /* BUGBUG - Ignores the repeat count
  358.      It's questionable whether we want to obey the repeat count anyway
  359.      since keys usually aren't repeated unless key events back up in
  360.      the queue.  If they're backing up then we don't generally want
  361.      to honor them later since that leads to significant slop in
  362.      cursor motion when the system is under heavy load.  */
  363.  
  364.   map = map_virt_key[event->wVirtualKeyCode];
  365.   if (map == -1)
  366.     {
  367.       return 0;
  368.     }
  369.   else if (map == -2)
  370.     {
  371.       /* ASCII */
  372.       emacs_ev->kind = ascii_keystroke;
  373.       key_flag = w32_kbd_patch_key (event); /* 95.7.25 by himi */
  374.       if (key_flag == 0) 
  375.     return 0;
  376.       if (key_flag < 0)
  377.     *isdead = 1;
  378.       XSETINT (emacs_ev->code, event->uChar.AsciiChar);
  379.     }
  380. #ifdef MULE
  381.   /* for IME */
  382.   else if (map == -3)
  383.     {
  384.       if ((event->dwControlKeyState & NLS_IME_CONVERSION)
  385.       && !(event->dwControlKeyState & RIGHT_ALT_PRESSED)
  386.       && !(event->dwControlKeyState & LEFT_ALT_PRESSED)
  387.       && !(event->dwControlKeyState & RIGHT_CTRL_PRESSED)
  388.       && !(event->dwControlKeyState & LEFT_CTRL_PRESSED))
  389.     {
  390.       emacs_ev->kind = ascii_keystroke;
  391.       XSETINT (emacs_ev->code, event->uChar.AsciiChar);
  392.     }
  393.       else
  394.     return 0;
  395.     }
  396. #endif
  397.   else
  398.     {
  399.       /* non-ASCII */
  400.       emacs_ev->kind = non_ascii_keystroke;
  401. #ifdef HAVE_NTGUI
  402.       /* use Windows keysym map */
  403.       XSETINT (emacs_ev->code, event->wVirtualKeyCode);
  404. #else
  405.       /*
  406.        * make_lispy_event () now requires non-ascii codes to have
  407.        * the full X keysym values (2nd byte is 0xff).  add it on.
  408.        */
  409.       map |= 0xff00;
  410.       XSETINT (emacs_ev->code, map);
  411. #endif /* HAVE_NTGUI */
  412.     }
  413. /* for Mule 2.2 (Based on Emacs 19.28) */
  414. #ifdef MULE
  415.   XSET (emacs_ev->frame_or_window, Lisp_Frame, get_frame ());
  416. #else
  417.   XSETFRAME (emacs_ev->frame_or_window, get_frame ());
  418. #endif
  419.   emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState,
  420.                            event->wVirtualKeyCode);
  421.   emacs_ev->timestamp = GetTickCount ();
  422.   if (key_flag == 2) return -1; /* 95.7.25 by himi */
  423.   return 1;
  424. }
  425.  
  426. /* Mouse position hook.  */
  427. void 
  428. w32_console_mouse_position (FRAME_PTR *f,
  429. #ifndef MULE
  430.                 int insist,
  431. #endif
  432.                 Lisp_Object *bar_window,
  433.                 enum scroll_bar_part *part,
  434.                 Lisp_Object *x,
  435.                 Lisp_Object *y,
  436.                 unsigned long *time)
  437. {
  438.   BLOCK_INPUT;
  439.  
  440. #ifndef MULE  
  441.   insist = insist;
  442. #endif
  443.  
  444.   *f = get_frame ();
  445.   *bar_window = Qnil;
  446.   *part = 0;
  447.   selected_frame->mouse_moved = 0;
  448.   
  449.   *x = movement_pos.X;
  450.   *y = movement_pos.Y;
  451.   *time = movement_time;
  452.   
  453.   UNBLOCK_INPUT;
  454. }
  455.  
  456. /* Remember mouse motion and notify emacs.  */
  457. static void 
  458. mouse_moved_to (int x, int y)
  459. {
  460.   /* If we're in the same place, ignore it */
  461.   if (x != movement_pos.X || y != movement_pos.Y)
  462.     {
  463.       selected_frame->mouse_moved = 1;
  464.       movement_pos.X = x;
  465.       movement_pos.Y = y;
  466.       movement_time = GetTickCount ();
  467.     }
  468. }
  469.  
  470. /* Consoles return button bits in a strange order:
  471.      least significant - Leftmost button
  472.      next - Rightmost button
  473.      next - Leftmost+1
  474.      next - Leftmost+2...
  475.  
  476.    Assume emacs likes three button mice, so
  477.      Left == 0
  478.      Middle == 1
  479.      Right == 2
  480.    Others increase from there.  */
  481.  
  482. static int emacs_button_translation[NUM_MOUSE_BUTTONS] =
  483. {
  484.   0, 2, 1, 3, 4,
  485. };
  486.  
  487. static int 
  488. do_mouse_event (MOUSE_EVENT_RECORD *event,
  489.         struct input_event *emacs_ev)
  490. {
  491.   static DWORD button_state = 0;
  492.   DWORD but_change, mask;
  493.   int i;
  494.   
  495.   if (event->dwEventFlags == MOUSE_MOVED)
  496.     {
  497.       /* For movement events we just note that the mouse has moved
  498.      so that emacs will generate drag events.  */
  499.       mouse_moved_to (event->dwMousePosition.X, event->dwMousePosition.Y);
  500.       return 0;
  501.     }
  502.   
  503.   /* It looks like the console code sends us a mouse event with
  504.      dwButtonState == 0 when a window is activated.  Ignore this case.  */
  505.   if (event->dwButtonState == button_state)
  506.     return 0;
  507.   
  508.   emacs_ev->kind = mouse_click;
  509.   
  510.   /* Find out what button has changed state since the last button event.  */
  511.   but_change = button_state ^ event->dwButtonState;
  512.   mask = 1;
  513.   for (i = 0; i < NUM_MOUSE_BUTTONS; i++, mask <<= 1)
  514.     if (but_change & mask)
  515.       {
  516.     XSETINT (emacs_ev->code, emacs_button_translation[i]);
  517.     break;
  518.       }
  519.  
  520.   /* If the changed button is out of emacs' range (highly unlikely)
  521.      ignore this event.  */
  522.   if (i == NUM_MOUSE_BUTTONS)
  523.     return 0;
  524.   
  525.   button_state = event->dwButtonState;
  526.   emacs_ev->timestamp = GetTickCount ();
  527.   emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState, 0) |
  528.     ((event->dwButtonState & mask) ? down_modifier : up_modifier);
  529.   
  530.   XSETFASTINT (emacs_ev->x, event->dwMousePosition.X);
  531.   XSETFASTINT (emacs_ev->y, event->dwMousePosition.Y);
  532. /* for Mule 2.2 (Based on Emacs 19.28 */
  533. #ifdef MULE
  534.   XSET (emacs_ev->frame_or_window, Lisp_Frame, get_frame ());
  535. #else
  536.   XSETFRAME (emacs_ev->frame_or_window, get_frame ());
  537. #endif
  538.   
  539.   return 1;
  540. }
  541.  
  542. static void 
  543. resize_event (WINDOW_BUFFER_SIZE_RECORD *event)
  544. {
  545.   FRAME_PTR f = get_frame ();
  546.   
  547.   change_frame_size (f, event->dwSize.Y, event->dwSize.X, 0, 1);
  548.   SET_FRAME_GARBAGED (f);
  549. }
  550.  
  551. int 
  552. w32_console_read_socket (int sd, struct input_event *bufp, int numchars,
  553.              int expected)
  554. {
  555.   BOOL no_events = TRUE;
  556.   int nev, ret = 0, add;
  557.   int isdead;
  558.  
  559.   if (interrupt_input_blocked)
  560.     {
  561.       interrupt_input_pending = 1;
  562.       return -1;
  563.     }
  564.   
  565.   interrupt_input_pending = 0;
  566.   BLOCK_INPUT;
  567.   
  568.   for (;;)
  569.     {
  570.       nev = fill_queue (0);
  571.       if (nev <= 0)
  572.         {
  573.       /* If nev == -1, there was some kind of error
  574.          If nev == 0 then waitp must be zero and no events were available
  575.          so return.  */
  576.       UNBLOCK_INPUT;
  577.       return nev;
  578.         }
  579.  
  580.       while (nev > 0 && numchars > 0)
  581.         {
  582.       switch (queue_ptr->EventType)
  583.             {
  584.             case KEY_EVENT:
  585.           add = key_event (&queue_ptr->Event.KeyEvent, bufp, &isdead);
  586.           if (add == -1) /* 95.7.25 by himi */
  587.         { 
  588.           queue_ptr--;
  589.           add = 1;
  590.         }
  591.           bufp += add;
  592.           ret += add;
  593.           numchars -= add;
  594.           break;
  595.  
  596.             case MOUSE_EVENT:
  597.           add = do_mouse_event (&queue_ptr->Event.MouseEvent, bufp);
  598.           bufp += add;
  599.           ret += add;
  600.           numchars -= add;
  601.           break;
  602.  
  603.             case WINDOW_BUFFER_SIZE_EVENT:
  604.           resize_event (&queue_ptr->Event.WindowBufferSizeEvent);
  605.           break;
  606.             
  607.             case MENU_EVENT:
  608.             case FOCUS_EVENT:
  609.           /* Internal event types, ignored. */
  610.           break;
  611.             }
  612.             
  613.       queue_ptr++;
  614.       nev--;
  615.         }
  616.  
  617.       if (ret > 0 || expected == 0)
  618.     break;
  619.     }
  620.   
  621.   UNBLOCK_INPUT;
  622.   return ret;
  623. }
  624.