+ return 1;
+}
+
+/* Get the glyphs that comprise a layout. These are created internally
+ and so are otherwise inaccessible to lisp. We need some way of getting
+ properties from the widgets that comprise a layout and this is the
+ simplest way of doing it.
+
+ #### Eventually we should allow some more intelligent access to
+ sub-widgets. */
+static Lisp_Object
+layout_property (Lisp_Object image_instance, Lisp_Object prop)
+{
+ /* This function can GC. */
+ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ if (EQ (prop, Q_items))
+ {
+ if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii)) &&
+ CONSP (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii)))
+ return Fcopy_sequence (XCDR
+ (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii)));
+ else
+ return Fcopy_sequence (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii));
+ }
+ return Qunbound;
+}
+
+/* Layout subwindows if they are real subwindows. */
+static int
+native_layout_layout (Lisp_Object image_instance,
+ int width, int height, int xoffset, int yoffset,
+ Lisp_Object domain)
+{
+ Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object rest;
+
+ /* The first time this gets called, the layout will be only
+ partially instantiated. The children get done in
+ post_instantiate. */
+ if (!IMAGE_INSTANCE_INITIALIZED (ii))
+ return 0;
+
+ /* Defining this overrides the default layout_layout so we first have to call that to get
+ suitable instances and values set up. */
+ layout_layout (image_instance, width, height, xoffset, yoffset, domain);
+
+ LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (ii))
+ {
+ struct display_glyph_area dga;
+ dga.xoffset = 0;
+ dga.yoffset = 0;
+ dga.width = IMAGE_INSTANCE_WIDTH (ii);
+ dga.height = IMAGE_INSTANCE_HEIGHT (ii);
+
+ map_subwindow (XCAR (rest),
+ IMAGE_INSTANCE_XOFFSET (ii),
+ IMAGE_INSTANCE_YOFFSET (ii), &dga);
+ }
+ return 1;
+}
+
+DEFUN ("widget-logical-to-character-width", Fwidget_logical_to_character_width, 1, 3, 0, /*
+Convert the width in logical widget units to characters.
+Logical widget units do not take into account adjusments made for
+layout borders, so this adjusment is approximated.
+*/
+ (width, face, domain))
+{
+ int w, neww, charwidth;
+ int border_width = DEFAULT_WIDGET_BORDER_WIDTH;
+
+ if (NILP (domain))
+ domain = Fselected_frame (Qnil);
+
+ CHECK_INT (width);
+ w = XINT (width);
+
+ if (HAS_DEVMETH_P (DOMAIN_XDEVICE (domain), widget_border_width))
+ border_width = DEVMETH (DOMAIN_XDEVICE (domain), widget_border_width, ());
+
+ default_face_font_info (domain, 0, 0, 0, &charwidth, 0);
+ neww = ROUND_UP (charwidth * w + 4 * border_width + 2 * widget_spacing (domain),
+ charwidth) / charwidth;
+
+ return make_int (neww);
+}
+
+DEFUN ("widget-logical-to-character-height", Fwidget_logical_to_character_height, 1, 3, 0, /*
+Convert the height in logical widget units to characters.
+Logical widget units do not take into account adjusments made for
+layout borders, so this adjustment is approximated.
+
+If the components of a widget layout are justified to the top or the
+bottom then they are aligned in terms of `logical units'. This is a
+size quantity that is designed to be big enough to accomodate the
+largest `single height' widget. It is dependent on the widget face and
+some combination of spacing and border-width. Thus if you specify top
+or bottom justification in a vertical layout the subcontrols are laid
+out one per logical unit. This allows adjoining layouts to have
+identical alignment for their subcontrols.
+
+Since frame sizes are measured in characters, this function allows you
+to do appropriate conversion between logical units and characters.
+*/
+ (height, face, domain))
+{
+ int h, newh, charheight;
+
+ CHECK_INT (height);
+ if (NILP (domain))
+ domain = Fselected_frame (Qnil);
+
+ h = XINT (height);
+
+ default_face_font_info (domain, 0, 0, &charheight, 0, 0);
+ newh = ROUND_UP (logical_unit_height (Fsymbol_name (Qwidget),
+ Vwidget_face, domain) * h, charheight)
+ / charheight;
+
+ return make_int (newh);