+ if (!pw)
+ pw = glyph_width (glyph, image_instance) + 2 * WIDGET_BORDER_WIDTH;
+ if (!ph)
+ ph = glyph_height (glyph, image_instance) + 2 * WIDGET_BORDER_HEIGHT;
+ IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii) = 0;
+ IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii) = 0;
+ }
+
+ /* Pick up the margin width. */
+ if (!NILP (mwidth))
+ IMAGE_INSTANCE_MARGIN_WIDTH (ii) = XINT (mwidth);
+
+ IMAGE_INSTANCE_WANTS_INITIAL_FOCUS (ii) = !NILP (ifocus);
+
+ /* Layout for the layout widget is premature at this point since the
+ children will not have been instantiated. We can't instantiate
+ them until the device instantiation method for the layout has
+ been executed. We do however want to record any specified
+ dimensions. */
+ if (pw) IMAGE_INSTANCE_WIDTH (ii) = pw;
+ if (ph) IMAGE_INSTANCE_HEIGHT (ii) = ph;
+}
+
+static void
+widget_post_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object domain)
+{
+#ifdef DEBUG_WIDGETS
+ debug_widget_instances++;
+ stderr_out ("instantiated ");
+ debug_print (instantiator);
+ stderr_out ("%d widgets instantiated\n", debug_widget_instances);
+#endif
+}
+
+/* Get the geometry of a button control. We need to adjust the size
+ depending on the type of button. */
+static void
+button_query_geometry (Lisp_Object image_instance,
+ int* width, int* height,
+ enum image_instance_geometry disp, Lisp_Object domain)
+{
+ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ int w, h;
+ query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii),
+ IMAGE_INSTANCE_WIDGET_FACE (ii),
+ &w, &h, 0, domain);
+ /* Adjust the size for borders. */
+ if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii))
+ {
+ *width = w + 2 * WIDGET_BORDER_WIDTH;
+
+ if (EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qradio)
+ ||
+ EQ (XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (ii))->style, Qtoggle))
+ /* This is an approximation to the size of the actual button bit. */
+ *width += 12;
+ }
+ if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii))
+ *height = h + 2 * WIDGET_BORDER_HEIGHT;
+}
+
+/* tree-view geometry - get the height right */
+static void
+tree_view_query_geometry (Lisp_Object image_instance,
+ int* width, int* height,
+ enum image_instance_geometry disp, Lisp_Object domain)
+{
+ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object items = IMAGE_INSTANCE_WIDGET_ITEMS (ii);
+
+
+ if (*width)
+ {
+ /* #### what should this be. reconsider when X has tree views. */
+ query_string_geometry (IMAGE_INSTANCE_WIDGET_TEXT (ii),
+ IMAGE_INSTANCE_WIDGET_FACE (ii),
+ width, 0, 0, domain);
+ }
+ if (*height)
+ {
+ int len, h;
+ default_face_font_info (domain, 0, 0, &h, 0, 0);
+ GET_LIST_LENGTH (items, len);
+ *height = len * h;
+ }
+}
+
+/* Get the geometry of a tab control. This is based on the number of
+ items and text therin in the tab control. */
+static void
+tab_control_query_geometry (Lisp_Object image_instance,
+ int* width, int* height,
+ enum image_instance_geometry disp, Lisp_Object domain)
+{
+ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object items = XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii));
+ Lisp_Object rest;
+ int tw = 0, th = 0;
+
+ LIST_LOOP (rest, items)
+ {
+ int h, w;
+
+ query_string_geometry (XGUI_ITEM (XCAR (rest))->name,
+ IMAGE_INSTANCE_WIDGET_FACE (ii),
+ &w, &h, 0, domain);
+ tw += 5 * WIDGET_BORDER_WIDTH; /* some bias */
+ tw += w;
+ th = max (th, h + 2 * WIDGET_BORDER_HEIGHT);
+ }
+
+ /* Fixup returned values depending on orientation. */
+ if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii))
+ {
+ if (height) *height = tw;
+ if (width) *width = th;
+ }
+ else
+ {
+ if (height) *height = th;
+ if (width) *width = tw;
+ }
+}
+
+/* Update the contents of a tab control. */
+static void
+tab_control_update (Lisp_Object image_instance,
+ Lisp_Object instantiator)
+{
+ Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
+ /* Record new items for update. *_tab_control_redisplay will do the
+ rest. */
+ if (!NILP (items))
+ {
+ Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
+ check_valid_item_list (items);
+#ifdef DEBUG_WIDGET_OUTPUT
+ stderr_out ("tab control %p updated\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
+#endif
+ /* Don't set the actual items since we might decide not to use
+ the new ones (because nothing has really changed). If we did
+ set them and didn't use them then we would get into whole
+ heaps of trouble when the old items get GC'd. */
+ IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) =
+ Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
+ parse_gui_item_tree_children (items));
+ IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 1;