/[emacs]/emacs/src/w32term.c
ViewVC logotype

Diff of /emacs/src/w32term.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.115 by miles, Sat Oct 20 05:49:35 2001 UTC revision 1.116 by jasonr, Sun Oct 21 15:20:03 2001 UTC
# Line 168  static int any_help_event_p; Line 168  static int any_help_event_p;
168    
169  int x_stretch_cursor_p;  int x_stretch_cursor_p;
170    
171    /* Non-zero means make use of UNDERLINE_POSITION font properties.  */
172    
173    int x_use_underline_position_properties;
174    
175  extern unsigned int msh_mousewheel;  extern unsigned int msh_mousewheel;
176    
177  extern void free_frame_menubar ();  extern void free_frame_menubar ();
# Line 331  static void x_update_window_end P_ ((str Line 335  static void x_update_window_end P_ ((str
335  static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));  static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
336  void w32_delete_display P_ ((struct w32_display_info *));  void w32_delete_display P_ ((struct w32_display_info *));
337  static int fast_find_position P_ ((struct window *, int, int *, int *,  static int fast_find_position P_ ((struct window *, int, int *, int *,
338                                     int *, int *));                                     int *, int *, Lisp_Object));
339    static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object,
340                                         int *, int *, int *, int *, int));
341  static void set_output_cursor P_ ((struct cursor_pos *));  static void set_output_cursor P_ ((struct cursor_pos *));
342  static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,  static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
343                                             int *, int *, int *));                                             int *, int *, int *, int));
344  static void note_mode_line_highlight P_ ((struct window *, int, int));  static void note_mode_line_highlight P_ ((struct window *, int, int));
345  static void note_mouse_highlight P_ ((struct frame *, int, int));  static void note_mouse_highlight P_ ((struct frame *, int, int));
346  static void note_tool_bar_highlight P_ ((struct frame *f, int, int));  static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
# Line 342  static void w32_handle_tool_bar_click P_ Line 348  static void w32_handle_tool_bar_click P_
348                                            struct input_event *));                                            struct input_event *));
349  static void show_mouse_face P_ ((struct w32_display_info *,  static void show_mouse_face P_ ((struct w32_display_info *,
350                                   enum draw_glyphs_face));                                   enum draw_glyphs_face));
351  void clear_mouse_face P_ ((struct w32_display_info *));  static int cursor_in_mouse_face_p P_ ((struct window *));
352    static int clear_mouse_face P_ ((struct w32_display_info *));
353    
354  void x_lower_frame P_ ((struct frame *));  void x_lower_frame P_ ((struct frame *));
355  void x_scroll_bar_clear P_ ((struct frame *));  void x_scroll_bar_clear P_ ((struct frame *));
# Line 375  static void x_frame_rehighlight P_ ((str Line 382  static void x_frame_rehighlight P_ ((str
382  static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));  static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
383  static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));  static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
384  static void expose_frame P_ ((struct frame *, int, int, int, int));  static void expose_frame P_ ((struct frame *, int, int, int, int));
385  static void expose_window_tree P_ ((struct window *, RECT *));  static int expose_window_tree P_ ((struct window *, RECT *));
386  static void expose_window P_ ((struct window *, RECT *));  static int expose_window P_ ((struct window *, RECT *));
387  static void expose_area P_ ((struct window *, struct glyph_row *,  static void expose_area P_ ((struct window *, struct glyph_row *,
388                               RECT *, enum glyph_row_area));                               RECT *, enum glyph_row_area));
389  static void expose_line P_ ((struct window *, struct glyph_row *,  static int expose_line P_ ((struct window *, struct glyph_row *,
390                               RECT *));                              RECT *));
391  void x_update_cursor P_ ((struct frame *, int));  void x_update_cursor P_ ((struct frame *, int));
392  static void x_update_cursor_in_window_tree P_ ((struct window *, int));  static void x_update_cursor_in_window_tree P_ ((struct window *, int));
393  static void x_update_window_cursor P_ ((struct window *, int));  static void x_update_window_cursor P_ ((struct window *, int));
# Line 634  x_draw_vertical_border (w) Line 641  x_draw_vertical_border (w)
641        RECT r;        RECT r;
642        HDC hdc;        HDC hdc;
643    
644        window_box_edges (w, -1, &r.left, &r.top, &r.right, &r.bottom);        window_box_edges (w, -1, (int *) &r.left, (int *) &r.top,
645                            (int *) &r.right, (int *) &r.bottom);
646        r.left = r.right + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f);        r.left = r.right + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f);
647        r.right = r.left + 1;        r.right = r.left + 1;
648        r.bottom -= 1;        r.bottom -= 1;
# Line 664  x_update_window_end (w, cursor_on_p, mou Line 672  x_update_window_end (w, cursor_on_p, mou
672       struct window *w;       struct window *w;
673       int cursor_on_p, mouse_face_overwritten_p;       int cursor_on_p, mouse_face_overwritten_p;
674  {  {
675      struct w32_display_info *dpyinfo
676        = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
677    
678    if (!w->pseudo_window_p)    if (!w->pseudo_window_p)
679      {      {
       struct w32_display_info *dpyinfo  
         = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));  
   
680        BLOCK_INPUT;        BLOCK_INPUT;
681    
       /* If a row with mouse-face was overwritten, arrange for  
          XTframe_up_to_date to redisplay the mouse highlight.  */  
       if (mouse_face_overwritten_p)  
         {  
           dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;  
           dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;  
           dpyinfo->mouse_face_window = Qnil;  
         }  
   
682        if (cursor_on_p)        if (cursor_on_p)
683          x_display_and_set_cursor (w, 1, output_cursor.hpos,          x_display_and_set_cursor (w, 1, output_cursor.hpos,
684                                    output_cursor.vpos,                                    output_cursor.vpos,
# Line 688  x_update_window_end (w, cursor_on_p, mou Line 687  x_update_window_end (w, cursor_on_p, mou
687        x_draw_vertical_border (w);        x_draw_vertical_border (w);
688        UNBLOCK_INPUT;        UNBLOCK_INPUT;
689      }      }
690      
691      /* If a row with mouse-face was overwritten, arrange for
692         XTframe_up_to_date to redisplay the mouse highlight.  */
693      if (mouse_face_overwritten_p)
694        {
695          dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
696          dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
697          dpyinfo->mouse_face_window = Qnil;
698        }
699    
700    updated_window = NULL;    updated_window = NULL;
701  }  }
702    
# Line 1981  x_produce_glyphs (it) Line 1989  x_produce_glyphs (it)
1989            else if (!SINGLE_BYTE_CHAR_P (it->c)            else if (!SINGLE_BYTE_CHAR_P (it->c)
1990                     && !it->multibyte_p)                     && !it->multibyte_p)
1991              {              {
1992                it->char_to_display = multibyte_char_to_unibyte (it->c, Qnil);                it->multibyte_p = 1;
               it->multibyte_p = 0;  
1993                it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);                it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
1994                face = FACE_FROM_ID (it->f, it->face_id);                face = FACE_FROM_ID (it->f, it->face_id);
1995              }              }
# Line 2680  void W32_TEXTOUT (s, x, y,chars,nchars) Line 2687  void W32_TEXTOUT (s, x, y,chars,nchars)
2687                  nchars * charset_dim, NULL);                  nchars * charset_dim, NULL);
2688  }  }
2689    
2690  #if 0  #if GLYPH_DEBUG
2691    
2692  static void  static void
2693  x_dump_glyph_string (s)  x_dump_glyph_string (s)
# Line 3030  w32_get_glyph_string_clip_rect (s, r) Line 3037  w32_get_glyph_string_clip_rect (s, r)
3037        r_height = s->row->visible_height;        r_height = s->row->visible_height;
3038      }      }
3039    
   /* Don't use S->y for clipping because it doesn't take partially  
      visible lines into account.  For example, it can be negative for  
      partially visible lines at the top of a window.  */  
   if (!s->row->full_width_p  
       && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))  
     r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);  
   else  
     r->top = max (0, s->row->y);  
   
   /* If drawing a tool-bar window, draw it over the internal border  
      at the top of the window.  */  
   if (s->w == XWINDOW (s->f->tool_bar_window))  
     r->top -= s->f->output_data.w32->internal_border_width;  
   
3040    /* If S draws overlapping rows, it's sufficient to use the top and    /* If S draws overlapping rows, it's sufficient to use the top and
3041       bottom of the window for clipping because this glyph string       bottom of the window for clipping because this glyph string
3042       intentionally draws over other lines.  */       intentionally draws over other lines.  */
# Line 3052  w32_get_glyph_string_clip_rect (s, r) Line 3045  w32_get_glyph_string_clip_rect (s, r)
3045        r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);        r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
3046        r_height = window_text_bottom_y (s->w) - r->top;        r_height = window_text_bottom_y (s->w) - r->top;
3047      }      }
3048            else
3049        {
3050          /* Don't use S->y for clipping because it doesn't take partially
3051             visible lines into account.  For example, it can be negative for
3052             partially visible lines at the top of a window.  */
3053          if (!s->row->full_width_p
3054              && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
3055            r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
3056          else
3057            r->top = max (0, s->row->y);
3058    
3059          /* If drawing a tool-bar window, draw it over the internal border
3060             at the top of the window.  */
3061          if (s->w == XWINDOW (s->f->tool_bar_window))
3062            r->top -= s->f->output_data.w32->internal_border_width;
3063        }
3064    
3065    r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top);    r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top);
3066    
3067    r->bottom = r->top + r_height;    r->bottom = r->top + r_height;
# Line 3646  w32_draw_relief_rect (f, left_x, top_y, Line 3655  w32_draw_relief_rect (f, left_x, top_y,
3655    
3656    /* Top.  */    /* Top.  */
3657    for (i = 0; i < width; ++i)    for (i = 0; i < width; ++i)
3658      {      w32_fill_area (f, hdc, gc.foreground,
3659        w32_fill_area (f, hdc, gc.foreground,                     left_x + i * left_p, top_y + i,
3660                       left_x + i * left_p, top_y + i,                     (right_x + 1 - i * right_p) - (left_x + i * left_p), 1);
                      (right_x + 1 - i * right_p) - (left_x + i * left_p), 1);  
     }  
