XEmacs 21.2.36 "Notos"
[chise/xemacs-chise.git.1] / src / glyphs-x.c
index 5b35f11..9ce627b 100644 (file)
@@ -4,6 +4,7 @@
    Copyright (C) 1995 Tinker Systems
    Copyright (C) 1995, 1996 Ben Wing
    Copyright (C) 1995 Sun Microsystems
    Copyright (C) 1995 Tinker Systems
    Copyright (C) 1995, 1996 Ben Wing
    Copyright (C) 1995 Sun Microsystems
+   Copyright (C) 1999, 2000 Andy Piper
 
 This file is part of XEmacs.
 
 
 This file is part of XEmacs.
 
@@ -16,7 +17,6 @@ XEmacs is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
-
 You should have received a copy of the GNU General Public License
 along with XEmacs; see the file COPYING.  If not, write to
 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 You should have received a copy of the GNU General Public License
 along with XEmacs; see the file COPYING.  If not, write to
 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
@@ -24,6 +24,8 @@ Boston, MA 02111-1307, USA.  */
 
 /* Synched up with: Not in FSF. */
 
 
 /* Synched up with: Not in FSF. */
 
+/* 7-8-00 This file is more or less Mule-ized in my Mule workspace. */
+
 /* Original author: Jamie Zawinski for 19.8
    font-truename stuff added by Jamie Zawinski for 19.10
    subwindow support added by Chuck Thompson
 /* Original author: Jamie Zawinski for 19.8
    font-truename stuff added by Jamie Zawinski for 19.10
    subwindow support added by Chuck Thompson
@@ -39,8 +41,11 @@ Boston, MA 02111-1307, USA.  */
    Many changes for color work and optimizations by Jareth Hein for 21.0
    Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0
    TIFF code by Jareth Hein for 21.0
    Many changes for color work and optimizations by Jareth Hein for 21.0
    Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0
    TIFF code by Jareth Hein for 21.0
+   GIF/JPEG/PNG/TIFF code moved to new glyph-eimage.c by Andy Piper for 21.0
+   Subwindow and Widget support by Andy Piper for 21.2
 
    TODO:
 
    TODO:
+   Support the GrayScale, StaticColor and StaticGray visual classes.
    Convert images.el to C and stick it in here?
  */
 
    Convert images.el to C and stick it in here?
  */
 
@@ -50,12 +55,18 @@ Boston, MA 02111-1307, USA.  */
 #include "console-x.h"
 #include "glyphs-x.h"
 #include "objects-x.h"
 #include "console-x.h"
 #include "glyphs-x.h"
 #include "objects-x.h"
+#ifdef HAVE_WIDGETS
+#include "gui-x.h"
+#endif
 #include "xmu.h"
 
 #include "buffer.h"
 #include "xmu.h"
 
 #include "buffer.h"
+#include "window.h"
 #include "frame.h"
 #include "insdel.h"
 #include "opaque.h"
 #include "frame.h"
 #include "insdel.h"
 #include "opaque.h"
+#include "gui.h"
+#include "faces.h"
 
 #include "imgproc.h"
 
 
 #include "imgproc.h"
 
@@ -67,6 +78,11 @@ Boston, MA 02111-1307, USA.  */
 #include "file-coding.h"
 #endif
 
 #include "file-coding.h"
 #endif
 
+#ifdef LWLIB_WIDGETS_MOTIF
+#include <Xm/Xm.h>
+#endif
+#include <X11/IntrinsicP.h>
+
 #if INTBITS == 32
 # define FOUR_BYTE_TYPE unsigned int
 #elif LONGBITS == 32
 #if INTBITS == 32
 # define FOUR_BYTE_TYPE unsigned int
 #elif LONGBITS == 32
@@ -79,9 +95,29 @@ Boston, MA 02111-1307, USA.  */
 
 #define LISP_DEVICE_TO_X_SCREEN(dev) XDefaultScreenOfDisplay (DEVICE_X_DISPLAY (XDEVICE (dev)))
 
 
 #define LISP_DEVICE_TO_X_SCREEN(dev) XDefaultScreenOfDisplay (DEVICE_X_DISPLAY (XDEVICE (dev)))
 
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing);
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (string);
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit);
+#ifdef HAVE_JPEG
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
+#endif
+#ifdef HAVE_TIFF
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff);
+#endif
+#ifdef HAVE_PNG
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (png);
+#endif
+#ifdef HAVE_GIF
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif);
+#endif
+#ifdef HAVE_XPM
+DEFINE_DEVICE_IIFORMAT (x, xpm);
+#endif
+DEFINE_DEVICE_IIFORMAT (x, xbm);
+DEFINE_DEVICE_IIFORMAT (x, subwindow);
 #ifdef HAVE_XFACE
 #ifdef HAVE_XFACE
-DEFINE_IMAGE_INSTANTIATOR_FORMAT (xface);
-Lisp_Object Qxface;
+DEFINE_DEVICE_IIFORMAT (x, xface);
 #endif
 
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font);
 #endif
 
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font);
@@ -91,6 +127,20 @@ DEFINE_IMAGE_INSTANTIATOR_FORMAT (font);
 
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (autodetect);
 
 
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (autodetect);
 
+#ifdef HAVE_WIDGETS
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
+DEFINE_DEVICE_IIFORMAT (x, widget);
+DEFINE_DEVICE_IIFORMAT (x, native_layout);
+DEFINE_DEVICE_IIFORMAT (x, button);
+DEFINE_DEVICE_IIFORMAT (x, progress_gauge);
+DEFINE_DEVICE_IIFORMAT (x, edit_field);
+#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
+DEFINE_DEVICE_IIFORMAT (x, combo_box);
+#endif
+DEFINE_DEVICE_IIFORMAT (x, tab_control);
+DEFINE_DEVICE_IIFORMAT (x, label);
+#endif
+
 static void cursor_font_instantiate (Lisp_Object image_instance,
                                     Lisp_Object instantiator,
                                     Lisp_Object pointer_fg,
 static void cursor_font_instantiate (Lisp_Object image_instance,
                                     Lisp_Object instantiator,
                                     Lisp_Object pointer_fg,
@@ -98,6 +148,15 @@ static void cursor_font_instantiate (Lisp_Object image_instance,
                                     int dest_mask,
                                     Lisp_Object domain);
 
                                     int dest_mask,
                                     Lisp_Object domain);
 
+#ifdef HAVE_WIDGETS
+static void
+update_widget_face (widget_value* wv,
+                   Lisp_Image_Instance* ii, Lisp_Object domain);
+static void
+update_tab_widget_face (widget_value* wv,
+                       Lisp_Image_Instance* ii, Lisp_Object domain);
+#endif
+
 #include "bitmaps.h"
 
 \f
 #include "bitmaps.h"
 
 \f
@@ -118,10 +177,10 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height,
   Colormap cmap;
   Visual *vis;
   XImage *outimg;
   Colormap cmap;
   Visual *vis;
   XImage *outimg;
-  int depth, bitmap_pad, byte_cnt, i, j;
+  int depth, bitmap_pad, bits_per_pixel, byte_cnt, i, j;
   int rd,gr,bl,q;
   unsigned char *data, *ip, *dp;
   int rd,gr,bl,q;
   unsigned char *data, *ip, *dp;
-  quant_table *qtable;
+  quant_table *qtable = 0;
   union {
     FOUR_BYTE_TYPE val;
     char cp[4];
   union {
     FOUR_BYTE_TYPE val;
     char cp[4];
@@ -132,6 +191,13 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height,
   vis = DEVICE_X_VISUAL (XDEVICE(device));
   depth = DEVICE_X_DEPTH(XDEVICE(device));
 
   vis = DEVICE_X_VISUAL (XDEVICE(device));
   depth = DEVICE_X_DEPTH(XDEVICE(device));
 
+  if (vis->class == GrayScale || vis->class == StaticColor ||
+      vis->class == StaticGray)
+    {
+      /* #### Implement me!!! */
+      return NULL;
+    }
+
   if (vis->class == PseudoColor)
     {
       /* Quantize the image and get a histogram while we're at it.
   if (vis->class == PseudoColor)
     {
       /* Quantize the image and get a histogram while we're at it.
@@ -143,13 +209,15 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height,
   bitmap_pad = ((depth > 16) ? 32 :
                (depth >  8) ? 16 :
                8);
   bitmap_pad = ((depth > 16) ? 32 :
                (depth >  8) ? 16 :
                8);
-  byte_cnt = bitmap_pad >> 3;
-  
+
   outimg = XCreateImage (dpy, vis,
                         depth, ZPixmap, 0, 0, width, height,
                         bitmap_pad, 0);
   if (!outimg) return NULL;
 
   outimg = XCreateImage (dpy, vis,
                         depth, ZPixmap, 0, 0, width, height,
                         bitmap_pad, 0);
   if (!outimg) return NULL;
 
+  bits_per_pixel = outimg->bits_per_pixel;
+  byte_cnt = bits_per_pixel >> 3;
+
   data = (unsigned char *) xmalloc (outimg->bytes_per_line * height);
   if (!data)
     {
   data = (unsigned char *) xmalloc (outimg->bytes_per_line * height);
   if (!data)
     {
@@ -157,7 +225,7 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height,
       return NULL;
     }
   outimg->data = (char *) data;
       return NULL;
     }
   outimg->data = (char *) data;
-  
+
   if (vis->class == PseudoColor)
     {
       unsigned long pixarray[256];
   if (vis->class == PseudoColor)
     {
       unsigned long pixarray[256];
@@ -167,13 +235,13 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height,
       *pixtbl = xnew_array (unsigned long, pixcount);
       *npixels = 0;
 
       *pixtbl = xnew_array (unsigned long, pixcount);
       *npixels = 0;
 
-      /* ### should implement a sort by popularity to assure proper allocation */
+      /* #### should implement a sort by popularity to assure proper allocation */
       n = *npixels;
       for (i = 0; i < qtable->num_active_colors; i++)
        {
          XColor color;
          int res;
       n = *npixels;
       for (i = 0; i < qtable->num_active_colors; i++)
        {
          XColor color;
          int res;
-       
+
          color.red = qtable->rm[i] ? qtable->rm[i] << 8 : 0;
          color.green = qtable->gm[i] ? qtable->gm[i] << 8 : 0;
          color.blue = qtable->bm[i] ? qtable->bm[i] << 8 : 0;
          color.red = qtable->rm[i] ? qtable->rm[i] << 8 : 0;
          color.green = qtable->gm[i] ? qtable->gm[i] << 8 : 0;
          color.blue = qtable->bm[i] ? qtable->bm[i] << 8 : 0;
@@ -198,7 +266,7 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height,
              gr = *ip++;
              bl = *ip++;
              conv.val = pixarray[QUANT_GET_COLOR(qtable,rd,gr,bl)];
              gr = *ip++;
              bl = *ip++;
              conv.val = pixarray[QUANT_GET_COLOR(qtable,rd,gr,bl)];
-#if WORDS_BIGENDIAN
+#ifdef WORDS_BIGENDIAN
              if (outimg->byte_order == MSBFirst)
                for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q];
              else
              if (outimg->byte_order == MSBFirst)
                for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q];
              else
@@ -273,7 +341,7 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height,
                bl = *ip++ >> (8 - bbits);
 
              conv.val = (rd << rshift) | (gr << gshift) | (bl << bshift);
                bl = *ip++ >> (8 - bbits);
 
              conv.val = (rd << rshift) | (gr << gshift) | (bl << bshift);
-#if WORDS_BIGENDIAN
+#ifdef WORDS_BIGENDIAN
              if (outimg->byte_order == MSBFirst)
                for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q];
              else
              if (outimg->byte_order == MSBFirst)
                for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q];
              else
@@ -286,14 +354,14 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height,
 #endif
            }
        }
 #endif
            }
        }
