+ if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW)
+ {
+ XResizeWindow (DisplayOfScreen (IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (ii)),
+ IMAGE_INSTANCE_X_SUBWINDOW_ID (ii),
+ w, h);
+ }
+ else /* must be a widget */
+ {
+ Arg al[2];
+ XtSetArg (al [0], XtNwidth, (Dimension)w);
+ XtSetArg (al [1], XtNheight, (Dimension)h);
+ XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 2);
+ }
+}
+
+/************************************************************************/
+/* widgets */
+/************************************************************************/
+
+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)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), pixel;
+ struct device* d = XDEVICE (device);
+ Lisp_Object frame = FW_FRAME (domain);
+ struct frame* f = XFRAME (frame);
+ XColor fcolor, bcolor;
+ Extbyte* nm=0;
+ Widget wid;
+ Arg al [32];
+ int ac = 0;
+ int id = new_lwlib_id ();
+#ifdef LWLIB_USES_MOTIF
+ XmFontList fontList;
+#endif
+
+ if (!DEVICE_X_P (d))
+ signal_simple_error ("Not an mswindows 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)))
+ GET_C_STRING_OS_DATA_ALLOCA (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm);
+
+ ii->data = xnew_and_zero (struct x_subwindow_data);
+
+ /* copy any args we were given */
+ if (wv->nargs)
+ lw_add_value_args_to_args (wv, al, &ac);
+
+ /* add our own arguments */
+ pixel = FACE_FOREGROUND
+ (IMAGE_INSTANCE_WIDGET_FACE (ii),
+ IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
+ fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+ pixel = FACE_BACKGROUND
+ (IMAGE_INSTANCE_WIDGET_FACE (ii),
+ IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
+ bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+
+ XtSetArg (al [ac], XtNbackground, bcolor.pixel); ac++;
+ XtSetArg (al [ac], XtNforeground, fcolor.pixel); ac++;
+#ifdef LWLIB_USES_MOTIF
+ fontList = XmFontListCreate
+ ((void*)FONT_INSTANCE_X_FONT
+ (XFONT_INSTANCE (widget_face_font_info
+ (domain, IMAGE_INSTANCE_WIDGET_FACE (ii),
+ 0, 0))), XmSTRING_DEFAULT_CHARSET);
+ XtSetArg (al [ac], XmNfontList, fontList ); ac++;
+#else
+ XtSetArg (al [ac], XtNfont, (void*)FONT_INSTANCE_X_FONT
+ (XFONT_INSTANCE (widget_face_font_info
+ (domain,
+ IMAGE_INSTANCE_WIDGET_FACE (ii),
+ 0, 0)))); ac++;
+#endif
+
+ wv->nargs = ac;
+ wv->args = al;
+
+ wid = lw_create_widget (type, wv->name, id, wv, FRAME_X_CONTAINER_WIDGET (f),
+ False, 0, popup_selection_callback, 0);
+
+ IMAGE_INSTANCE_X_WIDGET_LWID (ii) = id;
+#ifdef LWLIB_USES_MOTIF
+ XmFontListFree (fontList);
+#endif
+ /* 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], XtNwidth,
+ (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); ac++;
+ XtSetArg (al [ac], XtNheight,
+ (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); ac++;
+ XtSetValues (wid, al, ac);
+ /* finally get offsets in the frame */
+ 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);
+
+ IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid;
+
+ free_widget_value (wv);
+}
+
+static Lisp_Object
+x_widget_set_property (Lisp_Object image_instance, Lisp_Object prop,
+ Lisp_Object val)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+ if (EQ (prop, Q_text))
+ {
+ Extbyte* str=0;
+ widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii));
+ CHECK_STRING (val);
+ GET_C_STRING_OS_DATA_ALLOCA (val, str);
+ wv->value = str;
+ lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, False);
+ return Qt;
+ }
+ return Qunbound;
+}
+
+/* get properties of a control */
+static Lisp_Object
+x_widget_property (Lisp_Object image_instance, Lisp_Object prop)
+{
+ struct 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, FORMAT_OS);
+ }
+ return Qunbound;
+}
+
+/* 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)
+{
+ struct 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 = xmalloc_widget_value ();
+
+ button_item_to_widget_value (gui, wv, 1, 1);
+
+ if (!NILP (glyph))
+ {
+ if (!IMAGE_INSTANCEP (glyph))
+ glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
+ }
+
+ x_widget_instantiate (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, "button", wv);
+
+ /* add the image if one was given */
+ if (!NILP (glyph) && IMAGE_INSTANCEP (glyph))
+ {
+ Arg al [2];
+ int ac =0;
+#ifdef LWLIB_USES_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);
+ }
+}
+
+/* get properties of a button */
+static Lisp_Object
+x_button_property (Lisp_Object image_instance, Lisp_Object prop)
+{
+ struct 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));
+
+ 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)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
+ widget_value* wv = xmalloc_widget_value ();
+
+ button_item_to_widget_value (gui, wv, 1, 1);
+
+ x_widget_instantiate (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, "progress", wv);
+}
+
+/* set the properties of a progres guage */
+static Lisp_Object
+x_progress_gauge_set_property (Lisp_Object image_instance, Lisp_Object prop,
+ Lisp_Object val)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+ if (EQ (prop, Q_percent))
+ {
+ Arg al [1];
+ CHECK_INT (val);
+ XtSetArg (al[0], XtNvalue, XINT (val));
+ XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 1);
+ return Qt;
+ }
+ return Qunbound;
+}
+
+/* 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)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
+ widget_value* wv = xmalloc_widget_value ();
+
+ button_item_to_widget_value (gui, wv, 1, 1);
+
+ x_widget_instantiate (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, "text-field", wv);
+}
+
+/* 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)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object rest;
+ Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
+ widget_value* wv = xmalloc_widget_value ();
+
+ button_item_to_widget_value (gui, wv, 1, 1);
+
+ x_widget_instantiate (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, "combo-box", wv);
+ /* add items to the combo box */
+ LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
+ {
+#if 0
+ Extbyte* str;
+ XmString xmstr;
+ GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), str);
+ xmstr = XmStringCreate (str, XmSTRING_DEFAULT_CHARSET);
+ XmListAddItem (IMAGE_INSTANCE_X_WIDGET_ID (ii), xmstr, 0);
+ XmStringFree (xmstr);
+#endif
+ }