]> code.delx.au - gnu-emacs/blobdiff - src/w32term.c
Simplify read_dirent's MSDOS hacks
[gnu-emacs] / src / w32term.c
index dfda29fb903993fff5f4beacfa98ef0a167e8fbc..251c46c73cf2c864603c8a37607900c1897398a3 100644 (file)
@@ -1,6 +1,6 @@
 /* Implementation of GUI terminal on the Microsoft Windows API.
 
-Copyright (C) 1989, 1993-2014 Free Software Foundation, Inc.
+Copyright (C) 1989, 1993-2015 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -101,10 +101,10 @@ extern Cursor w32_load_cursor (LPCTSTR name);
 struct w32_display_info one_w32_display_info;
 struct w32_display_info *x_display_list;
 
-#if _WIN32_WINNT < 0x0500 && !defined(_W64)
+#if _WIN32_WINNT < 0x0500 && !defined(MINGW_W64)
 /* Pre Windows 2000, this was not available, but define it here so
    that Emacs compiled on such a platform will run on newer versions.
-   MinGW64 (_W64) defines these unconditionally, so avoid redefining.  */
+   MinGW64 defines these unconditionally, so avoid redefining.  */
 
 typedef struct tagWCRANGE
 {
@@ -185,7 +185,7 @@ void x_lower_frame (struct frame *);
 void x_scroll_bar_clear (struct frame *);
 void x_wm_set_size_hint (struct frame *, long, bool);
 void x_raise_frame (struct frame *);
-void x_set_window_size (struct frame *, int, int, int, bool);
+void x_set_window_size (struct frame *, bool, int, int, bool);
 void x_wm_set_window_state (struct frame *, int);
 void x_wm_set_icon_pixmap (struct frame *, int);
 static void w32_initialize (void);
@@ -220,10 +220,6 @@ static void w32fullscreen_hook (struct frame *);
 static void x_check_font (struct frame *, struct font *);
 #endif
 
-static Lisp_Object Qvendor_specific_keysyms;
-static Lisp_Object Qadded, Qremoved, Qmodified;
-static Lisp_Object Qrenamed_from, Qrenamed_to;
-
 \f
 /***********************************************************************
                              Debugging
@@ -563,7 +559,7 @@ x_update_window_begin (struct window *w)
   if (f == hlinfo->mouse_face_mouse_frame)
     {
       /* Don't do highlighting for mouse motion during the update.  */
-      hlinfo->mouse_face_defer = 1;
+      hlinfo->mouse_face_defer = true;
 
       /* If F needs to be redrawn, simply forget about any prior mouse
         highlighting.  */
@@ -686,11 +682,11 @@ x_update_window_end (struct window *w, bool cursor_on_p,
       block_input ();
 
       if (cursor_on_p)
-       display_and_set_cursor (w, 1,
+       display_and_set_cursor (w, true,
                                w->output_cursor.hpos, w->output_cursor.vpos,
                                w->output_cursor.x, w->output_cursor.y);
 
-      if (draw_window_fringes (w, 1))
+      if (draw_window_fringes (w, true))
        {
          if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
            x_draw_right_divider (w);
@@ -732,7 +728,7 @@ x_update_end (struct frame *f)
     return;
 
   /* Mouse highlight may be displayed again.  */
-  MOUSE_HL_INFO (f)->mouse_face_defer = 0;
+  MOUSE_HL_INFO (f)->mouse_face_defer = false;
 }
 
 
@@ -762,7 +758,7 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
   eassert (w);
 
   if (!desired_row->mode_line_p && !w->pseudo_window_p)
-    desired_row->redraw_fringe_bitmaps_p = 1;
+    desired_row->redraw_fringe_bitmaps_p = true;
 
   /* When a window has disappeared, make sure that no rest of
      full-width rows stays visible in the internal border.  Could
@@ -907,7 +903,7 @@ w32_destroy_fringe_bitmap (int which)
 static void x_set_glyph_string_clipping (struct glyph_string *);
 static void x_set_glyph_string_gc (struct glyph_string *);
 static void x_draw_glyph_string_background (struct glyph_string *,
-                                            int);
+                                            bool);
 static void x_draw_glyph_string_foreground (struct glyph_string *);
 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
 static void x_draw_glyph_string_box (struct glyph_string *);
@@ -929,7 +925,7 @@ static void w32_draw_relief_rect (struct frame *, int, int, int, int,
                                   int, int, int, int, int, int,
                                   RECT *);
 static void w32_draw_box_rect (struct glyph_string *, int, int, int, int,
-                               int, int, int, RECT *);
+                               int, bool, bool, RECT *);
 
 
 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
@@ -1068,7 +1064,7 @@ x_set_glyph_string_gc (struct glyph_string *s)
   else if (s->hl == DRAW_CURSOR)
     {
       x_set_cursor_gc (s);
-      s->stippled_p = 0;
+      s->stippled_p = false;
     }
   else if (s->hl == DRAW_MOUSE_FACE)
     {
@@ -1194,7 +1190,7 @@ x_clear_glyph_string_rect (struct glyph_string *s,
    contains the first component of a composition.  */
 
 static void
-x_draw_glyph_string_background (struct glyph_string *s, int force_p)
+x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
 {
   /* Nothing to do if background has already been drawn or if it
      shouldn't be drawn in the first place.  */
@@ -1212,7 +1208,7 @@ x_draw_glyph_string_background (struct glyph_string *s, int force_p)
                          s->background_width,
                          s->height - 2 * box_line_width);
          XSetFillStyle (s->display, s->gc, FillSolid);
-         s->background_filled_p = 1;
+         s->background_filled_p = true;
        }
       else
 #endif
@@ -1224,7 +1220,7 @@ x_draw_glyph_string_background (struct glyph_string *s, int force_p)
          x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
                                     s->background_width,
                                     s->height - 2 * box_line_width);
-         s->background_filled_p = 1;
+         s->background_filled_p = true;
        }
     }
 }
