import -ko -b 1.1.3 XEmacs XEmacs-21_2 r21-2-35
[chise/xemacs-chise.git.1] / src / glyphs-msw.c
index 4cd61ab..56c6b65 100644 (file)
@@ -20,7 +20,7 @@ Boston, MA 02111-1307, USA.  */
 
 /* Synched up with: Not in FSF. */
 
-/* written by Andy Piper <andy@xemacs.org> plagerising bits from
+/* written by Andy Piper <andy@xemacs.org> plagiarising bits from
    glyphs-x.c */
 
 #include <config.h>
@@ -57,7 +57,6 @@ DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing);
 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string);
 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit);
-DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
 #ifdef HAVE_JPEG
 DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
 #endif
@@ -80,6 +79,8 @@ DEFINE_DEVICE_IIFORMAT (msprinter, xbm);
 DEFINE_DEVICE_IIFORMAT (mswindows, xface);
 DEFINE_DEVICE_IIFORMAT (msprinter, xface);
 #endif
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
+DEFINE_DEVICE_IIFORMAT (mswindows, native_layout);
 DEFINE_DEVICE_IIFORMAT (mswindows, button);
 DEFINE_DEVICE_IIFORMAT (mswindows, edit_field);
 DEFINE_DEVICE_IIFORMAT (mswindows, subwindow);
@@ -121,6 +122,41 @@ get_device_compdc (struct device *d)
     return DEVICE_MSPRINTER_HCDC (d);
 }
 
+/*
+ * Initialize image instance pixel sizes in II.  For a display bitmap,
+ * these will be same as real bitmap sizes.  For a printer bitmap,
+ * these will be scaled up so that the bitmap is proportionally enlarged
+ * when output to printer.  Redisplay code takes care of scaling, to
+ * conserve memory we do not really scale bitmaps.  Set the watermark
+ * only here.
+ * #### Add support for unscalable bitmaps.
+ */
+static void init_image_instance_geometry (Lisp_Image_Instance *ii)
+{
+  struct device *d = DOMAIN_XDEVICE (ii->domain);
+  
+  if (/* #### Scaleable && */ DEVICE_MSPRINTER_P (d))
+    {
+      HDC printer_dc = DEVICE_MSPRINTER_HCDC (d);
+      HDC display_dc = CreateCompatibleDC (NULL);
+      IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
+       MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
+               GetDeviceCaps (printer_dc, LOGPIXELSX),
+               GetDeviceCaps (display_dc, LOGPIXELSX));
+      IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
+       MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
+               GetDeviceCaps (printer_dc, LOGPIXELSY),
+               GetDeviceCaps (display_dc, LOGPIXELSY));
+    }
+  else
+    {
+      IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
+       IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii);
+      IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
+       IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii);
+    }      
+}
+
 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
 
 /************************************************************************/
@@ -313,8 +349,7 @@ init_image_instance_from_dibitmap (Lisp_Image_Instance *ii,
                                   int x_hot, int y_hot,
                                   int create_mask)
 {
-  Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
-  struct device *d = XDEVICE (device);
+  struct device *d = XDEVICE (IMAGE_INSTANCE_DEVICE (ii));
   void* bmp_buf=0;
   enum image_instance_type type;
   HBITMAP bitmap;
@@ -350,11 +385,14 @@ init_image_instance_from_dibitmap (Lisp_Image_Instance *ii,
   IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
 
   IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
-  IMAGE_INSTANCE_PIXMAP_WIDTH (ii)   = bmp_info->bmiHeader.biWidth;
-  IMAGE_INSTANCE_PIXMAP_HEIGHT (ii)  = bmp_info->bmiHeader.biHeight;
+  IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) =
+    bmp_info->bmiHeader.biWidth;
+  IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) =
+    bmp_info->bmiHeader.biHeight;
   IMAGE_INSTANCE_PIXMAP_DEPTH (ii)   = bmp_info->bmiHeader.biBitCount;
   XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot);
   XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot);
+  init_image_instance_geometry (ii);
 
   if (create_mask)
     {
@@ -469,15 +507,15 @@ mswindows_initialize_image_instance_mask (Lisp_Image_Instance* image,
   BITMAPINFO *bmp_info =
     (BITMAPINFO*) xmalloc_and_zero (sizeof (BITMAPINFO) + sizeof (RGBQUAD));
   int i, j;
-  int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image);
+  int height = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (image);
 
-  int maskbpline = BPLINE ((IMAGE_INSTANCE_PIXMAP_WIDTH (image) + 7) / 8);
-  int bpline = BPLINE (IMAGE_INSTANCE_PIXMAP_WIDTH (image) * 3);
+  int maskbpline = BPLINE ((IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image) + 7) / 8);
+  int bpline = BPLINE (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image) * 3);
 
   if (!bmp_info)
     return;
 