3661    
3662    /* Left.  */    /* Left.  */
3663    if (left_p)    if (left_p)
3664      for (i = 0; i < width; ++i)      for (i = 0; i < width; ++i)
3665        {        w32_fill_area (f, hdc, gc.foreground,
3666          w32_fill_area (f, hdc, gc.foreground,                       left_x + i, top_y + i, 1,
3667                         left_x + i, top_y + i, 1,                       (bottom_y - i + 1) - (top_y + i));
                        (bottom_y - i) - (top_y + i));  
       }  
   
   w32_set_clip_rectangle (hdc, NULL);  
3668    
3669    if (raised_p)    if (raised_p)
3670      gc.foreground = f->output_data.w32->black_relief.gc->foreground;      gc.foreground = f->output_data.w32->black_relief.gc->foreground;
3671    else    else
3672      gc.foreground = f->output_data.w32->white_relief.gc->foreground;      gc.foreground = f->output_data.w32->white_relief.gc->foreground;
   
   
   w32_set_clip_rectangle (hdc, clip_rect);  
3673        
3674    /* Bottom.  */    /* Bottom.  */
3675    for (i = 0; i < width; ++i)    for (i = 0; i < width; ++i)
3676      {      w32_fill_area (f, hdc, gc.foreground,
3677        w32_fill_area (f, hdc, gc.foreground,                     left_x + i * left_p, bottom_y - i,
3678                       left_x + i * left_p, bottom_y - i,                     (right_x + 2 - i * right_p) - (left_x + i * left_p), 1);
                      (right_x + 1 - i * right_p) - left_x + i * left_p, 1);  
     }  
3679    
3680    /* Right.  */    /* Right.  */
3681    if (right_p)    if (right_p)
3682      for (i = 0; i < width; ++i)      for (i = 0; i < width; ++i)
3683        {        w32_fill_area (f, hdc, gc.foreground,
3684          w32_fill_area (f, hdc, gc.foreground,                       right_x - i, top_y + i + 1, 1,
3685                         right_x - i, top_y + i + 1, 1,                       (bottom_y - i) - (top_y + i + 1));
                        (bottom_y - i) - (top_y + i + 1));  
       }  
3686    
3687    w32_set_clip_rectangle (hdc, NULL);    w32_set_clip_rectangle (hdc, NULL);
3688        
# Line 3764  x_draw_glyph_string_box (s) Line 3760  x_draw_glyph_string_box (s)
3760    width = abs (s->face->box_line_width);    width = abs (s->face->box_line_width);
3761    raised_p = s->face->box == FACE_RAISED_BOX;    raised_p = s->face->box == FACE_RAISED_BOX;
3762    left_x = s->x;    left_x = s->x;
3763    right_x = ((s->row->full_width_p    right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p
3764                ? last_x - 1                ? last_x - 1
3765                : min (last_x, s->x + s->background_width) - 1));                : min (last_x, s->x + s->background_width) - 1));
3766    top_y = s->y;    top_y = s->y;
# Line 4213  x_draw_stretch_glyph_string (s) Line 4209  x_draw_stretch_glyph_string (s)
4209            int w = s->background_width - width, h = s->height;            int w = s->background_width - width, h = s->height;
4210            RECT r;            RECT r;
4211            HDC hdc = s->hdc;            HDC hdc = s->hdc;
4212    
4213              if (s->row->mouse_face_p
4214                  && cursor_in_mouse_face_p (s->w))
4215                {
4216                  x_set_mouse_face_gc (s);
4217                  gc = s->gc;
4218                }
4219              else
4220                gc = s->face->gc;
4221      
4222            w32_get_glyph_string_clip_rect (s, &r);            w32_get_glyph_string_clip_rect (s, &r);
4223            w32_set_clip_rectangle (hdc, &r);            w32_set_clip_rectangle (hdc, &r);
4224    
# Line 4231  x_draw_stretch_glyph_string (s) Line 4237  x_draw_stretch_glyph_string (s)
4237              }              }
4238          }          }
4239      }      }
4240    else    else if (!s->background_filled_p)
4241      x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,      x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
4242                                   s->height);                                   s->height);
4243        
# Line 4260  x_draw_glyph_string (s) Line 4266  x_draw_glyph_string (s)
4266    
4267    /* Set up S->gc, set clipping and draw S.  */    /* Set up S->gc, set clipping and draw S.  */
4268    x_set_glyph_string_gc (s);    x_set_glyph_string_gc (s);
   x_set_glyph_string_clipping (s);  
4269    
4270    /* Draw relief (if any) in advance for char/composition so that the    /* Draw relief (if any) in advance for char/composition so that the
4271       glyph string can be drawn over it.  */       glyph string can be drawn over it.  */
# Line 4270  x_draw_glyph_string (s) Line 4275  x_draw_glyph_string (s)
4275            || s->first_glyph->type == COMPOSITE_GLYPH))            || s->first_glyph->type == COMPOSITE_GLYPH))
4276    
4277      {      {
4278          x_set_glyph_string_clipping (s);
4279        x_draw_glyph_string_background (s, 1);        x_draw_glyph_string_background (s, 1);
4280        x_draw_glyph_string_box (s);        x_draw_glyph_string_box (s);
4281          x_set_glyph_string_clipping (s);
4282        relief_drawn_p = 1;        relief_drawn_p = 1;
4283      }      }
4284      else
4285        x_set_glyph_string_clipping (s);
4286    
4287    switch (s->first_glyph->type)    switch (s->first_glyph->type)
4288      {      {
# Line 4314  x_draw_glyph_string (s) Line 4323  x_draw_glyph_string (s)
4323            unsigned long h = 1;            unsigned long h = 1;
4324            unsigned long dy = s->height - h;            unsigned long dy = s->height - h;
4325    
4326              /* TODO: Use font information for positioning and thickness
4327                 of underline.  See OUTLINETEXTMETRIC, and xterm.c.  */
4328            if (s->face->underline_defaulted_p)            if (s->face->underline_defaulted_p)
4329              {              {
4330                w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,                w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
# Line 4563  x_fill_stretch_glyph_string (s, row, are Line 4574  x_fill_stretch_glyph_string (s, row, are
4574    /* Adjust base line for subscript/superscript text.  */    /* Adjust base line for subscript/superscript text.  */
4575    s->ybase += voffset;    s->ybase += voffset;
4576    
4577    xassert (s->face && s->face->gc);    xassert (s->face);
4578    return glyph - s->row->glyphs[s->area];    return glyph - s->row->glyphs[s->area];
4579  }  }
4580    
# Line 5440  expose_frame (f, x, y, w, h) Line 5451  expose_frame (f, x, y, w, h)
5451       int x, y, w, h;       int x, y, w, h;
5452  {  {
5453    RECT r;    RECT r;
5454      int mouse_face_overwritten_p = 0;
5455    
5456    TRACE ((stderr, "expose_frame "));    TRACE ((stderr, "expose_frame "));
5457    
# Line 5475  expose_frame (f, x, y, w, h) Line 5487  expose_frame (f, x, y, w, h)
5487      }      }
5488    
5489    TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom));    TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom));
5490    expose_window_tree (XWINDOW (f->root_window), &r);    mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
5491    
5492    if (WINDOWP (f->tool_bar_window))    if (WINDOWP (f->tool_bar_window))
5493      {      mouse_face_overwritten_p
5494        struct window *w = XWINDOW (f->tool_bar_window);        |= expose_window (XWINDOW (f->tool_bar_window), &r);
       RECT window_rect;  
       RECT intersection_rect;  
       int window_x, window_y, window_width, window_height;  
   
       window_box (w, -1, &window_x, &window_y, &window_width, &window_height);  
       window_rect.left = window_x;  
       window_rect.top = window_y;  
       window_rect.right = window_x + window_width;  
       window_rect.bottom = window_y + window_height;  
5495    
5496        if (IntersectRect (&intersection_rect, &r, &window_rect))    /* Some window managers support a focus-follows-mouse style with
5497          expose_window (w, &intersection_rect);       delayed raising of frames.  Imagine a partially obscured frame,
5498         and moving the mouse into partially obscured mouse-face on that
5499         frame.  The visible part of the mouse-face will be highlighted,
5500         then the WM raises the obscured frame.  With at least one WM, KDE
5501         2.1, Emacs is not getting any event for the raising of the frame
5502         (even tried with SubstructureRedirectMask), only Expose events.
5503         These expose events will draw text normally, i.e. not
5504         highlighted.  Which means we must redo the highlight here.
5505         Subsume it under ``we love X''.  --gerd 2001-08-15  */
5506      /* Included in Windows version because Windows most likely does not
5507         do the right thing if any third party tool offers
5508         focus-follows-mouse with delayed raise.  --jason 2001-10-12  */
5509      if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
5510        {
5511          struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
5512          if (f == dpyinfo->mouse_face_mouse_frame)
5513            {
5514              int x = dpyinfo->mouse_face_mouse_x;
5515              int y = dpyinfo->mouse_face_mouse_y;
5516              clear_mouse_face (dpyinfo);
5517              note_mouse_highlight (f, x, y);
5518            }
5519      }      }
5520  }  }
5521    
# Line 5499  expose_frame (f, x, y, w, h) Line 5523  expose_frame (f, x, y, w, h)
5523  /* Redraw (parts) of all windows in the window tree rooted at W that  /* Redraw (parts) of all windows in the window tree rooted at W that
5524     intersect R.  R contains frame pixel coordinates.  */     intersect R.  R contains frame pixel coordinates.  */
5525    
5526  static void  static int
5527  expose_window_tree (w, r)  expose_window_tree (w, r)
5528       struct window *w;       struct window *w;
5529       RECT *r;       RECT *r;
5530  {  {
5531    while (w)    struct frame *f = XFRAME (w->frame);
5532      int mouse_face_overwritten_p = 0;
5533    
5534      while (w && !FRAME_GARBAGED_P (f))
5535      {      {
5536        if (!NILP (w->hchild))        if (!NILP (w->hchild))
5537          expose_window_tree (XWINDOW (w->hchild), r);          mouse_face_overwritten_p
5538              |= expose_window_tree (XWINDOW (w->hchild), r);
5539        else if (!NILP (w->vchild))        else if (!NILP (w->vchild))
5540          expose_window_tree (XWINDOW (w->vchild), r);          mouse_face_overwritten_p
5541              |= expose_window_tree (XWINDOW (w->vchild), r);
5542        else        else
5543          {          mouse_face_overwritten_p |= expose_window (w, r);
           RECT window_rect;  
           RECT intersection_rect;  
           struct frame *f = XFRAME (w->frame);  
           int window_x, window_y, window_width, window_height;  
   
           /* Frame-relative pixel rectangle of W.  */  
           window_box (w, -1, &window_x, &window_y, &window_width,  
                       &window_height);  
           window_rect.left  
             = (window_x  
                - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)  
                - FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_Y_UNIT (f));  
           window_rect.top = window_y;  
           window_rect.right = window_rect.left  
             + (window_width  
                + FRAME_X_FLAGS_AREA_WIDTH (f)  
                + FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f));  
           window_rect.bottom = window_rect.top  
             + window_height + CURRENT_MODE_LINE_HEIGHT (w);  
   
           if (IntersectRect (&intersection_rect, r, &window_rect))  
             expose_window (w, &intersection_rect);  
         }  
5544    
5545        w = NILP (w->next) ? 0 : XWINDOW (w->next);        w = NILP (w->next) ? NULL : XWINDOW (w->next);
5546      }      }
5547    
5548      return mouse_face_overwritten_p;
5549  }  }
5550    
5551    
# Line 5606  expose_area (w, row, r, area) Line 5614  expose_area (w, row, r, area)
5614    
5615    
5616  /* Redraw the parts of the glyph row ROW on window W intersecting  /* Redraw the parts of the glyph row ROW on window W intersecting
5617     rectangle R.  R is in window-relative coordinates.  */     rectangle R.  R is in window-relative coordinates.  Value is
5618       non-zero if mouse face was overwritten.  */
5619    
5620  static void  static int
5621  expose_line (w, row, r)  expose_line (w, row, r)
5622       struct window *w;       struct window *w;
5623       struct glyph_row *row;       struct glyph_row *row;
# Line 5629  expose_line (w, row, r) Line 5638  expose_line (w, row, r)
5638          expose_area (w, row, r, RIGHT_MARGIN_AREA);          expose_area (w, row, r, RIGHT_MARGIN_AREA);
5639        x_draw_row_bitmaps (w, row);        x_draw_row_bitmaps (w, row);
5640      }      }
5641    
5642      return row->mouse_face_p;
5643  }  }
5644    
5645    
# Line 5656  x_phys_cursor_in_rect_p (w, r) Line 5667  x_phys_cursor_in_rect_p (w, r)
5667  }  }
5668    
5669    
5670  /* Redraw a rectangle of window W.  R is a rectangle in window  /* Redraw the part of window W intersection rectagle FR.  Pixel
5671     relative coordinates.  Call this function with input blocked.  */     coordinates in FR are frame relative.  Call this function with
5672       input blocked.  Value is non-zero if the exposure overwrites
5673       mouse-face.  */
5674    
5675  static void  static int
5676  expose_window (w, r)  expose_window (w, fr)
5677       struct window *w;       struct window *w;
5678       RECT *r;       RECT *fr;
5679  {  {
5680    struct glyph_row *row;    struct frame *f = XFRAME (w->frame);
5681    int y;    RECT wr, r;
5682    int yb = window_text_bottom_y (w);    int mouse_face_overwritten_p = 0;
   int cursor_cleared_p;  
5683    
5684    /* If window is not yet fully initialized, do nothing.  This can    /* If window is not yet fully initialized, do nothing.  This can
5685       happen when toolkit scroll bars are used and a window is split.       happen when toolkit scroll bars are used and a window is split.
5686       Reconfiguring the scroll bar will generate an expose for a newly       Reconfiguring the scroll bar will generate an expose for a newly
5687       created window.  */       created window.  */
5688    if (w->current_matrix == NULL || w == updated_window)    if (w->current_matrix == NULL)
5689      return;      return 0;
   
   TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",  
           r->left, r->top, r->right, r->bottom));  
   
   /* Convert to window coordinates.  */  
   r->left = FRAME_TO_WINDOW_PIXEL_X (w, r->left);  
   r->top = FRAME_TO_WINDOW_PIXEL_Y (w, r->top);  
   r->right = FRAME_TO_WINDOW_PIXEL_X (w, r->right);  
   r->bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r->bottom);  