-    }  
+    }
   return outimg;
 }
 
 
 
 static void
   return outimg;
 }
 
 
 
 static void
-x_print_image_instance (struct Lisp_Image_Instance *p,
+x_print_image_instance (Lisp_Image_Instance *p,
                        Lisp_Object printcharfun,
                        int escapeflag)
 {
                        Lisp_Object printcharfun,
                        int escapeflag)
 {
@@ -313,49 +381,99 @@ x_print_image_instance (struct Lisp_Image_Instance *p,
        }
       write_c_string (")", printcharfun);
       break;
        }
       write_c_string (")", printcharfun);
       break;
-#if HAVE_SUBWINDOWS
-    case IMAGE_SUBWINDOW:
-      /* #### implement me */
-#endif
     default:
       break;
     }
 }
 
     default:
       break;
     }
 }
 
+#ifdef DEBUG_WIDGETS
+extern int debug_widget_instances;
+#endif
+
 static void
 static void
-x_finalize_image_instance (struct Lisp_Image_Instance *p)
+x_finalize_image_instance (Lisp_Image_Instance *p)
 {
   if (!p->data)
     return;
 
 {
   if (!p->data)
     return;
 
-  if (DEVICE_LIVE_P (XDEVICE (p->device)))
+  if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p))))
     {
     {
-      Display *dpy = DEVICE_X_DISPLAY (XDEVICE (p->device));
+      Display *dpy = DEVICE_X_DISPLAY
+       (XDEVICE (IMAGE_INSTANCE_DEVICE (p)));
+      if (0)
+       ;
+#ifdef HAVE_WIDGETS
+      else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET)
+       {
+         if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
+           {
+#ifdef DEBUG_WIDGETS
+             debug_widget_instances--;
+             stderr_out ("widget destroyed, %d left\n", debug_widget_instances);
+#endif
+             lw_destroy_widget (IMAGE_INSTANCE_X_WIDGET_ID (p));
+             lw_destroy_widget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
 
 
-      if (IMAGE_INSTANCE_X_PIXMAP (p))
-       XFreePixmap (dpy, IMAGE_INSTANCE_X_PIXMAP (p));
-      if (IMAGE_INSTANCE_X_MASK (p) &&
-         IMAGE_INSTANCE_X_MASK (p) != IMAGE_INSTANCE_X_PIXMAP (p))
-       XFreePixmap (dpy, IMAGE_INSTANCE_X_MASK (p));
-      IMAGE_INSTANCE_X_PIXMAP (p) = 0;
-      IMAGE_INSTANCE_X_MASK (p) = 0;
+             /* We can release the callbacks again. */
+             ungcpro_popup_callbacks (IMAGE_INSTANCE_X_WIDGET_LWID (p));
 
 
-      if (IMAGE_INSTANCE_X_CURSOR (p))
+             IMAGE_INSTANCE_X_WIDGET_ID (p) = 0;
+             IMAGE_INSTANCE_X_CLIPWIDGET (p) = 0;
+           }
+       }
+#endif
+      else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
        {
        {
-         XFreeCursor (dpy, IMAGE_INSTANCE_X_CURSOR (p));
-         IMAGE_INSTANCE_X_CURSOR (p) = 0;
+         if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
+           XDestroyWindow (dpy, IMAGE_INSTANCE_X_SUBWINDOW_ID (p));
+         IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
        }
        }
-
-      if (IMAGE_INSTANCE_X_NPIXELS (p) != 0)
+      else
        {
        {
-         XFreeColors (dpy,
-                      IMAGE_INSTANCE_X_COLORMAP (p),
-                      IMAGE_INSTANCE_X_PIXELS (p),
-                      IMAGE_INSTANCE_X_NPIXELS (p), 0);
-         IMAGE_INSTANCE_X_NPIXELS (p) = 0;
+         int i;
+         if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
+           disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
+
+         if (IMAGE_INSTANCE_X_MASK (p) &&
+             IMAGE_INSTANCE_X_MASK (p) != IMAGE_INSTANCE_X_PIXMAP (p))
+           XFreePixmap (dpy, IMAGE_INSTANCE_X_MASK (p));
+         IMAGE_INSTANCE_PIXMAP_MASK (p) = 0;
+
+         if (IMAGE_INSTANCE_X_PIXMAP_SLICES (p))
+           {
+             for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++)
+               if (IMAGE_INSTANCE_X_PIXMAP_SLICE (p,i))
+                 {
+                   XFreePixmap (dpy, IMAGE_INSTANCE_X_PIXMAP_SLICE (p,i));
+                   IMAGE_INSTANCE_X_PIXMAP_SLICE (p, i) = 0;
+                 }
+             xfree (IMAGE_INSTANCE_X_PIXMAP_SLICES (p));
+             IMAGE_INSTANCE_X_PIXMAP_SLICES (p) = 0;
+           }
+
+         if (IMAGE_INSTANCE_X_CURSOR (p))
+           {
+             XFreeCursor (dpy, IMAGE_INSTANCE_X_CURSOR (p));
+             IMAGE_INSTANCE_X_CURSOR (p) = 0;
+           }
+
+         if (IMAGE_INSTANCE_X_NPIXELS (p) != 0)
+           {
+             XFreeColors (dpy,
+                          IMAGE_INSTANCE_X_COLORMAP (p),
+                          IMAGE_INSTANCE_X_PIXELS (p),
+                          IMAGE_INSTANCE_X_NPIXELS (p), 0);
+             IMAGE_INSTANCE_X_NPIXELS (p) = 0;
+           }
        }
     }
        }
     }
-  if (IMAGE_INSTANCE_X_PIXELS (p))
+  /* You can sometimes have pixels without a live device. I forget
+     why, but that's why we free them here if we have a pixmap type
+     image instance. It probably means that we might also get a memory
+     leak with widgets. */
+  if (IMAGE_INSTANCE_TYPE (p) != IMAGE_WIDGET
+      && IMAGE_INSTANCE_TYPE (p) != IMAGE_SUBWINDOW
+      && IMAGE_INSTANCE_X_PIXELS (p))
     {
       xfree (IMAGE_INSTANCE_X_PIXELS (p));
       IMAGE_INSTANCE_X_PIXELS (p) = 0;
     {
       xfree (IMAGE_INSTANCE_X_PIXELS (p));
       IMAGE_INSTANCE_X_PIXELS (p) = 0;
@@ -366,8 +484,8 @@ x_finalize_image_instance (struct Lisp_Image_Instance *p)
 }
 
 static int
 }
 
 static int
-x_image_instance_equal (struct Lisp_Image_Instance *p1,
-                       struct Lisp_Image_Instance *p2, int depth)
+x_image_instance_equal (Lisp_Image_Instance *p1,
+                       Lisp_Image_Instance *p2, int depth)
 {
   switch (IMAGE_INSTANCE_TYPE (p1))
     {
 {
   switch (IMAGE_INSTANCE_TYPE (p1))
     {
@@ -377,10 +495,6 @@ x_image_instance_equal (struct Lisp_Image_Instance *p1,
       if (IMAGE_INSTANCE_X_COLORMAP (p1) != IMAGE_INSTANCE_X_COLORMAP (p2) ||
          IMAGE_INSTANCE_X_NPIXELS (p1) != IMAGE_INSTANCE_X_NPIXELS (p2))
        return 0;
       if (IMAGE_INSTANCE_X_COLORMAP (p1) != IMAGE_INSTANCE_X_COLORMAP (p2) ||
          IMAGE_INSTANCE_X_NPIXELS (p1) != IMAGE_INSTANCE_X_NPIXELS (p2))
        return 0;
-#if HAVE_SUBWINDOWS
-    case IMAGE_SUBWINDOW:
-      /* #### implement me */
-#endif
       break;
     default:
       break;
       break;
     default:
       break;
@@ -390,7 +504,7 @@ x_image_instance_equal (struct Lisp_Image_Instance *p1,
 }
 
 static unsigned long
 }
 
 static unsigned long
-x_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
+x_image_instance_hash (Lisp_Image_Instance *p, int depth)
 {
   switch (IMAGE_INSTANCE_TYPE (p))
     {
 {
   switch (IMAGE_INSTANCE_TYPE (p))
     {
@@ -398,11 +512,6 @@ x_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
     case IMAGE_COLOR_PIXMAP:
     case IMAGE_POINTER:
       return IMAGE_INSTANCE_X_NPIXELS (p);
     case IMAGE_COLOR_PIXMAP:
     case IMAGE_POINTER:
       return IMAGE_INSTANCE_X_NPIXELS (p);
-#if HAVE_SUBWINDOWS
-    case IMAGE_SUBWINDOW:
-      /* #### implement me */
-      return 0;
-#endif
     default:
       return 0;
     }
     default:
       return 0;
     }
@@ -415,10 +524,14 @@ x_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
    methods are called. */
 
 static void
    methods are called. */
 
 static void
-x_initialize_pixmap_image_instance (struct Lisp_Image_Instance *ii,
+x_initialize_pixmap_image_instance (Lisp_Image_Instance *ii,
+                                   int slices,
                                    enum image_instance_type type)
 {
   ii->data = xnew_and_zero (struct x_image_instance_data);
                                    enum image_instance_type type)
 {
   ii->data = xnew_and_zero (struct x_image_instance_data);
+  IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices;
+  IMAGE_INSTANCE_X_PIXMAP_SLICES (ii) =
+    xnew_array_and_zero (Pixmap, slices);
   IMAGE_INSTANCE_TYPE (ii) = type;
   IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
   IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
   IMAGE_INSTANCE_TYPE (ii) = type;
   IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
   IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
@@ -462,13 +575,13 @@ x_locate_pixmap_file (Lisp_Object name)
         (XSTRING_BYTE (name, 2) == '/')))))
     {
       if (!NILP (Ffile_readable_p (name)))
         (XSTRING_BYTE (name, 2) == '/')))))
     {
       if (!NILP (Ffile_readable_p (name)))
-       return name;
+       return Fexpand_file_name (name, Qnil);
       else
        return Qnil;
     }
 
   if (NILP (Vdefault_x_device))
       else
        return Qnil;
     }
 
   if (NILP (Vdefault_x_device))