@@ -1277,11 +1273,11 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
       y = s->ybase - boff;
       if (s->for_overlaps
          || (s->background_filled_p && s->hl != DRAW_CURSOR))
-       font->driver->draw (s, 0, s->nchars, x, y, 0);
+       font->driver->draw (s, 0, s->nchars, x, y, false);
       else
-       font->driver->draw (s, 0, s->nchars, x, y, 1);
+       font->driver->draw (s, 0, s->nchars, x, y, true);
       if (s->face->overstrike)
-       font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
+       font->driver->draw (s, 0, s->nchars, x + 1, y, false);
 
       SelectObject (s->hdc, old_font);
     }
@@ -1335,9 +1331,9 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s)
            int xx = x + s->cmp->offsets[j * 2];
            int yy = y - s->cmp->offsets[j * 2 + 1];
 
-           font->driver->draw (s, j, j + 1, xx, yy, 0);
+           font->driver->draw (s, j, j + 1, xx, yy, false);
            if (s->face->overstrike)
-             font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
+             font->driver->draw (s, j, j + 1, xx + 1, yy, false);
          }
       SelectObject (s->hdc, old_font);
     }
@@ -1362,20 +1358,20 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s)
 
              if (j < i)
                {
-                 font->driver->draw (s, j, i, x, y, 0);
+                 font->driver->draw (s, j, i, x, y, false);
                  x += width;
                }
              xoff = LGLYPH_XOFF (glyph);
              yoff = LGLYPH_YOFF (glyph);
              wadjust = LGLYPH_WADJUST (glyph);
-             font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
+             font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
              x += wadjust;
              j = i + 1;
              width = 0;
            }
        }
       if (j < i)
-       font->driver->draw (s, j, i, x, y, 0);
+       font->driver->draw (s, j, i, x, y, false);
 
       SelectObject (s->hdc, old_font);
     }
@@ -1390,7 +1386,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
   struct glyph *glyph = s->first_glyph;
   XChar2b char2b[8];
   int x, i, j;
-  int with_background;
+  bool with_background;
 
   /* If first glyph of S has a left box line, start drawing the text
      of S to the right of that box line.  */
@@ -1405,8 +1401,8 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
 
   s->char2b = char2b;
