]> code.delx.au - gnu-emacs/commitdiff
Support mouse highlight on w32 text-mode frames.
authorEli Zaretskii <eliz@gnu.org>
Sat, 26 May 2012 09:31:59 +0000 (12:31 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 26 May 2012 09:31:59 +0000 (12:31 +0300)
 src/xdisp.c (draw_row_with_mouse_face): Call
 tty_draw_row_with_mouse_face for WINDOWSNT as well.
 src/w32inevt.c (mouse_moved_to): When the mouse moves, call
 note_mouse_highlight.
 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/ChangeLog
src/w32console.c
src/w32inevt.c
src/xdisp.c

index acae070f068be0ffde033a28abc28a1bbb619974..173ed04da73fdd30140cf570f197ace3c1e12790 100644 (file)
@@ -1,3 +1,17 @@
+2012-05-26  Eli Zaretskii  <eliz@gnu.org>
+
+       Support mouse highlight on w32 text-mode frames.
+       * xdisp.c (draw_row_with_mouse_face): Call
+       tty_draw_row_with_mouse_face for WINDOWSNT as well.
+
+       * w32inevt.c (mouse_moved_to): When the mouse moves, call
+       note_mouse_highlight.
+
+       * 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.
+
 2012-05-26  Eli Zaretskii  <eliz@gnu.org>
 
        * bidi.c (bidi_mirror_char): Revert last change: an int is
index e8b0f621b4f8f7447d41f2c825f5239811e59945..22f329e239d7d964a048a8ab71fbc9914ec18968 100644 (file)
@@ -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 ();
 
index e7a8bf629d63184c408d40b8531bb519c7b7fd57..cd4a8dd1d49cf26ad01e65527ff6ffa9961a7128 100644 (file)
@@ -562,14 +562,17 @@ w32_console_mouse_position (FRAME_PTR *f,
   UNBLOCK_INPUT;
 }
 
-/* Remember mouse motion and notify emacs.  */
+/* Remember mouse motion, notify emacs, and trigger mouse highlight.  */
 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;
+      FRAME_PTR f = SELECTED_FRAME ();
+
+      f->mouse_moved = 1;
+      note_mouse_highlight (f, x, y);
       movement_pos.X = x;
       movement_pos.Y = y;
       movement_time = GetTickCount ();
@@ -604,8 +607,9 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
 
   if (event->dwEventFlags == MOUSE_MOVED)
     {
-      /* For movement events we just note that the mouse has moved
-        so that emacs will generate drag events.  */
+      /* For movement events we just note that the mouse has moved so
+        that emacs will generate drag events and perhaps trigger
+        mouse highlighting.  */
       mouse_moved_to (event->dwMousePosition.X, event->dwMousePosition.Y);
       return 0;
     }
index 0a25eab1cbc34f3662afe326ba4cf2e0c1185086..794355af153ed88e2dcdc23e151b86c2da67b369 100644 (file)
@@ -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
 }