]> code.delx.au - gnu-emacs/blobdiff - src/w32term.c
Reformat copyright line.
[gnu-emacs] / src / w32term.c
index a5f3ebaae21b28cd269cfba267117c15db798b3d..4ed7beda233c2e8b367e68da3191368f1dacb6cf 100644 (file)
@@ -1,7 +1,7 @@
 /* Implementation of GUI terminal on the Microsoft W32 API.
    Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998,
                  1999, 2000, 2001, 2002, 2003, 2004, 2005,
-                 2006, 2007, 2008 Free Software Foundation, Inc.
+                 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -22,6 +22,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <setjmp.h>
 #include "lisp.h"
 #include "blockinput.h"
 #include "w32term.h"
@@ -31,8 +32,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <ctype.h>
 #include <errno.h>
-#include <setjmp.h>
 #include <sys/stat.h>
+#include <imm.h>
 
 #include "charset.h"
 #include "character.h"
@@ -54,7 +55,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "keymap.h"
 
 #include "w32heap.h"
-#include "w32bdf.h"
 #include <shellapi.h>
 
 #include "font.h"
@@ -87,8 +87,7 @@ static int any_help_event_p;
 /* Last window where we saw the mouse.  Used by mouse-autoselect-window.  */
 static Lisp_Object last_window;
 
-/* Non-zero means make use of UNDERLINE_POSITION font properties.
-   (Not yet supported, see TODO in x_draw_glyph_string.)  */
+/* Non-zero means make use of UNDERLINE_POSITION font properties.  */
 int x_use_underline_position_properties;
 
 /* Non-zero means to draw the underline at the same place as the descent line.  */
@@ -102,8 +101,6 @@ extern void free_frame_menubar ();
 extern int w32_codepage_for_font (char *fontname);
 extern Cursor w32_load_cursor (LPCTSTR name);
 
-extern glyph_metric *w32_BDF_TextMetric(bdffont *fontp,
-                                       unsigned char *text, int dim);
 extern Lisp_Object Vwindow_system;
 
 #define x_any_window_to_frame x_window_to_frame
@@ -142,8 +139,17 @@ typedef struct tagGLYPHSET
 
 #endif
 
-/* Dynamic linking to GetFontUnicodeRanges (not available on 95, 98, ME).  */
-DWORD (PASCAL *pfnGetFontUnicodeRanges) (HDC device, GLYPHSET *ranges);
+/* Dynamic linking to SetLayeredWindowAttribute (only since 2000).  */
+BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
+
+#ifndef LWA_ALPHA
+#define LWA_ALPHA 0x02
+#endif
+/* WS_EX_LAYERED is defined unconditionally by MingW, but only for W2K and
+   later targets by MSVC headers.  */
+#ifndef WS_EX_LAYERED
+#define WS_EX_LAYERED 0x80000
+#endif
 
 /* Frame being updated by update_frame.  This is declared in term.c.
    This is set by update_begin and looked at by all the
@@ -162,14 +168,6 @@ int w32_system_caret_x;
 int w32_system_caret_y;
 int w32_use_visible_system_caret;
 
-/* Flag to enable Unicode output in case users wish to use programs
-   like Twinbridge on '95 rather than installed system level support
-   for Far East languages.  */
-int w32_enable_unicode_output;
-
-/* Flag to enable Cleartype hack for font metrics.  */
-static int cleartype_active;
-
 DWORD dwWindowsThreadId = 0;
 HANDLE hWindowsThread = NULL;
 DWORD dwMainThreadId = 0;
@@ -184,7 +182,6 @@ int last_scroll_bar_drag_pos;
 /* Mouse movement. */
 
 /* Where the mouse was last time we reported a mouse event.  */
-
 static RECT last_mouse_glyph;
 static FRAME_PTR last_mouse_glyph_frame;
 static Lisp_Object last_mouse_press_frame;
@@ -219,12 +216,10 @@ static int last_mouse_scroll_bar_pos;
    along with the position query.  So, we just keep track of the time
    of the last movement we received, and return that in hopes that
    it's somewhat accurate.  */
-
 static Time last_mouse_movement_time;
 
 /* Incremented by w32_read_socket whenever it really tries to read
    events.  */
-
 #ifdef __STDC__
 static int volatile input_signal_count;
 #else