-    /* This may occur during intialization. */
+    /* This may occur during initialization. */
     return Qnil;
   else
     /* We only check the bitmapFilePath resource on the original X device. */
     return Qnil;
   else
     /* We only check the bitmapFilePath resource on the original X device. */
@@ -507,13 +620,13 @@ x_locate_pixmap_file (Lisp_Object name)
 
   {
     Lisp_Object found;
 
   {
     Lisp_Object found;
-    if (locate_file (Vx_bitmap_file_path, name, "", &found, R_OK) < 0)
+    if (locate_file (Vx_bitmap_file_path, name, Qnil, &found, R_OK) < 0)
       {
        Lisp_Object temp = list1 (Vdata_directory);
        struct gcpro gcpro1;
 
        GCPRO1 (temp);
       {
        Lisp_Object temp = list1 (Vdata_directory);
        struct gcpro gcpro1;
 
        GCPRO1 (temp);
-       locate_file (temp, name, "", &found, R_OK);
+       locate_file (temp, name, Qnil, &found, R_OK);
        UNGCPRO;
       }
 
        UNGCPRO;
       }
 
@@ -588,7 +701,7 @@ write_lisp_string_to_temp_file (Lisp_Object string, char *filename_out)
   /* Get the data while doing the conversion */
   while (1)
     {
   /* Get the data while doing the conversion */
   while (1)
     {
-      int size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
+      ssize_t size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
       if (!size_in_bytes)
        break;
       /* It does seem the flushes are necessary... */
       if (!size_in_bytes)
        break;
       /* It does seem the flushes are necessary... */
@@ -608,7 +721,7 @@ write_lisp_string_to_temp_file (Lisp_Object string, char *filename_out)
       /* reset the dynarr */
       Lstream_rewind(ostr);
     }
       /* reset the dynarr */
       Lstream_rewind(ostr);
     }
-  
+
   if (fclose (tmpfil) != 0)
     fubar = 1;
   Lstream_close (istr);
   if (fclose (tmpfil) != 0)
     fubar = 1;
   Lstream_close (istr);
@@ -731,12 +844,13 @@ maybe_recolor_cursor (Lisp_Object image_instance, Lisp_Object foreground,
    Use the same code as for `xpm'. */
 
 static void
    Use the same code as for `xpm'. */
 
 static void
-init_image_instance_from_x_image (struct Lisp_Image_Instance *ii,
+init_image_instance_from_x_image (Lisp_Image_Instance *ii,
                                  XImage *ximage,
                                  int dest_mask,
                                  Colormap cmap,
                                  unsigned long *pixels,
                                  int npixels,
                                  XImage *ximage,
                                  int dest_mask,
                                  Colormap cmap,
                                  unsigned long *pixels,
                                  int npixels,
+                                 int slices,
                                  Lisp_Object instantiator)
 {
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
                                  Lisp_Object instantiator)
 {
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
@@ -772,13 +886,15 @@ init_image_instance_from_x_image (struct Lisp_Image_Instance *ii,
 
   XFreeGC (dpy, gc);
 
 
   XFreeGC (dpy, gc);
 
-  x_initialize_pixmap_image_instance (ii, IMAGE_COLOR_PIXMAP);
+  x_initialize_pixmap_image_instance (ii, slices, IMAGE_COLOR_PIXMAP);
 
   IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
     find_keyword_in_vector (instantiator, Q_file);
 
 
   IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
     find_keyword_in_vector (instantiator, Q_file);
 
+  /* Fixup a set of pixmaps. */
   IMAGE_INSTANCE_X_PIXMAP (ii) = pixmap;
   IMAGE_INSTANCE_X_PIXMAP (ii) = pixmap;
-  IMAGE_INSTANCE_X_MASK (ii) = 0;
+
+  IMAGE_INSTANCE_PIXMAP_MASK (ii) = 0;
   IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = ximage->width;
   IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = ximage->height;
   IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = ximage->depth;
   IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = ximage->width;
   IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = ximage->height;
   IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = ximage->depth;
@@ -788,9 +904,45 @@ init_image_instance_from_x_image (struct Lisp_Image_Instance *ii,
 }
 
 static void
 }
 
 static void
-x_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
+image_instance_add_x_image (Lisp_Image_Instance *ii,
+                           XImage *ximage,
+                           int slice,
+                           Lisp_Object instantiator)
+{
+  Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+  Display *dpy;
+  GC gc;
+  Drawable d;
+  Pixmap pixmap;
+
+  dpy = DEVICE_X_DISPLAY (XDEVICE (device));
+  d = XtWindow(DEVICE_XT_APP_SHELL (XDEVICE (device)));
+
+  pixmap = XCreatePixmap (dpy, d, ximage->width,
+                         ximage->height, ximage->depth);
+  if (!pixmap)
+    signal_simple_error ("Unable to create pixmap", instantiator);
+
+  gc = XCreateGC (dpy, pixmap, 0, NULL);
+  if (!gc)
+    {
+      XFreePixmap (dpy, pixmap);
+      signal_simple_error ("Unable to create GC", instantiator);
+    }
+
+  XPutImage (dpy, pixmap, gc, ximage, 0, 0, 0, 0,
+            ximage->width, ximage->height);
+
+  XFreeGC (dpy, gc);
+
+  IMAGE_INSTANCE_X_PIXMAP_SLICE (ii, slice) = pixmap;
+}
+
+static void
+x_init_image_instance_from_eimage (Lisp_Image_Instance *ii,
                                   int width, int height,
                                   int width, int height,
-                                  unsigned char *eimage, 
+                                  int slices,
+                                  unsigned char *eimage,
                                   int dest_mask,
                                   Lisp_Object instantiator,
                                   Lisp_Object domain)
                                   int dest_mask,
                                   Lisp_Object instantiator,
                                   Lisp_Object domain)
@@ -799,37 +951,46 @@ x_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
   Colormap cmap = DEVICE_X_COLORMAP (XDEVICE(device));
   unsigned long *pixtbl = NULL;
   int npixels = 0;
   Colormap cmap = DEVICE_X_COLORMAP (XDEVICE(device));
   unsigned long *pixtbl = NULL;
   int npixels = 0;
+  int slice;
   XImage* ximage;
   XImage* ximage;
-  
-  ximage = convert_EImage_to_XImage (device, width, height, eimage,
-                                    &pixtbl, &npixels);
-  if (!ximage)
-    {
-      if (pixtbl) xfree (pixtbl);
-      signal_image_error("EImage to XImage conversion failed", instantiator);
-    }
-  
-  /* Now create the pixmap and set up the image instance */
-  init_image_instance_from_x_image (ii, ximage, dest_mask,
-                                   cmap, pixtbl, npixels,
-                                   instantiator);
 
 
-  if (ximage)
+  for (slice = 0; slice < slices; slice++)
     {
     {
-      if (ximage->data)
-        {
-         xfree (ximage->data);
-          ximage->data = 0;
-        }
-      XDestroyImage (ximage);
+      ximage = convert_EImage_to_XImage (device, width, height,
+                                        eimage + (width * height * 3 * slice),
+                                        &pixtbl, &npixels);
+      if (!ximage)
+       {
+         if (pixtbl) xfree (pixtbl);
+         signal_image_error("EImage to XImage conversion failed", instantiator);
+       }
+
+      /* Now create the pixmap and set up the image instance */
+      if (slice == 0)
+       init_image_instance_from_x_image (ii, ximage, dest_mask,
+                                         cmap, pixtbl, npixels, slices,
+                                         instantiator);
+      else
+       image_instance_add_x_image (ii, ximage, slice, instantiator);
+
+      if (ximage)
+       {
+         if (ximage->data)
+           {
+             xfree (ximage->data);
+             ximage->data = 0;
+           }
+         XDestroyImage (ximage);
+         ximage = 0;
+       }
     }
 }
 
     }
 }
 
-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)
 {
                                unsigned int *height, unsigned char **datap,
                                int *x_hot, int *y_hot)
 {
-  return XmuReadBitmapDataFromFile (filename, width, height, 
+  return XmuReadBitmapDataFromFile (filename, width, height,
                                    datap, x_hot, y_hot);
 }
 
                                    datap, x_hot, y_hot);
 }
 
@@ -839,7 +1000,7 @@ int read_bitmap_data_from_file (CONST char *filename, unsigned int *width,
 static Pixmap
 pixmap_from_xbm_inline (Lisp_Object device, int width, int height,
                        /* Note that data is in ext-format! */
 static Pixmap
 pixmap_from_xbm_inline (Lisp_Object device, int width, int height,
                        /* Note that data is in ext-format! */
-                       CONST Extbyte *bits)
+                       const Extbyte *bits)
 {
   return XCreatePixmapFromBitmapData (DEVICE_X_DISPLAY (XDEVICE(device)),
                                      XtWindow (DEVICE_XT_APP_SHELL (XDEVICE (device))),
 {
   return XCreatePixmapFromBitmapData (DEVICE_X_DISPLAY (XDEVICE(device)),
                                      XtWindow (DEVICE_XT_APP_SHELL (XDEVICE (device))),
@@ -851,10 +1012,10 @@ pixmap_from_xbm_inline (Lisp_Object device, int width, int height,
    image instance accordingly. */
 
 static void
    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! */
                                     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,
                                     Lisp_Object instantiator,
                                     Lisp_Object pointer_fg,
                                     Lisp_Object pointer_bg,
@@ -896,7 +1057,7 @@ init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii,
                              IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
                              | IMAGE_POINTER_MASK);
 
                              IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
                              | IMAGE_POINTER_MASK);
 
-  x_initialize_pixmap_image_instance (ii, type);
+  x_initialize_pixmap_image_instance (ii, 1, type);
   IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
   IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
   IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
   IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
   IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
   IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
@@ -992,24 +1153,22 @@ 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! */
                   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);
 {
   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);
   Pixmap mask = 0;
   Pixmap mask = 0;
-  CONST char *gcc_may_you_rot_in_hell;
 
   if (!NILP (mask_data))
     {
 
   if (!NILP (mask_data))
     {
-      GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (mask_data))),
-                                      gcc_may_you_rot_in_hell);
-      mask =
-       pixmap_from_xbm_inline (IMAGE_INSTANCE_DEVICE (ii),
-                               XINT (XCAR (mask_data)),
-                               XINT (XCAR (XCDR (mask_data))),
-                               (CONST unsigned char *)
-                               gcc_may_you_rot_in_hell);
+      const char *ext_data;
+
+      LISP_STRING_TO_EXTERNAL (XCAR (XCDR (XCDR (mask_data))), ext_data, Qbinary);
+      mask = pixmap_from_xbm_inline (IMAGE_INSTANCE_DEVICE (ii),
+                                    XINT (XCAR (mask_data)),
+                                    XINT (XCAR (XCDR (mask_data))),
+                                    (const unsigned char *) ext_data);
     }
 
   init_image_instance_from_xbm_inline (ii, width, height, bits,
     }
 
   init_image_instance_from_xbm_inline (ii, width, height, bits,
@@ -1025,16 +1184,15 @@ x_xbm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
                   int dest_mask, Lisp_Object domain)
 {
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
                   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));
 
 
   assert (!NILP (data));
 
