This commit was generated by cvs2svn to compensate for changes in r1383,
[chise/xemacs-chise.git.1] / src / glyphs-msw.c
index 00506b5..25c037f 100644 (file)
@@ -1,5 +1,5 @@
 /* mswindows-specific glyph objects.
-   Copyright (C) 1998, 1999 Andy Piper.
+   Copyright (C) 1998, 1999, 2000 Andy Piper.
 
 This file is part of XEmacs.
 
@@ -98,15 +98,13 @@ Lisp_Object Q_resource_type, Q_resource_id;
 Lisp_Object Qmswindows_resource;
 
 static void
-mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
+mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii,
                                             int slices,
                                             enum image_instance_type type);
 static void
-mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
+mswindows_initialize_image_instance_mask (Lisp_Image_Instance* image,
                                          struct frame* f);
 
-COLORREF mswindows_string_to_color (CONST char *name);
-
 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
 
 /************************************************************************/
@@ -259,7 +257,7 @@ mswindows_locate_pixmap_file (Lisp_Object name)
         (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2)))))))
     {
       if (!NILP (Ffile_readable_p (name)))
-       return name;
+       return Fexpand_file_name (name, Qnil);
       else
        return Qnil;
     }
@@ -286,7 +284,7 @@ mswindows_locate_pixmap_file (Lisp_Object name)
    in the error message. */
 
 static void
-init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii,
+init_image_instance_from_dibitmap (Lisp_Image_Instance *ii,
                                   BITMAPINFO *bmp_info,
                                   int dest_mask,
                                   void *bmp_data,
@@ -300,7 +298,7 @@ init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii,
   struct device *d = XDEVICE (device);
   struct frame *f;
   void* bmp_buf=0;
-  int type = 0;
+  enum image_instance_type type;
   HBITMAP bitmap;
   HDC hdc;
 
@@ -360,7 +358,7 @@ init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii,
 }
 
 static void
-image_instance_add_dibitmap (struct Lisp_Image_Instance *ii,
+image_instance_add_dibitmap (Lisp_Image_Instance *ii,
                             BITMAPINFO *bmp_info,
                             void *bmp_data,
                             int bmp_bits,
@@ -387,7 +385,7 @@ image_instance_add_dibitmap (struct Lisp_Image_Instance *ii,
 }
 
 static void
-mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
+mswindows_init_image_instance_from_eimage (Lisp_Image_Instance *ii,
                                           int width, int height,
                                           int slices,
                                           unsigned char *eimage,
@@ -439,34 +437,33 @@ static void set_mono_pixel ( unsigned char* bits,
                             int bpline, int height,
                             int x, int y, int white )
 {
-  int index;
+  int i;
   unsigned char    bitnum;
   /* Find the byte on which this scanline begins */
-  index = (height - y - 1) * bpline;
+  i = (height - y - 1) * bpline;
   /* Find the byte containing this pixel */
-  index += (x >> 3);
+  i += (x >> 3);
   /* Which bit is it? */
   bitnum = (unsigned char)( 7 - (x % 8) );
   if( white )         /* Turn it on */
-    bits[index] |= (1<<bitnum);
+    bits[i] |= (1<<bitnum);
   else         /* Turn it off */
-    bits[index] &= ~(1<<bitnum);
+    bits[i] &= ~(1<<bitnum);
 }
 
 static void
-mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
+mswindows_initialize_image_instance_mask (Lisp_Image_Instance* image,
                                          struct frame* f)
 {
   HBITMAP mask;
   HGDIOBJ old = NULL;
   HDC hcdc = FRAME_MSWINDOWS_CDC (f);
-  unsigned char* dibits;
-  BITMAPINFO* bmp_info =
-    xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
+  unsigned char *dibits, *and_bits;
+  BITMAPINFO *bmp_info =
+    (BITMAPINFO*) xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
   int i, j;
   int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image);
 
-  void* and_bits;
   int maskbpline = BPLINE ((IMAGE_INSTANCE_PIXMAP_WIDTH (image)+7)/8);
   int bpline = BPLINE (IMAGE_INSTANCE_PIXMAP_WIDTH (image) * 3);
 
@@ -494,7 +491,7 @@ mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
   if (!(mask = CreateDIBSection (hcdc,
                                 bmp_info,
                                 DIB_RGB_COLORS,
-                                &and_bits,
+                                (void**)&and_bits,
                                 0,0)))
     {
       xfree (bmp_info);
@@ -515,7 +512,7 @@ mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
   bmp_info->bmiHeader.biClrImportant = 0;
   bmp_info->bmiHeader.biSizeImage = height * bpline;
 
-  dibits = xmalloc_and_zero (bpline * height);
+  dibits = (unsigned char*) xmalloc_and_zero (bpline * height);
   if (GetDIBits (hcdc,
                 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
                 0,
@@ -530,20 +527,20 @@ mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
 
   /* now set the colored bits in the mask and transparent ones to
      black in the original */
-  for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++)
+  for (i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++)
     {
-      for(j=0; j<height; j++)
+      for (j=0; j<height; j++)
        {
          unsigned char* idx = &dibits[j * bpline + i * 3];
 
-         if( RGB (idx[2], idx[1], idx[0]) == transparent_color )
+         if (RGB (idx[2], idx[1], idx[0]) == transparent_color)
            {
              idx[0] = idx[1] = idx[2] = 0;
-             set_mono_pixel( and_bits, maskbpline, height, i, j, TRUE );
+             set_mono_pixel (and_bits, maskbpline, height, i, j, TRUE);
            }
          else
            {
-             set_mono_pixel( and_bits, maskbpline, height, i, j, FALSE );
+             set_mono_pixel (and_bits, maskbpline, height, i, j, FALSE);
             }
        }
     }
@@ -565,7 +562,7 @@ mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
 }
 
 void
-mswindows_initialize_image_instance_icon (struct Lisp_Image_Instance* image,
+mswindows_initialize_image_instance_icon (Lisp_Image_Instance* image,
                                          int cursor)
 {
   ICONINFO x_icon;
@@ -582,7 +579,7 @@ mswindows_initialize_image_instance_icon (struct Lisp_Image_Instance* image,
 }
 
 HBITMAP
-mswindows_create_resized_bitmap (struct Lisp_Image_Instance* ii,
+mswindows_create_resized_bitmap (Lisp_Image_Instance* ii,
                                 struct frame* f,
                                 int newx, int newy)
 {
@@ -616,7 +613,7 @@ mswindows_create_resized_bitmap (struct Lisp_Image_Instance* ii,
 }
 
 HBITMAP
-mswindows_create_resized_mask (struct Lisp_Image_Instance* ii,
+mswindows_create_resized_mask (Lisp_Image_Instance* ii,
                               struct frame* f,
                               int newx, int newy)
 {
@@ -654,7 +651,7 @@ mswindows_create_resized_mask (struct Lisp_Image_Instance* ii,
 }
 
 int
-mswindows_resize_dibitmap_instance (struct Lisp_Image_Instance* ii,
+mswindows_resize_dibitmap_instance (Lisp_Image_Instance* ii,
                                    struct frame* f,
                                    int newx, int newy)
 {
@@ -742,7 +739,9 @@ extract_xpm_color_names (Lisp_Object device,
       colortbl[j].color =
        COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
 
-      GET_C_STRING_OS_DATA_ALLOCA (XCAR (cons), colortbl[j].name);
+      TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (cons),
+                         C_STRING_ALLOCA, colortbl[j].name,
+                         Qnative);
       colortbl[j].name = xstrdup (colortbl[j].name); /* mustn't lose this when we return */
       free_cons (XCONS (cons));
       cons = results;
@@ -752,7 +751,7 @@ extract_xpm_color_names (Lisp_Object device,
   return colortbl;
 }
 
-static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer,
+static int xpm_to_eimage (Lisp_Object image, const Extbyte *buffer,
                          unsigned char** data,
                          int* width, int* height,
                          int* x_hot, int* y_hot,
@@ -906,9 +905,9 @@ mswindows_xpm_instantiate (Lisp_Object image_instance,
                           Lisp_Object pointer_fg, Lisp_Object pointer_bg,
                           int dest_mask, Lisp_Object domain)
 {
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
-  CONST Extbyte                *bytes;
+  const Extbyte                *bytes;
   Extcount             len;
   unsigned char                *eimage;
   int                  width, height, x_hot, y_hot;
@@ -927,7 +926,9 @@ mswindows_xpm_instantiate (Lisp_Object image_instance,
 
   assert (!NILP (data));
 
-  GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
+  TO_EXTERNAL_FORMAT (LISP_STRING, data,
+                     ALLOCA, (bytes, len),
+                     Qbinary);
 
   /* in case we have color symbols */
   color_symbols = extract_xpm_color_names (device, domain,
@@ -996,9 +997,9 @@ bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
                 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
                 int dest_mask, Lisp_Object domain)
 {
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
-  CONST Extbyte                *bytes;
+  const Extbyte                *bytes;
   Extcount             len;
   BITMAPFILEHEADER*    bmp_file_header;
   BITMAPINFO*          bmp_info;
@@ -1011,7 +1012,9 @@ bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
 
   assert (!NILP (data));
 
-  GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
+  TO_EXTERNAL_FORMAT (LISP_STRING, data,
+                     ALLOCA, (bytes, len),
+                     Qbinary);
 
   /* Then slurp the image into memory, decoding along the way.
      The result is the image in a simple one-byte-per-pixel
@@ -1105,7 +1108,7 @@ typedef struct
 #endif
 #endif
 
-static CONST resource_t bitmap_table[] =
+static const resource_t bitmap_table[] =
 {
   /* bitmaps */
   { "close", OBM_CLOSE },
@@ -1137,7 +1140,7 @@ static CONST resource_t bitmap_table[] =
   {0}
 };
 
-static CONST resource_t cursor_table[] =
+static const resource_t cursor_table[] =
 {
   /* cursors */
   { "normal", OCR_NORMAL },
@@ -1156,7 +1159,7 @@ static CONST resource_t cursor_table[] =
   { 0 }
 };
 
-static CONST resource_t icon_table[] =
+static const resource_t icon_table[] =
 {
   /* icons */
   { "sample", OIC_SAMPLE },
@@ -1170,7 +1173,7 @@ static CONST resource_t icon_table[] =
 
 static int resource_name_to_resource (Lisp_Object name, int type)
 {
-  CONST resource_t* res = (type == IMAGE_CURSOR ? cursor_table
+  const resource_t* res = (type == IMAGE_CURSOR ? cursor_table
                           : type == IMAGE_ICON ? icon_table
                           : bitmap_table);
 
@@ -1185,7 +1188,9 @@ static int resource_name_to_resource (Lisp_Object name, int type)
 
   do {
     Extbyte* nm=0;
-    GET_C_STRING_OS_DATA_ALLOCA (name, nm);
+    TO_EXTERNAL_FORMAT (LISP_STRING, name,
+                       C_STRING_ALLOCA, nm,
+                       Qnative);
       if (!strcasecmp ((char*)res->name, nm))
       return res->resource_id;
   } while ((++res)->name);
@@ -1210,13 +1215,13 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti
                    Lisp_Object pointer_fg, Lisp_Object pointer_bg,
                    int dest_mask, Lisp_Object domain)
 {
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   unsigned int type = 0;
   HANDLE himage = NULL;
   LPCTSTR resid=0;
   HINSTANCE hinst = NULL;
   ICONINFO iconinfo;
-  int iitype=0;
+  enum image_instance_type iitype;
   char* fname=0;
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
 
@@ -1245,7 +1250,9 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti
   if (!NILP (file))
     {
       Extbyte* f=0;
-      GET_C_STRING_FILENAME_DATA_ALLOCA (file, f);
+      TO_EXTERNAL_FORMAT (LISP_STRING, file,
+                         C_STRING_ALLOCA, f,
+                         Qfile_name);
 #ifdef __CYGWIN32__
       CYGWIN_WIN32_PATH (f, fname);
 #else
@@ -1262,7 +1269,9 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti
                                                           type));
 
          if (!resid)
-           GET_C_STRING_OS_DATA_ALLOCA (resource_id, resid);
+           TO_EXTERNAL_FORMAT (LISP_STRING, resource_id,
+                               C_STRING_ALLOCA, resid,
+                               Qnative);
        }
     }
   else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
@@ -1294,17 +1303,17 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti
      bitmap and mask */
   if (type != IMAGE_BITMAP)
     {
-      GetIconInfo (himage, &iconinfo);
+      GetIconInfo ((HICON)himage, &iconinfo);
       IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
       IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
       XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
       XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
-      IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = himage;
+      IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = (HICON) himage;
     }
   else
     {
       IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
-      IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = himage;
+      IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = (HBITMAP) himage;
       IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
       XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
       XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
@@ -1330,15 +1339,6 @@ check_valid_resource_id (Lisp_Object data)
     signal_simple_error ("invalid resource identifier", data);
 }
 
-void
-check_valid_string_or_int (Lisp_Object data)
-{
-  if (!INTP (data))
-    CHECK_STRING (data);
-  else
-    CHECK_INT (data);
-}
-
 /**********************************************************************
  *                             XBM                                    *
  **********************************************************************/
@@ -1475,11 +1475,9 @@ static int NextInt ( FILE *fstream )
  * its arguments won't have been touched.  This routine should look as much
  * like the Xlib routine XReadBitmapfile as possible.
  */
-int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot)
-    FILE *fstream;                     /* handle on file  */
-    unsigned int *width, *height;      /* RETURNED */
-    unsigned char **datap;             /* RETURNED */
-    int *x_hot, *y_hot;                        /* RETURNED */
+int read_bitmap_data (FILE* fstream, unsigned int *width,
+                     unsigned int *height, unsigned char **datap,
+                     int *x_hot, int *y_hot)
 {
     unsigned char *data = NULL;                /* working variable */
     char line[MAX_SIZE];               /* input line from file */
@@ -1599,7 +1597,7 @@ int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot)
 }
 
 
-int read_bitmap_data_from_file (CONST char *filename, unsigned int *width,
+int read_bitmap_data_from_file (const char *filename, unsigned int *width,
                                unsigned int *height, unsigned char **datap,
                                int *x_hot, int *y_hot)
 {
@@ -1628,7 +1626,7 @@ static int flip_table[] =
    padded to a multiple of 16.  Scan lines are stored in increasing
    byte order from left to right, big-endian within a byte.  0 =
    black, 1 = white.  */
-HBITMAP
+static HBITMAP
 xbm_create_bitmap_from_data (HDC hdc, char *data,
                             unsigned int width, unsigned int height,
                             int mask, COLORREF fg, COLORREF bg)
@@ -1639,8 +1637,8 @@ xbm_create_bitmap_from_data (HDC hdc, char *data,
   void *bmp_buf = 0;
   unsigned char *new_data, *new_offset;
   int i, j;
-  BITMAPINFO* bmp_info =
-    xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
+  BITMAPINFO *bmp_info =
+    (BITMAPINFO*) xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
   HBITMAP bitmap;
 
   if (!bmp_info)
@@ -1720,10 +1718,10 @@ xbm_create_bitmap_from_data (HDC hdc, char *data,
    image instance accordingly. */
 
 static void
-init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii,
+init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii,
                                     int width, int height,
                                     /* Note that data is in ext-format! */
-                                    CONST char *bits,
+                                    const char *bits,
                                     Lisp_Object instantiator,
                                     Lisp_Object pointer_fg,
                                     Lisp_Object pointer_bg,
@@ -1852,29 +1850,30 @@ xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
                   Lisp_Object pointer_fg, Lisp_Object pointer_bg,
                   int dest_mask, int width, int height,
                   /* Note that data is in ext-format! */
-                  CONST char *bits)
+                  const char *bits)
 {
   Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
   Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   struct frame* f = XFRAME (DEVICE_SELECTED_FRAME
                            (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))));
   HDC hdc = FRAME_MSWINDOWS_CDC (f);
   HBITMAP mask = 0;
-  CONST char *gcc_may_you_rot_in_hell;
 
   if (!NILP (mask_data))
     {
-      GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (mask_data))),
-                                      gcc_may_you_rot_in_hell);
-      mask =
-       xbm_create_bitmap_from_data ( hdc,
-                                     (unsigned char *)
-                                     gcc_may_you_rot_in_hell,
-                                     XINT (XCAR (mask_data)),
-                                     XINT (XCAR (XCDR (mask_data))), FALSE,
-                                     PALETTERGB (0,0,0),
-                                     PALETTERGB (255,255,255));
+      const char *ext_data;
+
+      TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (mask_data))),
+                         C_STRING_ALLOCA, ext_data,
+                         Qbinary);
+      mask = xbm_create_bitmap_from_data (hdc,
+                                         (unsigned char *) ext_data,
+                                         XINT (XCAR (mask_data)),
+                                         XINT (XCAR (XCDR (mask_data))),
+                                         FALSE,
+                                         PALETTERGB (0,0,0),
+                                         PALETTERGB (255,255,255));
     }
 
   init_image_instance_from_xbm_inline (ii, width, height, bits,
@@ -1891,16 +1890,17 @@ mswindows_xbm_instantiate (Lisp_Object image_instance,
                           int dest_mask, Lisp_Object domain)
 {
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
-  CONST char *gcc_go_home;
+  const char *ext_data;
 
   assert (!NILP (data));
 
-  GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (data))),
-                                  gcc_go_home);
+  TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (data))),
+                     C_STRING_ALLOCA, ext_data,
+                     Qbinary);
 
   xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
                     pointer_bg, dest_mask, XINT (XCAR (data)),
-                    XINT (XCAR (XCDR (data))), gcc_go_home);
+                    XINT (XCAR (XCDR (data))), ext_data);
 }
 
 #ifdef HAVE_XFACE
@@ -1935,12 +1935,14 @@ mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiato
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
   int i, stattis;
   char *p, *bits, *bp;
-  CONST char * volatile emsg = 0;
-  CONST char * volatile dstring;
+  const char * volatile emsg = 0;
+  const char * volatile dstring;
 
   assert (!NILP (data));
 
-  GET_C_STRING_BINARY_DATA_ALLOCA (data, dstring);
+  TO_EXTERNAL_FORMAT (LISP_STRING, data,
+                     C_STRING_ALLOCA, dstring,
+                     Qbinary);
 
   if ((p = strchr (dstring, ':')))
     {
@@ -1996,7 +1998,7 @@ mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiato
 /************************************************************************/
 
 static void
-mswindows_print_image_instance (struct Lisp_Image_Instance *p,
+mswindows_print_image_instance (Lisp_Image_Instance *p,
                                Lisp_Object printcharfun,
                                int escapeflag)
 {
@@ -2029,7 +2031,7 @@ extern int debug_widget_instances;
 #endif
 
 static void
-mswindows_finalize_image_instance (struct Lisp_Image_Instance *p)
+mswindows_finalize_image_instance (Lisp_Image_Instance *p)
 {
   if (DEVICE_LIVE_P (XDEVICE (p->device)))
     {
@@ -2085,10 +2087,23 @@ mswindows_finalize_image_instance (struct Lisp_Image_Instance *p)
 /*                      subwindow and widget support                      */
 /************************************************************************/
 
+static HFONT
+mswindows_widget_hfont (Lisp_Image_Instance *p,
+                       Lisp_Object domain)
+{
+  Lisp_Object face = IMAGE_INSTANCE_WIDGET_FACE (p);
+  int under = FACE_UNDERLINE_P (face, domain);
+  int strike = FACE_STRIKETHRU_P (face, domain);
+  Lisp_Object font = query_string_font (IMAGE_INSTANCE_WIDGET_TEXT (p),
+                                       face, domain);
+
+  return mswindows_get_hfont (XFONT_INSTANCE (font), under, strike);
+}
+
 /* unmap the image if it is a widget. This is used by redisplay via
    redisplay_unmap_subwindows */
 static void
-mswindows_unmap_subwindow (struct Lisp_Image_Instance *p)
+mswindows_unmap_subwindow (Lisp_Image_Instance *p)
 {
   if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
     {
@@ -2097,13 +2112,15 @@ mswindows_unmap_subwindow (struct Lisp_Image_Instance *p)
                    0, 0, 0, 0,
                    SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE
                    | SWP_NOSENDCHANGING);
+      if (GetFocus() == WIDGET_INSTANCE_MSWINDOWS_HANDLE (p))
+       SetFocus (GetParent (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p)));
     }
 }
 
 /* map the subwindow. This is used by redisplay via
    redisplay_output_subwindow */
 static void
-mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y,
+mswindows_map_subwindow (Lisp_Image_Instance *p, int x, int y,
                         struct display_glyph_area* dga)
 {
   /* move the window before mapping it ... */
@@ -2129,7 +2146,7 @@ mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y,
 
 /* resize the subwindow instance */
 static void
-mswindows_resize_subwindow (struct Lisp_Image_Instance* ii, int w, int h)
+mswindows_resize_subwindow (Lisp_Image_Instance* ii, int w, int h)
 {
   /* Set the size of the control .... */
   SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
@@ -2139,34 +2156,47 @@ mswindows_resize_subwindow (struct Lisp_Image_Instance* ii, int w, int h)
                | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
 }
 
+/* Simply resize the window here. */
+static void
+mswindows_update_subwindow (Lisp_Image_Instance *p)
+{
+  mswindows_resize_subwindow (p,
+                             IMAGE_INSTANCE_WIDTH (p),
+                             IMAGE_INSTANCE_HEIGHT (p));
+}
+
 /* when you click on a widget you may activate another widget this
    needs to be checked and all appropriate widgets updated */
 static void
-mswindows_update_subwindow (struct Lisp_Image_Instance *p)
+mswindows_update_widget (Lisp_Image_Instance *p)
 {
-  if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET)
+  /* Possibly update the face font and colors. */
+  if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p))
     {
-      /* buttons checked or otherwise */
-      if ( EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qbutton))
-       {
-         if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (p)))
-           SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
-                        BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
-         else
-           SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
-                        BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
-       }
-
       /* set the widget font from the widget face */
       SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
                   WM_SETFONT,
-                  (WPARAM)FONT_INSTANCE_MSWINDOWS_HFONT
-                  (XFONT_INSTANCE (widget_face_font_info
-                                   (IMAGE_INSTANCE_SUBWINDOW_FRAME (p),
-                                    IMAGE_INSTANCE_WIDGET_FACE (p),
-                                    0, 0))),
+                  (WPARAM) mswindows_widget_hfont
+                  (p, IMAGE_INSTANCE_SUBWINDOW_FRAME (p)),
                   MAKELPARAM (TRUE, 0));
     }
+  /* Possibly update the dimensions. */
+  if (IMAGE_INSTANCE_SIZE_CHANGED (p))
+    {
+      mswindows_resize_subwindow (p, 
+                                 IMAGE_INSTANCE_WIDTH (p),
+                                 IMAGE_INSTANCE_HEIGHT (p));
+    }
+  /* Possibly update the text in the widget. */
+  if (IMAGE_INSTANCE_TEXT_CHANGED (p))
+    {
+      Extbyte* lparam=0;
+      TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (p),
+                         C_STRING_ALLOCA, lparam,
+                         Qnative);
+      SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
+                  WM_SETTEXT, 0, (LPARAM)lparam);
+    }
 }
 
 /* register widgets into our hastable so that we can cope with the
@@ -2198,7 +2228,7 @@ mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instant
                                 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
                                 int dest_mask, Lisp_Object domain)
 {
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
   struct device* d = XDEVICE (device);
   Lisp_Object frame = FW_FRAME (domain);
@@ -2250,8 +2280,8 @@ mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instant
 }
 
 static int
-mswindows_image_instance_equal (struct Lisp_Image_Instance *p1,
-                               struct Lisp_Image_Instance *p2, int depth)
+mswindows_image_instance_equal (Lisp_Image_Instance *p1,
+                               Lisp_Image_Instance *p2, int depth)
 {
   switch (IMAGE_INSTANCE_TYPE (p1))
     {
@@ -2271,7 +2301,7 @@ mswindows_image_instance_equal (struct Lisp_Image_Instance *p1,
 }
 
 static unsigned long
-mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
+mswindows_image_instance_hash (Lisp_Image_Instance *p, int depth)
 {
   switch (IMAGE_INSTANCE_TYPE (p))
     {
@@ -2292,7 +2322,7 @@ mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
    methods are called. */
 
 static void
-mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
+mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii,
                                              int slices,
                                              enum image_instance_type type)
 {
@@ -2319,10 +2349,10 @@ static void
 mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
                              Lisp_Object pointer_fg, Lisp_Object pointer_bg,
                              int dest_mask, Lisp_Object domain,
-                             CONST char* class, int flags, int exflags)
+                             const char* class, int flags, int exflags)
 {
   /* this function can call lisp */
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
   struct device* d = XDEVICE (device);
   Lisp_Object frame = FW_FRAME (domain);
@@ -2330,7 +2360,7 @@ mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
   HWND wnd;
   int id = 0xffff;
   Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
-  struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
+  Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
 
   if (!DEVICE_MSWINDOWS_P (d))
     signal_simple_error ("Not an mswindows device", device);
@@ -2344,18 +2374,18 @@ mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
     {
       id = mswindows_register_widget_instance (image_instance, domain);
     }
-  /* have to set the type this late in case there is no device
-     instantiation for a widget */
-  IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET;
+
   if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
-    GET_C_STRING_OS_DATA_ALLOCA (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm);
+    TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (ii),
+                       C_STRING_ALLOCA, nm,
+                       Qnative);
 
   /* allocate space for the clip window and then allocate the clip window */
   ii->data = xnew_and_zero (struct mswindows_subwindow_data);
 
   if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
        = CreateWindowEx(
-                       0,              /* EX flags */
+                       WS_EX_CONTROLPARENT,    /* EX flags */
                        XEMACS_CONTROL_CLASS,
                        0,              /* text */
                        WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
@@ -2395,18 +2425,14 @@ mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
   SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
   /* set the widget font from the widget face */
   SendMessage (wnd, WM_SETFONT,
-              (WPARAM)FONT_INSTANCE_MSWINDOWS_HFONT
-              (XFONT_INSTANCE (widget_face_font_info
-                               (domain,
-                                IMAGE_INSTANCE_WIDGET_FACE (ii),
-                                0, 0))),
+              (WPARAM) mswindows_widget_hfont (ii, domain),
               MAKELPARAM (TRUE, 0));
 }
 
 /* Instantiate a button widget. Unfortunately instantiated widgets are
    particular to a frame since they need to have a parent. It's not
    like images where you just select the image into the context you
-   want to display it in and BitBlt it. So images instances can have a
+   want to display it in and BitBlt it. So image instances can have a
    many-to-one relationship with things you see, whereas widgets can
    only be one-to-one (i.e. per frame) */
 static void
@@ -2415,17 +2441,16 @@ mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
                              int dest_mask, Lisp_Object domain)
 {
   /* this function can call lisp */
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   HWND wnd;
-  int flags = BS_NOTIFY;
+  int flags = WS_TABSTOP;/* BS_NOTIFY #### is needed to get exotic feedback
+                           only. Since we seem to want nothing beyond BN_CLICK,
+                           the style is perhaps not necessary -- kkm */
   Lisp_Object style;
   Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
-  struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
+  Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
   Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
 
-  if (!gui_item_active_p (gui))
-    flags |= WS_DISABLED;
-
   if (!NILP (glyph))
     {
       if (!IMAGE_INSTANCEP (glyph))
@@ -2438,6 +2463,8 @@ mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
 
   style = pgui->style;
 
+  /* #### consider using the default face for radio and toggle
+     buttons. */
   if (EQ (style, Qradio))
     {
       flags |= BS_RADIOBUTTON;
@@ -2447,11 +2474,13 @@ mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
       flags |= BS_AUTOCHECKBOX;
     }
   else
-    flags |= BS_DEFPUSHBUTTON;
+    {
+      flags |= BS_DEFPUSHBUTTON;
+    }
 
   mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
-                               pointer_bg, dest_mask, domain, "BUTTON", flags,
-                               WS_EX_CONTROLPARENT);
+                               pointer_bg, dest_mask, domain, "BUTTON",
+                               flags, 0);
 
   wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
   /* set the checked state */
@@ -2460,17 +2489,35 @@ mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
   else
     SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
   /* add the image if one was given */
-  if (!NILP (glyph) && IMAGE_INSTANCEP (glyph))
+  if (!NILP (glyph) && IMAGE_INSTANCEP (glyph)
+      &&
+      IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph)))
     {
       SendMessage (wnd, BM_SETIMAGE,
                   (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
                             IMAGE_BITMAP : IMAGE_ICON),
-                  (LPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
-                            XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
-                            XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
+                  (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
+                   (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
+                   (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
     }
 }
 
+/* Update the state of a button. */
+static void
+mswindows_button_update (Lisp_Object image_instance)
+{
+  /* This function can GC if IN_REDISPLAY is false. */
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+  /* buttons checked or otherwise */
+  if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (ii)))
+    SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+                BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
+  else
+    SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+                BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+}
+
 /* instantiate an edit control */
 static void
 mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
@@ -2480,8 +2527,7 @@ mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instan
   mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
                                pointer_bg, dest_mask, domain, "EDIT",
                                ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP
-                               | WS_BORDER,
-                               WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
+                               | WS_BORDER, WS_EX_CLIENTEDGE);
 }
 
 /* instantiate a progress gauge */
@@ -2491,11 +2537,10 @@ mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object in
                                int dest_mask, Lisp_Object domain)
 {
   HWND wnd;
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
                                pointer_bg, dest_mask, domain, PROGRESS_CLASS,
-                               WS_TABSTOP | WS_BORDER | PBS_SMOOTH,
-                               WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
+                               WS_BORDER | PBS_SMOOTH, WS_EX_CLIENTEDGE);
   wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
   /* set the colors */
 #ifdef PBS_SETBKCOLOR
@@ -2533,11 +2578,14 @@ static HTREEITEM add_tree_item (Lisp_Object image_instance,
     {
       tvitem.item.lParam = mswindows_register_gui_item (item, domain);
       tvitem.item.mask |= TVIF_PARAM;
-      GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name,
-                                  tvitem.item.pszText);
+      TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
+                         C_STRING_ALLOCA, tvitem.item.pszText,
+                         Qnative);
     }
   else
-    GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.item.pszText);
+    TO_EXTERNAL_FORMAT (LISP_STRING, item,
+                       C_STRING_ALLOCA, tvitem.item.pszText,
+                       Qnative);
 
   tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
 
@@ -2574,12 +2622,12 @@ mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instant
   Lisp_Object rest;
   HWND wnd;
   HTREEITEM parent;
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
                                pointer_bg, dest_mask, domain, WC_TREEVIEW,
                                WS_TABSTOP | WS_BORDER | PBS_SMOOTH
                                | TVS_HASLINES | TVS_HASBUTTONS,
-                               WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
+                               WS_EX_CLIENTEDGE);
 
   wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
 
@@ -2602,7 +2650,7 @@ mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instant
 /* instantiate a tab control */
 static TC_ITEM* add_tab_item (Lisp_Object image_instance,
                             HWND wnd, Lisp_Object item,
-                            Lisp_Object domain, int index)
+                            Lisp_Object domain, int i)
 {
   TC_ITEM tvitem, *ret;
 
@@ -2612,19 +2660,22 @@ static TC_ITEM* add_tab_item (Lisp_Object image_instance,
     {
       tvitem.lParam = mswindows_register_gui_item (item, domain);
       tvitem.mask |= TCIF_PARAM;
-      GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name,
-                                  tvitem.pszText);
+      TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
+                         C_STRING_ALLOCA, tvitem.pszText,
+                         Qnative);
     }
   else
     {
       CHECK_STRING (item);
-      GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.pszText);
+      TO_EXTERNAL_FORMAT (LISP_STRING, item,
+                         C_STRING_ALLOCA, tvitem.pszText,
+                         Qnative);
     }
 
   tvitem.cchTextMax = strlen (tvitem.pszText);
 
   if ((ret = (TC_ITEM*)SendMessage (wnd, TCM_INSERTITEM,
-                                   index, (LPARAM)&tvitem)) < 0)
+                                   i, (LPARAM)&tvitem)) < 0)
     signal_simple_error ("error adding tab entry", item);
 
   return ret;
@@ -2637,55 +2688,57 @@ mswindows_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object insta
 {
   Lisp_Object rest;
   HWND wnd;
-  int index = 0;
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  int i = 0;
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
+  unsigned int flags = WS_TABSTOP;
+
+  if (EQ (orient, Qleft) || EQ (orient, Qright))
+    {
+      flags |= TCS_VERTICAL | TCS_MULTILINE;
+    }
+  if (EQ (orient, Qright) || EQ (orient, Qbottom))
+    {
+      flags |= TCS_BOTTOM;
+    }
+
   mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
                                pointer_bg, dest_mask, domain, WC_TABCONTROL,
                                /* borders don't suit tabs so well */
-                               WS_TABSTOP,
-                               WS_EX_CONTROLPARENT);
+                               flags, 0);
 
   wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
   /* add items to the tab */
   LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
     {
-      add_tab_item (image_instance, wnd, XCAR (rest), domain, index);
-      index++;
+      add_tab_item (image_instance, wnd, XCAR (rest), domain, i);
+      i++;
     }
 }
 
 /* set the properties of a tab control */
-static Lisp_Object
-mswindows_tab_control_set_property (Lisp_Object image_instance, Lisp_Object prop,
-                                   Lisp_Object val)
+static void
+mswindows_tab_control_update (Lisp_Object image_instance)
 {
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
 
-  if (EQ (prop, Q_items))
+  if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
     {
       HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
-      int index = 0;
+      int i = 0;
       Lisp_Object rest;
-      check_valid_item_list_1 (val);
 
       /* delete the pre-existing items */
       SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0);
 
-      IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
-       Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
-              parse_gui_item_tree_children (val));
-
       /* add items to the tab */
       LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
        {
          add_tab_item (image_instance, wnd, XCAR (rest),
-                       IMAGE_INSTANCE_SUBWINDOW_FRAME (ii), index);
-         index++;
+                       IMAGE_INSTANCE_SUBWINDOW_FRAME (ii), i);
+         i++;
        }
-
-      return Qt;
     }
-  return Qunbound;
 }
 
 /* instantiate a static control possible for putting other things in */
@@ -2707,8 +2760,7 @@ mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instant
 {
   mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
                                pointer_bg, dest_mask, domain, "SCROLLBAR",
-                               0,
-                               WS_EX_CLIENTEDGE );
+                               WS_TABSTOP, WS_EX_CLIENTEDGE);
 }
 
 /* instantiate a combo control */
@@ -2717,13 +2769,12 @@ mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instant
                             Lisp_Object pointer_fg, Lisp_Object pointer_bg,
                             int dest_mask, Lisp_Object domain)
 {
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
-  HANDLE wnd;
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  HWND wnd;
   Lisp_Object rest;
   Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
                                 Q_items, Qnil);
-  int len;
-  GET_LIST_LENGTH (data, len);
+  int len, height;
 
   /* Maybe ought to generalise this more but it may be very windows
      specific. In windows the window height of a combo box is the
@@ -2731,26 +2782,38 @@ mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instant
      before creating the window and then reset it to a single line
      after the window is created so that redisplay does the right
      thing. */
-  widget_instantiate_1 (image_instance, instantiator, pointer_fg,
-                       pointer_bg, dest_mask, domain, len + 1, 0, 0);
+  widget_instantiate (image_instance, instantiator, pointer_fg,
+                     pointer_bg, dest_mask, domain);
 
+  /* We now have everything right apart from the height. */
+  default_face_font_info (domain, 0, 0, &height, 0, 0);
+  GET_LIST_LENGTH (data, len);
+
+  height = (height + WIDGET_BORDER_HEIGHT * 2 ) * len;
+  IMAGE_INSTANCE_HEIGHT (ii) = height;
+
+  /* Now create the widget. */
   mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
                                pointer_bg, dest_mask, domain, "COMBOBOX",
                                WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
                                | CBS_AUTOHSCROLL
                                | CBS_HASSTRINGS | WS_VSCROLL,
-                               WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
-  /* reset the height */
-  widget_text_to_pixel_conversion (domain,
-                                  IMAGE_INSTANCE_WIDGET_FACE (ii), 1, 0,
-                                  &IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii), 0);
+                               WS_EX_CLIENTEDGE);
+  /* Reset the height. layout will probably do this safely, but better make sure. */
+  image_instance_layout (image_instance,
+                        IMAGE_UNSPECIFIED_GEOMETRY,
+                        IMAGE_UNSPECIFIED_GEOMETRY,
+                        domain);
+
   wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
   /* add items to the combo box */
   SendMessage (wnd, CB_RESETCONTENT, 0, 0);
   LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
     {
       Extbyte* lparam;
-      GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), lparam);
+      TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (rest),
+                         C_STRING_ALLOCA, lparam,
+                         Qnative);
       if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
        signal_simple_error ("error adding combo entries", instantiator);
     }
@@ -2760,16 +2823,16 @@ mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instant
 static Lisp_Object
 mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
 {
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
-  HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
   /* get the text from a control */
   if (EQ (prop, Q_text))
     {
       Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
-      Extbyte* buf =alloca (len+1);
+      Extbyte *buf = (Extbyte*) alloca (len+1);
 
       SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
-      return build_ext_string (buf, FORMAT_OS);
+      return build_ext_string (buf, Qnative);
     }
   return Qunbound;
 }
@@ -2778,8 +2841,8 @@ mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
 static Lisp_Object
 mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
 {
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
-  HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
   /* check the state of a button */
   if (EQ (prop, Q_selected))
     {
@@ -2795,61 +2858,42 @@ mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
 static Lisp_Object
 mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop)
 {
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
-  HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
   /* get the text from a control */
   if (EQ (prop, Q_text))
     {
       long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
       Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
-      Extbyte* buf = alloca (len+1);
+      Extbyte* buf = (Extbyte*) alloca (len+1);
       SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
-      return build_ext_string (buf, FORMAT_OS);
-    }
-  return Qunbound;
-}
-
-/* set the properties of a control */
-static Lisp_Object
-mswindows_widget_set_property (Lisp_Object image_instance, Lisp_Object prop,
-                              Lisp_Object val)
-{
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
-
-  if (EQ (prop, Q_text))
-    {
-      Extbyte* lparam=0;
-      CHECK_STRING (val);
-      GET_C_STRING_OS_DATA_ALLOCA (val, lparam);
-      SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
-                  WM_SETTEXT, 0, (LPARAM)lparam);
-      return Qt;
+      return build_ext_string (buf, Qnative);
     }
   return Qunbound;
 }
 
 /* set the properties of a progres guage */
-static Lisp_Object
-mswindows_progress_gauge_set_property (Lisp_Object image_instance, Lisp_Object prop,
-                                Lisp_Object val)
+static void
+mswindows_progress_gauge_update (Lisp_Object image_instance)
 {
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
-
-  if (EQ (prop, Q_percent))
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  
+  if (IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii))
     {
+      /* #### I'm not convinced we should store this in the plist. */
+      Lisp_Object val = Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii),
+                                   Q_percent, Qnil);
       CHECK_INT (val);
       SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
                   PBM_SETPOS, (WPARAM)XINT (val), 0);
-      return Qt;
     }
-  return Qunbound;
 }
 
 LRESULT WINAPI
-mswindows_control_wnd_proc (HWND hwnd, UINT message,
+mswindows_control_wnd_proc (HWND hwnd, UINT msg,
                            WPARAM wParam, LPARAM lParam)
 {
-  switch (message)
+  switch (msg)
     {
     case WM_NOTIFY:
     case WM_COMMAND:
@@ -2859,9 +2903,9 @@ mswindows_control_wnd_proc (HWND hwnd, UINT message,
     case WM_CTLCOLORSTATIC:
     case WM_CTLCOLORSCROLLBAR:
 
-      return mswindows_wnd_proc (GetParent (hwnd), message, wParam, lParam);
+      return mswindows_wnd_proc (GetParent (hwnd), msg, wParam, lParam);
     default:
-      return DefWindowProc (hwnd, message, wParam, lParam);
+      return DefWindowProc (hwnd, msg, wParam, lParam);
     }
 }
 
@@ -2889,6 +2933,7 @@ console_type_create_glyphs_mswindows (void)
   CONSOLE_HAS_METHOD (mswindows, unmap_subwindow);
   CONSOLE_HAS_METHOD (mswindows, map_subwindow);
   CONSOLE_HAS_METHOD (mswindows, update_subwindow);
+  CONSOLE_HAS_METHOD (mswindows, update_widget);
   CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
   CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
   CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
@@ -2932,6 +2977,7 @@ image_instantiator_format_create_glyphs_mswindows (void)
   INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
   IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
   IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, button, update);
 
   INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field);
   IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate);
@@ -2941,7 +2987,6 @@ image_instantiator_format_create_glyphs_mswindows (void)
 
   INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
   IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
-  IIFORMAT_HAS_DEVMETHOD (mswindows, widget, set_property);
 
   /* label */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
@@ -2958,7 +3003,7 @@ image_instantiator_format_create_glyphs_mswindows (void)
 
   /* progress gauge */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge);
-  IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, set_property);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, update);
   IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate);
 
   /* tree view widget */
@@ -2969,7 +3014,7 @@ image_instantiator_format_create_glyphs_mswindows (void)
   /* tab control widget */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control);
   IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate);
-  IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, set_property);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, update);
 #endif
   /* windows bitmap format */
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");