5690    
5691    /* Turn off the cursor.  */    /* When we're currently updating the window, display and current
5692    if (!w->pseudo_window_p       matrix usually don't agree.  Arrange for a thorough display
5693        && x_phys_cursor_in_rect_p (w, r))       later.  */
5694      if (w == updated_window)
5695      {      {
5696        x_clear_cursor (w);        SET_FRAME_GARBAGED (f);
5697        cursor_cleared_p = 1;        return 0;
5698      }      }
   else  
     cursor_cleared_p = 0;  
5699    
5700    /* Find the first row intersecting the rectangle R.  */    /* Frame-relative pixel rectangle of W.  */
5701    row = w->current_matrix->rows;    wr.left = XFASTINT (w->left) * CANON_X_UNIT (f);
5702    y = 0;    wr.top = XFASTINT (w->top) * CANON_Y_UNIT (f);
5703    while (row->enabled_p    wr.right = wr.left + XFASTINT (w->width) * CANON_X_UNIT (f);
5704           && y < yb    wr.bottom = wr.top + XFASTINT (w->height) * CANON_Y_UNIT (f);
5705           && y + row->height < r->top)  
5706      {    if (IntersectRect(&r, fr, &wr))
       y += row->height;  
       ++row;  
     }  
           
   /* Display the text in the rectangle, one text line at a time.  */  
   while (row->enabled_p  
          && y < yb  
          && y < r->bottom)  
5707      {      {
5708        expose_line (w, row, r);        int yb = window_text_bottom_y (w);
5709        y += row->height;        struct glyph_row *row;
5710        ++row;        int cursor_cleared_p;
     }  
5711    
5712    /* Display the mode line if there is one.  */        TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
5713    if (WINDOW_WANTS_MODELINE_P (w)                r.left, r.top, r.right, r.bottom));
       && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),  
           row->enabled_p)  
       && row->y < r->bottom)  
     expose_line (w, row, r);  
5714    
5715    if (!w->pseudo_window_p)        /* Convert to window coordinates.  */
5716      {        r.left = FRAME_TO_WINDOW_PIXEL_X (w, r.left);
5717        /* Draw border between windows.  */        r.right = FRAME_TO_WINDOW_PIXEL_X (w, r.right);
5718        x_draw_vertical_border (w);        r.top = FRAME_TO_WINDOW_PIXEL_Y (w, r.top);
5719                r.bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r.bottom);
5720        /* Turn the cursor on again.  */  
5721        if (cursor_cleared_p)        /* Turn off the cursor.  */
5722          x_update_window_cursor (w, 1);        if (!w->pseudo_window_p
5723              && x_phys_cursor_in_rect_p (w, &r))
5724            {
5725              x_clear_cursor (w);
5726              cursor_cleared_p = 1;
5727            }
5728          else
5729            cursor_cleared_p = 0;
5730    
5731          /* Find the first row intersecting the rectangle R.  */
5732          for (row = w->current_matrix->rows;
5733               row->enabled_p;
5734               ++row)
5735            {
5736              int y0 = row->y;
5737              int y1 = MATRIX_ROW_BOTTOM_Y (row);
5738    
5739              if ((y0 >= r.top && y0 < r.bottom)
5740                  || (y1 > r.top && y1 < r.bottom)
5741                  || (r.top >= y0 && r.top < y1)
5742                  || (r.bottom > y0 && r.bottom < y1))
5743                {
5744                  if (expose_line (w, row, &r))
5745                    mouse_face_overwritten_p = 1;
5746                }
5747    
5748              if (y1 >= yb)
5749                break;
5750            }
5751    
5752          /* Display the mode line if there is one.  */
5753          if (WINDOW_WANTS_MODELINE_P (w)
5754              && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
5755                  row->enabled_p)
5756              && row->y < r.bottom)
5757            {
5758              if (expose_line (w, row, &r))
5759                mouse_face_overwritten_p = 1;
5760            }
5761    
5762          if (!w->pseudo_window_p)
5763            {
5764              /* Draw border between windows.  */
5765              x_draw_vertical_border (w);
5766    
5767              /* Turn the cursor on again.  */
5768              if (cursor_cleared_p)
5769                x_update_window_cursor (w, 1);
5770            }
5771      }      }
5772    
5773      return mouse_face_overwritten_p;
5774  }  }
5775    
5776    
# Line 6134  construct_drag_n_drop (result, msg, f) Line 6173  construct_drag_n_drop (result, msg, f)
6173  static MSG last_mouse_motion_event;  static MSG last_mouse_motion_event;
6174  static Lisp_Object last_mouse_motion_frame;  static Lisp_Object last_mouse_motion_frame;
6175    
6176    static void remember_mouse_glyph P_ ((struct frame *, int, int));
6177    
6178  static void  static void
6179  note_mouse_movement (frame, msg)  note_mouse_movement (frame, msg)
6180       FRAME_PTR frame;       FRAME_PTR frame;
6181       MSG *msg;       MSG *msg;
6182  {  {
6183      int mouse_x = LOWORD (msg->lParam);
6184      int mouse_y = HIWORD (msg->lParam);
6185    
6186    last_mouse_movement_time = msg->time;    last_mouse_movement_time = msg->time;
6187    memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));    memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));
6188    XSETFRAME (last_mouse_motion_frame, frame);    XSETFRAME (last_mouse_motion_frame, frame);
# Line 6151  note_mouse_movement (frame, msg) Line 6195  note_mouse_movement (frame, msg)
6195      }      }
6196    
6197    /* Has the mouse moved off the glyph it was on at the last sighting?  */    /* Has the mouse moved off the glyph it was on at the last sighting?  */
6198    else if (LOWORD (msg->lParam) < last_mouse_glyph.left    else if (mouse_x < last_mouse_glyph.left
6199             || LOWORD (msg->lParam) > last_mouse_glyph.right             || mouse_x > last_mouse_glyph.right
6200             || HIWORD (msg->lParam) < last_mouse_glyph.top             || mouse_y < last_mouse_glyph.top
6201             || HIWORD (msg->lParam) > last_mouse_glyph.bottom)             || mouse_y > last_mouse_glyph.bottom)
6202      {      {
6203        frame->mouse_moved = 1;        frame->mouse_moved = 1;
6204        last_mouse_scroll_bar = Qnil;        last_mouse_scroll_bar = Qnil;
6205        note_mouse_highlight (frame, LOWORD (msg->lParam), HIWORD (msg->lParam));        note_mouse_highlight (frame, mouse_x, mouse_y);
6206          /* Remember the mouse position here, as w32_mouse_position only
6207             gets called when mouse tracking is enabled but we also need
6208             to keep track of the mouse for help_echo and highlighting at
6209             other times.  */
6210          remember_mouse_glyph (frame, mouse_x, mouse_y);
6211      }      }
6212  }  }
6213    
# Line 6181  int disable_mouse_highlight; Line 6230  int disable_mouse_highlight;
6230     date.  */     date.  */
6231    
6232  static struct glyph *  static struct glyph *
6233  x_y_to_hpos_vpos (w, x, y, hpos, vpos, area)  x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
6234       struct window *w;       struct window *w;
6235       int x, y;       int x, y;
6236       int *hpos, *vpos, *area;       int *hpos, *vpos, *area;
6237         int buffer_only_p;
6238  {  {
6239    struct glyph *glyph, *end;    struct glyph *glyph, *end;
6240    struct glyph_row *row = NULL;    struct glyph_row *row = NULL;
# Line 6242  x_y_to_hpos_vpos (w, x, y, hpos, vpos, a Line 6292  x_y_to_hpos_vpos (w, x, y, hpos, vpos, a
6292          {          {
6293            if (w->pseudo_window_p)            if (w->pseudo_window_p)
6294              break;              break;
6295            else if (BUFFERP (glyph->object))            else if (!buffer_only_p || BUFFERP (glyph->object))
6296              break;              break;
6297          }          }
6298                
# Line 6376  note_mouse_highlight (f, x, y) Line 6426  note_mouse_highlight (f, x, y)
6426    int portion;    int portion;
6427    Lisp_Object window;    Lisp_Object window;
6428    struct window *w;    struct window *w;
6429      struct buffer *b;
6430    
6431    /* When a menu is active, don't highlight because this looks odd. */    /* When a menu is active, don't highlight because this looks odd. */
6432    if (popup_activated ())    if (popup_activated ())
# Line 6421  note_mouse_highlight (f, x, y) Line 6472  note_mouse_highlight (f, x, y)
6472        return;        return;
6473      }      }
6474    
6475      /* Mouse is on the mode or header line?  */
6476    if (portion == 1 || portion == 3)    if (portion == 1 || portion == 3)
6477      {      {
       /* Mouse is on the mode or top line.  */  
6478        note_mode_line_highlight (w, x, portion == 1);        note_mode_line_highlight (w, x, portion == 1);
6479        return;        return;
6480      }      }
6481  #if 0 /* TODO: mouse cursor */  #if 0 /* TODO: mouse cursor */
6482    else if (portion == 2)    if (portion == 2)
6483      XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),      cursor = f->output_data.x->horizontal_drag_cursor;
                    f->output_data.x->horizontal_drag_cursor);  