-  GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (data))),
-                                  gcc_go_home);
+  LISP_STRING_TO_EXTERNAL (XCAR (XCDR (XCDR (data))), ext_data, Qbinary);
 
   xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
                     pointer_bg, dest_mask, XINT (XCAR (data)),
 
   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);
 }
 
 \f
 }
 
 \f
@@ -1138,11 +1296,11 @@ xpm_free (XpmAttributes *xpmattrs)
 
 static void
 x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
 
 static void
 x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
-                                  Lisp_Object pointer_fg, Lisp_Object pointer_bg,
-                                  int dest_mask, Lisp_Object domain)
+                  Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+                  int dest_mask, Lisp_Object domain)
 {
   /* This function can GC */
 {
   /* This function can GC */
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
   Display *dpy;
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
   Display *dpy;
@@ -1200,7 +1358,7 @@ x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
   visual = DEVICE_X_VISUAL (XDEVICE(device));
 #endif
 
   visual = DEVICE_X_VISUAL (XDEVICE(device));
 #endif
 
-  x_initialize_pixmap_image_instance (ii, type);
+  x_initialize_pixmap_image_instance (ii, 1, type);
 
   assert (!NILP (data));
 
 
   assert (!NILP (data));
 
@@ -1310,7 +1468,7 @@ x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
       pixels = NULL;
 
     IMAGE_INSTANCE_X_PIXMAP (ii) = pixmap;
       pixels = NULL;
 
     IMAGE_INSTANCE_X_PIXMAP (ii) = pixmap;
-    IMAGE_INSTANCE_X_MASK (ii) = mask;
+    IMAGE_INSTANCE_PIXMAP_MASK (ii) = (void*)mask;
     IMAGE_INSTANCE_X_COLORMAP (ii) = cmap;
     IMAGE_INSTANCE_X_PIXELS (ii) = pixels;
     IMAGE_INSTANCE_X_NPIXELS (ii) = npixels;
     IMAGE_INSTANCE_X_COLORMAP (ii) = cmap;
     IMAGE_INSTANCE_X_PIXELS (ii) = pixels;
     IMAGE_INSTANCE_X_NPIXELS (ii) = npixels;
@@ -1482,73 +1640,6 @@ x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
 /**********************************************************************
  *                             X-Face                                 *
  **********************************************************************/
 /**********************************************************************
  *                             X-Face                                 *
  **********************************************************************/
-
-static void
-xface_validate (Lisp_Object instantiator)
-{
-  file_or_data_must_be_present (instantiator);
-}
-
-static Lisp_Object
-xface_normalize (Lisp_Object inst, Lisp_Object console_type)
-{
-  /* This funcation can call lisp */
-  Lisp_Object file = Qnil, mask_file = Qnil;
-  struct gcpro gcpro1, gcpro2, gcpro3;
-  Lisp_Object alist = Qnil;
-
-  GCPRO3 (file, mask_file, alist);
-
-  /* Now, convert any file data into inline data for both the regular
-     data and the mask data.  At the end of this, `data' will contain
-     the inline data (if any) or Qnil, and `file' will contain
-     the name this data was derived from (if known) or Qnil.
-     Likewise for `mask_file' and `mask_data'.
-
-     Note that if we cannot generate any regular inline data, we
-     skip out. */
-
-  file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
-                                            console_type);
-  mask_file = potential_pixmap_file_instantiator (inst, Q_mask_file,
-                                                 Q_mask_data, console_type);
-
-  if (CONSP (file)) /* failure locating filename */
-    signal_double_file_error ("Opening bitmap file",
-                             "no such file or directory",
-                             Fcar (file));
-
-  if (NILP (file) && NILP (mask_file)) /* no conversion necessary */
-    RETURN_UNGCPRO (inst);
-
-  alist = tagged_vector_to_alist (inst);
-
-  {
-    Lisp_Object data = make_string_from_file (file);
-    alist = remassq_no_quit (Q_file, alist);
-    /* there can't be a :data at this point. */
-    alist = Fcons (Fcons (Q_file, file),
-                  Fcons (Fcons (Q_data, data), alist));
-  }
-
-  alist = xbm_mask_file_munging (alist, file, mask_file, console_type);
-
-  {
-    Lisp_Object result = alist_to_tagged_vector (Qxface, alist);
-    free_alist (alist);
-    RETURN_UNGCPRO (result);
-  }
-}
-
-static int
-xface_possible_dest_types (void)
-{
-  return
-    IMAGE_MONO_PIXMAP_MASK  |
-    IMAGE_COLOR_PIXMAP_MASK |
-    IMAGE_POINTER_MASK;
-}
-
 #if defined(EXTERN)
 /* This is about to get redefined! */
 #undef EXTERN
 #if defined(EXTERN)
 /* This is about to get redefined! */
 #undef EXTERN
@@ -1570,19 +1661,20 @@ extern jmp_buf comp_env;
 #undef SYSV32
 
 static void
 #undef SYSV32
 
 static void
-xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
-                  Lisp_Object pointer_fg, Lisp_Object pointer_bg,
-                  int dest_mask, Lisp_Object domain)
+x_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+                    Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+                    int dest_mask, Lisp_Object domain)
 {
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
   int i, stattis;
 {
   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;
+  char *bits, *bp;
+  const char *p;
+  const char * volatile emsg = 0;
+  const char * volatile dstring;
 
   assert (!NILP (data));
 
 
   assert (!NILP (data));
 
-  GET_C_STRING_BINARY_DATA_ALLOCA (data, dstring);
+  LISP_STRING_TO_EXTERNAL (data, dstring, Qbinary);
 
   if ((p = strchr (dstring, ':')))
     {
 
   if ((p = strchr (dstring, ':')))
     {
@@ -1646,7 +1738,8 @@ autodetect_validate (Lisp_Object instantiator)
 
 static Lisp_Object
 autodetect_normalize (Lisp_Object instantiator,
 
 static Lisp_Object
 autodetect_normalize (Lisp_Object instantiator,
-                               Lisp_Object console_type)
+                     Lisp_Object console_type,
+                     Lisp_Object dest_mask)
 {
   Lisp_Object file = find_keyword_in_vector (instantiator, Q_data);
   Lisp_Object filename = Qnil;
 {
   Lisp_Object file = find_keyword_in_vector (instantiator, Q_data);
   Lisp_Object filename = Qnil;
@@ -1737,10 +1830,10 @@ autodetect_possible_dest_types (void)
 
 static void
 autodetect_instantiate (Lisp_Object image_instance,
 
 static void
 autodetect_instantiate (Lisp_Object image_instance,
-                                 Lisp_Object instantiator,
-                                 Lisp_Object pointer_fg,
-                                 Lisp_Object pointer_bg,
-                                 int dest_mask, Lisp_Object domain)
+                       Lisp_Object instantiator,
+                       Lisp_Object pointer_fg,
+                       Lisp_Object pointer_bg,
+                       int dest_mask, Lisp_Object domain)
 {
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
   struct gcpro gcpro1, gcpro2, gcpro3;
 {
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
   struct gcpro gcpro1, gcpro2, gcpro3;
@@ -1753,8 +1846,8 @@ autodetect_instantiate (Lisp_Object image_instance,
   alist = tagged_vector_to_alist (instantiator);
   if (dest_mask & IMAGE_POINTER_MASK)
     {
   alist = tagged_vector_to_alist (instantiator);
   if (dest_mask & IMAGE_POINTER_MASK)
     {
-      CONST char *name_ext;
-      GET_C_STRING_FILENAME_DATA_ALLOCA (data, name_ext);
+      const char *name_ext;
+      LISP_STRING_TO_EXTERNAL (data, name_ext, Qfile_name);
       if (XmuCursorNameToIndex (name_ext) != -1)
         {
           result = alist_to_tagged_vector (Qcursor_font, alist);
       if (XmuCursorNameToIndex (name_ext) != -1)
         {
           result = alist_to_tagged_vector (Qcursor_font, alist);
@@ -1841,7 +1934,7 @@ font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
 {
   /* This function can GC */
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
 {
   /* This function can GC */
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
   Display *dpy;
   XColor fg, bg;
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
   Display *dpy;
   XColor fg, bg;
@@ -1905,7 +1998,7 @@ font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
 
   /* #### call XQueryTextExtents() and check_pointer_sizes() here. */
 
 
   /* #### call XQueryTextExtents() and check_pointer_sizes() here. */
 
-  x_initialize_pixmap_image_instance (ii, IMAGE_POINTER);
+  x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER);
   IMAGE_INSTANCE_X_CURSOR (ii) =
     XCreateGlyphCursor (dpy, source, mask, source_char, mask_char,
                        &fg, &bg);
   IMAGE_INSTANCE_X_CURSOR (ii) =
     XCreateGlyphCursor (dpy, source, mask, source_char, mask_char,
                        &fg, &bg);
@@ -1939,11 +2032,11 @@ cursor_font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
 {
   /* This function can GC */
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
 {
   /* This function can GC */
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
-  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
   Display *dpy;
   int i;
   Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
   Display *dpy;
   int i;
-  CONST char *name_ext;
+  const char *name_ext;
   Lisp_Object foreground, background;
 
   if (!DEVICE_X_P (XDEVICE (device)))
   Lisp_Object foreground, background;
 
   if (!DEVICE_X_P (XDEVICE (device)))
@@ -1954,11 +2047,11 @@ cursor_font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
   if (!(dest_mask & IMAGE_POINTER_MASK))
     incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK);
 
   if (!(dest_mask & IMAGE_POINTER_MASK))
     incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK);
 
-  GET_C_STRING_FILENAME_DATA_ALLOCA (data, name_ext);
+  LISP_STRING_TO_EXTERNAL (data, name_ext, Qfile_name);
   if ((i = XmuCursorNameToIndex (name_ext)) == -1)
     signal_simple_error ("Unrecognized cursor-font name", data);
 
   if ((i = XmuCursorNameToIndex (name_ext)) == -1)
     signal_simple_error ("Unrecognized cursor-font name", data);
 
-  x_initialize_pixmap_image_instance (ii, IMAGE_POINTER);
+  x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER);
   IMAGE_INSTANCE_X_CURSOR (ii) = XCreateFontCursor (dpy, i);
   foreground = find_keyword_in_vector (instantiator, Q_foreground);
   if (NILP (foreground))
   IMAGE_INSTANCE_X_CURSOR (ii) = XCreateFontCursor (dpy, i);
   foreground = find_keyword_in_vector (instantiator, Q_foreground);
   if (NILP (foreground))
@@ -1973,7 +2066,7 @@ static int
 x_colorize_image_instance (Lisp_Object image_instance,
                           Lisp_Object foreground, Lisp_Object background)
 {
 x_colorize_image_instance (Lisp_Object image_instance,
                           Lisp_Object foreground, Lisp_Object background)
 {
-  struct Lisp_Image_Instance *p;
+  Lisp_Image_Instance *p;
 
   p = XIMAGE_INSTANCE (image_instance);
 
 
   p = XIMAGE_INSTANCE (image_instance);
 
@@ -1983,7 +2076,7 @@ x_colorize_image_instance (Lisp_Object image_instance,
       IMAGE_INSTANCE_TYPE (p) = IMAGE_COLOR_PIXMAP;
       /* Make sure there aren't two pointers to the same mask, causing
         it to get freed twice. */
       IMAGE_INSTANCE_TYPE (p) = IMAGE_COLOR_PIXMAP;
       /* Make sure there aren't two pointers to the same mask, causing
         it to get freed twice. */
-      IMAGE_INSTANCE_X_MASK (p) = 0;
+      IMAGE_INSTANCE_PIXMAP_MASK (p) = 0;
       break;
 
     default:
       break;
 
     default:
@@ -2019,168 +2112,215 @@ x_colorize_image_instance (Lisp_Object image_instance,
 }
 
 \f
 }
 
 \f
-#if HAVE_SUBWINDOWS
 /************************************************************************/
 /************************************************************************/
-/*                               subwindows                             */
+/*                      subwindow and widget support                      */
 /************************************************************************/
 
 /************************************************************************/
 
-Lisp_Object Qsubwindowp;
-
-static Lisp_Object
-mark_subwindow (Lisp_Object obj, void (*markobj) (Lisp_Object))
+/* unmap the image if it is a widget. This is used by redisplay via
+   redisplay_unmap_subwindows */
+static void
+x_unmap_subwindow (Lisp_Image_Instance *p)
 {
 {
-  struct Lisp_Subwindow *sw = XSUBWINDOW (obj);
-  return sw->frame;
+  if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
+    {
+      XUnmapWindow
+       (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
+        IMAGE_INSTANCE_X_CLIPWINDOW (p));
+    }
+  else                         /* must be a widget */
+    {
+      XtUnmapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
+    }
 }
 
 }
 
+/* map the subwindow. This is used by redisplay via
+   redisplay_output_subwindow */
 static void
 static void
-print_subwindow (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+x_map_subwindow (Lisp_Image_Instance *p, int x, int y,
+                struct display_glyph_area* dga)
 {
 {
-  char buf[100];
-  struct Lisp_Subwindow *sw = XSUBWINDOW (obj);
-  struct frame *frm = XFRAME (sw->frame);
-
-  if (print_readably)
-    error ("printing unreadable object #<subwindow 0x%x>",
-          sw->header.uid);
-
-  write_c_string ("#<subwindow", printcharfun);
-  sprintf (buf, " %dx%d", sw->width, sw->height);
-  write_c_string (buf, printcharfun);
-
-  /* This is stolen from frame.c.  Subwindows are strange in that they
-     are specific to a particular frame so we want to print in their
-     description what that frame is. */
-
-  write_c_string (" on #<", printcharfun);
-  if (!FRAME_LIVE_P (frm))
-    write_c_string ("dead", printcharfun);
-  else if (FRAME_TTY_P (frm))
-    write_c_string ("tty", printcharfun);
-  else if (FRAME_X_P (frm))
-    write_c_string ("x", printcharfun);
-  else
-    write_c_string ("UNKNOWN", printcharfun);
-  write_c_string ("-frame ", printcharfun);
-  print_internal (frm->name, printcharfun, 1);
-  sprintf (buf, " 0x%x>", frm->header.uid);
-  write_c_string (buf, printcharfun);
-
-  sprintf (buf, ") 0x%x>", sw->header.uid);
-  write_c_string (buf, printcharfun);
+  if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
+    {
+      Window subwindow = IMAGE_INSTANCE_X_SUBWINDOW_ID (p);
+      XMoveResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
+                        IMAGE_INSTANCE_X_CLIPWINDOW (p),
+                        x, y, dga->width, dga->height);
+      XMoveWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
+                  subwindow, -dga->xoffset, -dga->yoffset);
+      if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
+       XMapWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
+                   IMAGE_INSTANCE_X_CLIPWINDOW (p));
+    }
+  else                         /* must be a widget */
+    {
+      XtConfigureWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p),
+                        x + IMAGE_INSTANCE_X_WIDGET_XOFFSET (p),
+                        y + IMAGE_INSTANCE_X_WIDGET_YOFFSET (p),
+                        dga->width, dga->height, 0);
+      XtMoveWidget (IMAGE_INSTANCE_X_WIDGET_ID (p),
+                   -dga->xoffset, -dga->yoffset);
+      if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
+       XtMapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
+    }
 }
 
 }
 
+/* when you click on a widget you may activate another widget this
+   needs to be checked and all appropriate widgets updated */
 static void
 static void
-finalize_subwindow (void *header, int for_disksave)
+x_redisplay_subwindow (Lisp_Image_Instance *p)
 {
 {
-  struct Lisp_Subwindow *sw = (struct Lisp_Subwindow *) header;
-  if (for_disksave) finalose (sw);
-  if (sw->subwindow)
+  /* Update the subwindow size if necessary. */
+  if (IMAGE_INSTANCE_SIZE_CHANGED (p))
     {
     {
-      XDestroyWindow (DisplayOfScreen (sw->xscreen), sw->subwindow);
-      sw->subwindow = 0;
+      XResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
+                    IMAGE_INSTANCE_X_SUBWINDOW_ID (p),
+                    IMAGE_INSTANCE_WIDTH (p),
+                    IMAGE_INSTANCE_HEIGHT (p));
     }
 }
 
     }
 }
 
-/* subwindows are equal iff they have the same window XID */
-static int
-subwindow_equal (Lisp_Object o1, Lisp_Object o2, int depth)
+/* Update all attributes that have changed. Lwlib actually does most
+   of this for us. */
+static void
+x_redisplay_widget (Lisp_Image_Instance *p)
 {
 {
-  return (XSUBWINDOW (o1)->subwindow == XSUBWINDOW (o2)->subwindow);
-}
+  /* This function can GC if IN_REDISPLAY is false. */
+#ifdef HAVE_WIDGETS
+  widget_value* wv = 0;
+
+  /* First get the items if they have changed since this is a
+     structural change. As such it will nuke all added values so we
+     need to update most other things after the items have changed.*/
+  if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
+    {
+      Lisp_Object image_instance;
+
+      XSETIMAGE_INSTANCE (image_instance, p);
+      wv = gui_items_to_widget_values
+       (image_instance, IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (p),
+        /* #### this is not right; we need to keep track of which widgets
+           want accelerators and which don't */ 0);
+      wv->change = STRUCTURAL_CHANGE;
+    }
+  else
+    {
+      /* Assume the lotus position, breath deeply and chant to
+        yourself lwlibsux, lwlibsux ... lw_get_all_values returns a
+        reference to the real values rather than a copy thus any
+        changes we make to the values we get back will look like they
+        have already been applied. If we rebuild the widget tree then
+        we may lose propertie. */
+      wv = copy_widget_value_tree (lw_get_all_values
+                                  (IMAGE_INSTANCE_X_WIDGET_LWID (p)),
+                                  NO_CHANGE);
+    }
 
 
-static unsigned long
-subwindow_hash (Lisp_Object obj, int depth)
-{
-  return XSUBWINDOW (obj)->subwindow;
-}
+  /* Possibly update the colors and font */
+  if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
+      ||
+      XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed
+      ||
+      IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
+    {
+      update_widget_face (wv, p, IMAGE_INSTANCE_FRAME (p));
+    }
 
 
-DEFINE_LRECORD_IMPLEMENTATION ("subwindow", subwindow,
-                              mark_subwindow, print_subwindow,
-                              finalize_subwindow, subwindow_equal,
-                              subwindow_hash, struct Lisp_Subwindow);
-\f
-/* #### PROBLEM: The display routines assume that the glyph is only
- being displayed in one buffer.  If it is in two different buffers
- which are both being displayed simultaneously you will lose big time.
- This can be dealt with in the new redisplay. */
-
-/* #### These are completely un-re-implemented in 19.14.  Get it done
-   for 19.15. */
-
-DEFUN ("make-subwindow", Fmake_subwindow, 0, 3, 0, /*
-Creates a new `subwindow' object of size WIDTH x HEIGHT.
-The default is a window of size 1x1, which is also the minimum allowed
-window size.  Subwindows are per-frame.  A buffer being shown in two
-different frames will only display a subwindow glyph in the frame in
-which it was actually created.  If two windows on the same frame are
-displaying the buffer then the most recently used window will actually
-display the window.  If the frame is not specified, the selected frame
-is used.
+  /* Possibly update the text. */
+  if (IMAGE_INSTANCE_TEXT_CHANGED (p))
+    {
+      char* str;
+      Lisp_Object val = IMAGE_INSTANCE_WIDGET_TEXT (p);
+      LISP_STRING_TO_EXTERNAL (val, str, Qnative);
+      wv->value = str;
+    }
 
 
-Subwindows are not currently implemented.
-*/
-       (width, height, frame))
+  /* Possibly update the size. */
+  if (IMAGE_INSTANCE_SIZE_CHANGED (p)
+      ||
+      IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)
+      ||
+      IMAGE_INSTANCE_TEXT_CHANGED (p))
+    {
+      assert (IMAGE_INSTANCE_X_WIDGET_ID (p) &&
+             IMAGE_INSTANCE_X_CLIPWIDGET (p)) ;
+
+      if (IMAGE_INSTANCE_X_WIDGET_ID (p)->core.being_destroyed
+         || !XtIsManaged(IMAGE_INSTANCE_X_WIDGET_ID (p)))
+       {
+         Lisp_Object sw;
+         XSETIMAGE_INSTANCE (sw, p);
+         signal_simple_error ("XEmacs bug: subwindow is deleted", sw);
+       }
+
+      lw_add_widget_value_arg (wv, XtNwidth,
+                              (Dimension)IMAGE_INSTANCE_WIDTH (p));
+      lw_add_widget_value_arg (wv, XtNheight,
+                              (Dimension)IMAGE_INSTANCE_HEIGHT (p));
+    }
+
+  /* now modify the widget */
+  lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p),
+                        wv, True);
+  free_widget_value_tree (wv);
+#endif
+}
+
+/* instantiate and x type subwindow */
+static void
+x_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+                       Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+                       int dest_mask, Lisp_Object domain)
 {
 {
+  /* This function can GC */
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+  Lisp_Object frame = DOMAIN_FRAME (domain);
+  struct frame* f = XFRAME (frame);
   Display *dpy;
   Screen *xs;
   Display *dpy;
   Screen *xs;
-  Window pw;
-  struct frame *f;
-  unsigned int iw, ih;
+  Window pw, win;
   XSetWindowAttributes xswa;
   Mask valueMask = 0;
   XSetWindowAttributes xswa;
   Mask valueMask = 0;
+  unsigned int w = IMAGE_INSTANCE_WIDTH (ii),
+    h = IMAGE_INSTANCE_HEIGHT (ii);
 
 
-  error ("subwindows are not functional in 20.2; they may be again someday");
+  if (!DEVICE_X_P (XDEVICE (device)))
+    signal_simple_error ("Not an X device", device);
 
 
-  f = decode_x_frame (frame);
+  dpy = DEVICE_X_DISPLAY (XDEVICE (device));
+  xs = DefaultScreenOfDisplay (dpy);
+
+  IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
 
 
-  xs = LISP_DEVICE_TO_X_SCREEN (FRAME_DEVICE (f));
-  dpy = DisplayOfScreen (xs);
   pw = XtWindow (FRAME_X_TEXT_WIDGET (f));
 
   pw = XtWindow (FRAME_X_TEXT_WIDGET (f));
 
-  if (NILP (width))
-    iw = 1;
-  else
-    {
-      CHECK_INT (width);
-      iw = XINT (width);
-      if (iw < 1) iw = 1;
-    }
-  if (NILP (height))
-    ih = 1;
-  else
-    {
-      CHECK_INT (height);
-      ih = XINT (height);
-      if (ih < 1) ih = 1;
-    }
+  ii->data = xnew_and_zero (struct x_subwindow_data);
 
 
-  {
-    struct Lisp_Subwindow *sw =
-      alloc_lcrecord_type (struct Lisp_Subwindow, lrecord_subwindow);
-    Lisp_Object val;
-    sw->frame = frame;
-    sw->xscreen = xs;
-    sw->parent_window = pw;
-    sw->height = ih;
-    sw->width = iw;
-
-    xswa.backing_store = Always;
-    valueMask |= CWBackingStore;
-
-    xswa.colormap = DefaultColormapOfScreen (xs);
-    valueMask |= CWColormap;
-
-    sw->subwindow = XCreateWindow (dpy, pw, 0, 0, iw, ih, 0, CopyFromParent,
-                                  InputOutput, CopyFromParent, valueMask,
-                                  &xswa);
-
-    XSETSUBWINDOW (val, sw);
-    return val;
-  }
+  IMAGE_INSTANCE_X_SUBWINDOW_PARENT (ii) = pw;
+  IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (ii) = DisplayOfScreen (xs);
+
+  xswa.backing_store = Always;
+  valueMask |= CWBackingStore;
+  xswa.colormap = DefaultColormapOfScreen (xs);
+  valueMask |= CWColormap;
+
+  /* Create a window for clipping */
+  IMAGE_INSTANCE_X_CLIPWINDOW (ii) =
+    XCreateWindow (dpy, pw, 0, 0, w, h, 0, CopyFromParent,
+                  InputOutput, CopyFromParent, valueMask,
+                  &xswa);
+
+  /* Now put the subwindow inside the clip window. */
+  win = XCreateWindow (dpy, IMAGE_INSTANCE_X_CLIPWINDOW (ii),
+                      0, 0, w, h, 0, CopyFromParent,
+                      InputOutput, CopyFromParent, valueMask,
+                      &xswa);
+
+  IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)win;
 }
 
 }
 
-/* #### Should this function exist? */
+#if 0
+/* #### Should this function exist? If there's any doubt I'm not implementing it --andyp */
 DEFUN ("change-subwindow-property", Fchange_subwindow_property, 3, 3, 0, /*
 For the given SUBWINDOW, set PROPERTY to DATA, which is a string.
 Subwindows are not currently implemented.
 DEFUN ("change-subwindow-property", Fchange_subwindow_property, 3, 3, 0, /*
 For the given SUBWINDOW, set PROPERTY to DATA, which is a string.
 Subwindows are not currently implemented.
@@ -2188,7 +2328,7 @@ Subwindows are not currently implemented.
        (subwindow, property, data))
 {
   Atom property_atom;
        (subwindow, property, data))
 {
   Atom property_atom;
-  struct Lisp_Subwindow *sw;
+  Lisp_Subwindow *sw;
   Display *dpy;
 
   CHECK_SUBWINDOW (subwindow);
   Display *dpy;
 
   CHECK_SUBWINDOW (subwindow);
@@ -2207,91 +2347,484 @@ Subwindows are not currently implemented.
 
   return property;
 }
 
   return property;
 }
+#endif
 
 
-DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /*
-Return non-nil if OBJECT is a subwindow.
-Subwindows are not currently implemented.
-*/
-       (object))
+\f
+#ifdef HAVE_WIDGETS
+
+/************************************************************************/
+/*                            widgets                            */
+/************************************************************************/
+
+static void
+update_widget_face (widget_value* wv, Lisp_Image_Instance *ii,
+                   Lisp_Object domain)
 {
 {
-  return SUBWINDOWP (object) ? Qt : Qnil;
+#ifdef LWLIB_WIDGETS_MOTIF
+  XmFontList fontList;
+#endif
+  /* Update the foreground. */
+  Lisp_Object pixel = FACE_FOREGROUND
+    (IMAGE_INSTANCE_WIDGET_FACE (ii),
+     domain);
+  XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)), bcolor;
+  lw_add_widget_value_arg (wv, XtNforeground, fcolor.pixel);
+
+  /* Update the background. */
+  pixel = FACE_BACKGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii),
+                          domain);
+  bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+  lw_add_widget_value_arg (wv, XtNbackground, bcolor.pixel);
+
+#ifdef LWLIB_WIDGETS_MOTIF
+  fontList = XmFontListCreate
+    (FONT_INSTANCE_X_FONT
+     (XFONT_INSTANCE (query_string_font
+                     (IMAGE_INSTANCE_WIDGET_TEXT (ii),
+                      IMAGE_INSTANCE_WIDGET_FACE (ii),
+                      domain))),  XmSTRING_DEFAULT_CHARSET);
+  lw_add_widget_value_arg (wv, XmNfontList, (XtArgVal)fontList);
+#endif
+  lw_add_widget_value_arg
+    (wv, XtNfont, (XtArgVal)FONT_INSTANCE_X_FONT
+     (XFONT_INSTANCE (query_string_font
+                     (IMAGE_INSTANCE_WIDGET_TEXT (ii),
+                      IMAGE_INSTANCE_WIDGET_FACE (ii),
+                      domain))));
+  wv->change = VISIBLE_CHANGE;
+  /* #### Megahack - but its just getting too complicated to do this
+     in the right place. */
+  if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qtab_control))
+    update_tab_widget_face (wv, ii, domain);
 }
 
 }
 
-DEFUN ("subwindow-width", Fsubwindow_width, 1, 1, 0, /*
-Width of SUBWINDOW.
-Subwindows are not currently implemented.
-*/
-       (subwindow))
+static void
+update_tab_widget_face (widget_value* wv, Lisp_Image_Instance *ii,
+                       Lisp_Object domain)
 {
 {
-  CHECK_SUBWINDOW (subwindow);
-  return make_int (XSUBWINDOW (subwindow)->width);
+  if (wv->contents)
+    {
+      widget_value* val = wv->contents, *cur;
+
+      /* Give each child label the correct foreground color. */
+      Lisp_Object pixel = FACE_FOREGROUND
+       (IMAGE_INSTANCE_WIDGET_FACE (ii),
+        domain);
+      XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+      lw_add_widget_value_arg (val, XtNtabForeground, fcolor.pixel);
+      wv->change = VISIBLE_CHANGE;
+      val->change = VISIBLE_CHANGE;
+
+      for (cur = val->next; cur; cur = cur->next)
+       {
+         cur->change = VISIBLE_CHANGE;
+         if (cur->value)
+           {
+             lw_copy_widget_value_args (val, cur);
+           }
+       }
+    }
 }
 
 }
 
-DEFUN ("subwindow-height", Fsubwindow_height, 1, 1, 0, /*
-Height of SUBWINDOW.
-Subwindows are not currently implemented.
-*/
-       (subwindow))
+static void
+x_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* type, widget_value* wv)
 {
 {
-  CHECK_SUBWINDOW (subwindow);
-  return make_int (XSUBWINDOW (subwindow)->height);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), pixel;
+  struct device* d = XDEVICE (device);
+  Lisp_Object frame = DOMAIN_FRAME (domain);
+  struct frame* f = XFRAME (frame);
+  char* nm=0;
+  Widget wid;
+  Arg al [32];
+  int ac = 0;
+  int id = new_lwlib_id ();
+  widget_value* clip_wv;
+  XColor fcolor, bcolor;
+
+  if (!DEVICE_X_P (d))
+    signal_simple_error ("Not an X device", device);
+
+  /* have to set the type this late in case there is no device
+     instantiation for a widget. But we can go ahead and do it without
+     checking because there is always a generic instantiator. */
+  IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET;
+
+  if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
+    LISP_STRING_TO_EXTERNAL (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm, Qnative);
+
+  ii->data = xnew_and_zero (struct x_subwindow_data);
+
+  /* Create a clip window to contain the subwidget. Incredibly the
+     XEmacs manager seems to be the most appropriate widget for
+     this. Nothing else is simple enough and yet does what is
+     required. */
+  clip_wv = xmalloc_widget_value ();
+
+  lw_add_widget_value_arg (clip_wv, XtNresize, False);
+  lw_add_widget_value_arg (clip_wv, XtNwidth,
+                          (Dimension)IMAGE_INSTANCE_WIDTH (ii));
+  lw_add_widget_value_arg (clip_wv, XtNheight,
+                          (Dimension)IMAGE_INSTANCE_HEIGHT (ii));
+  clip_wv->enabled = True;
+
+  clip_wv->name = xstrdup ("clip-window");
+  clip_wv->value = xstrdup ("clip-window");
+
+  IMAGE_INSTANCE_X_CLIPWIDGET (ii)
+    = lw_create_widget ("clip-window", "clip-window", new_lwlib_id (),
+                       clip_wv, FRAME_X_CONTAINER_WIDGET (f),
+                       False, 0, 0, 0);
+
+  free_widget_value_tree (clip_wv);
+
+  /* copy any args we were given */
+  ac = 0;
+  lw_add_value_args_to_args (wv, al, &ac);
+
+  /* Fixup the colors. We have to do this *before* the widget gets
+     created so that Motif will fix up the shadow colors
+     correctly. Once the widget is created Motif won't do this
+     anymore...*/
+  pixel = FACE_FOREGROUND
+    (IMAGE_INSTANCE_WIDGET_FACE (ii),
+     IMAGE_INSTANCE_FRAME (ii));
+  fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+
+  pixel = FACE_BACKGROUND
+    (IMAGE_INSTANCE_WIDGET_FACE (ii),
+     IMAGE_INSTANCE_FRAME (ii));
+  bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+
+  lw_add_widget_value_arg (wv, XtNbackground, bcolor.pixel);
+  lw_add_widget_value_arg (wv, XtNforeground, fcolor.pixel);
+  /* we cannot allow widgets to resize themselves */
+  lw_add_widget_value_arg (wv, XtNresize, False);
+  lw_add_widget_value_arg (wv, XtNwidth,
+                          (Dimension)IMAGE_INSTANCE_WIDTH (ii));
+  lw_add_widget_value_arg (wv, XtNheight,
+                          (Dimension)IMAGE_INSTANCE_HEIGHT (ii));
+  /* update the font. */
+  update_widget_face (wv, ii, domain);
+
+  wid = lw_create_widget (type, wv->name, id, wv, IMAGE_INSTANCE_X_CLIPWIDGET (ii),
+                         False, 0, popup_selection_callback, 0);
+
+  IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid;
+  IMAGE_INSTANCE_X_WIDGET_LWID (ii) = id;
+  /* because the EmacsManager is the widgets parent we have to
+     offset the redisplay of the widget by the amount the text
+     widget is inside the manager. */
+  ac = 0;
+  XtSetArg (al [ac], XtNx, &IMAGE_INSTANCE_X_WIDGET_XOFFSET (ii)); ac++;
+  XtSetArg (al [ac], XtNy, &IMAGE_INSTANCE_X_WIDGET_YOFFSET (ii)); ac++;
+  XtGetValues (FRAME_X_TEXT_WIDGET (f), al, ac);
+
+  XtSetMappedWhenManaged (wid, TRUE);
+
+  free_widget_value_tree (wv);
+  /* A kludgy but simple way to make sure the callback for a widget
+     doesn't get deleted. */
+  gcpro_popup_callbacks (id);
 }
 
 }
 
-DEFUN ("subwindow-xid", Fsubwindow_xid, 1, 1, 0, /*
-Return the xid of SUBWINDOW as a number.
-Subwindows are not currently implemented.
-*/
-       (subwindow))
+/* get properties of a control */
+static Lisp_Object
+x_widget_property (Lisp_Object image_instance, Lisp_Object prop)
 {
 {
-  CHECK_SUBWINDOW (subwindow);
-  return make_int (XSUBWINDOW (subwindow)->subwindow);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  /* get the text from a control */
+  if (EQ (prop, Q_text))
+    {
+      widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii));
+      return build_ext_string (wv->value, Qnative);
+    }
+  return Qunbound;
 }
 
 }
 
-DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /*
-Resize SUBWINDOW to WIDTH x HEIGHT.
-If a value is nil that parameter is not changed.
-Subwindows are not currently implemented.
-*/
-       (subwindow, width, height))
+/* Instantiate a layout control for putting other widgets in. */
+static void
+x_native_layout_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+                            Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+                            int dest_mask, Lisp_Object domain)
 {
 {
-  int neww, newh;
-  struct Lisp_Subwindow *sw;
+  x_widget_instantiate (image_instance, instantiator, pointer_fg,
+                       pointer_bg, dest_mask, domain, "layout", 0);
+}
 
 
-  CHECK_SUBWINDOW (subwindow);
-  sw = XSUBWINDOW (subwindow);
+/* 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
+   many-to-one relationship with things you see, whereas widgets can
+   only be one-to-one (i.e. per frame) */
+static void
+x_button_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);
+  Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
+  Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
+  widget_value* wv = gui_items_to_widget_values (image_instance, gui, 1);
 
 
-  if (NILP (width))
-    neww = sw->width;
-  else
-    neww = XINT (width);
+  if (!NILP (glyph))
+    {
+      if (!IMAGE_INSTANCEP (glyph))
+       glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
+    }
 
 
-  if (NILP (height))
-    newh = sw->height;
-  else
-    newh = XINT (height);
+  x_widget_instantiate (image_instance, instantiator, pointer_fg,
+                       pointer_bg, dest_mask, domain, "button", wv);
 
 
-  XResizeWindow (DisplayOfScreen (sw->xscreen), sw->subwindow, neww, newh);
+  /* add the image if one was given */
+  if (!NILP (glyph) && IMAGE_INSTANCEP (glyph)
+      && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph)))
+    {
+      Arg al [2];
+      int ac =0;
+#ifdef LWLIB_WIDGETS_MOTIF
+      XtSetArg (al [ac], XmNlabelType, XmPIXMAP);      ac++;
+      XtSetArg (al [ac], XmNlabelPixmap, XIMAGE_INSTANCE_X_PIXMAP (glyph));ac++;
+#else
+      XtSetArg (al [ac], XtNpixmap, XIMAGE_INSTANCE_X_PIXMAP (glyph)); ac++;
+#endif
+      XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, ac);
+    }
+}
 
 
-  sw->height = newh;
-  sw->width = neww;
+/* Update a button's clicked state.
 
 
-  return subwindow;
+   #### This is overkill, but it works. Right now this causes all
+   button instances to flash for some reason buried deep in lwlib. In
+   theory this should be the Right Thing to do since lwlib should only
+   merge in changed values - and if nothing has changed then nothing
+   should get done. This may be because of the args stuff,
+   i.e. although the arg contents may be the same the args look
+   different and so are re-applied to the widget. */
+static void
+x_button_redisplay (Lisp_Object image_instance)
+{
+  /* This function can GC if IN_REDISPLAY is false. */
+  Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
+  widget_value* wv =
+    gui_items_to_widget_values (image_instance,
+                               IMAGE_INSTANCE_WIDGET_ITEMS (p), 1);
+
+  /* now modify the widget */
+  lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p),
+                        wv, True);
+  free_widget_value_tree (wv);
 }
 
 }
 
-DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /*
-Generate a Map event for SUBWINDOW.
-Subwindows are not currently implemented.
-*/
-       (subwindow))
+/* get properties of a button */
+static Lisp_Object
+x_button_property (Lisp_Object image_instance, Lisp_Object prop)
 {
 {
-  CHECK_SUBWINDOW (subwindow);
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  /* check the state of a button */
+  if (EQ (prop, Q_selected))
+    {
+      widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii));
 
 
-  XMapWindow (DisplayOfScreen (XSUBWINDOW (subwindow)->xscreen),
-             XSUBWINDOW (subwindow)->subwindow);
+      if (wv->selected)
+       return Qt;
+      else
+       return Qnil;
+    }
+  return Qunbound;
+}
+
+/* instantiate a progress gauge */
+static void
+x_progress_gauge_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);
+  Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
+  widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0);
 
 
-  return subwindow;
+  x_widget_instantiate (image_instance, instantiator, pointer_fg,
+                       pointer_bg, dest_mask, domain, "progress", wv);
+}
+
+/* set the properties of a progress gauge */
+static void
+x_progress_gauge_redisplay (Lisp_Object image_instance)
+{
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+  if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
+    {
+      Arg al [1];
+      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;
+      XtSetArg (al[0], XtNvalue, XINT (val));
+      XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 1);
+    }
+}
+
+/* instantiate an edit control */
+static void
+x_edit_field_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);
+  Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
+  widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0);
+
+  x_widget_instantiate (image_instance, instantiator, pointer_fg,
+                       pointer_bg, dest_mask, domain, "text-field", wv);
+}
+
+#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
+/* instantiate a combo control */
+static void
+x_combo_box_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);
+  widget_value * wv = 0;
+  /* This is not done generically because of sizing problems under
+     mswindows. */
+  widget_instantiate (image_instance, instantiator, pointer_fg,
+                     pointer_bg, dest_mask, domain);
+
+  wv = gui_items_to_widget_values (image_instance,
+                                  IMAGE_INSTANCE_WIDGET_ITEMS (ii), 0);
+
+  x_widget_instantiate (image_instance, instantiator, pointer_fg,
+                       pointer_bg, dest_mask, domain, "combo-box", wv);
 }
 #endif
 }
 #endif
+
+static void
+x_tab_control_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);
+  widget_value * wv =
+    gui_items_to_widget_values (image_instance,
+                               IMAGE_INSTANCE_WIDGET_ITEMS (ii), 0);
+  update_tab_widget_face (wv, ii,
+                         IMAGE_INSTANCE_FRAME (ii));
+  x_widget_instantiate (image_instance, instantiator, pointer_fg,
+                       pointer_bg, dest_mask, domain, "tab-control", wv);
+}
+
+/* Set the properties of a tab control */
+static void
+x_tab_control_redisplay (Lisp_Object image_instance)
+{
+  Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+  if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)
+      ||
+      IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii))
+    {
+      /* If only the order has changed then simply select the first
+        one of the pending set. This stops horrendous rebuilding -
+        and hence flicker - of the tabs each time you click on
+        one. */
+      if (tab_control_order_only_changed (image_instance))
+       {
+         Lisp_Object rest, selected =
+           gui_item_list_find_selected
+           (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ?
+            XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) :
+            XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
+
+         LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
+           {
+             if (gui_item_equal_sans_selected (XCAR (rest), selected, 0))
+               {
+                 /* There may be an encapsulated way of doing this,
+                    but I couldn't find it. */
+                 Lisp_Object old_selected =gui_item_list_find_selected
+                   (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
+                 Arg al [1];
+                 char* name;
+                 unsigned int num_children, i;
+                 Widget* children;
+
+                 LISP_STRING_TO_EXTERNAL (XGUI_ITEM (XCAR (rest))->name,
+                                          name, Qnative);
+                 /* The name may contain a `.' which confuses
+                    XtNameToWidget, so we do it ourselves. */
+                 children = XtCompositeChildren (IMAGE_INSTANCE_X_WIDGET_ID (ii),
+                                                 &num_children);
+                 for (i = 0; i < num_children; i++)
+                   {
+                     if (!strcmp (XtName (children [i]), name))
+                       {
+                         XtSetArg (al [0], XtNtopWidget, children [i]);
+                         XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 1);
+                         break;
+                       }
+                   }
+                 /* Pick up the new selected item. */
+                 XGUI_ITEM (old_selected)->selected =
+                   XGUI_ITEM (XCAR (rest))->selected;
+                 XGUI_ITEM (XCAR (rest))->selected =
+                   XGUI_ITEM (selected)->selected;
+                 /* We're not actually changing the items anymore. */
+                 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
+                 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
+                 break;
+               }
+           }
+       }
+    }
+  /* Possibly update the face. */
+  if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii)
+      ||
+      XFRAME (IMAGE_INSTANCE_FRAME (ii))->faces_changed
+      ||
+      IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
+    {
+      /* See previous comments on the brokeness of lwlib.
+
+        #### There's actually not much point in doing this here
+        since, colors will have been set appropriately by
+        x_redisplay_widget. */
+      widget_value* wv =copy_widget_value_tree
+       (lw_get_all_values
+        (IMAGE_INSTANCE_X_WIDGET_LWID (ii)),
+        NO_CHANGE);
+
+      update_tab_widget_face (wv, ii,
+                             IMAGE_INSTANCE_FRAME (ii));
+
+      lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, True);
+      free_widget_value_tree (wv);
+    }
+}
+
+/* instantiate a static control possible for putting other things in */
+static void
+x_label_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);
+  Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
+  widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0);
+
+  x_widget_instantiate (image_instance, instantiator, pointer_fg,
+                       pointer_bg, dest_mask, domain, "button", wv);
+}
+#endif /* HAVE_WIDGETS */
+
 \f
 /************************************************************************/
 /*                            initialization                            */
 \f
 /************************************************************************/
 /*                            initialization                            */