@@ -238,9 +233,11 @@ extern int errno;
 #endif
 
 /* A mask of extra modifier bits to put into every keyboard char.  */
-
 extern EMACS_INT extra_keyboard_modifiers;
 
+/* Keyboard code page - may be changed by language-change events.  */
+static int keyboard_codepage;
+
 static void x_update_window_end P_ ((struct window *, int, int));
 static void w32_handle_tool_bar_click P_ ((struct frame *,
                                           struct input_event *));
@@ -254,8 +251,6 @@ void x_set_window_size P_ ((struct frame *, int, int, int));
 void x_wm_set_window_state P_ ((struct frame *, int));
 void x_wm_set_icon_pixmap P_ ((struct frame *, int));
 static void w32_initialize P_ ((void));
-static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
-int x_compute_min_glyph_bounds P_ ((struct frame *));
 static void x_update_end P_ ((struct frame *));
 static void w32_frame_up_to_date P_ ((struct frame *));
 static void w32_set_terminal_modes P_ ((struct terminal *));
@@ -417,6 +412,75 @@ w32_clear_window (f)
   release_frame_dc (f, hdc);
 }
 
+#define OPAQUE_FRAME 255
+
+void
+x_set_frame_alpha (f)
+     struct frame *f;
+{
+  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
+  double alpha = 1.0;
+  double alpha_min = 1.0;
+  BYTE opac;
+  LONG ex_style;
+  HWND window = FRAME_W32_WINDOW (f);
+
+  /* Older versions of Windows do not support transparency.  */
+  if (!pfnSetLayeredWindowAttributes)
+    return;
+
+  if (dpyinfo->x_highlight_frame == f)
+    alpha = f->alpha[0];
+  else
+    alpha = f->alpha[1];
+
+  if (FLOATP (Vframe_alpha_lower_limit))
+    alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
+  else if (INTEGERP (Vframe_alpha_lower_limit))
+    alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
+
+  if (alpha < 0.0)
+    return;
+  else if (alpha > 1.0)
+    alpha = 1.0;
+  else if (alpha < alpha_min && alpha_min <= 1.0)
+    alpha = alpha_min;
+
+  opac = alpha * OPAQUE_FRAME;
+
+  ex_style = GetWindowLong (window, GWL_EXSTYLE);
+
+  if (opac == OPAQUE_FRAME)
+    ex_style &= ~WS_EX_LAYERED;
+  else
+    ex_style |= WS_EX_LAYERED;
+
+  SetWindowLong (window, GWL_EXSTYLE, ex_style);
+
+  if (opac != OPAQUE_FRAME)
+    pfnSetLayeredWindowAttributes (window, 0, opac, LWA_ALPHA);
+}
+
+int
+x_display_pixel_height (dpyinfo)
+     struct w32_display_info *dpyinfo;
+{
+  HDC dc = GetDC (NULL);
+  int pixels = GetDeviceCaps (dc, VERTRES);
+  ReleaseDC (NULL, dc);
+  return pixels;
+}
+
+int
+x_display_pixel_width (dpyinfo)
+     struct w32_display_info *dpyinfo;
+{
+  HDC dc = GetDC (NULL);
+  int pixels = GetDeviceCaps (dc, HORZRES);
+  ReleaseDC (NULL, dc);
+  return pixels;
+}
+
 \f
 /***********************************************************************
                    Starting and ending an update
@@ -670,11 +734,6 @@ x_after_update_window_line (desired_row)
     {
       int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
 
-      /* Internal border is drawn below the tool bar.  */
-      if (WINDOWP (f->tool_bar_window)
-         && w == XWINDOW (f->tool_bar_window))
-       y -= width;
-
       BLOCK_INPUT;
       {
        HDC hdc = get_frame_dc (f);
@@ -1223,8 +1282,6 @@ x_draw_glyph_string_background (s, force_p)
         if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
               || s->font_not_found_p
               || s->extends_to_end_of_line_p
-              || FONT_COMPAT (s->font)->bdf
-              || cleartype_active
               || force_p)
        {
          x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
@@ -1243,7 +1300,6 @@ x_draw_glyph_string_foreground (s)
      struct glyph_string *s;
 {
   int i, x;
-  HFONT old_font;
 
   /* If first glyph of S has a left box line, start drawing the text
      of S to the right of that box line.  */
@@ -1253,19 +1309,10 @@ x_draw_glyph_string_foreground (s)
   else
     x = s->x;
 
-  if (s->for_overlaps || (s->background_filled_p && s->hl != DRAW_CURSOR)
-      || cleartype_active)
-    SetBkMode (s->hdc, TRANSPARENT);
-  else
-    SetBkMode (s->hdc, OPAQUE);
-
   SetTextColor (s->hdc, s->gc->foreground);
   SetBkColor (s->hdc, s->gc->background);
   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
 
-  if (s->font && FONT_COMPAT (s->font)->hfont)
-    old_font = SelectObject (s->hdc, FONT_COMPAT (s->font)->hfont);
-
   /* Draw characters of S as rectangles if S's font could not be
      loaded. */
   if (s->font_not_found_p)
@@ -1281,12 +1328,15 @@ x_draw_glyph_string_foreground (s)
     }
   else
     {
-      int boff = s->font->baseline_offset;
       struct font *font = s->font;
+      int boff = font->baseline_offset;
       int y;
+      HFONT old_font;
+
+      old_font = SelectObject (s->hdc, FONT_HANDLE (font));
 
-      if (s->font->vertical_centering)
-       boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
+      if (font->vertical_centering)
+       boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
 
       y = s->ybase - boff;
       if (s->for_overlaps
@@ -1296,10 +1346,9 @@ x_draw_glyph_string_foreground (s)
        font->driver->draw (s, 0, s->nchars, x, y, 1);
       if (s->face->overstrike)
        font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
-    }
 
-  if (s->font && FONT_COMPAT (s->font)->hfont)
-    SelectObject (s->hdc, old_font);
+      SelectObject (s->hdc, old_font);
+    }
 }
 
 /* Draw the foreground of composite glyph string S.  */
@@ -1309,7 +1358,7 @@ x_draw_composite_glyph_string_foreground (s)
      struct glyph_string *s;
 {
   int i, j, x;
-  HFONT old_font;
+  struct font *font = s->font;
 
   /* If first glyph of S has a left box line, start drawing the text
      of S to the right of that box line.  */
@@ -1319,85 +1368,81 @@ x_draw_composite_glyph_string_foreground (s)
   else
     x = s->x;
 
-  /* S is a glyph string for a composition.  S->gidx is the index of
-     the first character drawn for glyphs of this composition.
-     S->gidx == 0 means we are drawing the very first character of
+  /* S is a glyph string for a composition.  S->cmp_from is the index
+     of the first character drawn for glyphs of this composition.
+     S->cmp_from == 0 means we are drawing the very first character of
      this composition.  */
 
   SetTextColor (s->hdc, s->gc->foreground);
   SetBkColor (s->hdc, s->gc->background);
-  SetBkMode (s->hdc, TRANSPARENT);
   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
 
-  if (s->font && FONT_COMPAT (s->font)->hfont)
-    old_font = SelectObject (s->hdc, FONT_COMPAT (s->font)->hfont);
-
   /* Draw a rectangle for the composition if the font for the very
      first character of the composition could not be loaded.  */
   if (s->font_not_found_p)
     {
-      if (s->gidx == 0)
+      if (s->cmp_from == 0)
         w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
                             s->height - 1);
     }
+  else if (! s->first_glyph->u.cmp.automatic)
+    {
+      int y = s->ybase;
+      int width = 0;
+      HFONT old_font;
 
+      old_font = SelectObject (s->hdc, FONT_HANDLE (font));
+
+      for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
+       if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
+         {
+           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);
+           if (s->face->overstrike)
+             font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
+         }
+      SelectObject (s->hdc, old_font);
+    }
+  else
     {
-      struct font *font = s->font;
+      Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
+      Lisp_Object glyph;
       int y = s->ybase;
       int width = 0;
+      HFONT old_font;
 
-      if (s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
-       {
-         Lisp_Object gstring = AREF (XHASH_TABLE (composition_hash_table)
-                                     ->key_and_value,
-                                     s->cmp->hash_index * 2);
-         int from;
+      old_font = SelectObject (s->hdc, FONT_HANDLE (font));
 
-         for (i = from = 0; i < s->nchars; i++)
+      for (i = j = s->cmp_from; i < s->cmp_to; i++)
+       {
+         glyph = LGSTRING_GLYPH (gstring, i);
+         if (NILP (LGLYPH_ADJUSTMENT (glyph)))
+           width += LGLYPH_WIDTH (glyph);
+         else
            {
-             Lisp_Object g = LGSTRING_GLYPH (gstring, i);
-             Lisp_Object adjustment = LGLYPH_ADJUSTMENT (g);
              int xoff, yoff, wadjust;
 
-             if (! VECTORP (adjustment))
-               {
-                 width += LGLYPH_WIDTH (g);
-                 continue;
-               }
-             if (from < i)
+             if (j < i)
                {
-                 font->driver->draw (s, from, i, x, y, 0);
+                 font->driver->draw (s, j, i, x, y, 0);
                  x += width;
                }
-             xoff = XINT (AREF (adjustment, 0));
-             yoff = XINT (AREF (adjustment, 1));
-             wadjust = XINT (AREF (adjustment, 2));
-
+             xoff = LGLYPH_XOFF (glyph);
+             yoff = LGLYPH_YOFF (glyph);
+             wadjust = LGLYPH_WADJUST (glyph);
              font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
              x += wadjust;
-             from = i + 1;
+             j = i + 1;
              width = 0;
            }
-         if (from < i)
-           font->driver->draw (s, from, i, x, y, 0);
        }
-      else
-       {
-         for (i = 0, j = s->gidx; i < s->nchars; i++, j++)
-           if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
-             {
-               int xx = x + s->cmp->offsets[j * 2];
-               int yy = y - s->cmp->offsets[j * 2 + 1];
+      if (j < i)
+       font->driver->draw (s, j, i, x, y, 0);
 
-               font->driver->draw (s, j, j + 1, xx, yy, 0);
-               if (s->face->overstrike)
-                 font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
-             }
-       }
+      SelectObject (s->hdc, old_font);
     }
-
-  if (s->font && FONT_COMPAT (s->font)->hfont)
-    SelectObject (s->hdc, old_font);
 }
 
 
@@ -1482,6 +1527,35 @@ w32_alloc_lighter_color (f, color, factor, delta)
   return 1;
 }
 
+/* On frame F, translate pixel colors to RGB values for the NCOLORS
+   colors in COLORS.  On W32, we no longer try to map colors to
+   a palette.  */
+void
+x_query_colors (f, colors, ncolors)
+     struct frame *f;
+     XColor *colors;
+     int ncolors;
+{
+  int i;
+
+  for (i = 0; i < ncolors; i++)
+    {
+      DWORD pixel = colors[i].pixel;
+      /* Convert to a 16 bit value in range 0 - 0xffff. */
+      colors[i].red = GetRValue (pixel) * 257;
+      colors[i].green = GetGValue (pixel) * 257;
+      colors[i].blue = GetBValue (pixel) * 257;
+    }
+}
+
+void
+x_query_color (f, color)
+     struct frame *f;
+     XColor *color;
+{
+  x_query_colors (f, color, 1);
+}
+
 
 /* Set up the foreground color for drawing relief lines of glyph
    string S.  RELIEF is a pointer to a struct relief containing the GC
@@ -2197,13 +2271,17 @@ x_draw_glyph_string (s)
     {
       int width;
       struct glyph_string *next;
-      for (width = 0, next = s->next; next;
+      for (width = 0, next = s->next;
+          next && width < s->right_overhang;
            width += next->width, next = next->next)
         if (next->first_glyph->type != IMAGE_GLYPH)
           {
             x_set_glyph_string_gc (next);
             x_set_glyph_string_clipping (next);
-            x_draw_glyph_string_background (next, 1);
+           if (next->first_glyph->type == STRETCH_GLYPH)
+             x_draw_stretch_glyph_string (next);
+           else
+             x_draw_glyph_string_background (next, 1);
             next->num_clips = 0;
           }
     }
@@ -2255,7 +2333,8 @@ x_draw_glyph_string (s)
       break;
 
     case COMPOSITE_GLYPH:
-      if (s->for_overlaps || s->gidx > 0)
+      if (s->for_overlaps || (s->cmp_from > 0
+                             && ! s->first_glyph->u.cmp.automatic))
        s->background_filled_p = 1;
       else
        x_draw_glyph_string_background (s, 1);
@@ -2319,12 +2398,12 @@ x_draw_glyph_string (s)
           if (s->face->underline_defaulted_p)
             {
               w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
-                             y, s->background_width, 1);
+                             y, s->width, 1);
             }
           else
             {
               w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
-                             y, s->background_width, 1);
+                             y, s->width, 1);
             }
         }
       /* Draw overline.  */
@@ -2335,19 +2414,18 @@ x_draw_glyph_string (s)
           if (s->face->overline_color_defaulted_p)
             {
               w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
-                             s->y + dy, s->background_width, h);
+                             s->y + dy, s->width, h);
             }
           else
             {
               w32_fill_area (s->f, s->hdc, s->face->overline_color, s->x,
-                             s->y + dy, s->background_width, h);
+                             s->y + dy, s->width, h);
             }
         }
 
       /* Draw strike-through.  */
       if (s->face->strike_through_p
-          && (FONT_COMPAT (s->font)->bdf
-             || !FONT_COMPAT (s->font)->tm.tmStruckOut))
+          && !FONT_TEXTMETRIC(s->font).tmStruckOut)
         {
           unsigned long h = 1;
           unsigned long dy = (s->height - h) / 2;
@@ -2635,6 +2713,7 @@ frame_highlight (f)
      struct frame *f;
 {
   x_update_cursor (f, 1);
+  x_set_frame_alpha (f);
 }
 
 static void
@@ -2642,6 +2721,7 @@ frame_unhighlight (f)
      struct frame *f;
 {
   x_update_cursor (f, 1);
+  x_set_frame_alpha (f);
 }
 
 /* The focus has changed.  Update the frames as necessary to reflect
@@ -2824,6 +2904,15 @@ x_get_keysym_name (keysym)
   return value;
 }
 
+static int codepage_for_locale(LCID locale)
+{
+  char cp[20];
+
+  if (GetLocaleInfo (locale, LOCALE_IDEFAULTANSICODEPAGE, cp, 20) > 0)
+    return atoi (cp);
+  else
+    return CP_ACP;
+}
 
 \f
 /* Mouse clicks and mouse movement.  Rah.  */
@@ -4021,7 +4110,7 @@ w32_read_socket (sd, expected, hold_quit)
 
       switch (msg.msg.message)
        {
-       case WM_PAINT:
+       case WM_EMACS_PAINT:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
 
          if (f)
@@ -4076,6 +4165,11 @@ w32_read_socket (sd, expected, hold_quit)
          /* 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));
+
          if (f)
            {
              inev.kind = LANGUAGE_CHANGE_EVENT;
@@ -4146,7 +4240,8 @@ w32_read_socket (sd, expected, hold_quit)
                     {
                       dbcs[0] = dbcs_lead;
                       dbcs_lead = 0;
-                      if (!MultiByteToWideChar (CP_ACP, 0, dbcs, 2, &code, 1))
+                      if (!MultiByteToWideChar (keyboard_codepage, 0,
+                                               dbcs, 2, &code, 1))
                         {
                           /* Garbage */
                           DebPrint (("Invalid DBCS sequence: %d %d\n",
@@ -4155,7 +4250,8 @@ w32_read_socket (sd, expected, hold_quit)
                           break;
                         }
                     }
-                  else if (IsDBCSLeadByteEx (CP_ACP, (BYTE) msg.msg.wParam))
+                  else if (IsDBCSLeadByteEx (keyboard_codepage,
+                                            (BYTE) msg.msg.wParam))
                     {
                       dbcs_lead = (char) msg.msg.wParam;
                       inev.kind = NO_EVENT;
@@ -4163,8 +4259,8 @@ w32_read_socket (sd, expected, hold_quit)
                     }
                   else
                     {
-                      if (!MultiByteToWideChar (CP_ACP, 0, &dbcs[1], 1,
-                                                &code, 1))
+                      if (!MultiByteToWideChar (keyboard_codepage, 0,
+                                               &dbcs[1], 1, &code, 1))
                         {
                           /* What to do with garbage? */
                           DebPrint (("Invalid character: %d\n", dbcs[1]));
@@ -4656,11 +4752,10 @@ w32_read_socket (sd, expected, hold_quit)
 
          if (f)
            {
-             dpyinfo->width = (short) LOWORD (msg.msg.lParam);
-             dpyinfo->height = (short) HIWORD (msg.msg.lParam);
              dpyinfo->n_cbits = msg.msg.wParam;
-             DebPrint (("display change: %d %d\n", dpyinfo->width,
-                        dpyinfo->height));
+             DebPrint (("display change: %d %d\n",
+                        (short) LOWORD (msg.msg.lParam),
+                        (short) HIWORD (msg.msg.lParam)));
            }
 
          check_visibility = 1;
@@ -4887,8 +4982,6 @@ x_draw_bar_cursor (w, row, width, kind)
 {
   struct frame *f = XFRAME (w->frame);
   struct glyph *cursor_glyph;
-  int x;
-  HDC hdc;
 
   /* If cursor is out of bounds, don't draw garbage.  This can happen
      in mini-buffer windows when switching between echo area glyphs
@@ -4910,6 +5003,8 @@ x_draw_bar_cursor (w, row, width, kind)
     {
       COLORREF cursor_color = f->output_data.w32->cursor_pixel;
       struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
+      int x;
+      HDC hdc;
 
       /* If the glyph's background equals the color we normally draw
         the bar cursor in, the bar cursor in its normal color is
@@ -4921,28 +5016,36 @@ x_draw_bar_cursor (w, row, width, kind)
 
       x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
 
-      if (width < 0)
-        width = FRAME_CURSOR_WIDTH (f);
-      width = min (cursor_glyph->pixel_width, width);
-
-      w->phys_cursor_width = width;
-
-
       hdc = get_frame_dc (f);
       w32_clip_to_row (w, row, TEXT_AREA, hdc);
 
       if (kind == BAR_CURSOR)
        {
+         if (width < 0)
+           width = FRAME_CURSOR_WIDTH (f);
+         width = min (cursor_glyph->pixel_width, width);
+
+         w->phys_cursor_width = width;
+
          w32_fill_area (f, hdc, cursor_color, x,
                         WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
                         width, row->height);
        }
       else
        {
+         int dummy_x, dummy_y, dummy_h;
+
+         if (width < 0)
+           width = row->height;
+
+         width = min (row->height, width);
+
+         get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
+                                   &dummy_y, &dummy_h);
          w32_fill_area (f, hdc, cursor_color, x,
                         WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
                                                  row->height - width),
-                        cursor_glyph->pixel_width, width);
+                        w->phys_cursor_width, width);
        }
 
       w32_set_clip_rectangle (hdc, NULL);
@@ -5022,6 +5125,8 @@ w32_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
            = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
               + glyph_row->ascent - w->phys_cursor_ascent);
 
+         PostMessage (hwnd, WM_IME_STARTCOMPOSITION, 0, 0);
+
          /* If the size of the active cursor changed, destroy the old
             system caret.  */
          if (w32_system_caret_hwnd
@@ -5179,9 +5284,7 @@ x_new_font (f, font_object, fontset)
   if (FRAME_FONT (f) == font)
     /* This font is already set in frame F.  There's nothing more to
        do.  */
-    return fontset_name (fontset);
-
-  BLOCK_INPUT;
+    return font_object;
 
   FRAME_FONT (f) = font;
   FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
@@ -5214,15 +5317,9 @@ x_new_font (f, font_object, fontset)
        x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
     }
 
-#ifdef HAVE_X_I18N
-  if (FRAME_XIC (f)
-      && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
-    xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
-#endif
-
-  UNBLOCK_INPUT;
+  /* X version sets font of input methods here also.  */
 
-  return fontset_name (fontset);
+  return font_object;
 }
 
 \f
@@ -5283,13 +5380,13 @@ x_calc_absolute_position (f)
   /* Treat negative positions as relative to the rightmost bottommost
      position that fits on the screen.  */
   if (flags & XNegative)
-    f->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width
+    f->left_pos = (x_display_pixel_width (FRAME_W32_DISPLAY_INFO (f))
                   - FRAME_PIXEL_WIDTH (f)
                   + f->left_pos
                   - (left_right_borders_width - 1));
 
   if (flags & YNegative)
-    f->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
+    f->top_pos = (x_display_pixel_height (FRAME_W32_DISPLAY_INFO (f))
                  - FRAME_PIXEL_HEIGHT (f)
                  + f->top_pos
                  - (top_bottom_borders_height - 1));
@@ -5420,7 +5517,7 @@ x_set_window_size (f, change_gravity, cols, rows)
      resize will happen asynchronously. But on Windows, the menu bar
      automatically wraps when the frame is too narrow to contain it,
      and that causes any calculations made here to come out wrong. The
-     end is some nasty buggy behaviour, including the potential loss
+     end is some nasty buggy behavior, including the potential loss
      of the minibuffer.
 
      Disabling this code is either not sufficient to fix the problems
@@ -5543,9 +5640,9 @@ x_raise_frame (f)
   BLOCK_INPUT;
 
   /* Strictly speaking, raise-frame should only change the frame's Z
-     order, leaving input focus unchanged.  This is reasonable behaviour
+     order, leaving input focus unchanged.  This is reasonable behavior
      on X where the usual policy is point-to-focus.  However, this
-     behaviour would be very odd on Windows where the usual policy is
+     behavior would be very odd on Windows where the usual policy is
      click-to-focus.
 
      On X, if the mouse happens to be over the raised frame, it gets
@@ -5922,8 +6019,6 @@ w32_initialize_display_info (display_name)
      with values obtained from system metrics.  */
   dpyinfo->resx = 1;
   dpyinfo->resy = 1;
-  dpyinfo->height_in = 1;
-  dpyinfo->width_in = 1;
   dpyinfo->n_planes = 1;
   dpyinfo->n_cbits = 4;
   dpyinfo->n_fonts = 0;
@@ -6079,7 +6174,6 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
   terminal->memory_below_frame = 0;   /* We don't remember what scrolls
                                         off the bottom. */
 
-#ifdef MULTI_KBOARD
   /* 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.  */
@@ -6094,7 +6188,6 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
   if (current_kboard == initial_kboard)
     current_kboard = terminal->kboard;
   terminal->kboard->reference_count++;
-#endif
 
   return terminal;
 }
@@ -6105,7 +6198,7 @@ x_delete_terminal (struct terminal *terminal)
   struct w32_display_info *dpyinfo = terminal->display_info.w32;
   int i;
 
-  /* Protect against recursive calls.  Fdelete_frame in
+  /* Protect against recursive calls.  delete_frame in
      delete_terminal calls us back when it deletes our last frame.  */
   if (!terminal->name)
     return;
@@ -6150,20 +6243,15 @@ w32_term_init (display_name, xrm_option, resource_name)
   dpyinfo->next = x_display_list;
   x_display_list = dpyinfo;
 
-  hdc = GetDC (GetDesktopWindow ());
+  hdc = GetDC (NULL);
 
-  dpyinfo->height = GetDeviceCaps (hdc, VERTRES);
-  dpyinfo->width = GetDeviceCaps (hdc, HORZRES);
   dpyinfo->root_window = GetDesktopWindow ();
   dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
   dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
   dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
   dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
   dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
-  dpyinfo->terminal->image_cache = make_image_cache ();
-  dpyinfo->height_in = dpyinfo->height / dpyinfo->resx;
-  dpyinfo->width_in = dpyinfo->width / dpyinfo->resy;
-  ReleaseDC (GetDesktopWindow (), hdc);
+  ReleaseDC (NULL, hdc);
 
   /* initialise palette with white and black */
   {
@@ -6251,6 +6339,9 @@ DWORD WINAPI w32_msg_worker (void * arg);
 static void
 w32_initialize ()
 {
+  HANDLE shell;
+  HRESULT (WINAPI * set_user_model) (wchar_t * id);
+
   baud_rate = 19200;
 
   w32_system_caret_hwnd = NULL;
@@ -6258,6 +6349,25 @@ w32_initialize ()
   w32_system_caret_x = 0;
   w32_system_caret_y = 0;
 
+  /* On Windows 7 and later, we need to set the user model ID
+     to associate emacsclient launched files with Emacs frames
+     in the UI.  */
+  shell = GetModuleHandle ("shell32.dll");
+  if (shell)
+    {
+      set_user_model
+       = (void *) GetProcAddress (shell,
+                                  "SetCurrentProcessExplicitAppUserModelID");
+
+      /* If the function is defined, then we are running on Windows 7
+        or newer, and the UI uses this to group related windows
+        together.  Since emacs, runemacs, emacsclient are related, we
+        want them grouped even though the executables are different,
+        so we need to set a consistent ID between them.  */
+      if (set_user_model)
+       set_user_model (L"GNU.Emacs");
+    }
+
   /* Initialize w32_use_visible_system_caret based on whether a screen
      reader is in use.  */
   if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
@@ -6271,8 +6381,13 @@ w32_initialize ()
      8 bit character input, standard quit char.  */
   Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
 
-  /* Create the window thread - it will terminate itself or when the app terminates */
+  {
+    DWORD input_locale_id = (DWORD) GetKeyboardLayout (0);
+    keyboard_codepage = codepage_for_locale ((LCID) (input_locale_id & 0xffff));
+  }
 
+  /* Create the window thread - it will terminate itself when the app
+     terminates */
   init_crit ();
 
   dwMainThreadId = GetCurrentThreadId ();
@@ -6280,7 +6395,6 @@ w32_initialize ()
                   GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
 
   /* Wait for thread to start */
-
   {
     MSG msg;
 
@@ -6307,19 +6421,14 @@ w32_initialize ()
 
   /* Dynamically link to optional system components.  */
   {
-    UINT smoothing_type;
-    BOOL smoothing_enabled;
-
-    HANDLE gdi_lib = LoadLibrary ("gdi32.dll");
+    HMODULE user_lib = GetModuleHandle ("user32.dll");
 
 #define LOAD_PROC(lib, fn) pfn##fn = (void *) GetProcAddress (lib, #fn)
 
-    LOAD_PROC (gdi_lib, GetFontUnicodeRanges);
+    LOAD_PROC (user_lib, SetLayeredWindowAttributes);
 
 #undef LOAD_PROC
 
-    FreeLibrary (gdi_lib);
-
     /* Ensure scrollbar handle is at least 5 pixels.  */
     vertical_scroll_bar_min_handle = 5;
 
@@ -6327,28 +6436,6 @@ w32_initialize ()
        effectively form the border of the main scroll bar range.  */
     vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
       = GetSystemMetrics (SM_CYVSCROLL);
-
-    /* Constants that are not always defined by the system headers
-       since they only exist on certain versions of Windows.  */
-#ifndef SPI_GETFONTSMOOTHING
-#define SPI_GETFONTSMOOTHING 0x4A
-#endif
-#ifndef SPI_GETFONTSMOOTHINGTYPE
-#define SPI_GETFONTSMOOTHINGTYPE 0x0200A
-#endif
-#ifndef FE_FONTSMOOTHINGCLEARTYPE
-#define FE_FONTSMOOTHINGCLEARTYPE 0x2
-#endif
-
-    /* Determine if Cleartype is in use.  Used to enable a hack in
-       the char metric calculations which adds extra pixels to
-       compensate for the "sub-pixels" that are not counted by the
-       system APIs. */
-    cleartype_active =
-      SystemParametersInfo (SPI_GETFONTSMOOTHING, 0, &smoothing_enabled, 0)
-      && smoothing_enabled
-      && SystemParametersInfo (SPI_GETFONTSMOOTHINGTYPE, 0, &smoothing_type, 0)
-      && smoothing_type == FE_FONTSMOOTHINGCLEARTYPE;
   }
 }
 
@@ -6395,15 +6482,6 @@ When nil, the right-alt and left-ctrl key combination is
 interpreted normally.  */);
   Vw32_recognize_altgr = Qt;
 
-  DEFVAR_BOOL ("w32-enable-unicode-output",
-               &w32_enable_unicode_output,
-               doc: /* Enable the use of Unicode for text output if non-nil.
-Unicode output may prevent some third party applications for displaying
-Far-East Languages on Windows 95/98 from working properly.
-NT uses Unicode internally anyway, so this flag will probably have no
-effect on NT machines.  */);
-  w32_enable_unicode_output = 1;
-
   DEFVAR_BOOL ("w32-use-visible-system-caret",
               &w32_use_visible_system_caret,
               doc: /* Flag to make the system caret visible.
@@ -6426,9 +6504,7 @@ the cursor have no effect.  */);
      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.
-
-NOTE: Not supported on MS-Windows yet.  */);
+to 4.1, set this to nil.  */);
   x_use_underline_position_properties = 0;
 
   DEFVAR_BOOL ("x-underline-at-descent-line",