-  with_background = (s->for_overlaps
-                      || (s->background_filled_p && s->hl != DRAW_CURSOR));
+  with_background = ((s->for_overlaps
+                     || (s->background_filled_p && s->hl != DRAW_CURSOR))) == 0;
   for (i = 0; i < s->nchars; i++, glyph++)
     {
       char buf[7], *str = NULL;
@@ -1716,7 +1712,7 @@ w32_draw_relief_rect (struct frame *f,
 static void
 w32_draw_box_rect (struct glyph_string *s,
                   int left_x, int top_y, int right_x, int bottom_y, int width,
-                   int left_p, int right_p, RECT *clip_rect)
+                   bool left_p, bool right_p, RECT *clip_rect)
 {
   w32_set_clip_rectangle (s->hdc, clip_rect);
 
@@ -1751,8 +1747,8 @@ w32_draw_box_rect (struct glyph_string *s,
 static void
 x_draw_glyph_string_box (struct glyph_string *s)
 {
-  int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
-  int left_p, right_p;
+  int width, left_x, right_x, top_y, bottom_y, last_x;
+  bool left_p, right_p, raised_p;
   struct glyph *last_glyph;
   RECT clip_rect;
 
@@ -2161,7 +2157,7 @@ x_draw_image_glyph_string (struct glyph_string *s)
 #endif
        x_draw_glyph_string_bg_rect (s, x, y, width, height);
 
-      s->background_filled_p = 1;
+      s->background_filled_p = true;
     }
 
   /* Draw the foreground.  */
@@ -2228,7 +2224,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
        {
          /* In R2L rows, draw the cursor on the right edge of the
             stretch glyph.  */
-         int right_x = window_box_right_offset (s->w, TEXT_AREA);
+         int right_x = window_box_right (s->w, TEXT_AREA);
 
          if (x + background_width > right_x)
            background_width -= x - right_x;
@@ -2297,7 +2293,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
        x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
     }
 
-  s->background_filled_p = 1;
+  s->background_filled_p = true;
 }
 
 
@@ -2325,7 +2321,7 @@ x_draw_glyph_string (struct glyph_string *s)
            if (next->first_glyph->type == STRETCH_GLYPH)
              x_draw_stretch_glyph_string (next);
            else
-             x_draw_glyph_string_background (next, 1);
+             x_draw_glyph_string_background (next, true);
             next->num_clips = 0;
           }
     }