@@ -2300,17 +2833,8 @@ Subwindows are not currently implemented.
 void
 syms_of_glyphs_x (void)
 {
 void
 syms_of_glyphs_x (void)
 {
-#if HAVE_SUBWINDOWS
-  defsymbol (&Qsubwindowp, "subwindowp");
-
-  DEFSUBR (Fmake_subwindow);
+#if 0
   DEFSUBR (Fchange_subwindow_property);
   DEFSUBR (Fchange_subwindow_property);
-  DEFSUBR (Fsubwindowp);
-  DEFSUBR (Fsubwindow_width);
-  DEFSUBR (Fsubwindow_height);
-  DEFSUBR (Fsubwindow_xid);
-  DEFSUBR (Fresize_subwindow);
-  DEFSUBR (Fforce_subwindow_map);
 #endif
 }
 
 #endif
 }
 
@@ -2326,17 +2850,78 @@ console_type_create_glyphs_x (void)
   CONSOLE_HAS_METHOD (x, colorize_image_instance);
   CONSOLE_HAS_METHOD (x, init_image_instance_from_eimage);
   CONSOLE_HAS_METHOD (x, locate_pixmap_file);
   CONSOLE_HAS_METHOD (x, colorize_image_instance);
   CONSOLE_HAS_METHOD (x, init_image_instance_from_eimage);
   CONSOLE_HAS_METHOD (x, locate_pixmap_file);
-#ifdef HAVE_XPM
-  CONSOLE_HAS_METHOD (x, xpm_instantiate);
-#endif
-  CONSOLE_HAS_METHOD (x, xbm_instantiate);
+  CONSOLE_HAS_METHOD (x, unmap_subwindow);
+  CONSOLE_HAS_METHOD (x, map_subwindow);
+  CONSOLE_HAS_METHOD (x, redisplay_widget);
+  CONSOLE_HAS_METHOD (x, redisplay_subwindow);
 }
 
 void
 image_instantiator_format_create_glyphs_x (void)
 {
 }
 
 void
 image_instantiator_format_create_glyphs_x (void)
 {
-
+  IIFORMAT_VALID_CONSOLE (x, nothing);
+  IIFORMAT_VALID_CONSOLE (x, string);
+#ifdef HAVE_WIDGETS
+  IIFORMAT_VALID_CONSOLE (x, layout);
+#endif
+  IIFORMAT_VALID_CONSOLE (x, formatted_string);
+  IIFORMAT_VALID_CONSOLE (x, inherit);
+#ifdef HAVE_XPM
+  INITIALIZE_DEVICE_IIFORMAT (x, xpm);
+  IIFORMAT_HAS_DEVMETHOD (x, xpm, instantiate);
+#endif
+#ifdef HAVE_JPEG
+  IIFORMAT_VALID_CONSOLE (x, jpeg);
+#endif
+#ifdef HAVE_TIFF
+  IIFORMAT_VALID_CONSOLE (x, tiff);
+#endif
+#ifdef HAVE_PNG
+  IIFORMAT_VALID_CONSOLE (x, png);
+#endif
+#ifdef HAVE_GIF
+  IIFORMAT_VALID_CONSOLE (x, gif);
+#endif
+  INITIALIZE_DEVICE_IIFORMAT (x, xbm);
+  IIFORMAT_HAS_DEVMETHOD (x, xbm, instantiate);
+
+  INITIALIZE_DEVICE_IIFORMAT (x, subwindow);
+  IIFORMAT_HAS_DEVMETHOD (x, subwindow, instantiate);
+#ifdef HAVE_WIDGETS
+  /* layout widget */
+  INITIALIZE_DEVICE_IIFORMAT (x, native_layout);
+  IIFORMAT_HAS_DEVMETHOD (x, native_layout, instantiate);
+  /* button widget */
+  INITIALIZE_DEVICE_IIFORMAT (x, button);
+  IIFORMAT_HAS_DEVMETHOD (x, button, property);
+  IIFORMAT_HAS_DEVMETHOD (x, button, instantiate);
+  IIFORMAT_HAS_DEVMETHOD (x, button, redisplay);
+  /* general widget methods. */
+  INITIALIZE_DEVICE_IIFORMAT (x, widget);
+  IIFORMAT_HAS_DEVMETHOD (x, widget, property);
+  /* progress gauge */
+  INITIALIZE_DEVICE_IIFORMAT (x, progress_gauge);
+  IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, redisplay);
+  IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, instantiate);
+  /* text field */
+  INITIALIZE_DEVICE_IIFORMAT (x, edit_field);
+  IIFORMAT_HAS_DEVMETHOD (x, edit_field, instantiate);
+#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
+  /* combo box */
+  INITIALIZE_DEVICE_IIFORMAT (x, combo_box);
+  IIFORMAT_HAS_DEVMETHOD (x, combo_box, instantiate);
+  IIFORMAT_HAS_SHARED_DEVMETHOD (x, combo_box, redisplay, tab_control);
+#endif
+  /* tab control widget */
+  INITIALIZE_DEVICE_IIFORMAT (x, tab_control);
+  IIFORMAT_HAS_DEVMETHOD (x, tab_control, instantiate);
+  IIFORMAT_HAS_DEVMETHOD (x, tab_control, redisplay);
+  /* label */
+  INITIALIZE_DEVICE_IIFORMAT (x, label);
+  IIFORMAT_HAS_DEVMETHOD (x, label, instantiate);
+#endif
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font");
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font");
+  IIFORMAT_VALID_CONSOLE (x, cursor_font);
 
   IIFORMAT_HAS_METHOD (cursor_font, validate);
   IIFORMAT_HAS_METHOD (cursor_font, possible_dest_types);
 
   IIFORMAT_HAS_METHOD (cursor_font, validate);
   IIFORMAT_HAS_METHOD (cursor_font, possible_dest_types);
@@ -2351,25 +2936,15 @@ image_instantiator_format_create_glyphs_x (void)
   IIFORMAT_HAS_METHOD (font, validate);
   IIFORMAT_HAS_METHOD (font, possible_dest_types);
   IIFORMAT_HAS_METHOD (font, instantiate);
   IIFORMAT_HAS_METHOD (font, validate);
   IIFORMAT_HAS_METHOD (font, possible_dest_types);
   IIFORMAT_HAS_METHOD (font, instantiate);
+  IIFORMAT_VALID_CONSOLE (x, font);
 
   IIFORMAT_VALID_KEYWORD (font, Q_data, check_valid_string);
   IIFORMAT_VALID_KEYWORD (font, Q_foreground, check_valid_string);
   IIFORMAT_VALID_KEYWORD (font, Q_background, check_valid_string);
 
 #ifdef HAVE_XFACE
 
   IIFORMAT_VALID_KEYWORD (font, Q_data, check_valid_string);
   IIFORMAT_VALID_KEYWORD (font, Q_foreground, check_valid_string);
   IIFORMAT_VALID_KEYWORD (font, Q_background, check_valid_string);
 
 #ifdef HAVE_XFACE
-  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xface, "xface");
-
-  IIFORMAT_HAS_METHOD (xface, validate);
-  IIFORMAT_HAS_METHOD (xface, normalize);
-  IIFORMAT_HAS_METHOD (xface, possible_dest_types);
-  IIFORMAT_HAS_METHOD (xface, instantiate);
-
-  IIFORMAT_VALID_KEYWORD (xface, Q_data, check_valid_string);
-  IIFORMAT_VALID_KEYWORD (xface, Q_file, check_valid_string);
-  IIFORMAT_VALID_KEYWORD (xface, Q_hotspot_x, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (xface, Q_hotspot_y, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (xface, Q_foreground, check_valid_string);
-  IIFORMAT_VALID_KEYWORD (xface, Q_background, check_valid_string);
+  INITIALIZE_DEVICE_IIFORMAT (x, xface);
+  IIFORMAT_HAS_DEVMETHOD (x, xface, instantiate);
 #endif
 
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (autodetect,
 #endif
 
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (autodetect,
@@ -2379,6 +2954,7 @@ image_instantiator_format_create_glyphs_x (void)
   IIFORMAT_HAS_METHOD (autodetect, normalize);
   IIFORMAT_HAS_METHOD (autodetect, possible_dest_types);
   IIFORMAT_HAS_METHOD (autodetect, instantiate);
   IIFORMAT_HAS_METHOD (autodetect, normalize);
   IIFORMAT_HAS_METHOD (autodetect, possible_dest_types);
   IIFORMAT_HAS_METHOD (autodetect, instantiate);
+  IIFORMAT_VALID_CONSOLE (x, autodetect);
 
   IIFORMAT_VALID_KEYWORD (autodetect, Q_data, check_valid_string);
 }
 
   IIFORMAT_VALID_KEYWORD (autodetect, Q_data, check_valid_string);
 }
@@ -2386,10 +2962,6 @@ image_instantiator_format_create_glyphs_x (void)
 void
 vars_of_glyphs_x (void)
 {
 void
 vars_of_glyphs_x (void)
 {
-#ifdef HAVE_XFACE
-  Fprovide (Qxface);
-#endif
-
   DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path /*
 A list of the directories in which X bitmap files may be found.
 If nil, this is initialized from the "*bitmapFilePath" resource.
   DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path /*
 A list of the directories in which X bitmap files may be found.
 If nil, this is initialized from the "*bitmapFilePath" resource.
@@ -2410,7 +2982,7 @@ complex_vars_of_glyphs_x (void)
                     make_int (name##_height),                  \
                     make_ext_string (name##_bits,              \
                                      sizeof (name##_bits),     \
                     make_int (name##_height),                  \
                     make_ext_string (name##_bits,              \
                                      sizeof (name##_bits),     \
-                                     FORMAT_BINARY))),         \
+                                     Qbinary))),               \
      Qglobal, Qx, Qnil)
 
   BUILD_GLYPH_INST (Vtruncation_glyph, truncator);
      Qglobal, Qx, Qnil)
 
   BUILD_GLYPH_INST (Vtruncation_glyph, truncator);