* window.h (WSET): Remove.
[bpt/emacs.git] / src / w32term.c
index b7c0d61..6948a98 100644 (file)
@@ -1,6 +1,6 @@
-/* Implementation of GUI terminal on the Microsoft W32 API.
+/* Implementation of GUI terminal on the Microsoft Windows API.
 
-Copyright (C) 1989, 1993-201 Free Software Foundation, Inc.
+Copyright (C) 1989, 1993-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -155,6 +155,9 @@ int vertical_scroll_bar_bottom_border;
 
 int last_scroll_bar_drag_pos;
 
+/* Keyboard code page - may be changed by language-change events.  */
+int w32_keyboard_codepage;
+
 /* Mouse movement. */
 
 /* Where the mouse was last time we reported a mouse event.  */
@@ -188,9 +191,6 @@ static int volatile input_signal_count;
 static int input_signal_count;
 #endif
 
-/* Keyboard code page - may be changed by language-change events.  */
-static int keyboard_codepage;
-
 static void x_update_window_end (struct window *, int, int);
 static void w32_handle_tool_bar_click (struct frame *,
                                        struct input_event *);
@@ -231,6 +231,10 @@ static void my_set_focus (struct frame *, HWND);
 static void my_set_foreground_window (HWND);
 static void my_destroy_window (struct frame *, HWND);
 
+#ifdef GLYPH_DEBUG
+static void x_check_font (struct frame *, struct font *);
+#endif
+
 static Lisp_Object Qvendor_specific_keysyms;
 
 \f
@@ -281,8 +285,7 @@ XChangeGC (void *ignore, XGCValues *gc, unsigned long mask,
 XGCValues *
 XCreateGC (void *ignore, Window window, unsigned long mask, XGCValues *xgcv)
 {
-  XGCValues *gc = (XGCValues *) xmalloc (sizeof (XGCValues));
-  memset (gc, 0, sizeof (XGCValues));
+  XGCValues *gc = xzalloc (sizeof (XGCValues));
 
   XChangeGC (ignore, gc, mask, xgcv);
 
@@ -309,6 +312,94 @@ w32_set_clip_rectangle (HDC hdc, RECT *rect)
     SelectClipRgn (hdc, NULL);
 }
 
+/* Restore clipping rectangle in S */
+static void
+w32_restore_glyph_string_clip (struct glyph_string *s)
+{
+  RECT *r = s->clip;
+  int n = s->num_clips;
+
+  if (n == 1)
+    w32_set_clip_rectangle (s->hdc, r);
+  else if (n > 1)
+    {
+      HRGN clip1 = CreateRectRgnIndirect (r);
+      HRGN clip2 = CreateRectRgnIndirect (r + 1);
+      if (CombineRgn (clip1, clip1, clip2, RGN_OR) != ERROR)
+        SelectClipRgn (s->hdc, clip1);
+      DeleteObject (clip1);
+      DeleteObject (clip2);
+    }
+}
+
+/*
+   Draw a wavy line under S. The wave fills wave_height pixels from y0.
+
+                    x0         wave_length = 2
+                                 --
+                y0   *   *   *   *   *
+                     |* * * * * * * * *
+    wave_height = 3  | *   *   *   *
+
+*/
+
+void
+w32_draw_underwave (struct glyph_string *s, COLORREF color)
+{
+  int wave_height = 2, wave_length = 3;
+  int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
+  XRectangle wave_clip, string_clip, final_clip;
+  RECT w32_final_clip, w32_string_clip;
+  HPEN hp, oldhp;
+
+  dx = wave_length;
+  dy = wave_height - 1;
+  x0 = s->x;
+  y0 = s->ybase + 1;
+  width = s->width;
+  xmax = x0 + width;
+
+  /* Find and set clipping rectangle */
+
+  wave_clip = (XRectangle){ x0, y0, width, wave_height };
+  get_glyph_string_clip_rect (s, &w32_string_clip);
+  CONVERT_TO_XRECT (string_clip, w32_string_clip);
+
+  if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
+    return;
+
+  hp = CreatePen (PS_SOLID, 0, color);
+  oldhp = SelectObject (s->hdc, hp);
+  CONVERT_FROM_XRECT (final_clip, w32_final_clip);
+  w32_set_clip_rectangle (s->hdc, &w32_final_clip);
+
+  /* Draw the waves */
+
+  x1 = x0 - (x0 % dx);
+  x2 = x1 + dx;
+  odd = (x1/dx) % 2;
+  y1 = y2 = y0;
+
+  if (odd)
+    y1 += dy;
+  else
+    y2 += dy;
+
+  MoveToEx (s->hdc, x1, y1, NULL);
+
+  while (x1 <= xmax)
+    {
+      LineTo (s->hdc, x2, y2);
+      x1  = x2, y1 = y2;
+      x2 += dx, y2 = y0 + odd*dy;
+      odd = !odd;
+    }
+
+  /* Restore previous pen and clipping rectangle(s) */
+  w32_restore_glyph_string_clip (s);
+  SelectObject (s->hdc, oldhp);
+  DeleteObject (hp);
+}
 
 /* Draw a hollow rectangle at the specified position.  */
 void
@@ -650,7 +741,7 @@ x_after_update_window_line (struct glyph_row *desired_row)
   struct frame *f;
   int width, height;
 
-  xassert (w);
+  eassert (w);
 
   if (!desired_row->mode_line_p && !w->pseudo_window_p)
     desired_row->redraw_fringe_bitmaps_p = 1;
@@ -994,7 +1085,7 @@ x_set_mouse_face_gc (struct glyph_string *s)
       s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
     }
 