@@ -2342,7 +2338,7 @@ x_draw_glyph_string (struct glyph_string *s)
 
     {
       x_set_glyph_string_clipping (s);
-      x_draw_glyph_string_background (s, 1);
+      x_draw_glyph_string_background (s, true);
       x_draw_glyph_string_box (s);
       x_set_glyph_string_clipping (s);
       relief_drawn_p = 1;
@@ -2370,26 +2366,26 @@ x_draw_glyph_string (struct glyph_string *s)
 
     case CHAR_GLYPH:
       if (s->for_overlaps)
-       s->background_filled_p = 1;
+       s->background_filled_p = true;
       else
-        x_draw_glyph_string_background (s, 0);
+        x_draw_glyph_string_background (s, false);
       x_draw_glyph_string_foreground (s);
       break;
 
     case COMPOSITE_GLYPH:
       if (s->for_overlaps || (s->cmp_from > 0
                              && ! s->first_glyph->u.cmp.automatic))
-       s->background_filled_p = 1;
+       s->background_filled_p = true;
       else
-       x_draw_glyph_string_background (s, 1);
+       x_draw_glyph_string_background (s, true);
       x_draw_composite_glyph_string_foreground (s);
       break;
 
     case GLYPHLESS_GLYPH:
       if (s->for_overlaps)
-       s->background_filled_p = 1;
+       s->background_filled_p = true;
       else
-       x_draw_glyph_string_background (s, 0);
+       x_draw_glyph_string_background (s, false);
       x_draw_glyphless_glyph_string_foreground (s);
       break;
 
@@ -3251,12 +3247,11 @@ queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f,
              Lisp_Object action = lispy_file_action (fni->Action);
 
              event->kind = FILE_NOTIFY_EVENT;
-             event->code
-               = (ptrdiff_t)XINT (XIL ((EMACS_INT)notifications_desc));
              event->timestamp = msg->msg.time;
              event->modifiers = 0;
              event->frame_or_window = callback;
-             event->arg = Fcons (action, fname);
+             event->arg = list3 (make_pointer_integer (notifications_desc),
+                                 action, fname);
              kbd_buffer_store_event (event);
              (*evcount)++;
 
@@ -3307,7 +3302,7 @@ note_mouse_movement (struct frame *frame, MSG *msg)
 
   if (msg->hwnd != FRAME_W32_WINDOW (frame))
     {
-      frame->mouse_moved = 1;
+      frame->mouse_moved = true;
       dpyinfo->last_mouse_scroll_bar = NULL;
       note_mouse_highlight (frame, -1, -1);
       dpyinfo->last_mouse_glyph_frame = NULL;
@@ -3320,7 +3315,7 @@ note_mouse_movement (struct frame *frame, MSG *msg)
       || mouse_x < r->left || mouse_x >= r->right
       || mouse_y < r->top  || mouse_y >= r->bottom)
     {
-      frame->mouse_moved = 1;
+      frame->mouse_moved = true;
       dpyinfo->last_mouse_scroll_bar = NULL;
       note_mouse_highlight (frame, mouse_x, mouse_y);
       /* Remember the mouse position here, as w32_mouse_position only
@@ -3344,11 +3339,11 @@ static struct scroll_bar *x_window_to_scroll_bar (Window, int);
 static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
                                        enum scroll_bar_part *,
                                        Lisp_Object *, Lisp_Object *,
-                                       unsigned long *);
+                                       Time *);
 static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
                                                   enum scroll_bar_part *,
                                                   Lisp_Object *, Lisp_Object *,
-                                                  unsigned long *);
+                                                  Time *);
 static void x_check_fullscreen (struct frame *);
 
 static void
@@ -3380,7 +3375,7 @@ w32_define_cursor (Window window, Cursor cursor)
 static void
 w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
                    enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
-                   unsigned long *time)
+                   Time *time)
 {
   struct frame *f1;
   struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
@@ -3404,7 +3399,7 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 
       /* Clear the mouse-moved flag for every frame on this display.  */
       FOR_EACH_FRAME (tail, frame)
-       XFRAME (frame)->mouse_moved = 0;
+       XFRAME (frame)->mouse_moved = false;
 
       dpyinfo->last_mouse_scroll_bar = NULL;
 
@@ -3448,7 +3443,7 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
            dpyinfo->last_mouse_glyph_frame = f1;
 
            *bar_window = Qnil;
-           *part = 0;
+           *part = scroll_bar_above_handle;
            *fp = f1;
            XSETINT (*x, pt.x);
            XSETINT (*y, pt.y);
@@ -3827,7 +3822,7 @@ w32_set_vertical_scroll_bar (struct window *w,
        }
       unblock_input ();
 
-      bar = x_scroll_bar_create (w, left, top, width, height, 0);
+      bar = x_scroll_bar_create (w, left, top, width, height, false);
     }
   else
     {
@@ -3927,7 +3922,7 @@ w32_set_horizontal_scroll_bar (struct window *w,
        }
       unblock_input ();
 
-      bar = x_scroll_bar_create (w, left, top, width, height, 1);
+      bar = x_scroll_bar_create (w, left, top, width, height, true);
     }
   else
     {
@@ -4166,17 +4161,24 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
     int y;
     int dragging = bar->dragging;
     SCROLLINFO si;
+    int sb_event = LOWORD (msg->msg.wParam);
 
     si.cbSize = sizeof (si);
-    si.fMask = SIF_POS;
+    if (sb_event == SB_THUMBTRACK)
+      si.fMask = SIF_TRACKPOS;
+    else
+      si.fMask = SIF_POS;
 
     GetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
-    y = si.nPos;
+    if (sb_event == SB_THUMBTRACK)
+      y = si.nTrackPos;
+    else
+      y = si.nPos;
 
     bar->dragging = 0;
     FRAME_DISPLAY_INFO (f)->last_mouse_scroll_bar_pos = msg->msg.wParam;
 
-    switch (LOWORD (msg->msg.wParam))
+    switch (sb_event)
       {
       case SB_LINEDOWN:
        emacs_event->part = scroll_bar_down_arrow;
@@ -4200,8 +4202,6 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
        break;
       case SB_THUMBTRACK:
       case SB_THUMBPOSITION:
-       if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height) <= 0xffff)
-          y = HIWORD (msg->msg.wParam);
        bar->dragging = 1; /* ??????? */
        emacs_event->part = scroll_bar_handle;
 
@@ -4272,20 +4272,28 @@ w32_horizontal_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
 
   {
     int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
-    int x;
+    int x, y;
     int dragging = bar->dragging;
     SCROLLINFO si;
+    int sb_event = LOWORD (msg->msg.wParam);
 
     si.cbSize = sizeof (si);
-    si.fMask = SIF_POS;
+    if (sb_event == SB_THUMBTRACK)
+      si.fMask = SIF_TRACKPOS | SIF_PAGE | SIF_RANGE;
+    else
+      si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
 
     GetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
-    x = si.nPos;
+    if (sb_event == SB_THUMBTRACK)
+      x = si.nTrackPos;
+    else
+      x = si.nPos;
+    y = si.nMax - si.nPage;
 
     bar->dragging = 0;
     FRAME_DISPLAY_INFO (f)->last_mouse_scroll_bar_pos = msg->msg.wParam;
 
-    switch (LOWORD (msg->msg.wParam))
+    switch (sb_event)
       {
       case SB_LINELEFT:
        emacs_event->part = scroll_bar_left_arrow;
@@ -4309,8 +4317,6 @@ w32_horizontal_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
        break;
       case SB_THUMBTRACK:
       case SB_THUMBPOSITION:
-       if (HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width) <= 0xffff)
-          x = HIWORD (msg->msg.wParam);
        bar->dragging = 1;
        emacs_event->part = scroll_bar_horizontal_handle;
 
@@ -4339,12 +4345,9 @@ w32_horizontal_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
            int end = bar->end;
 
            si.cbSize = sizeof (si);
-/**        si.fMask = SIF_PAGE | SIF_POS; **/
            si.fMask = SIF_POS;
-/**        si.nPage = end - start + HORIZONTAL_SCROLL_BAR_MIN_HANDLE; **/
            si.nPos = min (last_scroll_bar_drag_pos,
                           XWINDOW (bar->window)->hscroll_whole - 1);
-/**        si.nPos = last_scroll_bar_drag_pos; **/
            SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
          }
        /* fall through */
@@ -4354,7 +4357,7 @@ w32_horizontal_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
       }
 
     XSETINT (emacs_event->x, x);