-  bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
+  bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image);
   bmp_info->bmiHeader.biHeight = height;
   bmp_info->bmiHeader.biPlanes = 1;
   bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
@@ -509,10 +547,10 @@ mswindows_initialize_image_instance_mask (Lisp_Image_Instance* image,
   /* build up an in-memory set of bits to mess with */
   xzero (*bmp_info);
 
-  bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
+  bmp_info->bmiHeader.biWidth = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image);
   bmp_info->bmiHeader.biHeight = -height;
   bmp_info->bmiHeader.biPlanes = 1;
-  bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+  bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   bmp_info->bmiHeader.biBitCount = 24;
   bmp_info->bmiHeader.biCompression = BI_RGB;
   bmp_info->bmiHeader.biClrUsed = 0;
@@ -534,7 +572,7 @@ mswindows_initialize_image_instance_mask (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_MSWINDOWS_BITMAP_REAL_WIDTH (image); i++)
     {
       for (j=0; j<height; j++)
        {
@@ -627,8 +665,8 @@ mswindows_create_resized_bitmap (Lisp_Image_Instance* ii,
 {
   return create_resized_bitmap (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii),
                                f,
-                               IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
-                               IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
+                               IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
+                               IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
                                newx, newy);
 }
 
@@ -642,12 +680,14 @@ mswindows_create_resized_mask (Lisp_Image_Instance* ii,
 
   return create_resized_bitmap (IMAGE_INSTANCE_MSWINDOWS_MASK (ii),
                                f,
-                               IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
-                               IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
+                               IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
+                               IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
                                newx, newy);
 }
 
 #if 0 /* Currently unused */
+/* #### Warining: This function is not correct anymore with
+   resizable printer bitmaps.  If you uncomment it, clean it. --kkm */
 int
 mswindows_resize_dibitmap_instance (Lisp_Image_Instance* ii,
                                    struct frame* f,
@@ -1100,7 +1140,7 @@ typedef struct
 #define OIC_BANG            32515
 #define OIC_NOTE            32516
 #define OIC_WINLOGO         32517
-#if defined (__CYGWIN32__) && CYGWIN_VERSION_DLL_MAJOR < 21
+#if defined (CYGWIN) && CYGWIN_VERSION_DLL_MAJOR < 21
 #define LR_SHARED           0x8000
 #endif
 #endif
@@ -1249,7 +1289,7 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti
       TO_EXTERNAL_FORMAT (LISP_STRING, file,
                          C_STRING_ALLOCA, f,
                          Qfile_name);
-#ifdef __CYGWIN32__
+#ifdef CYGWIN
       CYGWIN_WIN32_PATH (f, fname);
 #else
       fname = f;
@@ -1289,11 +1329,12 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti
   mswindows_initialize_dibitmap_image_instance (ii, 1, iitype);
 
   IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
-  IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
+  IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) =
     GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
-  IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
+  IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) =
     GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
   IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
+  init_image_instance_geometry (ii);
 
   /* hey, we've got an icon type thing so we can reverse engineer the
      bitmap and mask */
@@ -1762,11 +1803,13 @@ init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii,
 
   IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
     find_keyword_in_vector (instantiator, Q_file);
-  IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
-  IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
+  IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) = width;
+  IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) = height;
   IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
   XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
   XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
+  init_image_instance_geometry (ii);
+
   IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask :
     xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
                                 TRUE, black, white);