-  xassert (s->gc != 0);
+  eassert (s->gc != 0);
 }
 
 
@@ -1051,7 +1142,7 @@ x_set_glyph_string_gc (struct glyph_string *s)
     }
 
   /* GC must have been set.  */
-  xassert (s->gc != 0);
+  eassert (s->gc != 0);
 }
 
 
@@ -1294,6 +1385,8 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s)
       old_font = SelectObject (s->hdc, FONT_HANDLE (font));
 
       for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
+       /* TAB in a composition means display glyphs with padding
+          space on the left or right.  */
        if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
          {
            int xx = x + s->cmp->offsets[j * 2];
@@ -1439,7 +1532,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
 
    Nominally, highlight colors for `3d' faces are calculated by
    brightening an object's color by a constant scale factor, but this
-   doesn't yield good results for dark colors, so for colors who's
+   doesn't yield good results for dark colors, so for colors whose
    brightness is less than this value (on a scale of 0-255) have to
    use an additional additive factor.
 
@@ -1466,7 +1559,7 @@ w32_alloc_lighter_color (struct frame *f, COLORREF *color,
   delta /= 256;
 
   /* Change RGB values by specified FACTOR.  Avoid overflow!  */
-  xassert (factor >= 0);
+  eassert (factor >= 0);
   new = PALETTERGB (min (0xff, factor * GetRValue (*color)),
                     min (0xff, factor * GetGValue (*color)),
                     min (0xff, factor * GetBValue (*color)));
@@ -1618,8 +1711,9 @@ x_setup_relief_colors (struct glyph_string *s)
 
 static void
 w32_draw_relief_rect (struct frame *f,
-                     int left_x, int top_y, int right_x, int bottom_y, int width,
-                     int raised_p, int top_p, int bot_p, int left_p, int right_p,
+                     int left_x, int top_y, int right_x, int bottom_y,
+                     int width, int raised_p,
+                     int top_p, int bot_p, int left_p, int right_p,
                      RECT *clip_rect)
 {
   int i;
@@ -1880,7 +1974,8 @@ x_draw_image_relief (struct glyph_string *s)
   if (s->hl == DRAW_IMAGE_SUNKEN
       || s->hl == DRAW_IMAGE_RAISED)
     {
-      thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
+      thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief
+       : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
       raised_p = s->hl == DRAW_IMAGE_RAISED;
     }
   else
@@ -2141,7 +2236,7 @@ x_draw_image_glyph_string (struct glyph_string *s)
 static void
 x_draw_stretch_glyph_string (struct glyph_string *s)
 {
-  xassert (s->first_glyph->type == STRETCH_GLYPH);
+  eassert (s->first_glyph->type == STRETCH_GLYPH);
 
   if (s->hl == DRAW_CURSOR
       && !x_stretch_cursor_p)
@@ -2339,60 +2434,74 @@ x_draw_glyph_string (struct glyph_string *s)
       /* Draw underline.  */
       if (s->face->underline_p)
         {
-          unsigned long thickness, position;
-          int y;
-
-          if (s->prev && s->prev->face->underline_p)
+          if (s->face->underline_type == FACE_UNDER_WAVE)
             {
-              /* We use the same underline style as the previous one.  */
-              thickness = s->prev->underline_thickness;
-              position = s->prev->underline_position;
+              COLORREF color;
+
+              if (s->face->underline_defaulted_p)
+                color = s->gc->foreground;
+              else
+                color = s->face->underline_color;
+
+              w32_draw_underwave (s, color);
             }
-          else
+          else if (s->face->underline_type == FACE_UNDER_LINE)
             {
-              /* Get the underline thickness.  Default is 1 pixel.  */
-              if (s->font && s->font->underline_thickness > 0)
-                thickness = s->font->underline_thickness;
+              unsigned long thickness, position;
+              int y;
+
+              if (s->prev && s->prev->face->underline_p)
+                {
+                  /* We use the same underline style as the previous one.  */
+                  thickness = s->prev->underline_thickness;
+                  position = s->prev->underline_position;
+                }
               else
-                thickness = 1;
-              if (x_underline_at_descent_line)
-                position = (s->height - thickness) - (s->ybase - s->y);
+                {
+                  /* Get the underline thickness.  Default is 1 pixel.  */
+                  if (s->font && s->font->underline_thickness > 0)
+                    thickness = s->font->underline_thickness;
+                  else
+                    thickness = 1;
+                  if (x_underline_at_descent_line)
+                    position = (s->height - thickness) - (s->ybase - s->y);
+                  else
+                    {
+                      /* Get the underline position.  This is the recommended
+                         vertical offset in pixels from the baseline to the top of
+                         the underline.  This is a signed value according to the
+                         specs, and its default is
+
+                         ROUND ((maximum_descent) / 2), with
+                         ROUND (x) = floor (x + 0.5)  */
+
+                      if (x_use_underline_position_properties
+                          && s->font && s->font->underline_position >= 0)
+                        position = s->font->underline_position;
+                      else if (s->font)
+                        position = (s->font->descent + 1) / 2;
+                    }
+                  position = max (position, underline_minimum_offset);
+                }
+              /* Check the sanity of thickness and position.  We should
+                 avoid drawing underline out of the current line area.  */
+              if (s->y + s->height <= s->ybase + position)
+                position = (s->height - 1) - (s->ybase - s->y);
+              if (s->y + s->height < s->ybase + position + thickness)
+                thickness = (s->y + s->height) - (s->ybase + position);
+              s->underline_thickness = thickness;
+              s->underline_position =position;
+              y = s->ybase + position;
+              if (s->face->underline_defaulted_p)
+                {
+                  w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
+                                 y, s->width, 1);
+                }
               else
                 {
-                /* Get the underline position.  This is the recommended
-                   vertical offset in pixels from the baseline to the top of
-                   the underline.  This is a signed value according to the
-                   specs, and its default is
-
-                   ROUND ((maximum_descent) / 2), with
-                   ROUND (x) = floor (x + 0.5)  */
-
-                if (x_use_underline_position_properties
-                    && s->font && s->font->underline_position >= 0)
-                  position = s->font->underline_position;
-                else if (s->font)
-                  position = (s->font->descent + 1) / 2;
+                  w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
+                                 y, s->width, 1);
                 }
-             position = max (position, underline_minimum_offset);
-            }
-         /* Check the sanity of thickness and position.  We should
-            avoid drawing underline out of the current line area.  */
-         if (s->y + s->height <= s->ybase + position)
-           position = (s->height - 1) - (s->ybase - s->y);
-         if (s->y + s->height < s->ybase + position + thickness)
-           thickness = (s->y + s->height) - (s->ybase + position);
-         s->underline_thickness = thickness;
-         s->underline_position =position;
-          y = s->ybase + position;
-          if (s->face->underline_defaulted_p)
-            {
-              w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
-                             y, s->width, 1);
-            }
-          else
-            {
-              w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
-                             y, s->width, 1);
             }
         }
       /* Draw overline.  */
@@ -2661,7 +2770,7 @@ x_scroll_run (struct window *w, struct run *run)
     }
   else
     {
-      /* Scolling down.  Make sure we don't copy over the mode line.
+      /* Scrolling down.  Make sure we don't copy over the mode line.
         at the bottom.  */
       if (to_y + run->height > bottom_y)
        height = bottom_y - to_y;
@@ -2863,7 +2972,7 @@ x_frame_rehighlight (struct w32_display_info *dpyinfo)
           : dpyinfo->w32_focus_frame);
       if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
        {
-         FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame) = Qnil;
+         fset_focus_frame (dpyinfo->w32_focus_frame, Qnil);
          dpyinfo->x_highlight_frame = dpyinfo->w32_focus_frame;
        }
     }
@@ -3282,8 +3391,8 @@ w32_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
  ***********************************************************************/
 
 /* Handle mouse button event on the tool-bar of frame F, at
-   frame-relative coordinates X/Y.  EVENT_TYPE is either ButtionPress
-   or ButtonRelase.  */
+   frame-relative coordinates X/Y.  EVENT_TYPE is either ButtonPress
+   or ButtonRelease.  */
 
 static void
 w32_handle_tool_bar_click (struct frame *f, struct input_event *button_event)
@@ -3384,7 +3493,7 @@ w32_set_scroll_bar_thumb (struct scroll_bar *bar,
   if (whole)
     {
       /* Position scroll bar at rock bottom if the bottom of the
-         buffer is visible. This avoids shinking the thumb away
+         buffer is visible. This avoids shrinking the thumb away
          to nothing if it is held at the bottom of the buffer.  */
       if (position + portion >= whole && !draggingp)
        {
@@ -3484,9 +3593,15 @@ my_destroy_window (struct frame * f, HWND hwnd)
               (WPARAM) hwnd, 0);
 }
 
+static void
+my_bring_window_to_top (HWND hwnd)
+{
+  SendMessage (hwnd, WM_EMACS_BRINGTOTOP, (WPARAM) hwnd, 0);
+}
+
 /* Create a scroll bar and return the scroll bar vector for it.  W is
    the Emacs window on which to create the scroll bar. TOP, LEFT,
-   WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
+   WIDTH and HEIGHT are the pixel coordinates and dimensions of the
    scroll bar. */
 
 static struct scroll_bar *
@@ -3497,6 +3612,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
   SCROLLINFO si;
   struct scroll_bar *bar
     = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
+  Lisp_Object barobj;
 
   BLOCK_INPUT;
 
@@ -3529,7 +3645,8 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
   /* Add bar to its frame's list of scroll bars.  */
   bar->next = FRAME_SCROLL_BARS (f);
   bar->prev = Qnil;
-  XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
+  XSETVECTOR (barobj, bar);
+  fset_scroll_bars (f, barobj);
   if (! NILP (bar->next))
     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 
@@ -3552,8 +3669,8 @@ x_scroll_bar_remove (struct scroll_bar *bar)
   /* Destroy the window.  */
   my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
 
-  /* Disassociate this scroll bar from its window.  */
-  XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
+  /* Dissociate this scroll bar from its window.  */
+  wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
 
   UNBLOCK_INPUT;
 }
@@ -3567,6 +3684,7 @@ w32_set_vertical_scroll_bar (struct window *w,
                             int portion, int whole, int position)
 {
   struct frame *f = XFRAME (w->frame);
+  Lisp_Object barobj;
   struct scroll_bar *bar;
   int top, height, left, sb_left, width, sb_width;
   int window_y, window_height;
@@ -3689,8 +3807,8 @@ w32_set_vertical_scroll_bar (struct window *w,
   bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
 
   w32_set_scroll_bar_thumb (bar, portion, position, whole);
-
-  XSETVECTOR (w->vertical_scroll_bar, bar);
+  XSETVECTOR (barobj, bar);
+  wset_vertical_scroll_bar (w, barobj);
 }
 
 
@@ -3714,12 +3832,12 @@ w32_condemn_scroll_bars (FRAME_PTR frame)
     {
       Lisp_Object bar;
       bar = FRAME_SCROLL_BARS (frame);
-      FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
+      fset_scroll_bars (frame, XSCROLL_BAR (bar)->next);
       XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
       XSCROLL_BAR (bar)->prev = Qnil;
       if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
        XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
-      FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
+      fset_condemned_scroll_bars (frame, bar);
     }
 }
 
@@ -3731,6 +3849,7 @@ static void
 w32_redeem_scroll_bar (struct window *window)
 {
   struct scroll_bar *bar;
+  Lisp_Object barobj;
   struct frame *f;
 
   /* We can't redeem this window's scroll bar if it doesn't have one.  */
@@ -3750,7 +3869,7 @@ w32_redeem_scroll_bar (struct window *window)
         return;
       else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
                    window->vertical_scroll_bar))
-        FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
+        fset_condemned_scroll_bars (f, bar->next);
       else
         /* If its prev pointer is nil, it must be at the front of
            one or the other!  */
@@ -3764,7 +3883,8 @@ w32_redeem_scroll_bar (struct window *window)
 
   bar->next = FRAME_SCROLL_BARS (f);
   bar->prev = Qnil;
-  XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
+  XSETVECTOR (barobj, bar);
+  fset_scroll_bars (f, barobj);
   if (! NILP (bar->next))
     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 }
@@ -3781,7 +3901,7 @@ w32_judge_scroll_bars (FRAME_PTR f)
 
   /* Clear out the condemned list now so we won't try to process any
      more events on the hapless scroll bars.  */
-  FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
+  fset_condemned_scroll_bars (f, Qnil);
 
   for (; ! NILP (bar); bar = next)
     {
@@ -3872,7 +3992,7 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
          si.fMask = SIF_POS;
          si.nPos = y;
          /* Remember apparent position (we actually lag behind the real
-            position, so don't set that directly.  */
+            position, so don't set that directly).  */
          last_scroll_bar_drag_pos = y;
 
          SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
@@ -4118,16 +4238,16 @@ w32_read_socket (struct terminal *terminal, int expected,
          /* Generate a language change event.  */
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
 
-         /* lParam contains the input lang ID.  Use it to update our
-            record of the keyboard codepage.  */
-         keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam
-                                                         & 0xffff));
+         /* lParam contains the input language ID in its low 16 bits.
+            Use it to update our record of the keyboard codepage.  */
+         w32_keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam
+                                                             & 0xffff));
 
          if (f)
            {
              inev.kind = LANGUAGE_CHANGE_EVENT;
              XSETFRAME (inev.frame_or_window, f);
-             inev.code = msg.msg.wParam;
+             inev.code = w32_keyboard_codepage;
              inev.modifiers = msg.msg.lParam & 0xffff;
            }
          break;
@@ -4193,7 +4313,7 @@ w32_read_socket (struct terminal *terminal, int expected,
                     {
                       dbcs[0] = dbcs_lead;
                       dbcs_lead = 0;
-                      if (!MultiByteToWideChar (keyboard_codepage, 0,
+                      if (!MultiByteToWideChar (w32_keyboard_codepage, 0,
                                                dbcs, 2, &code, 1))
                         {
                           /* Garbage */
@@ -4203,7 +4323,7 @@ w32_read_socket (struct terminal *terminal, int expected,
                           break;
                         }
                     }
-                  else if (IsDBCSLeadByteEx (keyboard_codepage,
+                  else if (IsDBCSLeadByteEx (w32_keyboard_codepage,
                                             (BYTE) msg.msg.wParam))
                     {
                       dbcs_lead = (char) msg.msg.wParam;
@@ -4212,7 +4332,7 @@ w32_read_socket (struct terminal *terminal, int expected,
                     }
                   else
                     {
-                      if (!MultiByteToWideChar (keyboard_codepage, 0,
+                      if (!MultiByteToWideChar (w32_keyboard_codepage, 0,
                                                &dbcs[1], 1, &code, 1))
                         {
                           /* What to do with garbage? */
@@ -4328,7 +4448,7 @@ w32_read_socket (struct terminal *terminal, int expected,
 
           /* If the contents of the global variable help_echo_string
              has changed, generate a HELP_EVENT.  */
-#if 0 /* The below is an invalid comparison when USE_LISP_UNION_TYPE.
+#if 0 /* The below is an invalid comparison when CHECK_LISP_OBJECT_TYPE.
         But it was originally changed to this to fix a bug, so I have
         not removed it completely in case the bug is still there.  */
           if (help_echo_string != previous_help_echo_string ||
@@ -4502,7 +4622,7 @@ w32_read_socket (struct terminal *terminal, int expected,
            }
 
          /* If window has been obscured or exposed by another window
-            being maximised or minimised/restored, then recheck
+            being maximized or minimized/restored, then recheck
             visibility of all frames.  Direct changes to our own
             windows get handled by WM_SIZE.  */
 #if 0
@@ -4771,7 +4891,7 @@ w32_read_socket (struct terminal *terminal, int expected,
       pending_autoraise_frame = 0;
     }
 
-  /* Check which frames are still visisble, if we have enqueued any user
+  /* Check which frames are still visible, if we have enqueued any user
      events or been notified of events that may affect visibility.  We
      do this here because there doesn't seem to be any direct
      notification from Windows that the visibility of a window has
@@ -5195,7 +5315,6 @@ x_catch_errors (dpy)
 x_catch_errors_unwind (old_val)
 x_check_errors (dpy, format)
 x_fully_uncatch_errors ()
-x_catching_errors ()
 x_had_errors_p (dpy)
 x_clear_errors (dpy)
 x_uncatch_errors (dpy, count)
@@ -5374,7 +5493,7 @@ x_set_offset (struct frame *f, register int xoff, register int yoff,
 
 
 /* Check if we need to resize the frame due to a fullscreen request.
-   If so needed, resize the frame. */
+   If so needed, resize the frame.  */
 static void
 x_check_fullscreen (struct frame *f)
 {
@@ -5394,7 +5513,7 @@ x_check_fullscreen (struct frame *f)
           SET_FRAME_GARBAGED (f);
           cancel_mouse_face (f);
 
-          /* Wait for the change of frame size to occur */
+          /* Wait for the change of frame size to occur */
           f->want_fullscreen |= FULLSCREEN_WAIT;
         }
     }
@@ -5573,7 +5692,7 @@ x_raise_frame (struct frame *f)
      input focus anyway (so the window with focus will never be
      completely obscured) - if not, then just moving the mouse over it
      is sufficient to give it focus.  On Windows, the user must actually
-     click on the frame (preferrably the title bar so as not to move
+     click on the frame (preferably the title bar so as not to move
      point), which is more awkward.  Also, no other Windows program
      raises a window to the top but leaves another window (possibly now
      completely obscured) with input focus.
@@ -5593,24 +5712,27 @@ x_raise_frame (struct frame *f)
       HDWP handle = BeginDeferWindowPos (2);
       if (handle)
        {
-         DeferWindowPos (handle,
-                         FRAME_W32_WINDOW (f),
-                         HWND_TOP,
-                         0, 0, 0, 0,
-                         SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
-
-         DeferWindowPos (handle,
-                         GetForegroundWindow (),
-                         FRAME_W32_WINDOW (f),
-                         0, 0, 0, 0,
-                         SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
-
-         EndDeferWindowPos (handle);
+         handle = DeferWindowPos (handle,
+                                  FRAME_W32_WINDOW (f),
+                                  HWND_TOP,
+                                  0, 0, 0, 0,
+                                  SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+         if (handle)
+           {
+             handle = DeferWindowPos (handle,
+                                      GetForegroundWindow (),
+                                      FRAME_W32_WINDOW (f),
+                                      0, 0, 0, 0,
+                                      SWP_NOSIZE | SWP_NOMOVE |
+                                      SWP_NOACTIVATE);
+             if (handle)
+               EndDeferWindowPos (handle);
+           }
        }
     }
   else
     {
-      my_set_foreground_window (FRAME_W32_WINDOW (f));
+      my_bring_window_to_top (FRAME_W32_WINDOW (f));
     }
 
   UNBLOCK_INPUT;
@@ -5687,15 +5809,15 @@ x_make_frame_visible (struct frame *f)
 
       f->output_data.w32->asked_for_visible = 1;
 
-      /* The first of these seems to give more expected behavior, but
-         was added as a commented out line in Sept 1997, with the
-         second version remaining uncommented. There may have been
-         some problem with it that led to it not being enabled,
-         so the old version remains commented out below in case we
-         decide we need to go back to it [23.0.60 2008-06-09].  */
+      /* According to a report in emacs-devel 2008-06-03, SW_SHOWNORMAL
+        causes unexpected behavior when unminimizing frames that were
+        previously maximized.  But only SW_SHOWNORMAL works properly for
+        frames that were truely hidden (using make-frame-invisible), so
+        we need it to avoid Bug#5482.  It seems that async_iconified
+        is only set for minimized windows that are still visible, so
+         use that to determine the appropriate flag to pass ShowWindow.  */
       my_show_window (f, FRAME_W32_WINDOW (f),
-                      f->async_iconified ? SW_RESTORE : SW_SHOW);
-      /* my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);  */
+                      f->async_iconified ? SW_RESTORE : SW_SHOWNORMAL);
     }
 
   /* Synchronize to ensure Emacs knows the frame is visible
@@ -5902,6 +6024,27 @@ x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
 }
 
 \f
+/***********************************************************************
+                               Fonts
+ ***********************************************************************/
+
+#ifdef GLYPH_DEBUG
+
+/* Check that FONT is valid on frame F.  It is if it can be found in F's
+   font table.  */
+
+static void
+x_check_font (struct frame *f, struct font *font)
+{
+  eassert (font != NULL && ! NILP (font->props[FONT_TYPE_INDEX]));
+  if (font->driver->check)
+    eassert (font->driver->check (f, font) == 0);
+}
+
+#endif /* GLYPH_DEBUG */
+
+
+\f
 /***********************************************************************
                            Initialization
  ***********************************************************************/
@@ -5921,10 +6064,8 @@ w32_initialize_display_info (Lisp_Object display_name)
                                  w32_display_name_list);
   dpyinfo->name_list_element = XCAR (w32_display_name_list);
 
-  dpyinfo->w32_id_name
-    = (char *) xmalloc (SCHARS (Vinvocation_name)
-                       + SCHARS (Vsystem_name)
-                       + 2);
+  dpyinfo->w32_id_name = xmalloc (SCHARS (Vinvocation_name)
+                                 + SCHARS (Vsystem_name) + 2);
   sprintf (dpyinfo->w32_id_name, "%s@%s",
           SDATA (Vinvocation_name), SDATA (Vsystem_name));
 
@@ -6089,9 +6230,9 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
   /* We don't yet support separate terminals on W32, so don't try to share
      keyboards between virtual terminals that are on the same physical
      terminal like X does.  */
-  terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+  terminal->kboard = xmalloc (sizeof (KBOARD));
   init_kboard (terminal->kboard);
-  KVAR (terminal->kboard, Vwindow_system) = intern ("w32");
+  kset_window_system (terminal->kboard, intern ("w32"));
   terminal->kboard->next_kboard = all_kboards;
   all_kboards = terminal->kboard;
   /* Don't let the initial kboard remain current longer than necessary.
@@ -6141,7 +6282,7 @@ w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   terminal = w32_create_terminal (dpyinfo);
 
   /* Set the name of the terminal. */
-  terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+  terminal->name = xmalloc (SBYTES (display_name) + 1);
   strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
   terminal->name[SBYTES (display_name)] = 0;
 
@@ -6161,7 +6302,7 @@ w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
   ReleaseDC (NULL, hdc);
 
-  /* initialise palette with white and black */
+  /* initialize palette with white and black */
   {
     XColor color;
     w32_defined_color (0, "white", &color, 1);
@@ -6290,7 +6431,8 @@ w32_initialize (void)
 
   {
     DWORD input_locale_id = (DWORD) GetKeyboardLayout (0);
-    keyboard_codepage = codepage_for_locale ((LCID) (input_locale_id & 0xffff));
+    w32_keyboard_codepage =
+      codepage_for_locale ((LCID) (input_locale_id & 0xffff));
   }
 
   /* Create the window thread - it will terminate itself when the app
@@ -6408,7 +6550,7 @@ the cursor have no effect.  */);
      from cus-start.el and other places, like "M-x set-variable".  */
   DEFVAR_BOOL ("x-use-underline-position-properties",
               x_use_underline_position_properties,
-     doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
+     doc: /* Non-nil means make use of UNDERLINE_POSITION font properties.
 A value of nil means ignore them.  If you encounter fonts with bogus
 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
 to 4.1, set this to nil.  You can also use `underline-minimum-offset'
@@ -6418,7 +6560,7 @@ sizes.  */);
 
   DEFVAR_BOOL ("x-underline-at-descent-line",
               x_underline_at_descent_line,
-     doc: /* *Non-nil means to draw the underline at the same place as the descent line.
+     doc: /* Non-nil means to draw the underline at the same place as the descent line.
 A value of nil means to draw the underline according to the value of the
 variable `x-use-underline-position-properties', which is usually at the
 baseline level.  The default value is nil.  */);
@@ -6429,7 +6571,7 @@ baseline level.  The default value is nil.  */);
 A value of nil means Emacs doesn't use toolkit scroll bars.
 With the X Window system, the value is a symbol describing the
 X toolkit.  Possible values are: gtk, motif, xaw, or xaw3d.
-With MS Windows, the value is t.  */);
+With MS Windows or Nextstep, the value is t.  */);
   Vx_toolkit_scroll_bars = Qt;
 
   staticpro (&last_mouse_motion_frame);