-    XSETINT (emacs_event->y, left_range);
+    XSETINT (emacs_event->y, y);
 
     return TRUE;
   }
@@ -4366,7 +4369,7 @@ static void
 x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
                            enum scroll_bar_part *part,
                            Lisp_Object *x, Lisp_Object *y,
-                           unsigned long *time)
+                           Time *time)
 {
   struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
   struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
@@ -4375,6 +4378,7 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
   int pos;
   int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
   SCROLLINFO si;
+  int sb_event = LOWORD (dpyinfo->last_mouse_scroll_bar_pos);
 
   block_input ();
 
@@ -4382,33 +4386,26 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
   *bar_window = bar->window;
 
   si.cbSize = sizeof (si);
-  si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
+  if (sb_event == SB_THUMBTRACK)
+    si.fMask = SIF_TRACKPOS | SIF_PAGE | SIF_RANGE;
+  else
+    si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
 
   GetScrollInfo (w, SB_CTL, &si);
-  pos = si.nPos;
+  if (sb_event == SB_THUMBTRACK)
+    pos = si.nTrackPos;
+  else
+    pos = si.nPos;
   top_range = si.nMax - si.nPage + 1;
 
-  switch (LOWORD (dpyinfo->last_mouse_scroll_bar_pos))
-  {
-  case SB_THUMBPOSITION:
-  case SB_THUMBTRACK:
-      *part = scroll_bar_handle;
-      if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height) <= 0xffff)
-       pos = HIWORD (dpyinfo->last_mouse_scroll_bar_pos);
-      break;
-  case SB_LINEDOWN:
-      *part = scroll_bar_handle;
-      pos++;
-      break;
-  default:
-      *part = scroll_bar_handle;
-      break;
-  }
+  *part = scroll_bar_handle;
+  if (sb_event == SB_LINEDOWN)
+    pos++;
 
   XSETINT (*x, pos);
   XSETINT (*y, top_range);
 
-  f->mouse_moved = 0;
+  f->mouse_moved = false;
   dpyinfo->last_mouse_scroll_bar = NULL;
 
   *time = dpyinfo->last_mouse_movement_time;
@@ -4422,7 +4419,7 @@ static void
 x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
                                       enum scroll_bar_part *part,
                                       Lisp_Object *x, Lisp_Object *y,
-                                      unsigned long *time)
+                                      Time *time)
 {
   struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
   struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
@@ -4431,6 +4428,7 @@ x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_windo
   int pos;
   int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
   SCROLLINFO si;
+  int sb_event = LOWORD (dpyinfo->last_mouse_scroll_bar_pos);
 
   block_input ();
 
@@ -4438,33 +4436,27 @@ x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_windo
   *bar_window = bar->window;
 
   si.cbSize = sizeof (si);
-  si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
+  if (sb_event == SB_THUMBTRACK)
+    si.fMask = SIF_TRACKPOS | SIF_PAGE | SIF_RANGE;
+  else
+    si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
 
   GetScrollInfo (w, SB_CTL, &si);
-  pos = si.nPos;
+  if (sb_event == SB_THUMBTRACK)
+    pos = si.nTrackPos;
+  else
+    pos = si.nPos;
   left_range = si.nMax - si.nPage + 1;
 
-  switch (LOWORD (dpyinfo->last_mouse_scroll_bar_pos))
-  {
-  case SB_THUMBPOSITION:
-  case SB_THUMBTRACK:
-      *part = scroll_bar_handle;
-      if (HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width) <= 0xffff)
-       pos = HIWORD (dpyinfo->last_mouse_scroll_bar_pos);
-      break;
-  case SB_LINERIGHT:
-      *part = scroll_bar_handle;
-      pos++;
-      break;
-  default:
-      *part = scroll_bar_handle;
-      break;
-  }
+  *part = scroll_bar_handle;
+  if (sb_event == SB_LINERIGHT)
+    pos++;
+
 
   XSETINT (*y, pos);
   XSETINT (*x, left_range);
 