6484    else    else
6485      XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),      cursor = f->output_data.x->text_cursor;
                    f->output_data.x->text_cursor);  
6486  #endif  #endif
   
6487    /* Are we in a window whose display is up to date?    /* Are we in a window whose display is up to date?
6488       And verify the buffer's text has not changed.  */       And verify the buffer's text has not changed.  */
6489      b = XBUFFER (w->buffer);
6490    if (/* Within text portion of the window.  */    if (/* Within text portion of the window.  */
6491        portion == 0        portion == 0
6492        && EQ (w->window_end_valid, w->buffer)        && EQ (w->window_end_valid, w->buffer)
6493        && XFASTINT (w->last_modified) == BUF_MODIFF (XBUFFER (w->buffer))        && XFASTINT (w->last_modified) == BUF_MODIFF (b)
6494        && (XFASTINT (w->last_overlay_modified)        && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
           == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer))))  
6495      {      {
6496        int hpos, vpos, pos, i, area;        int hpos, vpos, pos, i, area;
6497        struct glyph *glyph;        struct glyph *glyph;
6498          Lisp_Object object;
6499          Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
6500          Lisp_Object *overlay_vec = NULL;
6501          int len, noverlays;
6502          struct buffer *obuf;
6503          int obegv, ozv, same_region;
6504    
6505        /* Find the glyph under X/Y.  */        /* Find the glyph under X/Y.  */
6506        glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area);        glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
6507    
6508        /* Clear mouse face if X/Y not over text.  */        /* Clear mouse face if X/Y not over text.  */
6509        if (glyph == NULL        if (glyph == NULL
# Line 6457  note_mouse_highlight (f, x, y) Line 6511  note_mouse_highlight (f, x, y)
6511            || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)            || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
6512          {          {
6513            clear_mouse_face (dpyinfo);            clear_mouse_face (dpyinfo);
6514            return;            /* TODO: mouse cursor */
6515              goto set_cursor;
6516          }          }
6517    
6518        pos = glyph->charpos;        pos = glyph->charpos;
6519        xassert (w->pseudo_window_p || BUFFERP (glyph->object));        object = glyph->object;
6520          if (!STRINGP (object) && !BUFFERP (object))
6521            goto set_cursor;
6522    
6523          /* If we get an out-of-range value, return now; avoid an error.  */
6524          if (BUFFERP (object) && pos > BUF_Z (b))
6525            goto set_cursor;
6526    
6527          /* Make the window's buffer temporarily current for
6528             overlays_at and compute_char_face.  */
6529          obuf = current_buffer;
6530          current_buffer = b;
6531          obegv = BEGV;
6532          ozv = ZV;
6533          BEGV = BEG;
6534          ZV = Z;
6535    
6536          /* Is this char mouse-active or does it have help-echo?  */
6537          position = make_number (pos);
6538    
6539          if (BUFFERP (object))
6540            {
6541              /* Put all the overlays we want in a vector in overlay_vec.
6542                 Store the length in len.  If there are more than 10, make
6543                 enough space for all, and try again.  */
6544              len = 10;
6545              overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6546              noverlays =  overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
6547              if (noverlays > len)
6548                {
6549                  len = noverlays;
6550                  overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6551                  noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
6552                }
6553    
6554        /* Check for mouse-face and help-echo.  */            /* Sort overlays into increasing priority order.  */
6555        {            noverlays = sort_overlays (overlay_vec, noverlays, w);
6556          Lisp_Object mouse_face, overlay, position;          }
6557          Lisp_Object *overlay_vec;        else
6558          int len, noverlays;          noverlays = 0;
         struct buffer *obuf;  
         int obegv, ozv;  
   
         /* If we get an out-of-range value, return now; avoid an error.  */  
         if (pos > BUF_Z (XBUFFER (w->buffer)))  
           return;  
   
         /* Make the window's buffer temporarily current for  
            overlays_at and compute_char_face.  */  
         obuf = current_buffer;  
         current_buffer = XBUFFER (w->buffer);  
         obegv = BEGV;  
         ozv = ZV;  
         BEGV = BEG;  
         ZV = Z;  
   
         /* Is this char mouse-active or does it have help-echo?  */  
         XSETINT (position, pos);  
   
         /* Put all the overlays we want in a vector in overlay_vec.  
            Store the length in len.  If there are more than 10, make  
            enough space for all, and try again.  */  
         len = 10;  
         overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));  
         noverlays =  overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);  
         if (noverlays > len)  
           {  
             len = noverlays;  
             overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));  
             noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);  
           }  
6559    
6560          /* Sort overlays into increasing priority order.  */        same_region = (EQ (window, dpyinfo->mouse_face_window)
6561          noverlays = sort_overlays (overlay_vec, noverlays, w);                       && vpos >= dpyinfo->mouse_face_beg_row
6562                         && vpos <= dpyinfo->mouse_face_end_row
6563                         && (vpos > dpyinfo->mouse_face_beg_row
6564                             || hpos >= dpyinfo->mouse_face_beg_col)
6565                         && (vpos < dpyinfo->mouse_face_end_row
6566                             || hpos < dpyinfo->mouse_face_end_col
6567                             || dpyinfo->mouse_face_past_end));
6568    
6569          /* TODO: if (same_region)
6570             mouse cursor */
6571    
6572          /* Check mouse-face highlighting.  */
6573          if (! same_region
6574              /* If there exists an overlay with mouse-face overlapping
6575                 the one we are currently highlighting, we have to
6576                 check if we enter the overlapping overlay, and then
6577                 highlight that.  */
6578              || (OVERLAYP (dpyinfo->mouse_face_overlay)
6579                  && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
6580            {
6581              /* Find the highest priority overlay that has a mouse-face
6582                 property.  */
6583              overlay = Qnil;
6584              for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
6585                {
6586                  mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
6587                  if (!NILP (mouse_face))
6588                    overlay = overlay_vec[i];
6589                }
6590    
6591          /* Check mouse-face highlighting.  */            /* If we're actually highlighting the same overlay as
6592          if (! (EQ (window, dpyinfo->mouse_face_window)               before, there's no need to do that again.  */
6593                 && vpos >= dpyinfo->mouse_face_beg_row            if (!NILP (overlay)
6594                 && vpos <= dpyinfo->mouse_face_end_row                && EQ (overlay, dpyinfo->mouse_face_overlay))
6595                 && (vpos > dpyinfo->mouse_face_beg_row              goto check_help_echo;
                    || hpos >= dpyinfo->mouse_face_beg_col)  
                && (vpos < dpyinfo->mouse_face_end_row  
                    || hpos < dpyinfo->mouse_face_end_col  
                    || dpyinfo->mouse_face_past_end)))  
           {  
             /* Clear the display of the old active region, if any.  */  
             clear_mouse_face (dpyinfo);  
6596    
6597              /* Find the highest priority overlay that has a mouse-face prop.  */            dpyinfo->mouse_face_overlay = overlay;
6598              overlay = Qnil;  
6599              for (i = noverlays - 1; i >= 0; --i)            /* Clear the display of the old active region, if any.  */
6600                {            clear_mouse_face (dpyinfo);
6601                  mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);            /* TODO: mouse cursor changes.  */
6602                  if (!NILP (mouse_face))  
6603                    {            /* If no overlay applies, get a text property.  */
6604                      overlay = overlay_vec[i];            if (NILP (overlay))
6605                      break;              mouse_face = Fget_text_property (position, Qmouse_face, object);
6606                    }  
6607                }            /* Handle the overlay case.  */
6608              if (!NILP (overlay))
6609                {
6610                  /* Find the range of text around this char that
6611                     should be active.  */
6612                  Lisp_Object before, after;
6613                  int ignore;
6614    
6615                  before = Foverlay_start (overlay);
6616                  after = Foverlay_end (overlay);
6617                  /* Record this as the current active region.  */
6618                  fast_find_position (w, XFASTINT (before),
6619                                      &dpyinfo->mouse_face_beg_col,
6620                                      &dpyinfo->mouse_face_beg_row,
6621                                      &dpyinfo->mouse_face_beg_x,
6622                                      &dpyinfo->mouse_face_beg_y, Qnil);
6623    
6624                  dpyinfo->mouse_face_past_end
6625                    = !fast_find_position (w, XFASTINT (after),
6626                                           &dpyinfo->mouse_face_end_col,
6627                                           &dpyinfo->mouse_face_end_row,
6628                                           &dpyinfo->mouse_face_end_x,
6629                                           &dpyinfo->mouse_face_end_y, Qnil);
6630                  dpyinfo->mouse_face_window = window;
6631    
6632                  dpyinfo->mouse_face_face_id
6633                    = face_at_buffer_position (w, pos, 0, 0,
6634                                               &ignore, pos + 1, 1);
6635    
6636                  /* Display it as active.  */
6637                  show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6638                  /* TODO: mouse cursor changes.  */
6639                }
6640              /* Handle the text property case.  */
6641              else if (! NILP (mouse_face) && BUFFERP (object))
6642                {
6643                  /* Find the range of text around this char that
6644                     should be active.  */
6645                  Lisp_Object before, after, beginning, end;
6646                  int ignore;
6647    
6648                  beginning = Fmarker_position (w->start);
6649                  end = make_number (BUF_Z (XBUFFER (object))
6650                                     - XFASTINT (w->window_end_pos));
6651                  before
6652                    = Fprevious_single_property_change (make_number (pos + 1),
6653                                                        Qmouse_face,
6654                                                        object, beginning);
6655                  after
6656                    = Fnext_single_property_change (position, Qmouse_face,
6657                                                    object, end);
6658    
6659                  /* Record this as the current active region.  */
6660                  fast_find_position (w, XFASTINT (before),
6661                                      &dpyinfo->mouse_face_beg_col,
6662                                      &dpyinfo->mouse_face_beg_row,
6663                                      &dpyinfo->mouse_face_beg_x,
6664                                      &dpyinfo->mouse_face_beg_y, Qnil);
6665                  dpyinfo->mouse_face_past_end
6666                    = !fast_find_position (w, XFASTINT (after),
6667                                           &dpyinfo->mouse_face_end_col,
6668                                           &dpyinfo->mouse_face_end_row,
6669                                           &dpyinfo->mouse_face_end_x,
6670                                           &dpyinfo->mouse_face_end_y, Qnil);
6671                  dpyinfo->mouse_face_window = window;
6672    
6673                  if (BUFFERP (object))
6674                    dpyinfo->mouse_face_face_id
6675                      = face_at_buffer_position (w, pos, 0, 0,
6676                                                 &ignore, pos + 1, 1);
6677    
6678                  /* Display it as active.  */
6679                  show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6680                  /* TODO: mouse cursor changes.  */
6681                }
6682              else if (!NILP (mouse_face) && STRINGP (object))
6683                {
6684                  Lisp_Object b, e;
6685                  int ignore;
6686    
6687              /* If no overlay applies, get a text property.  */                b = Fprevious_single_property_change (make_number (pos + 1),
6688              if (NILP (overlay))                                                      Qmouse_face,
6689                mouse_face = Fget_text_property (position, Qmouse_face, w->buffer);                                                      object, Qnil);
6690                  e = Fnext_single_property_change (position, Qmouse_face,
6691              /* Handle the overlay case.  */                                                  object, Qnil);
6692              if (! NILP (overlay))                if (NILP (b))
6693                {                  b = make_number (0);
6694                  /* Find the range of text around this char that                if (NILP (e))
6695                     should be active.  */                  e = make_number (XSTRING (object)->size - 1);
6696                  Lisp_Object before, after;                fast_find_string_pos (w, XINT (b), object,
6697                  int ignore;                                      &dpyinfo->mouse_face_beg_col,
6698                                        &dpyinfo->mouse_face_beg_row,
                 before = Foverlay_start (overlay);  
                 after = Foverlay_end (overlay);  
                 /* Record this as the current active region.  */  
                 fast_find_position (w, XFASTINT (before),  
                                     &dpyinfo->mouse_face_beg_col,  
                                     &dpyinfo->mouse_face_beg_row,  
6699                                      &dpyinfo->mouse_face_beg_x,                                      &dpyinfo->mouse_face_beg_x,
6700                                      &dpyinfo->mouse_face_beg_y);                                      &dpyinfo->mouse_face_beg_y, 0);
6701                  dpyinfo->mouse_face_past_end                fast_find_string_pos (w, XINT (e), object,
6702                    = !fast_find_position (w, XFASTINT (after),                                      &dpyinfo->mouse_face_end_col,
6703                                           &dpyinfo->mouse_face_end_col,                                      &dpyinfo->mouse_face_end_row,
6704                                           &dpyinfo->mouse_face_end_row,                                      &dpyinfo->mouse_face_end_x,
6705                                           &dpyinfo->mouse_face_end_x,                                      &dpyinfo->mouse_face_end_y, 1);
6706                                           &dpyinfo->mouse_face_end_y);                dpyinfo->mouse_face_past_end = 0;
6707                  dpyinfo->mouse_face_window = window;                dpyinfo->mouse_face_window = window;
6708                  dpyinfo->mouse_face_face_id                dpyinfo->mouse_face_face_id
6709                    = face_at_buffer_position (w, pos, 0, 0,                  = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
6710                                               &ignore, pos + 1, 1);                                             glyph->face_id, 1);
6711                  show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6712                  /* Display it as active.  */                /* TODO: mouse cursor changes.  */
6713                  show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);              }
6714                }            else if (STRINGP (object) && NILP (mouse_face))
6715              /* Handle the text property case.  */              {
6716              else if (! NILP (mouse_face))                /* A string which doesn't have mouse-face, but
6717                {                   the text ``under'' it might have.  */
6718                  /* Find the range of text around this char that                struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
6719                     should be active.  */                int start = MATRIX_ROW_START_CHARPOS (r);
6720                  Lisp_Object before, after, beginning, end;                
6721                  int ignore;                pos = string_buffer_position (w, object, start);
6722                  if (pos > 0)
6723                  beginning = Fmarker_position (w->start);                  mouse_face = get_char_property_and_overlay (make_number (pos),
6724                  XSETINT (end, (BUF_Z (XBUFFER (w->buffer))                                                              Qmouse_face,
6725                                 - XFASTINT (w->window_end_pos)));                                                              w->buffer,
6726                  before                                                              &overlay);
6727                    = Fprevious_single_property_change (make_number (pos + 1),                if (!NILP (mouse_face) && !NILP (overlay))
6728                                                        Qmouse_face,                  {
6729                                                        w->buffer, beginning);                    Lisp_Object before = Foverlay_start (overlay);
6730                  after                    Lisp_Object after = Foverlay_end (overlay);
6731                    = Fnext_single_property_change (position, Qmouse_face,                    Lisp_Object ignore;
6732                                                    w->buffer, end);  
6733                  /* Record this as the current active region.  */                    /* Note that we might not be able to find position
6734                  fast_find_position (w, XFASTINT (before),                       BEFORE in the glyph matrix if the overlay is
6735                                      &dpyinfo->mouse_face_beg_col,                       entirely covered by a `display' property.  In
6736                                      &dpyinfo->mouse_face_beg_row,                       this case, we overshoot.  So let's stop in
6737                                      &dpyinfo->mouse_face_beg_x,                       the glyph matrix before glyphs for OBJECT.  */
6738                                      &dpyinfo->mouse_face_beg_y);                    fast_find_position (w, XFASTINT (before),
6739                  dpyinfo->mouse_face_past_end                                        &dpyinfo->mouse_face_beg_col,
6740                    = !fast_find_position (w, XFASTINT (after),                                        &dpyinfo->mouse_face_beg_row,
6741                                           &dpyinfo->mouse_face_end_col,                                        &dpyinfo->mouse_face_beg_x,
6742                                           &dpyinfo->mouse_face_end_row,                                        &dpyinfo->mouse_face_beg_y,
6743                                           &dpyinfo->mouse_face_end_x,                                        object);
6744                                           &dpyinfo->mouse_face_end_y);                        
6745                  dpyinfo->mouse_face_window = window;                    dpyinfo->mouse_face_past_end
6746                  dpyinfo->mouse_face_face_id                      = !fast_find_position (w, XFASTINT (after),
6747                    = face_at_buffer_position (w, pos, 0, 0,                                             &dpyinfo->mouse_face_end_col,
6748                                               &ignore, pos + 1, 1);                                             &dpyinfo->mouse_face_end_row,
6749                                               &dpyinfo->mouse_face_end_x,
6750                  /* Display it as active.  */                                             &dpyinfo->mouse_face_end_y,
6751                  show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);                                             Qnil);
6752                }                    dpyinfo->mouse_face_window = window;
6753            }                    dpyinfo->mouse_face_face_id
6754                        = face_at_buffer_position (w, pos, 0, 0,
6755                                                   &ignore, pos + 1, 1);
6756    
6757                      /* Display it as active.  */
6758                      show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6759                      /* TODO: mouse cursor changes.  */
6760                    }
6761                }
6762            }
6763    
6764          /* Look for a `help-echo' property.  */      check_help_echo:
         {  
           Lisp_Object help, overlay;  
6765    
6766            /* Check overlays first.  */        /* Look for a `help-echo' property.  */
6767            help = overlay = Qnil;        {
6768            for (i = noverlays - 1; i >= 0 && NILP (help); --i)          Lisp_Object help, overlay;
             {  
               overlay = overlay_vec[i];  
               help = Foverlay_get (overlay, Qhelp_echo);  
             }  
6769    
6770            if (!NILP (help))          /* Check overlays first.  */
6771              {          help = overlay = Qnil;
6772                help_echo = help;          for (i = noverlays - 1; i >= 0 && NILP (help); --i)
6773                help_echo_window = window;            {
6774                help_echo_object = overlay;              overlay = overlay_vec[i];
6775                help_echo_pos = pos;              help = Foverlay_get (overlay, Qhelp_echo);
6776              }            }
6777            else  
6778              {          if (!NILP (help))
6779                /* Try text properties.  */            {
6780                if ((STRINGP (glyph->object)              help_echo = help;
6781                     && glyph->charpos >= 0              help_echo_window = window;
6782                     && glyph->charpos < XSTRING (glyph->object)->size)              help_echo_object = overlay;
6783                    || (BUFFERP (glyph->object)              help_echo_pos = pos;
6784                        && glyph->charpos >= BEGV            }
6785                        && glyph->charpos < ZV))          else
6786                  help = Fget_text_property (make_number (glyph->charpos),            {
6787                                             Qhelp_echo, glyph->object);              Lisp_Object object = glyph->object;
6788                int charpos = glyph->charpos;
6789    
6790                /* Try text properties.  */
6791                if (STRINGP (object)
6792                    && charpos >= 0
6793                    && charpos < XSTRING (object)->size)
6794                  {
6795                    help = Fget_text_property (make_number (charpos),
6796                                               Qhelp_echo, object);
6797                    if (NILP (help))
6798                      {
6799                        /* If the string itself doesn't specify a help-echo,
6800                           see if the buffer text ``under'' it does.  */
6801                        struct glyph_row *r
6802                          = MATRIX_ROW (w->current_matrix, vpos);
6803                        int start = MATRIX_ROW_START_CHARPOS (r);
6804                        int pos = string_buffer_position (w, object, start);
6805                        if (pos > 0)
6806                          {
6807                            help = Fget_char_property (make_number (pos),
6808                                                       Qhelp_echo, w->buffer);
6809                            if (!NILP (help))
6810                              {
6811                                charpos = pos;
6812                                object = w->buffer;
6813                              }
6814                          }
6815                      }
6816                  }
6817                else if (BUFFERP (object)
6818                         && charpos >= BEGV
6819                         && charpos < ZV)
6820                  help = Fget_text_property (make_number (charpos), Qhelp_echo,
6821                                             object);
6822                            
6823                if (!NILP (help))              if (!NILP (help))
6824                  {                {
6825                    help_echo = help;                  help_echo = help;
6826                    help_echo_window = window;                  help_echo_window = window;
6827                    help_echo_object = glyph->object;                  help_echo_object = object;
6828                    help_echo_pos = glyph->charpos;                  help_echo_pos = charpos;
6829                  }                }
6830              }            }
         }  
           
         BEGV = obegv;  
         ZV = ozv;  
         current_buffer = obuf;  
6831        }        }
6832    
6833          BEGV = obegv;
6834          ZV = ozv;
6835          current_buffer = obuf;
6836      }      }
6837    
6838     set_cursor:
6839      /* TODO: mouse cursor changes. */
6840      ;
6841  }  }
6842    
6843  static void  static void
# Line 6697  x_tool_bar_item (f, x, y, glyph, hpos, v Line 6887  x_tool_bar_item (f, x, y, glyph, hpos, v
6887    int area;    int area;
6888    
6889    /* Find the glyph under X/Y.  */    /* Find the glyph under X/Y.  */
6890    *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area);    *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
6891    if (*glyph == NULL)    if (*glyph == NULL)
6892      return -1;      return -1;
6893    
# Line 6877  note_tool_bar_highlight (f, x, y) Line 7067  note_tool_bar_highlight (f, x, y)
7067    
7068    
7069    
7070  /* Find the glyph matrix position of buffer position POS in window W.  /* Find the glyph matrix position of buffer position CHARPOS in window
7071     *HPOS, *VPOS, *X, and *Y are set to the positions found.  W's     *W.  HPOS, *VPOS, *X, and *Y are set to the positions found.  W's
7072     current glyphs must be up to date.  If POS is above window start     current glyphs must be up to date.  If CHARPOS is above window
7073     return (0, 0, 0, 0).  If POS is after end of W, return end of     start return (0, 0, 0, 0).  If CHARPOS is after end of W, return end
7074     last line in W.  */     of last line in W.  In the row containing CHARPOS, stop before glyphs
7075       having STOP as object.  */
7076    
7077    #if 0 /* This is a version of fast_find_position that's more correct
7078             in the presence of hscrolling, for example.  I didn't install
7079             it right away because the problem fixed is minor, it failed
7080             in 20.x as well, and I think it's too risky to install
7081             so near the release of 21.1.  2001-09-25 gerd.  */
7082    
7083  static int  static int
7084  fast_find_position (w, pos, hpos, vpos, x, y)  fast_find_position (w, charpos, hpos, vpos, x, y, stop)
7085         struct window *w;
7086         int charpos;
7087         int *hpos, *vpos, *x, *y;
7088         Lisp_Object stop;
7089    {
7090      struct glyph_row *row, *first;
7091      struct glyph *glyph, *end;
7092      int i, past_end = 0;
7093    
7094      first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7095      row = row_containing_pos (w, charpos, first, NULL);
7096      if (row == NULL)
7097        {
7098          if (charpos < MATRIX_ROW_START_CHARPOS (first))
7099            {
7100              *x = *y = *hpos = *vpos = 0;
7101              return 0;
7102            }
7103          else
7104            {
7105              row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
7106              past_end = 1;
7107            }
7108        }
7109    
7110      *x = row->x;
7111      *y = row->y;
7112      *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
7113      
7114      glyph = row->glyphs[TEXT_AREA];
7115      end = glyph + row->used[TEXT_AREA];
7116      
7117      /* Skip over glyphs not having an object at the start of the row.
7118         These are special glyphs like truncation marks on terminal
7119         frames.  */
7120      if (row->displays_text_p)
7121        while (glyph < end
7122               && INTEGERP (glyph->object)
7123               && !EQ (stop, glyph->object)
7124               && glyph->charpos < 0)
7125          {
7126            *x += glyph->pixel_width;
7127            ++glyph;
7128          }
7129    
7130      while (glyph < end
7131             && !INTEGERP (glyph->object)
7132             && !EQ (stop, glyph->object)
7133             && (!BUFFERP (glyph->object)
7134                 || glyph->charpos < charpos))
7135        {
7136          *x += glyph->pixel_width;
7137          ++glyph;
7138        }
7139    
7140      *hpos = glyph - row->glyphs[TEXT_AREA];
7141      return past_end;
7142    }
7143    
7144    #else /* not 0 */
7145    
7146    static int
7147    fast_find_position (w, pos, hpos, vpos, x, y, stop)
7148       struct window *w;       struct window *w;
7149       int pos;       int pos;
7150       int *hpos, *vpos, *x, *y;       int *hpos, *vpos, *x, *y;
7151         Lisp_Object stop;
7152  {  {
7153    int i;    int i;
7154    int lastcol;    int lastcol;
7155    int maybe_next_line_p = 0;    int maybe_next_line_p = 0;
7156    int line_start_position;    int line_start_position;
7157    int yb = window_text_bottom_y (w);    int yb = window_text_bottom_y (w);
7158    struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0);    struct glyph_row *row, *best_row;
7159    struct glyph_row *best_row = row;    int row_vpos, best_row_vpos;
   int row_vpos = 0, best_row_vpos = 0;  
7160    int current_x;    int current_x;
7161    
7162      row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7163      row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
7164    
7165    while (row->y < yb)    while (row->y < yb)
7166      {      {
7167        if (row->used[TEXT_AREA])        if (row->used[TEXT_AREA])
# Line 6935  fast_find_position (w, pos, hpos, vpos, Line 7198  fast_find_position (w, pos, hpos, vpos,
7198    for (i = 0; i < best_row->used[TEXT_AREA]; i++)    for (i = 0; i < best_row->used[TEXT_AREA]; i++)
7199      {      {
7200        struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;        struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
7201        int charpos;        int charpos = glyph->charpos;
7202    
7203        charpos = glyph->charpos;        if (BUFFERP (glyph->object))
       if (charpos == pos)  
7204          {          {
7205            *hpos = i;            if (charpos == pos)
7206            *vpos = best_row_vpos;              {
7207            *x = current_x;                *hpos = i;
7208            *y = best_row->y;                *vpos = best_row_vpos;
7209            return 1;                *x = current_x;
7210                  *y = best_row->y;
7211                  return 1;
7212                }
7213              else if (charpos > pos)
7214                break;
7215          }          }
7216        else if (charpos > pos)        else if (EQ (glyph->object, stop))
7217          break;          break;
       else if (charpos > 0)  
         lastcol = i;  
7218    
7219          if (charpos > 0)
7220            lastcol = i;
7221        current_x += glyph->pixel_width;        current_x += glyph->pixel_width;
7222      }      }
7223    
# Line 6972  fast_find_position (w, pos, hpos, vpos, Line 7239  fast_find_position (w, pos, hpos, vpos,
7239    return 0;    return 0;
7240  }  }
7241    
7242    #endif /* not 0 */
7243    
7244    
7245    /* Find the position of the the glyph for position POS in OBJECT in
7246       window W's current matrix, and return in *X/*Y the pixel
7247       coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7248    
7249       RIGHT_P non-zero means return the position of the right edge of the
7250       glyph, RIGHT_P zero means return the left edge position.
7251    
7252       If no glyph for POS exists in the matrix, return the position of
7253       the glyph with the next smaller position that is in the matrix, if
7254       RIGHT_P is zero.  If RIGHT_P is non-zero, and no glyph for POS
7255       exists in the matrix, return the position of the glyph with the
7256       next larger position in OBJECT.
7257    
7258       Value is non-zero if a glyph was found.  */
7259    
7260    static int
7261    fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
7262         struct window *w;
7263         int pos;
7264         Lisp_Object object;
7265         int *hpos, *vpos, *x, *y;
7266         int right_p;
7267    {
7268      int yb = window_text_bottom_y (w);
7269      struct glyph_row *r;
7270      struct glyph *best_glyph = NULL;
7271      struct glyph_row *best_row = NULL;
7272      int best_x = 0;
7273    
7274      for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7275           r->enabled_p && r->y < yb;
7276           ++r)
7277        {
7278          struct glyph *g = r->glyphs[TEXT_AREA];
7279          struct glyph *e = g + r->used[TEXT_AREA];
7280          int gx;
7281    
7282          for (gx = r->x; g < e; gx += g->pixel_width, ++g)
7283            if (EQ (g->object, object))
7284              {
7285                if (g->charpos == pos)
7286                  {
7287                    best_glyph = g;
7288                    best_x = gx;
7289                    best_row = r;
7290                    goto found;
7291                  }
7292                else if (best_glyph == NULL
7293                         || ((abs (g->charpos - pos)
7294                             < abs (best_glyph->charpos - pos))
7295                             && (right_p
7296                                 ? g->charpos < pos
7297                                 : g->charpos > pos)))
7298                  {
7299                    best_glyph = g;
7300                    best_x = gx;
7301                    best_row = r;
7302                  }
7303              }
7304        }
7305    
7306     found:
7307    
7308      if (best_glyph)
7309        {
7310          *x = best_x;
7311          *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
7312    
7313          if (right_p)
7314            {
7315              *x += best_glyph->pixel_width;
7316              ++*hpos;
7317            }
7318          
7319          *y = best_row->y;
7320          *vpos = best_row - w->current_matrix->rows;
7321        }
7322    
7323      return best_glyph != NULL;
7324    }
7325    
7326    
7327  /* Display the active region described by mouse_face_*  /* Display the active region described by mouse_face_*
7328     in its mouse-face if HL > 0, in its normal face if HL = 0.  */     in its mouse-face if HL > 0, in its normal face if HL = 0.  */
# Line 7045  show_mouse_face (dpyinfo, draw) Line 7396  show_mouse_face (dpyinfo, draw)
7396          {          {
7397            x_draw_glyphs (w, start_x, row, TEXT_AREA,            x_draw_glyphs (w, start_x, row, TEXT_AREA,
7398                           start_hpos, end_hpos, draw, NULL, NULL, 0);                           start_hpos, end_hpos, draw, NULL, NULL, 0);
7399            row->mouse_face_p = draw == DRAW_MOUSE_FACE;            row->mouse_face_p = draw == DRAW_MOUSE_FACE || DRAW_IMAGE_RAISED;
7400          }          }
7401      }      }
7402    
# Line 7076  show_mouse_face (dpyinfo, draw) Line 7427  show_mouse_face (dpyinfo, draw)
7427  /* Clear out the mouse-highlighted active region.  /* Clear out the mouse-highlighted active region.
7428     Redraw it un-highlighted first.  */     Redraw it un-highlighted first.  */
7429    
7430  void  static int
7431  clear_mouse_face (dpyinfo)  clear_mouse_face (dpyinfo)
7432       struct w32_display_info *dpyinfo;       struct w32_display_info *dpyinfo;
7433  {  {
7434  #if 0 /* This prevents redrawing tool bar items when changing from one    int cleared = 0;
          to another while a tooltip is open, so don't do it.  */  
   if (!NILP (tip_frame))  
     return;  
 #endif  
7435    
7436    if (! NILP (dpyinfo->mouse_face_window))    if (! NILP (dpyinfo->mouse_face_window))
7437      show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);      {
7438          show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
7439          cleared = 1;
7440        }
7441    
7442    dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;    dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7443    dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;    dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7444    dpyinfo->mouse_face_window = Qnil;    dpyinfo->mouse_face_window = Qnil;
7445      dpyinfo->mouse_face_overlay = Qnil;
7446      return cleared;
7447  }  }
7448    
7449    
# Line 7136  cancel_mouse_face (f) Line 7488  cancel_mouse_face (f)
7488    
7489  static struct scroll_bar *x_window_to_scroll_bar ();  static struct scroll_bar *x_window_to_scroll_bar ();
7490  static void x_scroll_bar_report_motion ();  static void x_scroll_bar_report_motion ();
7491    static int glyph_rect P_ ((struct frame *f, int, int, RECT *));
7492    
7493    
7494    /* Try to determine frame pixel position and size of the glyph under
7495       frame pixel coordinates X/Y on frame F .  Return the position and
7496       size in *RECT.  Value is non-zero if we could compute these
7497       values.  */
7498    
7499    static int
7500    glyph_rect (f, x, y, rect)
7501         struct frame *f;
7502         int x, y;
7503         RECT *rect;
7504    {
7505      Lisp_Object window;
7506      int part, found = 0;
7507    
7508      window = window_from_coordinates (f, x, y, &part, 0);
7509      if (!NILP (window))
7510        {
7511          struct window *w = XWINDOW (window);
7512          struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7513          struct glyph_row *end = r + w->current_matrix->nrows - 1;
7514          int area;
7515    
7516          frame_to_window_pixel_xy (w, &x, &y);
7517          
7518          for (; !found && r < end && r->enabled_p; ++r)
7519            if (r->y + r->height >= y)
7520              {
7521                struct glyph *g = r->glyphs[TEXT_AREA];
7522                struct glyph *end = g + r->used[TEXT_AREA];
7523                int gx;
7524                  
7525                for (gx = r->x; !found && g < end; gx += g->pixel_width, ++g)
7526                  if (gx + g->pixel_width >= x)
7527                    {
7528                      rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
7529                      rect->top = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
7530                      rect->right = rect->left + g->pixel_width;
7531                      rect->bottom = rect->top + r->height;
7532                      found = 1;
7533                    }
7534              }
7535        }
7536    
7537      return found;
7538    }
7539    
7540    /* Record the position of the mouse in last_mouse_glyph.  */
7541    static void remember_mouse_glyph (f1, gx, gy)
7542         struct frame * f1;
7543         int gx, gy;
7544    {
7545      if (!glyph_rect (f1, gx, gy, &last_mouse_glyph))
7546        {
7547          int width = FRAME_SMALLEST_CHAR_WIDTH (f1);
7548          int height = FRAME_SMALLEST_FONT_HEIGHT (f1);
7549    
7550          /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7551             round down even for negative values.  */
7552          if (gx < 0)
7553            gx -= width - 1;
7554          if (gy < 0)
7555            gy -= height - 1;
7556    #if 0
7557          /* This was the original code from XTmouse_position, but it seems
7558             to give the position of the glyph diagonally next to the one
7559             the mouse is over.  */
7560          gx = (gx + width - 1) / width * width;
7561          gy = (gy + height - 1) / height * height;
7562    #else
7563          gx = gx / width * width;
7564          gy = gy / height * height;
7565    #endif
7566    
7567          last_mouse_glyph.left = gx;
7568          last_mouse_glyph.top = gy;
7569          last_mouse_glyph.right  = gx + width;
7570          last_mouse_glyph.bottom = gy + height;
7571        }
7572    }
7573    
7574  /* Return the current position of the mouse.  /* Return the current position of the mouse.
7575     *fp should be a frame which indicates which display to ask about.     *fp should be a frame which indicates which display to ask about.
# Line 7199  w32_mouse_position (fp, insist, bar_wind Line 7633  w32_mouse_position (fp, insist, bar_wind
7633          else          else
7634            {            {
7635              /* Is window under mouse one of our frames?  */              /* Is window under mouse one of our frames?  */
7636              f1 = x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp),              f1 = x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp),
7637                                      WindowFromPoint (pt));                                      WindowFromPoint (pt));
7638            }            }
7639    
# Line 7239  w32_mouse_position (fp, insist, bar_wind Line 7673  w32_mouse_position (fp, insist, bar_wind
7673                                     || insist);                                     || insist);
7674  #else  #else
7675              ScreenToClient (FRAME_W32_WINDOW (f1), &pt);              ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7676              {              remember_mouse_glyph (f1, pt.x, pt.y);
               int width = FRAME_SMALLEST_CHAR_WIDTH (f1);  
               int height = FRAME_SMALLEST_FONT_HEIGHT (f1);  
               int x = pt.x;  
               int y = pt.y;  
                 
               /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to  
                  round down even for negative values.  */  
               if (x < 0)  
                 x -= width - 1;  
               if (y < 0)  
                 y -= height - 1;  
                 
               last_mouse_glyph.left = (x + width - 1) / width * width;  
               last_mouse_glyph.top = (y + height - 1) / height * height;  
               last_mouse_glyph.right  = last_mouse_glyph.left + width;  
               last_mouse_glyph.bottom = last_mouse_glyph.top + height;  
             }  
