Extend mouse support on W32 text-mode console.
src/xdisp.c (draw_row_with_mouse_face): Call tty_draw_row_with_mouse_face for WINDOWSNT as well. src/w32console.c: Include window.h. (w32con_write_glyphs_with_face, tty_draw_row_with_mouse_face): New functions. (initialize_w32_display): Initialize mouse-highlight data. src/w32inevt.c: Include termchar.h and window.h. (do_mouse_event): Support mouse-autoselect-window. When the mouse moves, call note_mouse_highlight. If help_echo changed, call gen_help_event to produce help-echo message in the echo area. Call clear_mouse_face if mouse_face_hidden is set in the mouse highlight info. etc/NEWS: Describe the changes.
This commit is contained in:
commit
53a63be64d
5 changed files with 167 additions and 5 deletions
4
etc/NEWS
4
etc/NEWS
|
@ -313,6 +313,10 @@ by the underlying C implementation.
|
|||
*** --without-libxml2 omits support for libxml2, even if its presence
|
||||
is detected.
|
||||
|
||||
** When invoked with the -nw switch to run on the Windows text-mode terminal,
|
||||
Emacs now supports mouse highlight, help-echo (in the echo area), and
|
||||
mouse-autoselect-window.
|
||||
|
||||
|
||||
* Installation Changes in Emacs 24.1
|
||||
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
2012-05-26 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
Extend mouse support on W32 text-mode console.
|
||||
* xdisp.c (draw_row_with_mouse_face): Call
|
||||
tty_draw_row_with_mouse_face for WINDOWSNT as well.
|
||||
|
||||
* w32console.c: Include window.h.
|
||||
(w32con_write_glyphs_with_face, tty_draw_row_with_mouse_face): New
|
||||
functions.
|
||||
(initialize_w32_display): Initialize mouse-highlight data.
|
||||
|
||||
* w32inevt.c: Include termchar.h and window.h.
|
||||
(do_mouse_event): Support mouse-autoselect-window. When the mouse
|
||||
moves, call note_mouse_highlight. If help_echo changed, call
|
||||
gen_help_event to produce help-echo message in the echo area.
|
||||
Call clear_mouse_face if mouse_face_hidden is set in the mouse
|
||||
highlight info.
|
||||
|
||||
2012-05-26 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* lread.c (read1): Simplify slightly to avoid an overflow warning
|
||||
|
|
|
@ -33,6 +33,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "coding.h"
|
||||
#include "disptab.h"
|
||||
#include "frame.h"
|
||||
#include "window.h"
|
||||
#include "termhooks.h"
|
||||
#include "termchar.h"
|
||||
#include "dispextern.h"
|
||||
|
@ -339,6 +340,84 @@ w32con_write_glyphs (struct frame *f, register struct glyph *string,
|
|||
}
|
||||
}
|
||||
|
||||
/* Used for mouse highlight. */
|
||||
static void
|
||||
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)
|
||||
{
|
||||
unsigned char *conversion_buffer;
|
||||
struct coding_system *coding;
|
||||
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
/* 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;
|
||||
|
||||
conversion_buffer = encode_terminal_code (string, len, coding);
|
||||
if (coding->produced > 0)
|
||||
{
|
||||
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 ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
w32con_delete_glyphs (struct frame *f, int n)
|
||||
|
@ -570,6 +649,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;
|
||||
|
@ -600,6 +680,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 ();
|
||||
|
||||
|
|
|
@ -35,8 +35,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "keyboard.h"
|
||||
#include "frame.h"
|
||||
#include "dispextern.h"
|
||||
#include "window.h"
|
||||
#include "blockinput.h"
|
||||
#include "termhooks.h"
|
||||
#include "termchar.h"
|
||||
#include "w32heap.h"
|
||||
#include "w32term.h"
|
||||
|
||||
|
@ -566,7 +568,7 @@ w32_console_mouse_position (FRAME_PTR *f,
|
|||
static void
|
||||
mouse_moved_to (int x, int y)
|
||||
{
|
||||
/* If we're in the same place, ignore it */
|
||||
/* If we're in the same place, ignore it. */
|
||||
if (x != movement_pos.X || y != movement_pos.Y)
|
||||
{
|
||||
SELECTED_FRAME ()->mouse_moved = 1;
|
||||
|
@ -599,14 +601,63 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
|
|||
struct input_event *emacs_ev)
|
||||
{
|
||||
static DWORD button_state = 0;
|
||||
static Lisp_Object last_mouse_window;
|
||||
DWORD but_change, mask;
|
||||
int i;
|
||||
|
||||
if (event->dwEventFlags == MOUSE_MOVED)
|
||||
{
|
||||
/* For movement events we just note that the mouse has moved
|
||||
so that emacs will generate drag events. */
|
||||
mouse_moved_to (event->dwMousePosition.X, event->dwMousePosition.Y);
|
||||
FRAME_PTR f = SELECTED_FRAME ();
|
||||
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
|
||||
int mx = event->dwMousePosition.X, my = event->dwMousePosition.Y;
|
||||
|
||||
mouse_moved_to (mx, my);
|
||||
|
||||
if (f->mouse_moved)
|
||||
{
|
||||
if (hlinfo->mouse_face_hidden)
|
||||
{
|
||||
hlinfo->mouse_face_hidden = 0;
|
||||
clear_mouse_face (hlinfo);
|
||||
}
|
||||
|
||||
/* Generate SELECT_WINDOW_EVENTs when needed. */
|
||||
if (!NILP (Vmouse_autoselect_window))
|
||||
{
|
||||
Lisp_Object mouse_window = window_from_coordinates (f, mx, my,
|
||||
0, 0);
|
||||
/* A window will be selected only when it is not
|
||||
selected now, and the last mouse movement event was
|
||||
not in it. A minibuffer window will be selected iff
|
||||
it is active. */
|
||||
if (WINDOWP (mouse_window)
|
||||
&& !EQ (mouse_window, last_mouse_window)
|
||||
&& !EQ (mouse_window, selected_window))
|
||||
{
|
||||
struct input_event event;
|
||||
|
||||
EVENT_INIT (event);
|
||||
event.kind = SELECT_WINDOW_EVENT;
|
||||
event.frame_or_window = mouse_window;
|
||||
event.arg = Qnil;
|
||||
event.timestamp = movement_time;
|
||||
kbd_buffer_store_event (&event);
|
||||
}
|
||||
last_mouse_window = mouse_window;
|
||||
}
|
||||
else
|
||||
last_mouse_window = Qnil;
|
||||
|
||||
previous_help_echo_string = help_echo_string;
|
||||
help_echo_string = help_echo_object = help_echo_window = Qnil;
|
||||
help_echo_pos = -1;
|
||||
note_mouse_highlight (f, mx, my);
|
||||
/* If the contents of the global variable help_echo has
|
||||
changed (inside note_mouse_highlight), generate a HELP_EVENT. */
|
||||
if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
|
||||
gen_help_event (help_echo_string, selected_frame, help_echo_window,
|
||||
help_echo_object, help_echo_pos);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -25832,7 +25832,7 @@ draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined (HAVE_GPM) || defined (MSDOS)
|
||||
#if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
|
||||
tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue