+
+ {
+ Lisp_Object result = alist_to_tagged_vector (XVECTOR_DATA (inst)[0],
+ alist);
+ free_alist (alist);
+ RETURN_UNGCPRO (result);
+ }
+}
+
+/* Update the instances in the layout. */
+static void
+layout_update (Lisp_Object image_instance, Lisp_Object instantiator)
+{
+ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
+ Lisp_Object border_inst = find_keyword_in_vector (instantiator, Q_border);
+ Lisp_Object justify = find_keyword_in_vector (instantiator, Q_justify);
+ Lisp_Object hjustify = find_keyword_in_vector (instantiator, Q_horizontally_justify);
+ Lisp_Object vjustify = find_keyword_in_vector (instantiator, Q_vertically_justify);
+ Lisp_Object border = Qnil;
+ Lisp_Object children = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii);
+ int structure_changed = 0;
+ struct gcpro gcpro1;
+
+ /* Pick up horizontal justification, left is the default.*/
+ if (!NILP (hjustify))
+ {
+ if (EQ (hjustify, Qright) || EQ (hjustify, Qbottom))
+ IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_RIGHT;
+ else if (EQ (hjustify, Qcenter))
+ IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER;
+ }
+ /* If not set use general justification. */
+ else if (!NILP (justify))
+ {
+ if (EQ (justify, Qright) || EQ (justify, Qbottom))
+ IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_RIGHT;
+ else if (EQ (justify, Qcenter))
+ IMAGE_INSTANCE_SUBWINDOW_H_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER;
+ }
+
+ /* Pick up vertical justification, top is the default. */
+ if (!NILP (vjustify))
+ {
+ if (EQ (vjustify, Qright) || EQ (vjustify, Qbottom))
+ IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_BOTTOM;
+ else if (EQ (vjustify, Qcenter))
+ IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER;
+ }
+ /* If not set use general justification. */
+ else if (!NILP (justify))
+ {
+ if (EQ (justify, Qright) || EQ (justify, Qbottom))
+ IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_BOTTOM;
+ else if (EQ (justify, Qcenter))
+ IMAGE_INSTANCE_SUBWINDOW_V_JUSTIFY (ii) = LAYOUT_JUSTIFY_CENTER;
+ }
+
+ /* We want to avoid consing if we can. This is quite awkward because
+ we have to deal with the border as well as the items. */
+ GCPRO1 (border);
+
+ if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii)))
+ {
+ border = XCAR (children);
+ children = XCDR (children);
+ }
+
+#ifdef DEBUG_WIDGET_OUTPUT
+ stderr_out ("layout updated\n");
+#endif
+ /* Update the border. */
+ if (!NILP (border_inst))
+ {
+ if (VECTORP (border_inst))
+ {
+ /* We are going to be sneaky here and add the border text as
+ just another child, the layout and output routines don't know
+ this and will just display at the offsets we prescribe. */
+ if (!NILP (border))
+ call3 (Qset_glyph_image, border, border_inst,
+ IMAGE_INSTANCE_DOMAIN (ii));
+ else
+ {
+ border = Fcons (call1 (Qmake_glyph, border_inst), Qnil);
+ structure_changed = 1;
+ }
+ IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (0);
+ }
+ else
+ {
+ if (!NILP (border))
+ {
+ border = Qnil;
+ structure_changed = 1;
+ }
+ if (EQ (border_inst, Qt))
+ IMAGE_INSTANCE_LAYOUT_BORDER (ii) = Qetched_in;
+ else
+ IMAGE_INSTANCE_LAYOUT_BORDER (ii) = border_inst;
+ }
+ }
+
+ /* Pick up the sub-widgets. */
+ if (!NILP (items))
+ {
+ int len1, len2;
+ GET_LIST_LENGTH (items, len1);
+ GET_LIST_LENGTH (children, len2);
+ /* The structure hasn't changed so just update the images. */
+ if (!structure_changed && len1 == len2)
+ {
+ /* Pick up the sub-widgets. */
+ for (; !NILP (children); children = XCDR (children), items = XCDR (items))
+ {
+ call3 (Qset_glyph_image, XCAR (children), XCAR (items),
+ IMAGE_INSTANCE_DOMAIN (ii));
+ }
+ }
+ /* The structure has changed so start over. */
+ else
+ {
+ /* Instantiate any new glyphs. */
+ for (; !NILP (items); items = XCDR (items))
+ {
+ /* #### We really want to use call_with_suspended_errors
+ here, but it won't allow us to call lisp. */
+ border = Fcons (call1 (Qmake_glyph, XCAR (items)), border);
+ }
+ IMAGE_INSTANCE_LAYOUT_CHILDREN (ii) = Fnreverse (border);
+ }
+ }
+ UNGCPRO;
+}
+
+static void
+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);
+ Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
+
+#ifdef DEBUG_WIDGET_OUTPUT
+ stderr_out ("layout instantiated\n");
+#endif
+ /* Do widget type instantiation first. */
+ widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg,
+ dest_mask, domain);
+
+ if (NILP (orient))
+ {
+ IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) = LAYOUT_VERTICAL;
+ }
+
+ /* Get child glyphs and finish instantiation. We can't do image
+ instance children yet as we might not have a containing
+ window. */
+ layout_update (image_instance, instantiator);
+}
+
+static void
+layout_post_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object domain)
+{