X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/ca3fa30248b923c17c021c0fcdb945271d14e8c2..2ab329f3b5d52a39f0a45c3d9c129f1c19560142:/src/w32console.c diff --git a/src/w32console.c b/src/w32console.c index 35f0fc195f..5a44d3748a 100644 --- a/src/w32console.c +++ b/src/w32console.c @@ -1,6 +1,5 @@ -/* Terminal hooks for GNU Emacs on the Microsoft W32 API. - Copyright (C) 1992, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010 Free Software Foundation, Inc. +/* Terminal hooks for GNU Emacs on the Microsoft Windows API. + Copyright (C) 1992, 1999, 2001-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -27,27 +26,23 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include "lisp.h" #include "character.h" #include "coding.h" #include "disptab.h" #include "frame.h" +#include "window.h" #include "termhooks.h" #include "termchar.h" #include "dispextern.h" +#include "w32term.h" +#include "w32heap.h" /* for os_subtype */ #include "w32inevt.h" /* from window.c */ extern Lisp_Object Frecenter (Lisp_Object); -/* from keyboard.c */ -extern int detect_input_pending (void); - -/* from sysdep.c */ -extern int read_input_pending (void); - static void w32con_move_cursor (struct frame *f, int row, int col); static void w32con_clear_to_end (struct frame *f); static void w32con_clear_frame (struct frame *f); @@ -72,14 +67,8 @@ static DWORD prev_console_mode; static CONSOLE_CURSOR_INFO prev_console_cursor; #endif -extern Lisp_Object Vtty_defined_color_alist; - -/* Determine whether to make frame dimensions match the screen buffer, - or the current window size. The former is desirable when running - over telnet, while the latter is more useful when working directly at - the console with a large scroll-back buffer. */ -int w32_use_full_screen_buffer; HANDLE keyboard_handle; +int w32_console_unicode_input; /* Setting this as the ctrl handler prevents emacs from being killed when @@ -285,9 +274,6 @@ w32con_insert_glyphs (struct frame *f, register struct glyph *start, } } -extern unsigned char *encode_terminal_code (struct glyph *, int, - struct coding_system *); - static void w32con_write_glyphs (struct frame *f, register struct glyph *string, register int len) @@ -356,65 +342,96 @@ w32con_write_glyphs (struct frame *f, register struct glyph *string, } } - +/* Used for mouse highlight. */ static void -w32con_delete_glyphs (struct frame *f, int n) +w32con_write_glyphs_with_face (struct frame *f, register int x, register int y, + register struct glyph *string, register int len, + register int face_id) { - /* delete chars means scroll chars from cursor_coords.X + n to - cursor_coords.X, anything beyond the edge of the screen should - come out empty... */ + unsigned char *conversion_buffer; + struct coding_system *coding; - scroll_line (f, n, LEFT); -} + if (len <= 0) + return; -static unsigned int sound_type = 0xFFFFFFFF; -#define MB_EMACS_SILENT (0xFFFFFFFF - 1) + /* If terminal_coding does any conversion, use it, otherwise use + safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here + because it always return 1 if the member src_multibyte is 1. */ + coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK + ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding); + /* We are going to write the entire block of glyphs in one go, as + they all have the same face. So this _is_ the last block. */ + coding->mode |= CODING_MODE_LAST_BLOCK; -void -w32_sys_ring_bell (struct frame *f) -{ - if (sound_type == 0xFFFFFFFF) + conversion_buffer = encode_terminal_code (string, len, coding); + if (coding->produced > 0) { - Beep (666, 100); + DWORD filled, written; + /* Compute the character attributes corresponding to the face. */ + DWORD char_attr = w32_face_attributes (f, face_id); + COORD start_coords; + + start_coords.X = x; + start_coords.Y = y; + /* Set the attribute for these characters. */ + if (!FillConsoleOutputAttribute (cur_screen, char_attr, + coding->produced, start_coords, + &filled)) + DebPrint (("Failed writing console attributes: %d\n", GetLastError ())); + else + { + /* Write the characters. */ + if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer, + filled, start_coords, &written)) + DebPrint (("Failed writing console characters: %d\n", + GetLastError ())); + } } - else if (sound_type == MB_EMACS_SILENT) +} + +/* Implementation of draw_row_with_mouse_face for W32 console. */ +void +tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, + int start_hpos, int end_hpos, + enum draw_glyphs_face draw) +{ + int nglyphs = end_hpos - start_hpos; + struct frame *f = XFRAME (WINDOW_FRAME (w)); + struct tty_display_info *tty = FRAME_TTY (f); + int face_id = tty->mouse_highlight.mouse_face_face_id; + int pos_x, pos_y; + + if (end_hpos >= row->used[TEXT_AREA]) + nglyphs = row->used[TEXT_AREA] - start_hpos; + + pos_y = row->y + WINDOW_TOP_EDGE_Y (w); + pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w); + + if (draw == DRAW_MOUSE_FACE) + w32con_write_glyphs_with_face (f, pos_x, pos_y, + row->glyphs[TEXT_AREA] + start_hpos, + nglyphs, face_id); + else if (draw == DRAW_NORMAL_TEXT) { - /* Do nothing. */ + COORD save_coords = cursor_coords; + + w32con_move_cursor (f, pos_y, pos_x); + write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs); + w32con_move_cursor (f, save_coords.Y, save_coords.X); } - else - MessageBeep (sound_type); } -DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0, - doc: /* Set the sound generated when the bell is rung. -SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent -to use the corresponding system sound for the bell. The 'silent sound -prevents Emacs from making any sound at all. -SOUND is nil to use the normal beep. */) - (Lisp_Object sound) +static void +w32con_delete_glyphs (struct frame *f, int n) { - CHECK_SYMBOL (sound); - - if (NILP (sound)) - sound_type = 0xFFFFFFFF; - else if (EQ (sound, intern ("asterisk"))) - sound_type = MB_ICONASTERISK; - else if (EQ (sound, intern ("exclamation"))) - sound_type = MB_ICONEXCLAMATION; - else if (EQ (sound, intern ("hand"))) - sound_type = MB_ICONHAND; - else if (EQ (sound, intern ("question"))) - sound_type = MB_ICONQUESTION; - else if (EQ (sound, intern ("ok"))) - sound_type = MB_OK; - else if (EQ (sound, intern ("silent"))) - sound_type = MB_EMACS_SILENT; - else - sound_type = 0xFFFFFFFF; + /* delete chars means scroll chars from cursor_coords.X + n to + cursor_coords.X, anything beyond the edge of the screen should + come out empty... */ - return sound; + scroll_line (f, n, LEFT); } + static void w32con_reset_terminal_modes (struct terminal *t) { @@ -451,7 +468,7 @@ w32con_set_terminal_modes (struct terminal *t) { CONSOLE_CURSOR_INFO cci; - /* make cursor big and visible (100 on Win95 makes it disappear) */ + /* make cursor big and visible (100 on Windows 95 makes it disappear) */ cci.dwSize = 99; cci.bVisible = TRUE; (void) SetConsoleCursorInfo (cur_screen, &cci); @@ -554,7 +571,7 @@ w32_face_attributes (struct frame *f, int face_id) WORD char_attr; struct face *face = FACE_FROM_ID (f, face_id); - xassert (face != NULL); + eassert (face != NULL); char_attr = char_attr_normal; @@ -587,6 +604,7 @@ void initialize_w32_display (struct terminal *term) { CONSOLE_SCREEN_BUFFER_INFO info; + Mouse_HLInfo *hlinfo; term->rif = 0; /* No window based redisplay on the console. */ term->cursor_to_hook = w32con_move_cursor; @@ -617,6 +635,15 @@ initialize_w32_display (struct terminal *term) term->judge_scroll_bars_hook = 0; term->frame_up_to_date_hook = 0; + /* Initialize the mouse-highlight data. */ + hlinfo = &term->display_info.tty->mouse_highlight; + hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; + hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; + hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; + hlinfo->mouse_face_mouse_frame = NULL; + hlinfo->mouse_face_window = Qnil; + hlinfo->mouse_face_hidden = 0; + /* Initialize interrupt_handle. */ init_crit (); @@ -714,6 +741,11 @@ initialize_w32_display (struct terminal *term) info.srWindow.Left); } + if (os_subtype == OS_NT) + w32_console_unicode_input = 1; + else + w32_console_unicode_input = 0; + /* Setup w32_display_info structure for this frame. */ w32_initialize_display_info (build_string ("Console")); @@ -722,7 +754,9 @@ initialize_w32_display (struct terminal *term) DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0, - doc: /* Set screen colors. */) + doc: /* Set screen foreground and background colors. + +Arguments should be indices between 0 and 15, see w32console.el. */) (Lisp_Object foreground, Lisp_Object background) { char_attr_normal = XFASTINT (foreground) + (XFASTINT (background) << 4); @@ -731,6 +765,18 @@ DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0, return Qt; } +DEFUN ("get-screen-color", Fget_screen_color, Sget_screen_color, 0, 0, 0, + doc: /* Get color indices of the current screen foreground and background. + +The colors are returned as a list of 2 indices (FOREGROUND BACKGROUND). +See w32console.el and `tty-defined-color-alist' for mapping of indices +to colors. */) + (void) +{ + return Fcons (make_number (char_attr_normal & 0x000f), + Fcons (make_number ((char_attr_normal >> 4) & 0x000f), Qnil)); +} + DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0, doc: /* Set cursor size. */) (Lisp_Object size) @@ -747,18 +793,15 @@ void syms_of_ntterm (void) { DEFVAR_BOOL ("w32-use-full-screen-buffer", - &w32_use_full_screen_buffer, + w32_use_full_screen_buffer, doc: /* Non-nil means make terminal frames use the full screen buffer dimensions. This is desirable when running Emacs over telnet. A value of nil means use the current console window dimensions; this -may be preferrable when working directly at the console with a large +may be preferable when working directly at the console with a large scroll-back buffer. */); w32_use_full_screen_buffer = 0; defsubr (&Sset_screen_color); + defsubr (&Sget_screen_color); defsubr (&Sset_cursor_size); - defsubr (&Sset_message_beep); } - -/* arch-tag: a390a07f-f661-42bc-aeb4-e6d8bf860337 - (do not change this comment) */