-  f->mouse_moved = 0;
+  f->mouse_moved = false;
   dpyinfo->last_mouse_scroll_bar = NULL;
 
   *time = dpyinfo->last_mouse_movement_time;
@@ -4604,7 +4596,7 @@ w32_read_socket (struct terminal *terminal,
 
                  /* Definitely not obscured, so mark as visible.  */
                  SET_FRAME_VISIBLE (f, 1);
-                 SET_FRAME_ICONIFIED (f, 0);
+                 SET_FRAME_ICONIFIED (f, false);
                  SET_FRAME_GARBAGED (f);
                  if (!f->output_data.w32->asked_for_visible)
                    DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
@@ -4666,7 +4658,7 @@ w32_read_socket (struct terminal *terminal,
                  && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
                {
                  clear_mouse_face (hlinfo);
-                 hlinfo->mouse_face_hidden = 1;
+                 hlinfo->mouse_face_hidden = true;
                }
 
              if (temp_index == sizeof temp_buffer / sizeof (short))
@@ -4691,7 +4683,7 @@ w32_read_socket (struct terminal *terminal,
                  && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
                {
                  clear_mouse_face (hlinfo);
-                 hlinfo->mouse_face_hidden = 1;
+                 hlinfo->mouse_face_hidden = true;
                }
 
              if (temp_index == sizeof temp_buffer / sizeof (short))
@@ -4769,7 +4761,7 @@ w32_read_socket (struct terminal *terminal,
                  && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
                {
                  clear_mouse_face (hlinfo);
-                 hlinfo->mouse_face_hidden = 1;
+                 hlinfo->mouse_face_hidden = true;
                }
 
              if (temp_index == sizeof temp_buffer / sizeof (short))
@@ -4802,7 +4794,7 @@ w32_read_socket (struct terminal *terminal,
 
          if (hlinfo->mouse_face_hidden)
            {
-             hlinfo->mouse_face_hidden = 0;
+             hlinfo->mouse_face_hidden = false;
              clear_mouse_face (hlinfo);
            }
 
@@ -4921,7 +4913,7 @@ w32_read_socket (struct terminal *terminal,
                    the ButtonPress.  */
                 if (f != 0)
                  {
-                   f->mouse_moved = 0;
+                   f->mouse_moved = false;
                    if (!tool_bar_p)
                      f->last_tool_bar_item = -1;
                  }
@@ -4948,7 +4940,7 @@ w32_read_socket (struct terminal *terminal,
                   event; any subsequent mouse-movement Emacs events
                   should reflect only motion after the
                   ButtonPress.  */
-               f->mouse_moved = 0;
+               f->mouse_moved = false;
                f->last_tool_bar_item = -1;
              }
            dpyinfo->last_mouse_frame = f;
@@ -5049,7 +5041,7 @@ w32_read_socket (struct terminal *terminal,
                {
                case SIZE_MINIMIZED:
                  SET_FRAME_VISIBLE (f, 0);
-                 SET_FRAME_ICONIFIED (f, 1);
+                 SET_FRAME_ICONIFIED (f, true);
 
                  inev.kind = ICONIFY_EVENT;
                  XSETFRAME (inev.frame_or_window, f);
@@ -5060,7 +5052,7 @@ w32_read_socket (struct terminal *terminal,
                    bool iconified = FRAME_ICONIFIED_P (f);
 
                    SET_FRAME_VISIBLE (f, 1);
-                   SET_FRAME_ICONIFIED (f, 0);
+                   SET_FRAME_ICONIFIED (f, false);
 
                    /* wait_reading_process_output will notice this
                       and update the frame's display structures.  */
@@ -5107,7 +5099,7 @@ w32_read_socket (struct terminal *terminal,
                       conditional again in revision 116727.  martin */
                    if (iconified)
                      SET_FRAME_VISIBLE (f, 1);
-                   SET_FRAME_ICONIFIED (f, 0);
+                   SET_FRAME_ICONIFIED (f, false);
 
                    /* wait_reading_process_output will notice this
                       and update the frame's display structures.  */
@@ -5147,30 +5139,38 @@ w32_read_socket (struct terminal *terminal,
              RECT rect;
              int rows, columns, width, height, text_width, text_height;
 
-             GetClientRect (msg.msg.hwnd, &rect);
-
-             height = rect.bottom - rect.top;
-             width = rect.right - rect.left;
-             text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width);
-             text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height);
-             /* rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); */
-             /* columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); */
-
-             /* TODO: Clip size to the screen dimensions.  */
-
-             /* Even if the number of character rows and columns has
-                not changed, the font size may have changed, so we need
-                to check the pixel dimensions as well.  */
-
-             if (width != FRAME_PIXEL_WIDTH (f)
-                 || height != FRAME_PIXEL_HEIGHT (f)
-                 || text_width != FRAME_TEXT_WIDTH (f)
-                 || text_height != FRAME_TEXT_HEIGHT (f))
+             if (GetClientRect (msg.msg.hwnd, &rect)
+                 /* GetClientRect evidently returns (0, 0, 0, 0) if
+                    called on a minimized frame.  Such "dimensions"
+                    aren't useful anyway.  */
+                 && !(rect.bottom == 0
+                      && rect.top == 0
+                      && rect.left == 0
+                      && rect.right == 0))
                {
-                 change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
-                 SET_FRAME_GARBAGED (f);
-                 cancel_mouse_face (f);
-                 f->win_gravity = NorthWestGravity;
+                 height = rect.bottom - rect.top;
+                 width = rect.right - rect.left;
+                 text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width);
+                 text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height);
+                 /* rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); */
+                 /* columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); */
+
+                 /* TODO: Clip size to the screen dimensions.  */
+
+                 /* Even if the number of character rows and columns
+                    has not changed, the font size may have changed,
+                    so we need to check the pixel dimensions as well.  */
+
+                 if (width != FRAME_PIXEL_WIDTH (f)
+                     || height != FRAME_PIXEL_HEIGHT (f)
+                     || text_width != FRAME_TEXT_WIDTH (f)
+                     || text_height != FRAME_TEXT_HEIGHT (f))
+                   {
+                     change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
+                     SET_FRAME_GARBAGED (f);
+                     cancel_mouse_face (f);
+                     f->win_gravity = NorthWestGravity;
+                   }
                }
            }
 
@@ -5475,6 +5475,12 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
   /* Compute frame-relative coordinates for phys cursor.  */
   get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h);
   rect.left = left;
+  /* When on R2L character, show cursor at the right edge of the
+     glyph, unless the cursor box is as wide as the glyph or wider
+     (the latter happens when x-stretch-cursor is non-nil).  */
+  if ((cursor_glyph->resolved_level & 1) != 0
+      && cursor_glyph->pixel_width > w->phys_cursor_width)
+    rect.left += cursor_glyph->pixel_width - w->phys_cursor_width;
   rect.top = top;
   rect.bottom = rect.top + h;
   rect.right = rect.left + w->phys_cursor_width;
@@ -5556,7 +5562,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row,
                         WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
                         width, row->height);
        }
-      else
+      else     /* HBAR_CURSOR */
        {
          int dummy_x, dummy_y, dummy_h;
 
@@ -5567,6 +5573,9 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row,
 
          get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
                                    &dummy_y, &dummy_h);
+         if ((cursor_glyph->resolved_level & 1) != 0
+             && cursor_glyph->pixel_width > w->phys_cursor_width)
+           x += cursor_glyph->pixel_width - w->phys_cursor_width;
          w32_fill_area (f, hdc, cursor_color, x,
                         WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
                                                  row->height - width),
@@ -5627,7 +5636,7 @@ w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
          w->phys_cursor_type = cursor_type;
        }
 
-      w->phys_cursor_on_p = 1;
+      w->phys_cursor_on_p = true;
 
       /* If this is the active cursor, we need to track it with the
         system caret, so third party software like screen magnifiers
@@ -5665,7 +5674,7 @@ w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
              ? (w->phys_cursor.hpos < 0)
              : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
        {
-         glyph_row->cursor_in_fringe_p = 1;
+         glyph_row->cursor_in_fringe_p = true;
          draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
          return;
        }
@@ -5702,7 +5711,7 @@ w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
 \f
 /* Icons.  */
 
-int
+bool
 x_bitmap_icon (struct frame *f, Lisp_Object icon)
 {
   HANDLE main_icon;
@@ -5829,7 +5838,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
         problems because the tip frame has no widget.  */
       if (NILP (tip_frame) || XFRAME (tip_frame) != f)
        adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
-                          FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 0);
+                          FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
+                          false, Qfont);
     }
 
   /* X version sets font of input methods here also.  */
@@ -5936,7 +5946,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff,
   x_calc_absolute_position (f);
 
   block_input ();
-  x_wm_set_size_hint (f, (long) 0, 0);
+  x_wm_set_size_hint (f, (long) 0, false);
 
   modified_left = f->left_pos;
   modified_top = f->top_pos;
@@ -6082,12 +6092,13 @@ w32fullscreen_hook (struct frame *f)
 }
 
 /* Call this to change the size of frame F's x-window.
-   If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
+   If CHANGE_GRAVITY, change to top-left-corner window gravity
    for this size change and subsequent size changes.
    Otherwise we leave the window gravity unchanged.  */
 
 void
-x_set_window_size (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
+x_set_window_size (struct frame *f, bool change_gravity,
+                  int width, int height, bool pixelwise)
 {
   int pixelwidth, pixelheight;
   RECT rect;
@@ -6105,8 +6116,32 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
       pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
     }
 
+  if (w32_add_wrapped_menu_bar_lines)
+    {
+      /* When the menu bar wraps sending a SetWindowPos shrinks the
+        height of the frame when the wrapped menu bar lines are not
+        accounted for (Bug#15174 and Bug#18720).  Here we add these
+        extra lines to the frame height.  */
+      MENUBARINFO info;
+      int default_menu_bar_height;
+      int menu_bar_height;
+
+      /* Why is (apparently) SM_CYMENUSIZE needed here instead of
+        SM_CYMENU ??  */
+      default_menu_bar_height = GetSystemMetrics (SM_CYMENUSIZE);
+      info.cbSize = sizeof (info);
+      info.rcBar.top = info.rcBar.bottom = 0;
+      GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info);
+      menu_bar_height = info.rcBar.bottom - info.rcBar.top;
+
+      if ((default_menu_bar_height > 0)
+         && (menu_bar_height > default_menu_bar_height)
+         && ((menu_bar_height % default_menu_bar_height) == 0))
+       pixelheight = pixelheight + menu_bar_height - default_menu_bar_height;
+    }
+
   f->win_gravity = NorthWestGravity;
