]> code.delx.au - gnu-emacs/blobdiff - src/w32console.c
(substitute-key-definition): Fix previous change.
[gnu-emacs] / src / w32console.c
index 95d54a8c2045ae3e90c8b058ef1ea45270191f65..24ae959f5ea62bcec369fb1cd76faa0f7eeaead3 100644 (file)
@@ -1,32 +1,32 @@
-/* Terminal hooks for Windows NT port of GNU Emacs.
+/* Terminal hooks for GNU Emacs on the Microsoft W32 API.
    Copyright (C) 1992 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.
 
    Tim Fleehart (apollo@online.com)            1-17-92
    Geoff Voelker (voelker@cs.washington.edu)   9-12-93
 */
 
 
+#include <config.h>
+
 #include <stdlib.h>
 #include <stdio.h>
-
-#include "config.h"
-
 #include <windows.h>
 
 #include "lisp.h"
@@ -34,7 +34,7 @@
 #include "disptab.h"
 #include "termhooks.h"
 
-#include "ntinevt.h"
+#include "w32inevt.h"
 
 /* from window.c */
 extern Lisp_Object Frecenter ();
@@ -58,7 +58,7 @@ static void reassert_line_highlight (int, int);
 static void insert_glyphs (GLYPH *start, int len);
 static void write_glyphs (GLYPH *string, int len);
 static void delete_glyphs (int n);
-static void ring_bell (void);
+void w32_sys_ring_bell (void);
 static void reset_terminal_modes (void);
 static void set_terminal_modes (void);
 static void set_terminal_window (int size);
@@ -80,14 +80,17 @@ COORD       cursor_coords;
 HANDLE prev_screen, cur_screen;
 UCHAR  char_attr, char_attr_normal, char_attr_reverse;
 HANDLE  keyboard_handle;
+DWORD   prev_console_mode;
 
 
 /* Setting this as the ctrl handler prevents emacs from being killed when
- * someone hits ^C in a 'suspended' session (child shell).  */
+   someone hits ^C in a 'suspended' session (child shell).
+   Also ignore Ctrl-Break signals.  */
+
 BOOL
 ctrl_c_handler (unsigned long type)
 {
-  return (type == CTRL_C_EVENT) ? TRUE : FALSE;
+  return (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT);
 }
 
 /* If we're updating a frame, use it as the current frame
@@ -121,25 +124,18 @@ clear_to_end (void)
 void
 clear_frame (void)
 {
-  SMALL_RECT scroll;
-  COORD             dest;
-  CHAR_INFO  fill;
   FRAME_PTR  f = PICK_FRAME ();
-  
+  COORD             dest;
+  int        n, r;
+
   hl_mode (0);
   
-  scroll.Top = 0;
-  scroll.Bottom = FRAME_HEIGHT (f) - 1;
-  scroll.Left = 0;
-  scroll.Right = FRAME_WIDTH (f) - 1;
-  
-  dest.Y = FRAME_HEIGHT (f);
-  dest.X = 0;
-  
-  fill.Char.AsciiChar = 0x20;
-  fill.Attributes = char_attr;
-  
-  ScrollConsoleScreenBuffer (cur_screen, &scroll, NULL, dest, &fill);
+  n = FRAME_HEIGHT (f) * FRAME_WIDTH (f);
+  dest.X = dest.Y = 0;
+
+  FillConsoleOutputAttribute (cur_screen, char_attr, n, dest, &r);
+  FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
+
   move_cursor (0, 0);
 }
 
@@ -197,7 +193,7 @@ ins_del_lines (int vpos, int n)
   
   ScrollConsoleScreenBuffer (cur_screen, &scroll, NULL, dest, &fill);
 
-  /* Here we have to deal with a win32 console flake: If the scroll
+  /* Here we have to deal with a w32 console flake: If the scroll
      region looks like abc and we scroll c to a and fill with d we get
      cbd... if we scroll block c one line at a time to a, we get cdd...
      Emacs expects cdd consistently... So we have to deal with that
@@ -345,6 +341,9 @@ write_glyphs (register GLYPH *string, register int len)
   char *chars;
   int i;
   
+  if (len <= 0)
+    return;
+
   attrs = alloca (len * sizeof (*attrs));
   chars = alloca (len * sizeof (*chars));
   if (attrs == NULL || chars == NULL)
@@ -366,8 +365,10 @@ write_glyphs (register GLYPH *string, register int len)
          continue;
        }
       GLYPH_FOLLOW_ALIASES (glyph_table, glyph_len, glyph);
+#ifndef HAVE_NTGUI
       if (GLYPH_FACE (fixfix, glyph) != 0)
        printf ("Glyph face is %d\n", GLYPH_FACE (fixfix, glyph));
+#endif /* !HAVE_NTGUI */
       if (GLYPH_SIMPLE_P (glyph_table, glyph_len, glyph))
         {
          *ptr++ = glyph & 0xFF;
@@ -383,7 +384,8 @@ write_glyphs (register GLYPH *string, register int len)
   len = ptr-chars;
   
   /* Fill in the attributes for these characters.  */
-  memset (attrs, char_attr, len*sizeof (*attrs));
+  for (i = 0; i < len; i++)
+    attrs[i] = char_attr;
   
   /* Write the attributes.  */
   if (!WriteConsoleOutputAttribute (cur_screen, attrs, len, cursor_coords, &i))
@@ -416,7 +418,7 @@ delete_glyphs (int n)
 static unsigned int sound_type = 0xFFFFFFFF;
 
 void
-ring_bell (void)
+w32_sys_ring_bell (void)
 {
   if (sound_type == 0xFFFFFFFF) 
       Beep (666, 100);
@@ -490,8 +492,8 @@ set_terminal_modes (void)
 
       SetConsoleActiveScreenBuffer (cur_screen);
 
-      /* make cursor big and visible */
-      cci.dwSize = 100;
+      /* make cursor big and visible (100 on Windows 95 makes it disappear)  */
+      cci.dwSize = 99;
       cci.bVisible = TRUE;
       (void) SetConsoleCursorInfo (cur_screen, &cci);
     }
@@ -520,21 +522,24 @@ set_terminal_window (int size)
 void
 unset_kbd (void)
 {
-  SetConsoleMode (keyboard_handle, ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
-                 ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT);
+  SetConsoleMode (keyboard_handle, prev_console_mode);
 }
 
 void
 reset_kbd (void)
 {
   keyboard_handle = GetStdHandle (STD_INPUT_HANDLE);
+  GetConsoleMode (keyboard_handle, &prev_console_mode);
   SetConsoleMode (keyboard_handle, ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT);
+
+  /* Try to use interrupt input; if we can't, then start polling.  */
+  Fset_input_mode (Qt, Qnil, Qt, Qnil);
 }
 
 typedef int (*term_hook) ();
 
 void
-initialize_win_nt_display (void)
+initialize_w32_display (void)
 {
   CONSOLE_SCREEN_BUFFER_INFO   info;
   
@@ -549,15 +554,15 @@ initialize_win_nt_display (void)
   insert_glyphs_hook           = (term_hook) insert_glyphs;
   write_glyphs_hook            = (term_hook) write_glyphs;
   delete_glyphs_hook           = (term_hook) delete_glyphs;
-  ring_bell_hook               = (term_hook) ring_bell;
+  ring_bell_hook               = (term_hook) w32_sys_ring_bell;
   reset_terminal_modes_hook    = (term_hook) reset_terminal_modes;
   set_terminal_modes_hook      = (term_hook) set_terminal_modes;
   set_terminal_window_hook     = (term_hook) set_terminal_window;
   update_begin_hook            = (term_hook) update_begin;
   update_end_hook              = (term_hook) update_end;
   
-  read_socket_hook = win32_read_socket;
-  mouse_position_hook = win32_mouse_position;
+  read_socket_hook = w32_console_read_socket;
+  mouse_position_hook = w32_mouse_position;
   
   prev_screen = GetStdHandle (STD_OUTPUT_HANDLE);
   
@@ -571,7 +576,7 @@ initialize_win_nt_display (void)
   char_attr_reverse = ((char_attr & 0xf) << 4) + ((char_attr & 0xf0) >> 4);
   
   FRAME_HEIGHT (selected_frame) = info.dwSize.Y;       /* lines per page */
-  FRAME_WIDTH (selected_frame) = info.dwSize.X;  /* characters per line */
+  SET_FRAME_WIDTH (selected_frame, info.dwSize.X); /* characters per line */
   
   move_cursor (0, 0);
   
@@ -604,6 +609,7 @@ DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0,
   return Qt;
 }
 
+#ifndef HAVE_NTGUI
 void
 pixel_to_glyph_coords (FRAME_PTR f, int pix_x, int pix_y, int *x, int *y,
                      void *bounds, int noclip)
@@ -618,6 +624,7 @@ glyph_to_pixel_coords (FRAME_PTR f, int x, int y, int *pix_x, int *pix_y)
   *pix_x = x;
   *pix_y = y;
 }
+#endif /* !HAVE_NTGUI */
 
 void
 syms_of_ntterm ()