@@ -2028,11 +2071,13 @@ extern int debug_widget_instances;
 static void
 mswindows_finalize_image_instance (Lisp_Image_Instance *p)
 {
-  if (DEVICE_LIVE_P (XDEVICE (p->device)))
+  if (!p->data)
+    return;
+
+  if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p))))
     {
-      if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET
-         ||
-         IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
+      if (image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (p))
+         & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
        {
 #ifdef DEBUG_WIDGETS
          debug_widget_instances--;
@@ -2095,6 +2140,14 @@ mswindows_widget_hfont (Lisp_Image_Instance *p,
   return mswindows_get_hfont (XFONT_INSTANCE (font), under, strike);
 }
 
+static HDWP
+begin_defer_window_pos (struct frame *f)
+{
+  if (FRAME_MSWINDOWS_DATA (f)->hdwp == 0)
+    FRAME_MSWINDOWS_DATA (f)->hdwp = BeginDeferWindowPos (10);
+  return FRAME_MSWINDOWS_DATA (f)->hdwp;
+}
+  
 /* unmap the image if it is a widget. This is used by redisplay via
    redisplay_unmap_subwindows */
 static void
@@ -2102,11 +2155,26 @@ mswindows_unmap_subwindow (Lisp_Image_Instance *p)
 {
   if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
     {
-      SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
-                   NULL,
-                   0, 0, 0, 0,
-                   SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE
-                   | SWP_NOSENDCHANGING);
+      struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
+      HDWP hdwp = begin_defer_window_pos (f);
+      HDWP new_hdwp;
+      new_hdwp = DeferWindowPos (hdwp, IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
+                                NULL,
+                                0, 0, 0, 0,
+                                SWP_HIDEWINDOW | SWP_NOACTIVATE |
+                                SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
+                                /* Setting this flag causes the call to
+                                   DeferWindowPos to fail with
+                                   "Invalid parameter".  I don't understand
+                                   why we bother to try and set this
+                                   anyway. -- ben */
+                                /* | SWP_NOSENDCHANGING */
+                                );
+      if (!new_hdwp)
+       mswindows_output_last_error ("unmapping");
+      else
+       hdwp = new_hdwp;
+      FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
       if (GetFocus() == WIDGET_INSTANCE_MSWINDOWS_HANDLE (p))
        SetFocus (GetParent (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p)));
     }
@@ -2118,6 +2186,9 @@ static void
 mswindows_map_subwindow (Lisp_Image_Instance *p, int x, int y,
                         struct display_glyph_area* dga)
 {
+  struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
+  HDWP hdwp = begin_defer_window_pos (f);
+  HDWP new_hdwp;
   /* move the window before mapping it ... */
   SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
                NULL,
@@ -2131,12 +2202,24 @@ mswindows_map_subwindow (Lisp_Image_Instance *p, int x, int y,
                SWP_NOZORDER | SWP_NOSIZE
                | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
   /* ... now map it - we are not allowed to move it at the same time. */
-  SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
-               NULL,
-               0, 0, 0, 0,
-               SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
-               | SWP_SHOWWINDOW | SWP_NOCOPYBITS
-               | SWP_NOSENDCHANGING);
+  new_hdwp = DeferWindowPos (hdwp, IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
+                            NULL,
+                            0, 0, 0, 0,
+                            SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
+                            | SWP_SHOWWINDOW
+                            /* | SWP_NOCOPYBITS */
+                            /* Setting this flag causes the call to
+                               DeferWindowPos to fail with
+                               "Invalid parameter".  I don't understand
+                               why we bother to try and set this
+                               anyway. -- ben */
+                            /* | SWP_NOSENDCHANGING */
+                            | SWP_NOACTIVATE);
+  if (!new_hdwp)
+    mswindows_output_last_error ("mapping");
+  else
+    hdwp = new_hdwp;
+  FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
 }
 
 /* resize the subwindow instance */
@@ -2144,11 +2227,12 @@ static void
 mswindows_resize_subwindow (Lisp_Image_Instance* ii, int w, int h)
 {
   /* Set the size of the control .... */
-  SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
-               NULL,
-               0, 0, w, h,
-               SWP_NOZORDER | SWP_NOMOVE
-               | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
+  if (!SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+                    NULL,
+                    0, 0, w, h,
+                    SWP_NOZORDER | SWP_NOMOVE
+                    | SWP_NOCOPYBITS | SWP_NOSENDCHANGING))
+    mswindows_output_last_error ("resizing");
 }
 
 /* Simply resize the window here. */
@@ -2166,13 +2250,16 @@ static void
 mswindows_update_widget (Lisp_Image_Instance *p)
 {
   /* Possibly update the face font and colors. */
-  if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p))
+  if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (p))
+      && (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
+         || XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed
+         || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)))
     {
       /* set the widget font from the widget face */
       SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
                   WM_SETFONT,
                   (WPARAM) mswindows_widget_hfont
-                  (p, IMAGE_INSTANCE_SUBWINDOW_FRAME (p)),
+                  (p, IMAGE_INSTANCE_FRAME (p)),
                   MAKELPARAM (TRUE, 0));
     }
   /* Possibly update the dimensions. */
@@ -2183,7 +2270,8 @@ mswindows_update_widget (Lisp_Image_Instance *p)
                                  IMAGE_INSTANCE_HEIGHT (p));
     }
   /* Possibly update the text in the widget. */
-  if (IMAGE_INSTANCE_TEXT_CHANGED (p))
+  if (IMAGE_INSTANCE_TEXT_CHANGED (p)
+      && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (p)))
     {
       Extbyte* lparam=0;
       TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (p),
@@ -2198,23 +2286,28 @@ mswindows_update_widget (Lisp_Image_Instance *p)
    callbacks. The hashtable is weak so deregistration is handled
    automatically */
 static int
-mswindows_register_gui_item (Lisp_Object gui, Lisp_Object domain)
+mswindows_register_gui_item (Lisp_Object image_instance,
+                            Lisp_Object gui, Lisp_Object domain)
 {
-  Lisp_Object frame = FW_FRAME (domain);
+  Lisp_Object frame = DOMAIN_FRAME (domain);
   struct frame* f = XFRAME (frame);
-  int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f),
+  int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f),
                             gui,
                             WIDGET_GLYPH_SLOT);
-  Fputhash (make_int (id),
-           XGUI_ITEM (gui)->callback,
-           FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f));
+  Fputhash (make_int (id), image_instance,
+           FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f));
+  Fputhash (make_int (id), XGUI_ITEM (gui)->callback,
+           FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f));
+  Fputhash (make_int (id), XGUI_ITEM (gui)->callback_ex,
+           FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f));
   return id;
 }
 
 static int
 mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
 {
-  return mswindows_register_gui_item (XIMAGE_INSTANCE_WIDGET_ITEM (instance),
+  return mswindows_register_gui_item (instance,
+                                     XIMAGE_INSTANCE_WIDGET_ITEM (instance),
                                      domain);
 }
 
@@ -2225,7 +2318,7 @@ mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instant
 {
   Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
-  Lisp_Object frame = FW_FRAME (domain);
+  Lisp_Object frame = DOMAIN_FRAME (domain);
   HWND wnd;
 
   CHECK_MSWINDOWS_DEVICE (device);
@@ -2347,7 +2440,7 @@ mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
   /* this function can call lisp */
   Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
-  Lisp_Object frame = FW_FRAME (domain);
+  Lisp_Object frame = DOMAIN_FRAME (domain);
   Extbyte* nm=0;
   HWND wnd;
   int id = 0xffff;
@@ -2361,7 +2454,7 @@ mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
 
   style = pgui->style;
 
-  if (!NILP (pgui->callback))
+  if (!NILP (pgui->callback) || !NILP (pgui->callback_ex))
     {
       id = mswindows_register_widget_instance (image_instance, domain);
     }
@@ -2385,7 +2478,7 @@ mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
                        IMAGE_INSTANCE_WIDGET_WIDTH (ii),
                        IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
                        /* parent window */
-                       FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
+                       DOMAIN_MSWINDOWS_HANDLE (domain),
                        (HMENU)id,       /* No menu */
                        NULL, /* must be null for this class */
                        NULL)) == NULL)
@@ -2415,9 +2508,32 @@ mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
   IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
   SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
   /* set the widget font from the widget face */
-  SendMessage (wnd, WM_SETFONT,
-              (WPARAM) mswindows_widget_hfont (ii, domain),
-              MAKELPARAM (TRUE, 0));
+  if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
+    SendMessage (wnd, WM_SETFONT,
+                (WPARAM) mswindows_widget_hfont (ii, domain),
+                MAKELPARAM (TRUE, 0));
+}
+
+/* Instantiate a native layout widget. */
+static void
+mswindows_native_layout_instantiate (Lisp_Object image_instance,
+                                    Lisp_Object instantiator,
+                                    Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+                                    int dest_mask, Lisp_Object domain)
+{
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+  mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+                               pointer_bg, dest_mask, domain, "STATIC", 
+                               /* Approximation to styles available with
+                                  an XEmacs layout. */
+                               EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
+                                   Qetched_in) ||
+                               EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
+                                   Qetched_out) ||
+                               GLYPHP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))
+                               ? SS_ETCHEDFRAME : SS_SUNKEN,
+                               0);
 }
 
 /* Instantiate a button widget. Unfortunately instantiated widgets are
@@ -2540,7 +2656,7 @@ mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object in
                         (XCOLOR_INSTANCE
                          (FACE_BACKGROUND
                           (XIMAGE_INSTANCE_WIDGET_FACE (ii),
-                           XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
+                           XIMAGE_INSTANCE_FRAME (ii))))));
 #endif
 #ifdef PBS_SETBARCOLOR
   SendMessage (wnd, PBS_SETBARCOLOR, 0,
@@ -2548,7 +2664,7 @@ mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object in
                          (XCOLOR_INSTANCE
                           (FACE_FOREGROUND
                            (XIMAGE_INSTANCE_WIDGET_FACE (ii),
-                            XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
+                            XIMAGE_INSTANCE_FRAME (ii))))));
 #endif
 }
 
@@ -2567,7 +2683,8 @@ static HTREEITEM add_tree_item (Lisp_Object image_instance,
 
   if (GUI_ITEMP (item))
     {
-      tvitem.item.lParam = mswindows_register_gui_item (item, domain);
+      tvitem.item.lParam = mswindows_register_gui_item (image_instance,
+                                                       item, domain);
       tvitem.item.mask |= TVIF_PARAM;
       TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
                          C_STRING_ALLOCA, tvitem.item.pszText,
@@ -2649,7 +2766,8 @@ static TC_ITEM* add_tab_item (Lisp_Object image_instance,
 
   if (GUI_ITEMP (item))
     {
-      tvitem.lParam = mswindows_register_gui_item (item, domain);
+      tvitem.lParam = mswindows_register_gui_item (image_instance,
+                                                  item, domain);
       tvitem.mask |= TCIF_PARAM;
       TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
                          C_STRING_ALLOCA, tvitem.pszText,
@@ -2726,16 +2844,11 @@ mswindows_tab_control_update (Lisp_Object image_instance)
       /* delete the pre-existing items */
       SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0);
 
-      /* Pick up the items we recorded earlier. We do this here so
-         that the callbacks get set up with the new items. */
-      IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
-       IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii);
-      IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
       /* add items to the tab */
-      LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
+      LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
        {
          add_tab_item (image_instance, wnd, XCAR (rest),
-                       IMAGE_INSTANCE_SUBWINDOW_FRAME (ii), i);
+                       IMAGE_INSTANCE_FRAME (ii), i);
          if (gui_item_selected_p (XCAR (rest)))
            selected = i;
          i++;
@@ -2881,11 +2994,18 @@ mswindows_progress_gauge_update (Lisp_Object image_instance)
 {
   Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   
-  if (IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii))
+  if (IMAGE_INSTANCE_WIDGET_ITEMS_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);
+      Lisp_Object val;
+#ifdef ERROR_CHECK_GLYPHS
+      assert (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
+#endif
+      val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value;
+#ifdef DEBUG_WIDGET_OUTPUT     
+      printf ("progress gauge displayed value on %p updated to %ld\n",
+             WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+             XINT(val));
+#endif
       CHECK_INT (val);
       SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
                   PBM_SETPOS, (WPARAM)XINT (val), 0);
@@ -2956,7 +3076,6 @@ image_instantiator_format_create_glyphs_mswindows (void)
 {
   IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, nothing);
   IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, string);
-  IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, layout);
   IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, formatted_string);
   IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, inherit);
   /* image-instantiator types */
@@ -2989,44 +3108,41 @@ image_instantiator_format_create_glyphs_mswindows (void)
   IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, gif);
 #endif
 #ifdef HAVE_WIDGETS
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
+  /* layout widget */
+  IIFORMAT_VALID_CONSOLE (mswindows, layout);
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, native_layout);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, native_layout, instantiate);
   /* button widget */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
   IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
   IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
   IIFORMAT_HAS_DEVMETHOD (mswindows, button, update);
-
+  /* edit-field widget */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field);
   IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate);
-
+  /* subwindow */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow);
   IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate);
-
-  INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
-  IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
-
   /* label */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
   IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
-
   /* combo box */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, combo_box);
   IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, property);
   IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, instantiate);
-
   /* scrollbar */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
   IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
-
   /* progress gauge */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge);
   IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, update);
   IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate);
-
   /* tree view widget */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view);
   /*  IIFORMAT_HAS_DEVMETHOD (mswindows, progress, set_property);*/
   IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate);
-
   /* tab control widget */
   INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control);
   IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate);