X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fglyphs-x.c;h=9ce627b3b959f0938ca0913f6830774606c02060;hp=b162822ab26a13ec863507c1f6a0ddb698641ede;hb=59eec5f21669e81977b5b1fe9bf717cab49cf7fb;hpb=41e784bb39d67f3906871511cb30805a71a6d6b3 diff --git a/src/glyphs-x.c b/src/glyphs-x.c index b162822..9ce627b 100644 --- a/src/glyphs-x.c +++ b/src/glyphs-x.c @@ -4,7 +4,7 @@ Copyright (C) 1995 Tinker Systems Copyright (C) 1995, 1996 Ben Wing Copyright (C) 1995 Sun Microsystems - Copyright (C) 1999 Andy Piper + Copyright (C) 1999, 2000 Andy Piper This file is part of XEmacs. @@ -17,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. - 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, @@ -25,6 +24,8 @@ Boston, MA 02111-1307, USA. */ /* 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 @@ -98,19 +99,18 @@ DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing); DECLARE_IMAGE_INSTANTIATOR_FORMAT (string); DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit); -DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout); #ifdef HAVE_JPEG DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg); #endif #ifdef HAVE_TIFF DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff); -#endif +#endif #ifdef HAVE_PNG DECLARE_IMAGE_INSTANTIATOR_FORMAT (png); -#endif +#endif #ifdef HAVE_GIF DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif); -#endif +#endif #ifdef HAVE_XPM DEFINE_DEVICE_IIFORMAT (x, xpm); #endif @@ -128,7 +128,9 @@ DEFINE_IMAGE_INSTANTIATOR_FORMAT (font); 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); @@ -149,10 +151,10 @@ static void cursor_font_instantiate (Lisp_Object image_instance, #ifdef HAVE_WIDGETS static void update_widget_face (widget_value* wv, - struct Lisp_Image_Instance* ii, Lisp_Object domain); + Lisp_Image_Instance* ii, Lisp_Object domain); static void update_tab_widget_face (widget_value* wv, - struct Lisp_Image_Instance* ii, Lisp_Object domain); + Lisp_Image_Instance* ii, Lisp_Object domain); #endif #include "bitmaps.h" @@ -233,7 +235,7 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height, *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++) { @@ -264,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)]; -#if WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN if (outimg->byte_order == MSBFirst) for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q]; else @@ -339,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); -#if WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN if (outimg->byte_order == MSBFirst) for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q]; else @@ -359,7 +361,7 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height, static void -x_print_image_instance (struct Lisp_Image_Instance *p, +x_print_image_instance (Lisp_Image_Instance *p, Lisp_Object printcharfun, int escapeflag) { @@ -389,16 +391,19 @@ extern int debug_widget_instances; #endif static void -x_finalize_image_instance (struct Lisp_Image_Instance *p) +x_finalize_image_instance (Lisp_Image_Instance *p) { 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)); - - if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) + 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)) { @@ -408,9 +413,15 @@ x_finalize_image_instance (struct Lisp_Image_Instance *p) #endif lw_destroy_widget (IMAGE_INSTANCE_X_WIDGET_ID (p)); lw_destroy_widget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); - IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0; + + /* We can release the callbacks again. */ + ungcpro_popup_callbacks (IMAGE_INSTANCE_X_WIDGET_LWID (p)); + + IMAGE_INSTANCE_X_WIDGET_ID (p) = 0; + IMAGE_INSTANCE_X_CLIPWIDGET (p) = 0; } } +#endif else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) { if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) @@ -427,7 +438,7 @@ x_finalize_image_instance (struct Lisp_Image_Instance *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++) @@ -445,7 +456,7 @@ x_finalize_image_instance (struct Lisp_Image_Instance *p) XFreeCursor (dpy, IMAGE_INSTANCE_X_CURSOR (p)); IMAGE_INSTANCE_X_CURSOR (p) = 0; } - + if (IMAGE_INSTANCE_X_NPIXELS (p) != 0) { XFreeColors (dpy, @@ -473,8 +484,8 @@ x_finalize_image_instance (struct Lisp_Image_Instance *p) } 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)) { @@ -493,7 +504,7 @@ x_image_instance_equal (struct Lisp_Image_Instance *p1, } 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)) { @@ -513,13 +524,13 @@ x_image_instance_hash (struct Lisp_Image_Instance *p, int depth) 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); IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices; - IMAGE_INSTANCE_X_PIXMAP_SLICES (ii) = + IMAGE_INSTANCE_X_PIXMAP_SLICES (ii) = xnew_array_and_zero (Pixmap, slices); IMAGE_INSTANCE_TYPE (ii) = type; IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil; @@ -564,7 +575,7 @@ x_locate_pixmap_file (Lisp_Object name) (XSTRING_BYTE (name, 2) == '/'))))) { if (!NILP (Ffile_readable_p (name))) - return name; + return Fexpand_file_name (name, Qnil); else return Qnil; } @@ -833,7 +844,7 @@ maybe_recolor_cursor (Lisp_Object image_instance, Lisp_Object foreground, 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, @@ -893,7 +904,7 @@ init_image_instance_from_x_image (struct Lisp_Image_Instance *ii, } static void -image_instance_add_x_image (struct Lisp_Image_Instance *ii, +image_instance_add_x_image (Lisp_Image_Instance *ii, XImage *ximage, int slice, Lisp_Object instantiator) @@ -928,7 +939,7 @@ image_instance_add_x_image (struct Lisp_Image_Instance *ii, } static void -x_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, +x_init_image_instance_from_eimage (Lisp_Image_Instance *ii, int width, int height, int slices, unsigned char *eimage, @@ -945,7 +956,7 @@ x_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, for (slice = 0; slice < slices; slice++) { - ximage = convert_EImage_to_XImage (device, width, height, + ximage = convert_EImage_to_XImage (device, width, height, eimage + (width * height * 3 * slice), &pixtbl, &npixels); if (!ximage) @@ -975,7 +986,7 @@ x_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, } } -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) { @@ -989,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! */ - CONST Extbyte *bits) + const Extbyte *bits) { return XCreatePixmapFromBitmapData (DEVICE_X_DISPLAY (XDEVICE(device)), XtWindow (DEVICE_XT_APP_SHELL (XDEVICE (device))), @@ -1001,10 +1012,10 @@ pixmap_from_xbm_inline (Lisp_Object device, int width, int height, 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! */ - CONST char *bits, + const char *bits, Lisp_Object instantiator, Lisp_Object pointer_fg, Lisp_Object pointer_bg, @@ -1142,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! */ - 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); - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); Pixmap mask = 0; - CONST char *gcc_may_you_rot_in_hell; 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, @@ -1175,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); - CONST char *gcc_go_home; + const char *ext_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)), - XINT (XCAR (XCDR (data))), gcc_go_home); + XINT (XCAR (XCDR (data))), ext_data); } @@ -1288,11 +1296,11 @@ xpm_free (XpmAttributes *xpmattrs) 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 */ - 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; @@ -1659,13 +1667,14 @@ x_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, { 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)); - GET_C_STRING_BINARY_DATA_ALLOCA (data, dstring); + LISP_STRING_TO_EXTERNAL (data, dstring, Qbinary); if ((p = strchr (dstring, ':'))) { @@ -1729,7 +1738,8 @@ autodetect_validate (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; @@ -1820,10 +1830,10 @@ autodetect_possible_dest_types (void) 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; @@ -1836,8 +1846,8 @@ autodetect_instantiate (Lisp_Object image_instance, 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); @@ -1924,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); - 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; @@ -2022,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); - 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; - CONST char *name_ext; + const char *name_ext; Lisp_Object foreground, background; if (!DEVICE_X_P (XDEVICE (device))) @@ -2037,7 +2047,7 @@ 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); - 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); @@ -2056,7 +2066,7 @@ static int 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); @@ -2109,12 +2119,12 @@ x_colorize_image_instance (Lisp_Object image_instance, /* unmap the image if it is a widget. This is used by redisplay via redisplay_unmap_subwindows */ static void -x_unmap_subwindow (struct Lisp_Image_Instance *p) +x_unmap_subwindow (Lisp_Image_Instance *p) { if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) { - XUnmapWindow - (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), + XUnmapWindow + (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), IMAGE_INSTANCE_X_CLIPWINDOW (p)); } else /* must be a widget */ @@ -2126,63 +2136,132 @@ x_unmap_subwindow (struct Lisp_Image_Instance *p) /* map the subwindow. This is used by redisplay via redisplay_output_subwindow */ static void -x_map_subwindow (struct Lisp_Image_Instance *p, int x, int y, +x_map_subwindow (Lisp_Image_Instance *p, int x, int y, struct display_glyph_area* dga) { 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), + IMAGE_INSTANCE_X_CLIPWINDOW (p), x, y, dga->width, dga->height); XMoveWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), subwindow, -dga->xoffset, -dga->yoffset); - XMapWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), - IMAGE_INSTANCE_X_CLIPWINDOW (p)); + 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), + 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); - XtMapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); + 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 -x_update_subwindow (struct Lisp_Image_Instance *p) +x_redisplay_subwindow (Lisp_Image_Instance *p) +{ + /* Update the subwindow size if necessary. */ + if (IMAGE_INSTANCE_SIZE_CHANGED (p)) + { + XResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), + IMAGE_INSTANCE_X_SUBWINDOW_ID (p), + IMAGE_INSTANCE_WIDTH (p), + IMAGE_INSTANCE_HEIGHT (p)); + } +} + +/* Update all attributes that have changed. Lwlib actually does most + of this for us. */ +static void +x_redisplay_widget (Lisp_Image_Instance *p) { + /* This function can GC if IN_REDISPLAY is false. */ #ifdef HAVE_WIDGETS - if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) + 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); + } + + /* 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)); + } + + /* 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; + } + + /* Possibly update the size. */ + if (IMAGE_INSTANCE_SIZE_CHANGED (p) + || + IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p) + || + IMAGE_INSTANCE_TEXT_CHANGED (p)) { - Arg al[5]; - widget_value* wv = gui_items_to_widget_values - (IMAGE_INSTANCE_WIDGET_ITEMS (p)); + assert (IMAGE_INSTANCE_X_WIDGET_ID (p) && + IMAGE_INSTANCE_X_CLIPWIDGET (p)) ; - /* This seems ugly, but I'm not sure what else to do. */ - if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qtab_control)) + if (IMAGE_INSTANCE_X_WIDGET_ID (p)->core.being_destroyed + || !XtIsManaged(IMAGE_INSTANCE_X_WIDGET_ID (p))) { - update_tab_widget_face (wv, p, - IMAGE_INSTANCE_SUBWINDOW_FRAME (p)); + Lisp_Object sw; + XSETIMAGE_INSTANCE (sw, p); + signal_simple_error ("XEmacs bug: subwindow is deleted", sw); } - /* update the colors and font */ - update_widget_face (wv, p, IMAGE_INSTANCE_SUBWINDOW_FRAME (p)); - - /* now modify the widget */ - lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p), - wv, True); - free_widget_value_tree (wv); - /* We have to do this otherwise Motif will unceremoniously - resize us when the label gets set. */ - XtSetArg (al [0], XtNwidth, IMAGE_INSTANCE_WIDGET_WIDTH (p)); - XtSetArg (al [1], XtNheight, IMAGE_INSTANCE_WIDGET_HEIGHT (p)); - XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (p), al, 2); + + 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 } @@ -2193,17 +2272,17 @@ x_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, int dest_mask, Lisp_Object domain) { /* 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 frame = FW_FRAME (domain); + Lisp_Object frame = DOMAIN_FRAME (domain); struct frame* f = XFRAME (frame); Display *dpy; Screen *xs; Window pw, win; XSetWindowAttributes xswa; Mask valueMask = 0; - unsigned int w = IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), - h = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii); + unsigned int w = IMAGE_INSTANCE_WIDTH (ii), + h = IMAGE_INSTANCE_HEIGHT (ii); if (!DEVICE_X_P (XDEVICE (device))) signal_simple_error ("Not an X device", device); @@ -2224,9 +2303,9 @@ x_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, valueMask |= CWBackingStore; xswa.colormap = DefaultColormapOfScreen (xs); valueMask |= CWColormap; - + /* Create a window for clipping */ - IMAGE_INSTANCE_X_CLIPWINDOW (ii) = + IMAGE_INSTANCE_X_CLIPWINDOW (ii) = XCreateWindow (dpy, pw, 0, 0, w, h, 0, CopyFromParent, InputOutput, CopyFromParent, valueMask, &xswa); @@ -2236,7 +2315,7 @@ x_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 0, 0, w, h, 0, CopyFromParent, InputOutput, CopyFromParent, valueMask, &xswa); - + IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)win; } @@ -2249,7 +2328,7 @@ Subwindows are not currently implemented. (subwindow, property, data)) { Atom property_atom; - struct Lisp_Subwindow *sw; + Lisp_Subwindow *sw; Display *dpy; CHECK_SUBWINDOW (subwindow); @@ -2270,32 +2349,6 @@ Subwindows are not currently implemented. } #endif -static void -x_resize_subwindow (struct Lisp_Image_Instance* ii, int w, int h) -{ - if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW) - { - XResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (ii), - IMAGE_INSTANCE_X_SUBWINDOW_ID (ii), - w, h); - } - else /* must be a widget */ - { - Arg al[2]; - - if (!XtIsRealized (IMAGE_INSTANCE_X_WIDGET_ID (ii))) - { - Lisp_Object sw; - XSETIMAGE_INSTANCE (sw, ii); - signal_simple_error ("XEmacs bug: subwindow is not realized", sw); - } - - XtSetArg (al [0], XtNwidth, (Dimension)w); - XtSetArg (al [1], XtNheight, (Dimension)h); - XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 2); - } -} - #ifdef HAVE_WIDGETS @@ -2304,53 +2357,67 @@ x_resize_subwindow (struct Lisp_Image_Instance* ii, int w, int h) /************************************************************************/ static void -update_widget_face (widget_value* wv, struct Lisp_Image_Instance *ii, +update_widget_face (widget_value* wv, Lisp_Image_Instance *ii, Lisp_Object domain) { #ifdef LWLIB_WIDGETS_MOTIF XmFontList fontList; #endif - - Lisp_Object pixel = FACE_FOREGROUND + /* Update the foreground. */ + Lisp_Object pixel = FACE_FOREGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), domain); - XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); - + 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 (widget_face_font_info - (domain, + (FONT_INSTANCE_X_FONT + (XFONT_INSTANCE (query_string_font + (IMAGE_INSTANCE_WIDGET_TEXT (ii), IMAGE_INSTANCE_WIDGET_FACE (ii), - 0, 0))), XmSTRING_DEFAULT_CHARSET); + 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 (widget_face_font_info - (domain, + 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), - 0, 0)))); + 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); } static void -update_tab_widget_face (widget_value* wv, struct Lisp_Image_Instance *ii, +update_tab_widget_face (widget_value* wv, Lisp_Image_Instance *ii, Lisp_Object domain) { if (wv->contents) { widget_value* val = wv->contents, *cur; - + /* Give each child label the correct foreground color. */ - Lisp_Object pixel = FACE_FOREGROUND + 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); @@ -2363,12 +2430,12 @@ 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) + const char* type, widget_value* wv) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + 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); + Lisp_Object frame = DOMAIN_FRAME (domain); struct frame* f = XFRAME (frame); char* nm=0; Widget wid; @@ -2387,7 +2454,7 @@ x_widget_instantiate (Lisp_Object image_instance, Lisp_Object 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); + LISP_STRING_TO_EXTERNAL (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm, Qnative); ii->data = xnew_and_zero (struct x_subwindow_data); @@ -2398,10 +2465,10 @@ x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 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_SUBWINDOW_WIDTH (ii)); - lw_add_widget_value_arg (clip_wv, XtNheight, - (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); + 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"); @@ -2422,24 +2489,24 @@ x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 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 + pixel = FACE_FOREGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + IMAGE_INSTANCE_FRAME (ii)); fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); pixel = FACE_BACKGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), - IMAGE_INSTANCE_SUBWINDOW_FRAME (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_SUBWINDOW_WIDTH (ii)); - lw_add_widget_value_arg (wv, XtNheight, - (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); + 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); @@ -2448,15 +2515,6 @@ x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid; IMAGE_INSTANCE_X_WIDGET_LWID (ii) = id; - - /* Resize the widget here so that the values do not get copied by - lwlib. */ - 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 (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, ac); /* 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. */ @@ -2468,51 +2526,35 @@ x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, XtSetMappedWhenManaged (wid, TRUE); free_widget_value_tree (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); - - /* Modify the text properties of the widget */ - if (EQ (prop, Q_text)) - { - char* str; - 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; - } - - /* Modify the text properties of the widget */ - else if (EQ (prop, Q_face)) - { - widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii)); - update_widget_face (wv, ii, IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); - lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, False); - return Qt; - } - return Qunbound; + /* A kludgy but simple way to make sure the callback for a widget + doesn't get deleted. */ + gcpro_popup_callbacks (id); } /* 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); + 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 build_ext_string (wv->value, Qnative); } return Qunbound; } +/* 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) +{ + x_widget_instantiate (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, domain, "layout", 0); +} + /* 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 @@ -2524,12 +2566,10 @@ 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_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); + widget_value* wv = gui_items_to_widget_values (image_instance, gui, 1); if (!NILP (glyph)) { @@ -2541,7 +2581,8 @@ x_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, pointer_bg, dest_mask, domain, "button", wv); /* add the image if one was given */ - if (!NILP (glyph) && IMAGE_INSTANCEP (glyph)) + if (!NILP (glyph) && IMAGE_INSTANCEP (glyph) + && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph))) { Arg al [2]; int ac =0; @@ -2555,11 +2596,35 @@ x_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, } } +/* Update a button's clicked state. + + #### 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); +} + /* 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); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); /* check the state of a button */ if (EQ (prop, Q_selected)) { @@ -2579,32 +2644,31 @@ x_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object instantiat Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + 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); + 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, "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) +/* set the properties of a progress gauge */ +static void +x_progress_gauge_redisplay (Lisp_Object image_instance) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - if (EQ (prop, Q_percent)) + if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) { Arg al [1]; - CHECK_INT (val); + 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); - return Qt; } - return Qunbound; } /* instantiate an edit control */ @@ -2613,12 +2677,10 @@ 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_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); - + 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); } @@ -2630,15 +2692,16 @@ 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_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); widget_value * wv = 0; /* This is not done generically because of sizing problems under mswindows. */ - widget_instantiate_1 (image_instance, instantiator, pointer_fg, - pointer_bg, dest_mask, domain, 1, 0, 0); + 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); - wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); - x_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "combo-box", wv); } @@ -2649,45 +2712,102 @@ 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) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - widget_value * wv = - gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); - - update_tab_widget_face (wv, ii, - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); - + 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 Lisp_Object -x_tab_control_set_property (Lisp_Object image_instance, Lisp_Object prop, - Lisp_Object val) +/* Set the properties of a tab control */ +static void +x_tab_control_redisplay (Lisp_Object image_instance) { - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - - if (EQ (prop, Q_items)) + 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)) { - widget_value * wv = 0; - check_valid_item_list_1 (val); + /* See previous comments on the brokeness of lwlib. - IMAGE_INSTANCE_WIDGET_ITEMS (ii) = - Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)), - parse_gui_item_tree_children (val)); + #### 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); - wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); - - update_tab_widget_face (wv, ii, - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + 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); - return Qt; } - - return Qunbound; } /* instantiate a static control possible for putting other things in */ @@ -2696,12 +2816,10 @@ x_label_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_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); - + 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); } @@ -2734,8 +2852,8 @@ console_type_create_glyphs_x (void) CONSOLE_HAS_METHOD (x, locate_pixmap_file); CONSOLE_HAS_METHOD (x, unmap_subwindow); CONSOLE_HAS_METHOD (x, map_subwindow); - CONSOLE_HAS_METHOD (x, resize_subwindow); - CONSOLE_HAS_METHOD (x, update_subwindow); + CONSOLE_HAS_METHOD (x, redisplay_widget); + CONSOLE_HAS_METHOD (x, redisplay_subwindow); } void @@ -2743,7 +2861,9 @@ 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 @@ -2755,30 +2875,33 @@ image_instantiator_format_create_glyphs_x (void) #endif #ifdef HAVE_TIFF IIFORMAT_VALID_CONSOLE (x, tiff); -#endif +#endif #ifdef HAVE_PNG IIFORMAT_VALID_CONSOLE (x, png); -#endif +#endif #ifdef HAVE_GIF IIFORMAT_VALID_CONSOLE (x, gif); -#endif +#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); - IIFORMAT_HAS_DEVMETHOD (x, widget, set_property); /* progress gauge */ INITIALIZE_DEVICE_IIFORMAT (x, progress_gauge); - IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, set_property); + IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, redisplay); IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, instantiate); /* text field */ INITIALIZE_DEVICE_IIFORMAT (x, edit_field); @@ -2787,12 +2910,12 @@ image_instantiator_format_create_glyphs_x (void) /* combo box */ INITIALIZE_DEVICE_IIFORMAT (x, combo_box); IIFORMAT_HAS_DEVMETHOD (x, combo_box, instantiate); - IIFORMAT_HAS_SHARED_DEVMETHOD (x, combo_box, set_property, tab_control); + 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, set_property); + IIFORMAT_HAS_DEVMETHOD (x, tab_control, redisplay); /* label */ INITIALIZE_DEVICE_IIFORMAT (x, label); IIFORMAT_HAS_DEVMETHOD (x, label, instantiate); @@ -2859,7 +2982,7 @@ complex_vars_of_glyphs_x (void) make_int (name##_height), \ make_ext_string (name##_bits, \ sizeof (name##_bits), \ - FORMAT_BINARY))), \ + Qbinary))), \ Qglobal, Qx, Qnil) BUILD_GLYPH_INST (Vtruncation_glyph, truncator);