7677  #endif  #endif
7678    
7679              *bar_window = Qnil;              *bar_window = Qnil;
# Line 7576  w32_set_vertical_scroll_bar (w, portion, Line 7993  w32_set_vertical_scroll_bar (w, portion,
7993      {      {
7994        HDC hdc;        HDC hdc;
7995        BLOCK_INPUT;        BLOCK_INPUT;
7996        hdc = get_frame_dc (f);        if (width && height)
7997        w32_clear_area (f, hdc, left, top, width, height);          {
7998        release_frame_dc (f, hdc);            hdc = get_frame_dc (f);
7999              w32_clear_area (f, hdc, left, top, width, height);
8000              release_frame_dc (f, hdc);
8001            }
8002        UNBLOCK_INPUT;        UNBLOCK_INPUT;
8003    
8004        bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);        bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
# Line 7605  w32_set_vertical_scroll_bar (w, portion, Line 8025  w32_set_vertical_scroll_bar (w, portion,
8025          {          {
8026            HDC hdc;            HDC hdc;
8027            BLOCK_INPUT;            BLOCK_INPUT;
8028              if (width && height)
8029            hdc = get_frame_dc (f);              {
8030            /* Since Windows scroll bars are smaller than the space reserved                hdc = get_frame_dc (f);
8031               for them on the frame, we have to clear "under" them.  */                /* Since Windows scroll bars are smaller than the space reserved
8032            w32_clear_area (f, hdc,                   for them on the frame, we have to clear "under" them.  */
8033                            left,                w32_clear_area (f, hdc,
8034                            top,                                left,
8035                            width,                                top,
8036                            height);                                width,
8037            release_frame_dc (f, hdc);                                height);
8038                  release_frame_dc (f, hdc);
8039                }
8040            /* Make sure scroll bar is "visible" before moving, to ensure the            /* Make sure scroll bar is "visible" before moving, to ensure the
8041               area of the parent window now exposed will be refreshed.  */               area of the parent window now exposed will be refreshed.  */
8042            my_show_window (f, hwnd, SW_HIDE);            my_show_window (f, hwnd, SW_HIDE);
8043            MoveWindow (hwnd, sb_left, top,            MoveWindow (hwnd, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
8044                        sb_width, height, TRUE);                        top, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
8045                          max (height, 1), TRUE);
8046            if (pfnSetScrollInfo)            if (pfnSetScrollInfo)
8047              {              {
8048                SCROLLINFO si;                SCROLLINFO si;
# Line 8057  w32_read_socket (sd, bufp, numchars, exp Line 8479  w32_read_socket (sd, bufp, numchars, exp
8479        switch (msg.msg.message)        switch (msg.msg.message)
8480          {          {
8481          case WM_PAINT:          case WM_PAINT:
8482              f = x_window_to_frame (dpyinfo, msg.msg.hwnd);            f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8483    
8484              if (f)            if (f)
8485                {              {
8486                  if (msg.rect.right == msg.rect.left ||                if (msg.rect.right == msg.rect.left ||
8487                      msg.rect.bottom == msg.rect.top)                    msg.rect.bottom == msg.rect.top)
8488                    {                  {
8489                      /* We may get paint messages even though the client                    /* We may get paint messages even though the client
8490                         area is clipped - these are not expose events. */                       area is clipped - these are not expose events. */
8491                      DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f,                    DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f,
8492                                 XSTRING (f->name)->data));                               XSTRING (f->name)->data));
8493                    }                  }
8494                  else if (f->async_visible != 1)                else if (f->async_visible != 1)
8495                    {                  {
8496                      /* Definitely not obscured, so mark as visible.  */                    /* Definitely not obscured, so mark as visible.  */
8497                      f->async_visible = 1;                    f->async_visible = 1;
8498                      f->async_iconified = 0;                    f->async_iconified = 0;
8499                      SET_FRAME_GARBAGED (f);                    SET_FRAME_GARBAGED (f);
8500                      DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,                    DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
8501                                 XSTRING (f->name)->data));                               XSTRING (f->name)->data));
   
                     /* WM_PAINT serves as MapNotify as well, so report  
                        visibility changes properly.  */  
                     if (f->iconified)  
                       {  
                         bufp->kind = deiconify_event;  
                         XSETFRAME (bufp->frame_or_window, f);  
                         bufp->arg = Qnil;  
                         bufp++;  
                         count++;  
                         numchars--;  
                       }  
                     else if (! NILP (Vframe_list)  
                              && ! NILP (XCDR (Vframe_list)))  
                       /* Force a redisplay sooner or later to update the  
                          frame titles in case this is the second frame.  */  
                       record_asynch_buffer_change ();  
                   }  
                 else  
                   {  
                     HDC hdc = get_frame_dc (f);  
8502    
8503                      /* Erase background again for safety.  */                    /* WM_PAINT serves as MapNotify as well, so report
8504                      w32_clear_rect (f, hdc, &msg.rect);                       visibility changes properly.  */
8505                      release_frame_dc (f, hdc);                    if (f->iconified)
8506                      expose_frame (f,                      {
8507                                    msg.rect.left,                        bufp->kind = deiconify_event;
8508                                    msg.rect.top,                        XSETFRAME (bufp->frame_or_window, f);
8509                                    msg.rect.right - msg.rect.left,                        bufp->arg = Qnil;
8510                                    msg.rect.bottom - msg.rect.top);                        bufp++;
8511                    }                        count++;
8512                }                        numchars--;
8513                        }
8514                      else if (! NILP (Vframe_list)
8515                               && ! NILP (XCDR (Vframe_list)))
8516                        /* Force a redisplay sooner or later to update the
8517                           frame titles in case this is the second frame.  */
8518                        record_asynch_buffer_change ();
8519                    }
8520                  else
8521                    {
8522                      HDC hdc = get_frame_dc (f);
8523    
8524                      /* Erase background again for safety.  */
8525                      w32_clear_rect (f, hdc, &msg.rect);
8526                      release_frame_dc (f, hdc);
8527                      expose_frame (f,
8528                                    msg.rect.left,
8529                                    msg.rect.top,
8530                                    msg.rect.right - msg.rect.left,
8531                                    msg.rect.bottom - msg.rect.top);
8532                    }
8533                }
8534            break;            break;
8535    
8536          case WM_INPUTLANGCHANGE:          case WM_INPUTLANGCHANGE:
# Line 8175  w32_read_socket (sd, bufp, numchars, exp Line 8597  w32_read_socket (sd, bufp, numchars, exp
8597    
8598          case WM_MOUSEMOVE:          case WM_MOUSEMOVE:
8599            previous_help_echo = help_echo;            previous_help_echo = help_echo;
8600            help_echo = help_echo_object = help_echo_window = Qnil;            help_echo_object = help_echo_window = Qnil;
8601            help_echo_pos = -1;            help_echo_pos = -1;
8602    
8603            if (dpyinfo->grabbed && last_mouse_frame            if (dpyinfo->grabbed && last_mouse_frame
# Line 8195  w32_read_socket (sd, bufp, numchars, exp Line 8617  w32_read_socket (sd, bufp, numchars, exp
8617    
8618            /* If the contents of the global variable help_echo            /* If the contents of the global variable help_echo
8619               has changed, generate a HELP_EVENT.  */               has changed, generate a HELP_EVENT.  */
8620            if (!NILP (help_echo)            if (help_echo != previous_help_echo)
               || !NILP (previous_help_echo))  
8621              {              {
8622                Lisp_Object frame;                Lisp_Object frame;
8623                int n;                int n;
# Line 9005  x_erase_phys_cursor (w) Line 9426  x_erase_phys_cursor (w)
9426    /* Erase the cursor by redrawing the character underneath it.  */    /* Erase the cursor by redrawing the character underneath it.  */
9427    if (mouse_face_here_p)    if (mouse_face_here_p)
9428      hl = DRAW_MOUSE_FACE;      hl = DRAW_MOUSE_FACE;
9429      else if (cursor_row->inverse_p)
9430        hl = DRAW_INVERSE_VIDEO;
9431    else    else
9432      hl = DRAW_NORMAL_TEXT;      hl = DRAW_NORMAL_TEXT;
9433    x_draw_phys_cursor_glyph (w, cursor_row, hl);    x_draw_phys_cursor_glyph (w, cursor_row, hl);
# Line 9015  x_erase_phys_cursor (w) Line 9438  x_erase_phys_cursor (w)
9438  }  }
9439    
9440    
9441    /* Non-zero if physical cursor of window W is within mouse face.  */
9442    
9443    static int
9444    cursor_in_mouse_face_p (w)
9445         struct window *w;
9446    {
9447      struct w32_display_info *dpyinfo
9448        = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
9449      int in_mouse_face = 0;
9450      
9451      if (WINDOWP (dpyinfo->mouse_face_window)
9452          && XWINDOW (dpyinfo->mouse_face_window) == w)
9453        {
9454          int hpos = w->phys_cursor.hpos;
9455          int vpos = w->phys_cursor.vpos;
9456    
9457          if (vpos >= dpyinfo->mouse_face_beg_row
9458              && vpos <= dpyinfo->mouse_face_end_row
9459              && (vpos > dpyinfo->mouse_face_beg_row
9460                  || hpos >= dpyinfo->mouse_face_beg_col)
9461              && (vpos < dpyinfo->mouse_face_end_row
9462                  || hpos < dpyinfo->mouse_face_end_col
9463                  || dpyinfo->mouse_face_past_end))
9464            in_mouse_face = 1;
9465        }
9466    
9467      return in_mouse_face;
9468    }
9469    
9470    
9471  /* Display or clear cursor of window W.  If ON is zero, clear the  /* Display or clear cursor of window W.  If ON is zero, clear the
9472     cursor.  If it is non-zero, display the cursor.  If ON is nonzero,     cursor.  If it is non-zero, display the cursor.  If ON is nonzero,
9473     where to put the cursor is specified by HPOS, VPOS, X and Y.  */     where to put the cursor is specified by HPOS, VPOS, X and Y.  */
# Line 10126  w32_initialize_display_info (display_nam Line 10579  w32_initialize_display_info (display_nam
10579    dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;    dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
10580    dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;    dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
10581    dpyinfo->mouse_face_window = Qnil;    dpyinfo->mouse_face_window = Qnil;
10582      dpyinfo->mouse_face_overlay = Qnil;
10583    /* TODO: dpyinfo->gray */    /* TODO: dpyinfo->gray */
10584    
10585  }  }
# Line 10470  For example, if a block cursor is over a Line 10923  For example, if a block cursor is over a
10923  wide as that tab on the display.");  wide as that tab on the display.");
10924    x_stretch_cursor_p = 0;    x_stretch_cursor_p = 0;
10925    
10926    #if 0 /* TODO: Setting underline position from font properties.  */
10927      DEFVAR_BOOL ("x-use-underline-position-properties",
10928                   &x_use_underline_position_properties,
10929         "*Non-nil means make use of UNDERLINE_POSITION font properties.\n\
10930    Nil means ignore them.  If you encounter fonts with bogus\n\
10931    UNDERLINE_POSITION font properties, for example 7x13 on XFree prior\n\
10932    to 4.1, set this to nil.");
10933      x_use_underline_position_properties = 1;
10934    #endif
10935    
10936    DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,    DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
10937      "If not nil, Emacs uses toolkit scroll bars.");      "If not nil, Emacs uses toolkit scroll bars.");
10938    Vx_toolkit_scroll_bars = Qt;    Vx_toolkit_scroll_bars = Qt;

Legend:
Removed from v.1.115  
changed lines
  Added in v.1.116

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26