-  x_wm_set_size_hint (f, (long) 0, 0);
+  x_wm_set_size_hint (f, (long) 0, false);
 
   f->want_fullscreen = FULLSCREEN_NONE;
   w32fullscreen_hook (f);
@@ -6293,7 +6328,7 @@ x_lower_frame (struct frame *f)
 }
 
 static void
-w32_frame_raise_lower (struct frame *f, int raise_flag)
+w32_frame_raise_lower (struct frame *f, bool raise_flag)
 {
   if (! FRAME_W32_P (f))
     return;
@@ -6333,7 +6368,7 @@ x_make_frame_visible (struct frame *f)
          RECT window_rect;
 
          /* Adjust vertical window position in order to avoid being
-            covered by a task bar placed at the bottom of the desktop. */
+            covered by a taskbar placed at the bottom of the desktop. */
          SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0);
          GetWindowRect (FRAME_W32_WINDOW (f), &window_rect);
          if (window_rect.bottom > workarea_rect.bottom
@@ -6418,7 +6453,7 @@ x_make_frame_invisible (struct frame *f)
      FRAME_SAMPLE_VISIBILITY set this.  So do it by hand,
      and synchronize with the server to make sure we agree.  */
   SET_FRAME_VISIBLE (f, 0);
-  SET_FRAME_ICONIFIED (f, 0);
+  SET_FRAME_ICONIFIED (f, false);
 
   unblock_input ();
 }
@@ -6443,7 +6478,7 @@ x_iconify_frame (struct frame *f)
   SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
 
   SET_FRAME_VISIBLE (f, 0);
-  SET_FRAME_ICONIFIED (f, 1);
+  SET_FRAME_ICONIFIED (f, true);
 
   unblock_input ();
 }
@@ -7066,6 +7101,21 @@ systems of the NT family, including W2K, XP, Vista, Windows 7 and
 Windows 8.  It is set to nil on Windows 9X.  */);
   w32_unicode_filenames = 0;
 
+
+  /* FIXME: The following two variables will be (hopefully) removed
+     before Emacs 25.1 gets released.  */
+
+  DEFVAR_BOOL ("w32-add-wrapped-menu-bar-lines",
+              w32_add_wrapped_menu_bar_lines,
+     doc: /* Non-nil means frame resizing accounts for wrapped menu bar lines.
+A value of nil means frame resizing does not add the height of wrapped
+menu bar lines when sending a frame resize request to the Windows API.
+This usually means that the resulting frame height is off by the number
+of wrapped menu bar lines.  If this is non-nil, Emacs adds the height of
+wrapped menu bar lines when sending frame resize requests to the Windows
+API.  */);
+  w32_add_wrapped_menu_bar_lines = 1;
+
   DEFVAR_BOOL ("w32-enable-frame-resize-hack",
               w32_enable_frame_resize_hack,
      doc: /* Non-nil means enable hack for frame resizing on Windows.