X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fglyphs-x.c;h=c326e75ad70916cf1d17b914f56b0ae3673afb9c;hp=82cba3a7d0c1738fa2e6211dd4ecb263a3b8a9f0;hb=ea1ea793fe6e244ef5555ed983423a204101af13;hpb=77dcef404dc78635f6ffa8f71a803d2bc7cc8921 diff --git a/src/glyphs-x.c b/src/glyphs-x.c index 82cba3a..c326e75 100644 --- a/src/glyphs-x.c +++ b/src/glyphs-x.c @@ -4,6 +4,7 @@ Copyright (C) 1995 Tinker Systems Copyright (C) 1995, 1996 Ben Wing Copyright (C) 1995 Sun Microsystems + Copyright (C) 1999 Andy Piper This file is part of XEmacs. @@ -39,7 +40,8 @@ Boston, MA 02111-1307, USA. */ Many changes for color work and optimizations by Jareth Hein for 21.0 Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0 TIFF code by Jareth Hein for 21.0 - GIF/JPEG/PNG/TIFF code moved to new glyph-eimage.c for 21.0 + GIF/JPEG/PNG/TIFF code moved to new glyph-eimage.c by Andy Piper for 21.0 + Subwindow and Widget support by Andy Piper for 21.2 TODO: Convert images.el to C and stick it in here? @@ -51,12 +53,18 @@ Boston, MA 02111-1307, USA. */ #include "console-x.h" #include "glyphs-x.h" #include "objects-x.h" +#ifdef HAVE_WIDGETS +#include "gui-x.h" +#endif #include "xmu.h" #include "buffer.h" +#include "window.h" #include "frame.h" #include "insdel.h" #include "opaque.h" +#include "gui.h" +#include "faces.h" #include "imgproc.h" @@ -68,6 +76,11 @@ Boston, MA 02111-1307, USA. */ #include "file-coding.h" #endif +#ifdef LWLIB_WIDGETS_MOTIF +#include +#endif +#include + #if INTBITS == 32 # define FOUR_BYTE_TYPE unsigned int #elif LONGBITS == 32 @@ -80,9 +93,30 @@ Boston, MA 02111-1307, USA. */ #define LISP_DEVICE_TO_X_SCREEN(dev) XDefaultScreenOfDisplay (DEVICE_X_DISPLAY (XDEVICE (dev))) +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 +#ifdef HAVE_PNG +DECLARE_IMAGE_INSTANTIATOR_FORMAT (png); +#endif +#ifdef HAVE_GIF +DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif); +#endif +#ifdef HAVE_XPM +DEFINE_DEVICE_IIFORMAT (x, xpm); +#endif +DEFINE_DEVICE_IIFORMAT (x, xbm); +DEFINE_DEVICE_IIFORMAT (x, subwindow); #ifdef HAVE_XFACE -DEFINE_IMAGE_INSTANTIATOR_FORMAT (xface); -Lisp_Object Qxface; +DEFINE_DEVICE_IIFORMAT (x, xface); #endif DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font); @@ -92,6 +126,18 @@ DEFINE_IMAGE_INSTANTIATOR_FORMAT (font); DEFINE_IMAGE_INSTANTIATOR_FORMAT (autodetect); +#ifdef HAVE_WIDGETS +DEFINE_DEVICE_IIFORMAT (x, widget); +DEFINE_DEVICE_IIFORMAT (x, button); +DEFINE_DEVICE_IIFORMAT (x, progress_gauge); +DEFINE_DEVICE_IIFORMAT (x, edit_field); +#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 +DEFINE_DEVICE_IIFORMAT (x, combo_box); +#endif +DEFINE_DEVICE_IIFORMAT (x, tab_control); +DEFINE_DEVICE_IIFORMAT (x, label); +#endif + static void cursor_font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, Lisp_Object pointer_fg, @@ -99,6 +145,11 @@ static void cursor_font_instantiate (Lisp_Object image_instance, int dest_mask, Lisp_Object domain); +#ifdef HAVE_WIDGETS +static void +update_widget_face (struct Lisp_Image_Instance* ii, Lisp_Object domain); +#endif + #include "bitmaps.h" @@ -119,7 +170,7 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height, Colormap cmap; Visual *vis; XImage *outimg; - int depth, bitmap_pad, byte_cnt, i, j; + int depth, bitmap_pad, bits_per_pixel, byte_cnt, i, j; int rd,gr,bl,q; unsigned char *data, *ip, *dp; quant_table *qtable = 0; @@ -144,13 +195,15 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height, bitmap_pad = ((depth > 16) ? 32 : (depth > 8) ? 16 : 8); - byte_cnt = bitmap_pad >> 3; outimg = XCreateImage (dpy, vis, depth, ZPixmap, 0, 0, width, height, bitmap_pad, 0); if (!outimg) return NULL; + bits_per_pixel = outimg->bits_per_pixel; + byte_cnt = bits_per_pixel >> 3; + data = (unsigned char *) xmalloc (outimg->bytes_per_line * height); if (!data) { @@ -314,15 +367,15 @@ x_print_image_instance (struct Lisp_Image_Instance *p, } write_c_string (")", printcharfun); break; -#if HAVE_SUBWINDOWS - case IMAGE_SUBWINDOW: - /* #### implement me */ -#endif default: break; } } +#ifdef DEBUG_WIDGETS +extern int debug_widget_instances; +#endif + static void x_finalize_image_instance (struct Lisp_Image_Instance *p) { @@ -333,30 +386,71 @@ x_finalize_image_instance (struct Lisp_Image_Instance *p) { Display *dpy = DEVICE_X_DISPLAY (XDEVICE (p->device)); - if (IMAGE_INSTANCE_X_PIXMAP (p)) - XFreePixmap (dpy, IMAGE_INSTANCE_X_PIXMAP (p)); - if (IMAGE_INSTANCE_X_MASK (p) && - IMAGE_INSTANCE_X_MASK (p) != IMAGE_INSTANCE_X_PIXMAP (p)) - XFreePixmap (dpy, IMAGE_INSTANCE_X_MASK (p)); - IMAGE_INSTANCE_X_PIXMAP (p) = 0; - IMAGE_INSTANCE_X_MASK (p) = 0; - - if (IMAGE_INSTANCE_X_CURSOR (p)) + if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) + { + if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) + { +#ifdef DEBUG_WIDGETS + debug_widget_instances--; + stderr_out ("widget destroyed, %d left\n", debug_widget_instances); +#endif + lw_destroy_widget (IMAGE_INSTANCE_X_WIDGET_ID (p)); + lw_destroy_widget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); + IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0; + } + } + else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) { - XFreeCursor (dpy, IMAGE_INSTANCE_X_CURSOR (p)); - IMAGE_INSTANCE_X_CURSOR (p) = 0; + if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) + XDestroyWindow (dpy, IMAGE_INSTANCE_X_SUBWINDOW_ID (p)); + IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0; } - - if (IMAGE_INSTANCE_X_NPIXELS (p) != 0) + else { - XFreeColors (dpy, - IMAGE_INSTANCE_X_COLORMAP (p), - IMAGE_INSTANCE_X_PIXELS (p), - IMAGE_INSTANCE_X_NPIXELS (p), 0); - IMAGE_INSTANCE_X_NPIXELS (p) = 0; + int i; + if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p)) + disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p)); + + if (IMAGE_INSTANCE_X_MASK (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++) + if (IMAGE_INSTANCE_X_PIXMAP_SLICE (p,i)) + { + XFreePixmap (dpy, IMAGE_INSTANCE_X_PIXMAP_SLICE (p,i)); + IMAGE_INSTANCE_X_PIXMAP_SLICE (p, i) = 0; + } + xfree (IMAGE_INSTANCE_X_PIXMAP_SLICES (p)); + IMAGE_INSTANCE_X_PIXMAP_SLICES (p) = 0; + } + + if (IMAGE_INSTANCE_X_CURSOR (p)) + { + XFreeCursor (dpy, IMAGE_INSTANCE_X_CURSOR (p)); + IMAGE_INSTANCE_X_CURSOR (p) = 0; + } + + if (IMAGE_INSTANCE_X_NPIXELS (p) != 0) + { + XFreeColors (dpy, + IMAGE_INSTANCE_X_COLORMAP (p), + IMAGE_INSTANCE_X_PIXELS (p), + IMAGE_INSTANCE_X_NPIXELS (p), 0); + IMAGE_INSTANCE_X_NPIXELS (p) = 0; + } } } - if (IMAGE_INSTANCE_X_PIXELS (p)) + /* You can sometimes have pixels without a live device. I forget + why, but that's why we free them here if we have a pixmap type + image instance. It probably means that we might also get a memory + leak with widgets. */ + if (IMAGE_INSTANCE_TYPE (p) != IMAGE_WIDGET + && IMAGE_INSTANCE_TYPE (p) != IMAGE_SUBWINDOW + && IMAGE_INSTANCE_X_PIXELS (p)) { xfree (IMAGE_INSTANCE_X_PIXELS (p)); IMAGE_INSTANCE_X_PIXELS (p) = 0; @@ -378,10 +472,6 @@ x_image_instance_equal (struct Lisp_Image_Instance *p1, if (IMAGE_INSTANCE_X_COLORMAP (p1) != IMAGE_INSTANCE_X_COLORMAP (p2) || IMAGE_INSTANCE_X_NPIXELS (p1) != IMAGE_INSTANCE_X_NPIXELS (p2)) return 0; -#if HAVE_SUBWINDOWS - case IMAGE_SUBWINDOW: - /* #### implement me */ -#endif break; default: break; @@ -399,11 +489,6 @@ x_image_instance_hash (struct Lisp_Image_Instance *p, int depth) case IMAGE_COLOR_PIXMAP: case IMAGE_POINTER: return IMAGE_INSTANCE_X_NPIXELS (p); -#if HAVE_SUBWINDOWS - case IMAGE_SUBWINDOW: - /* #### implement me */ - return 0; -#endif default: return 0; } @@ -417,9 +502,13 @@ x_image_instance_hash (struct Lisp_Image_Instance *p, int depth) static void x_initialize_pixmap_image_instance (struct 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) = + xnew_array_and_zero (Pixmap, slices); IMAGE_INSTANCE_TYPE (ii) = type; IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil; IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil; @@ -508,13 +597,13 @@ x_locate_pixmap_file (Lisp_Object name) { Lisp_Object found; - if (locate_file (Vx_bitmap_file_path, name, "", &found, R_OK) < 0) + if (locate_file (Vx_bitmap_file_path, name, Qnil, &found, R_OK) < 0) { Lisp_Object temp = list1 (Vdata_directory); struct gcpro gcpro1; GCPRO1 (temp); - locate_file (temp, name, "", &found, R_OK); + locate_file (temp, name, Qnil, &found, R_OK); UNGCPRO; } @@ -738,6 +827,7 @@ init_image_instance_from_x_image (struct Lisp_Image_Instance *ii, Colormap cmap, unsigned long *pixels, int npixels, + int slices, Lisp_Object instantiator) { Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); @@ -773,13 +863,15 @@ init_image_instance_from_x_image (struct Lisp_Image_Instance *ii, XFreeGC (dpy, gc); - x_initialize_pixmap_image_instance (ii, IMAGE_COLOR_PIXMAP); + x_initialize_pixmap_image_instance (ii, slices, IMAGE_COLOR_PIXMAP); IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = find_keyword_in_vector (instantiator, Q_file); + /* Fixup a set of pixmaps. */ IMAGE_INSTANCE_X_PIXMAP (ii) = pixmap; - IMAGE_INSTANCE_X_MASK (ii) = 0; + + IMAGE_INSTANCE_PIXMAP_MASK (ii) = 0; IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = ximage->width; IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = ximage->height; IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = ximage->depth; @@ -789,8 +881,44 @@ init_image_instance_from_x_image (struct Lisp_Image_Instance *ii, } static void +image_instance_add_x_image (struct Lisp_Image_Instance *ii, + XImage *ximage, + int slice, + Lisp_Object instantiator) +{ + Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); + Display *dpy; + GC gc; + Drawable d; + Pixmap pixmap; + + dpy = DEVICE_X_DISPLAY (XDEVICE (device)); + d = XtWindow(DEVICE_XT_APP_SHELL (XDEVICE (device))); + + pixmap = XCreatePixmap (dpy, d, ximage->width, + ximage->height, ximage->depth); + if (!pixmap) + signal_simple_error ("Unable to create pixmap", instantiator); + + gc = XCreateGC (dpy, pixmap, 0, NULL); + if (!gc) + { + XFreePixmap (dpy, pixmap); + signal_simple_error ("Unable to create GC", instantiator); + } + + XPutImage (dpy, pixmap, gc, ximage, 0, 0, 0, 0, + ximage->width, ximage->height); + + XFreeGC (dpy, gc); + + IMAGE_INSTANCE_X_PIXMAP_SLICE (ii, slice) = pixmap; +} + +static void x_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, int width, int height, + int slices, unsigned char *eimage, int dest_mask, Lisp_Object instantiator, @@ -800,29 +928,38 @@ x_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, Colormap cmap = DEVICE_X_COLORMAP (XDEVICE(device)); unsigned long *pixtbl = NULL; int npixels = 0; + int slice; XImage* ximage; - ximage = convert_EImage_to_XImage (device, width, height, eimage, - &pixtbl, &npixels); - if (!ximage) + for (slice = 0; slice < slices; slice++) { - if (pixtbl) xfree (pixtbl); - signal_image_error("EImage to XImage conversion failed", instantiator); - } + ximage = convert_EImage_to_XImage (device, width, height, + eimage + (width * height * 3 * slice), + &pixtbl, &npixels); + if (!ximage) + { + if (pixtbl) xfree (pixtbl); + signal_image_error("EImage to XImage conversion failed", instantiator); + } - /* Now create the pixmap and set up the image instance */ - init_image_instance_from_x_image (ii, ximage, dest_mask, - cmap, pixtbl, npixels, - instantiator); + /* Now create the pixmap and set up the image instance */ + if (slice == 0) + init_image_instance_from_x_image (ii, ximage, dest_mask, + cmap, pixtbl, npixels, slices, + instantiator); + else + image_instance_add_x_image (ii, ximage, slice, instantiator); - if (ximage) - { - if (ximage->data) - { - xfree (ximage->data); - ximage->data = 0; - } - XDestroyImage (ximage); + if (ximage) + { + if (ximage->data) + { + xfree (ximage->data); + ximage->data = 0; + } + XDestroyImage (ximage); + ximage = 0; + } } } @@ -897,7 +1034,7 @@ init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii, IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK); - x_initialize_pixmap_image_instance (ii, type); + x_initialize_pixmap_image_instance (ii, 1, type); IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width; IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height; IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = @@ -1201,7 +1338,7 @@ x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, visual = DEVICE_X_VISUAL (XDEVICE(device)); #endif - x_initialize_pixmap_image_instance (ii, type); + x_initialize_pixmap_image_instance (ii, 1, type); assert (!NILP (data)); @@ -1311,7 +1448,7 @@ x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, pixels = NULL; IMAGE_INSTANCE_X_PIXMAP (ii) = pixmap; - IMAGE_INSTANCE_X_MASK (ii) = mask; + IMAGE_INSTANCE_PIXMAP_MASK (ii) = (void*)mask; IMAGE_INSTANCE_X_COLORMAP (ii) = cmap; IMAGE_INSTANCE_X_PIXELS (ii) = pixels; IMAGE_INSTANCE_X_NPIXELS (ii) = npixels; @@ -1483,73 +1620,6 @@ x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, /********************************************************************** * X-Face * **********************************************************************/ - -static void -xface_validate (Lisp_Object instantiator) -{ - file_or_data_must_be_present (instantiator); -} - -static Lisp_Object -xface_normalize (Lisp_Object inst, Lisp_Object console_type) -{ - /* This function can call lisp */ - Lisp_Object file = Qnil, mask_file = Qnil; - struct gcpro gcpro1, gcpro2, gcpro3; - Lisp_Object alist = Qnil; - - GCPRO3 (file, mask_file, alist); - - /* Now, convert any file data into inline data for both the regular - data and the mask data. At the end of this, `data' will contain - the inline data (if any) or Qnil, and `file' will contain - the name this data was derived from (if known) or Qnil. - Likewise for `mask_file' and `mask_data'. - - Note that if we cannot generate any regular inline data, we - skip out. */ - - file = potential_pixmap_file_instantiator (inst, Q_file, Q_data, - console_type); - mask_file = potential_pixmap_file_instantiator (inst, Q_mask_file, - Q_mask_data, console_type); - - if (CONSP (file)) /* failure locating filename */ - signal_double_file_error ("Opening bitmap file", - "no such file or directory", - Fcar (file)); - - if (NILP (file) && NILP (mask_file)) /* no conversion necessary */ - RETURN_UNGCPRO (inst); - - alist = tagged_vector_to_alist (inst); - - { - Lisp_Object data = make_string_from_file (file); - alist = remassq_no_quit (Q_file, alist); - /* there can't be a :data at this point. */ - alist = Fcons (Fcons (Q_file, file), - Fcons (Fcons (Q_data, data), alist)); - } - - alist = xbm_mask_file_munging (alist, file, mask_file, console_type); - - { - Lisp_Object result = alist_to_tagged_vector (Qxface, alist); - free_alist (alist); - RETURN_UNGCPRO (result); - } -} - -static int -xface_possible_dest_types (void) -{ - return - IMAGE_MONO_PIXMAP_MASK | - IMAGE_COLOR_PIXMAP_MASK | - IMAGE_POINTER_MASK; -} - #if defined(EXTERN) /* This is about to get redefined! */ #undef EXTERN @@ -1571,9 +1641,9 @@ extern jmp_buf comp_env; #undef SYSV32 static void -xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, - Lisp_Object pointer_fg, Lisp_Object pointer_bg, - int dest_mask, Lisp_Object domain) +x_xface_instantiate (Lisp_Object image_instance, 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); int i, stattis; @@ -1906,7 +1976,7 @@ font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, /* #### call XQueryTextExtents() and check_pointer_sizes() here. */ - x_initialize_pixmap_image_instance (ii, IMAGE_POINTER); + x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER); IMAGE_INSTANCE_X_CURSOR (ii) = XCreateGlyphCursor (dpy, source, mask, source_char, mask_char, &fg, &bg); @@ -1959,7 +2029,7 @@ cursor_font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, if ((i = XmuCursorNameToIndex (name_ext)) == -1) signal_simple_error ("Unrecognized cursor-font name", data); - x_initialize_pixmap_image_instance (ii, IMAGE_POINTER); + x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER); IMAGE_INSTANCE_X_CURSOR (ii) = XCreateFontCursor (dpy, i); foreground = find_keyword_in_vector (instantiator, Q_foreground); if (NILP (foreground)) @@ -1984,7 +2054,7 @@ x_colorize_image_instance (Lisp_Object image_instance, IMAGE_INSTANCE_TYPE (p) = IMAGE_COLOR_PIXMAP; /* Make sure there aren't two pointers to the same mask, causing it to get freed twice. */ - IMAGE_INSTANCE_X_MASK (p) = 0; + IMAGE_INSTANCE_PIXMAP_MASK (p) = 0; break; default: @@ -2020,168 +2090,160 @@ x_colorize_image_instance (Lisp_Object image_instance, } -#if HAVE_SUBWINDOWS /************************************************************************/ -/* subwindows */ +/* subwindow and widget support */ /************************************************************************/ -Lisp_Object Qsubwindowp; - -static Lisp_Object -mark_subwindow (Lisp_Object obj, void (*markobj) (Lisp_Object)) -{ - struct Lisp_Subwindow *sw = XSUBWINDOW (obj); - return sw->frame; -} - +/* unmap the image if it is a widget. This is used by redisplay via + redisplay_unmap_subwindows */ static void -print_subwindow (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) +x_unmap_subwindow (struct Lisp_Image_Instance *p) { - char buf[100]; - struct Lisp_Subwindow *sw = XSUBWINDOW (obj); - struct frame *frm = XFRAME (sw->frame); - - if (print_readably) - error ("printing unreadable object #", - sw->header.uid); - - write_c_string ("#width, sw->height); - write_c_string (buf, printcharfun); - - /* This is stolen from frame.c. Subwindows are strange in that they - are specific to a particular frame so we want to print in their - description what that frame is. */ - - write_c_string (" on #<", printcharfun); - if (!FRAME_LIVE_P (frm)) - write_c_string ("dead", printcharfun); - else if (FRAME_TTY_P (frm)) - write_c_string ("tty", printcharfun); - else if (FRAME_X_P (frm)) - write_c_string ("x", printcharfun); - else - write_c_string ("UNKNOWN", printcharfun); - write_c_string ("-frame ", printcharfun); - print_internal (frm->name, printcharfun, 1); - sprintf (buf, " 0x%x>", frm->header.uid); - write_c_string (buf, printcharfun); - - sprintf (buf, ") 0x%x>", sw->header.uid); - write_c_string (buf, printcharfun); + if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) + { + XUnmapWindow + (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), + IMAGE_INSTANCE_X_CLIPWINDOW (p)); + } + else /* must be a widget */ + { + XtUnmapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); + } } +/* map the subwindow. This is used by redisplay via + redisplay_output_subwindow */ static void -finalize_subwindow (void *header, int for_disksave) +x_map_subwindow (struct Lisp_Image_Instance *p, int x, int y, + struct display_glyph_area* dga) { - struct Lisp_Subwindow *sw = (struct Lisp_Subwindow *) header; - if (for_disksave) finalose (sw); - if (sw->subwindow) + if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) { - XDestroyWindow (DisplayOfScreen (sw->xscreen), sw->subwindow); - sw->subwindow = 0; + Window subwindow = IMAGE_INSTANCE_X_SUBWINDOW_ID (p); + XMoveResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (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)); + } + else /* must be a widget */ + { + 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)); } } -/* subwindows are equal iff they have the same window XID */ -static int -subwindow_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) +/* 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) { - return (XSUBWINDOW (obj1)->subwindow == XSUBWINDOW (obj2)->subwindow); -} +#ifdef HAVE_WIDGETS + if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) + { + Arg al[5]; + widget_value* wv = gui_items_to_widget_values + (IMAGE_INSTANCE_WIDGET_ITEMS (p)); -static unsigned long -subwindow_hash (Lisp_Object obj, int depth) -{ - return XSUBWINDOW (obj)->subwindow; -} + /* This seems ugly, but I'm not sure what else to do. */ + if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qtab_control)) + { + widget_value* cur = 0; + /* Give each child label the correct foreground color. */ + Lisp_Object pixel = FACE_FOREGROUND + (IMAGE_INSTANCE_WIDGET_FACE (p), + IMAGE_INSTANCE_SUBWINDOW_FRAME (p)); + XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); + XtSetArg (al [0], XtNtabForeground, fcolor.pixel); + + for (cur = wv->contents; cur; cur = cur->next) + { + if (cur->value) + { + cur->nargs = 1; + cur->args = al; + } + } + } -DEFINE_LRECORD_IMPLEMENTATION ("subwindow", subwindow, - mark_subwindow, print_subwindow, - finalize_subwindow, subwindow_equal, - subwindow_hash, struct Lisp_Subwindow); - -/* #### PROBLEM: The display routines assume that the glyph is only - being displayed in one buffer. If it is in two different buffers - which are both being displayed simultaneously you will lose big time. - This can be dealt with in the new redisplay. */ - -/* #### These are completely un-re-implemented in 19.14. Get it done - for 19.15. */ - -DEFUN ("make-subwindow", Fmake_subwindow, 0, 3, 0, /* -Creates a new `subwindow' object of size WIDTH x HEIGHT. -The default is a window of size 1x1, which is also the minimum allowed -window size. Subwindows are per-frame. A buffer being shown in two -different frames will only display a subwindow glyph in the frame in -which it was actually created. If two windows on the same frame are -displaying the buffer then the most recently used window will actually -display the window. If the frame is not specified, the selected frame -is used. + /* now modify the widget */ + lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p), + wv, True); + free_widget_value_tree (wv); + /* update the colors and font */ + update_widget_face (p, IMAGE_INSTANCE_SUBWINDOW_FRAME (p)); + /* 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); + } +#endif +} -Subwindows are not currently implemented. -*/ - (width, height, frame)) +/* instantiate and x type subwindow */ +static void +x_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + 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_Object device = IMAGE_INSTANCE_DEVICE (ii); + Lisp_Object frame = FW_FRAME (domain); + struct frame* f = XFRAME (frame); Display *dpy; Screen *xs; - Window pw; - struct frame *f; - unsigned int iw, ih; + Window pw, win; XSetWindowAttributes xswa; Mask valueMask = 0; + unsigned int w = IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), + h = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii); + + if (!DEVICE_X_P (XDEVICE (device))) + signal_simple_error ("Not an X device", device); - error ("subwindows are not functional in 20.2; they may be again someday"); + dpy = DEVICE_X_DISPLAY (XDEVICE (device)); + xs = DefaultScreenOfDisplay (dpy); - f = decode_x_frame (frame); + IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW; - xs = LISP_DEVICE_TO_X_SCREEN (FRAME_DEVICE (f)); - dpy = DisplayOfScreen (xs); pw = XtWindow (FRAME_X_TEXT_WIDGET (f)); - if (NILP (width)) - iw = 1; - else - { - CHECK_INT (width); - iw = XINT (width); - if (iw < 1) iw = 1; - } - if (NILP (height)) - ih = 1; - else - { - CHECK_INT (height); - ih = XINT (height); - if (ih < 1) ih = 1; - } - - { - struct Lisp_Subwindow *sw = - alloc_lcrecord_type (struct Lisp_Subwindow, lrecord_subwindow); - Lisp_Object val; - sw->frame = frame; - sw->xscreen = xs; - sw->parent_window = pw; - sw->height = ih; - sw->width = iw; - - xswa.backing_store = Always; - valueMask |= CWBackingStore; - - xswa.colormap = DefaultColormapOfScreen (xs); - valueMask |= CWColormap; - - sw->subwindow = XCreateWindow (dpy, pw, 0, 0, iw, ih, 0, CopyFromParent, - InputOutput, CopyFromParent, valueMask, - &xswa); - - XSETSUBWINDOW (val, sw); - return val; - } + ii->data = xnew_and_zero (struct x_subwindow_data); + + IMAGE_INSTANCE_X_SUBWINDOW_PARENT (ii) = pw; + IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (ii) = DisplayOfScreen (xs); + + xswa.backing_store = Always; + valueMask |= CWBackingStore; + xswa.colormap = DefaultColormapOfScreen (xs); + valueMask |= CWColormap; + + /* Create a window for clipping */ + IMAGE_INSTANCE_X_CLIPWINDOW (ii) = + XCreateWindow (dpy, pw, 0, 0, w, h, 0, CopyFromParent, + InputOutput, CopyFromParent, valueMask, + &xswa); + + /* Now put the subwindow inside the clip window. */ + win = XCreateWindow (dpy, IMAGE_INSTANCE_X_CLIPWINDOW (ii), + 0, 0, w, h, 0, CopyFromParent, + InputOutput, CopyFromParent, valueMask, + &xswa); + + IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)win; } -/* #### Should this function exist? */ +#if 0 +/* #### Should this function exist? If there's any doubt I'm not implementing it --andyp */ DEFUN ("change-subwindow-property", Fchange_subwindow_property, 3, 3, 0, /* For the given SUBWINDOW, set PROPERTY to DATA, which is a string. Subwindows are not currently implemented. @@ -2208,91 +2270,470 @@ Subwindows are not currently implemented. return property; } +#endif -DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /* -Return non-nil if OBJECT is a subwindow. -Subwindows are not currently implemented. -*/ - (object)) +static void +x_resize_subwindow (struct Lisp_Image_Instance* ii, int w, int h) { - return SUBWINDOWP (object) ? Qt : Qnil; + 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); + } } -DEFUN ("subwindow-width", Fsubwindow_width, 1, 1, 0, /* -Width of SUBWINDOW. -Subwindows are not currently implemented. -*/ - (subwindow)) + +#ifdef HAVE_WIDGETS + +/************************************************************************/ +/* widgets */ +/************************************************************************/ + +static void +update_widget_face (struct Lisp_Image_Instance* ii, Lisp_Object domain) { - CHECK_SUBWINDOW (subwindow); - return make_int (XSUBWINDOW (subwindow)->width); + Arg al[3]; +#ifdef LWLIB_WIDGETS_MOTIF + XmFontList fontList; +#endif + + Lisp_Object pixel = FACE_FOREGROUND + (IMAGE_INSTANCE_WIDGET_FACE (ii), + IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); + XColor bcolor; + + pixel = FACE_BACKGROUND + (IMAGE_INSTANCE_WIDGET_FACE (ii), + IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); + + XtSetArg (al [0], XtNbackground, bcolor.pixel); + XtSetArg (al [1], XtNforeground, fcolor.pixel); + +#ifdef LWLIB_WIDGETS_MOTIF + fontList = XmFontListCreate + (FONT_INSTANCE_X_FONT + (XFONT_INSTANCE (widget_face_font_info + (domain, IMAGE_INSTANCE_WIDGET_FACE (ii), + 0, 0))), XmSTRING_DEFAULT_CHARSET); + XtSetArg (al [2], XmNfontList, fontList ); +#else + XtSetArg (al [2], XtNfont, (void*)FONT_INSTANCE_X_FONT + (XFONT_INSTANCE (widget_face_font_info + (domain, + IMAGE_INSTANCE_WIDGET_FACE (ii), + 0, 0)))); +#endif + XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 3); +#ifdef LWLIB_WIDGETS_MOTIF + XmFontListFree (fontList); +#endif } -DEFUN ("subwindow-height", Fsubwindow_height, 1, 1, 0, /* -Height of SUBWINDOW. -Subwindows are not currently implemented. -*/ - (subwindow)) +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) { - CHECK_SUBWINDOW (subwindow); - return make_int (XSUBWINDOW (subwindow)->height); + 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); + char* nm=0; + Widget wid; + Arg al [32]; + int ac = 0; + int id = new_lwlib_id (); + widget_value* clip_wv; + XColor fcolor, bcolor; + + if (!DEVICE_X_P (d)) + signal_simple_error ("Not an X 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); + + /* Create a clip window to contain the subwidget. Incredibly the + XEmacs manager seems to be the most appropriate widget for + this. Nothing else is simple enough and yet does what is + required. */ + clip_wv = xmalloc_widget_value (); + + XtSetArg (al [ac], XtNresize, False); ac++; + XtSetArg (al [ac], XtNwidth, + (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); ac++; + XtSetArg (al [ac], XtNheight, + (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); ac++; + + clip_wv->enabled = True; + clip_wv->nargs = ac; + clip_wv->args = al; + clip_wv->name = xstrdup ("clip-window"); + clip_wv->value = xstrdup ("clip-window"); + + IMAGE_INSTANCE_X_CLIPWIDGET (ii) + = lw_create_widget ("clip-window", "clip-window", new_lwlib_id (), + clip_wv, FRAME_X_CONTAINER_WIDGET (f), + False, 0, 0, 0); + + free_widget_value_tree (clip_wv); + + /* copy any args we were given */ + ac = 0; + + if (wv->nargs) + lw_add_value_args_to_args (wv, al, &ac); + + /* Fixup the colors. We have to do this *before* the widget gets + 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 + (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++; + /* we cannot allow widgets to resize themselves */ + XtSetArg (al [ac], XtNresize, False); ac++; + XtSetArg (al [ac], XtNwidth, + (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); ac++; + XtSetArg (al [ac], XtNheight, + (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); ac++; + + wv->nargs = ac; + wv->args = al; + + wid = lw_create_widget (type, wv->name, id, wv, IMAGE_INSTANCE_X_CLIPWIDGET (ii), + False, 0, popup_selection_callback, 0); + + IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid; + IMAGE_INSTANCE_X_WIDGET_LWID (ii) = id; + + /* update the font. */ + update_widget_face (ii, domain); + + /* 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. */ + 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); + + XtMapWidget (wid); + + free_widget_value_tree (wv); } -DEFUN ("subwindow-xid", Fsubwindow_xid, 1, 1, 0, /* -Return the xid of SUBWINDOW as a number. -Subwindows are not currently implemented. -*/ - (subwindow)) +static Lisp_Object +x_widget_set_property (Lisp_Object image_instance, Lisp_Object prop, + Lisp_Object val) { - CHECK_SUBWINDOW (subwindow); - return make_int (XSUBWINDOW (subwindow)->subwindow); + struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + + 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 face properties of the widget */ + if (EQ (prop, Q_face)) + { + update_widget_face (ii, IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + return Qt; + } + return Qunbound; } -DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /* -Resize SUBWINDOW to WIDTH x HEIGHT. -If a value is nil that parameter is not changed. -Subwindows are not currently implemented. -*/ - (subwindow, width, height)) +/* get properties of a control */ +static Lisp_Object +x_widget_property (Lisp_Object image_instance, Lisp_Object prop) { - int neww, newh; - struct Lisp_Subwindow *sw; + 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; +} - CHECK_SUBWINDOW (subwindow); - sw = XSUBWINDOW (subwindow); +/* 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 (); - if (NILP (width)) - neww = sw->width; - else - neww = XINT (width); + button_item_to_widget_value (gui, wv, 1, 1); - if (NILP (height)) - newh = sw->height; - else - newh = XINT (height); + 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_WIDGETS_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); + } +} - XResizeWindow (DisplayOfScreen (sw->xscreen), sw->subwindow, neww, newh); +/* 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)); - sw->height = newh; - sw->width = neww; + 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 (); - return subwindow; + button_item_to_widget_value (gui, wv, 1, 1); + + x_widget_instantiate (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, domain, "progress", wv); } -DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /* -Generate a Map event for SUBWINDOW. -Subwindows are not currently implemented. -*/ - (subwindow)) +/* 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) { - CHECK_SUBWINDOW (subwindow); + struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - XMapWindow (DisplayOfScreen (XSUBWINDOW (subwindow)->xscreen), - XSUBWINDOW (subwindow)->subwindow); + 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; +} - return subwindow; +/* 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); +} + +#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 +/* 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); + 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); + + 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); } #endif + +static void +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); + Arg al [1]; + XColor fcolor; + Lisp_Object pixel; + widget_value* cur; + + widget_value * wv = + gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); + + /* Give each child label the correct foreground color. */ + pixel = FACE_FOREGROUND + (IMAGE_INSTANCE_WIDGET_FACE (ii), + IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); + XtSetArg (al [0], XtNtabForeground, fcolor.pixel); + + for (cur = wv->contents; cur; cur = cur->next) + { + if (cur->value) + { + cur->nargs = 1; + cur->args = al; + } + } + + 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) +{ + struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + + if (EQ (prop, Q_items)) + { + widget_value * wv = 0, *cur; + Arg al [1]; + XColor fcolor; + Lisp_Object pixel; + + check_valid_item_list_1 (val); + + IMAGE_INSTANCE_WIDGET_ITEMS (ii) = + Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)), + parse_gui_item_tree_children (val)); + + wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); + + /* Give each child label the correct foreground color. */ + pixel = FACE_FOREGROUND + (IMAGE_INSTANCE_WIDGET_FACE (ii), + IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); + XtSetArg (al [0], XtNtabForeground, fcolor.pixel); + + for (cur = wv->contents; cur; cur = cur->next) + { + if (cur->value) + { + cur->nargs = 1; + cur->args = al; + } + } + + 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 */ +static void +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_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, "button", wv); +} +#endif /* HAVE_WIDGETS */ + /************************************************************************/ /* initialization */ @@ -2301,17 +2742,8 @@ Subwindows are not currently implemented. void syms_of_glyphs_x (void) { -#if HAVE_SUBWINDOWS - defsymbol (&Qsubwindowp, "subwindowp"); - - DEFSUBR (Fmake_subwindow); +#if 0 DEFSUBR (Fchange_subwindow_property); - DEFSUBR (Fsubwindowp); - DEFSUBR (Fsubwindow_width); - DEFSUBR (Fsubwindow_height); - DEFSUBR (Fsubwindow_xid); - DEFSUBR (Fresize_subwindow); - DEFSUBR (Fforce_subwindow_map); #endif } @@ -2327,17 +2759,73 @@ console_type_create_glyphs_x (void) CONSOLE_HAS_METHOD (x, colorize_image_instance); CONSOLE_HAS_METHOD (x, init_image_instance_from_eimage); CONSOLE_HAS_METHOD (x, locate_pixmap_file); -#ifdef HAVE_XPM - CONSOLE_HAS_METHOD (x, xpm_instantiate); -#endif - CONSOLE_HAS_METHOD (x, xbm_instantiate); + CONSOLE_HAS_METHOD (x, unmap_subwindow); + CONSOLE_HAS_METHOD (x, map_subwindow); + CONSOLE_HAS_METHOD (x, resize_subwindow); + CONSOLE_HAS_METHOD (x, update_subwindow); } void image_instantiator_format_create_glyphs_x (void) { - + IIFORMAT_VALID_CONSOLE (x, nothing); + IIFORMAT_VALID_CONSOLE (x, string); + IIFORMAT_VALID_CONSOLE (x, layout); + IIFORMAT_VALID_CONSOLE (x, formatted_string); + IIFORMAT_VALID_CONSOLE (x, inherit); +#ifdef HAVE_XPM + INITIALIZE_DEVICE_IIFORMAT (x, xpm); + IIFORMAT_HAS_DEVMETHOD (x, xpm, instantiate); +#endif +#ifdef HAVE_JPEG + IIFORMAT_VALID_CONSOLE (x, jpeg); +#endif +#ifdef HAVE_TIFF + IIFORMAT_VALID_CONSOLE (x, tiff); +#endif +#ifdef HAVE_PNG + IIFORMAT_VALID_CONSOLE (x, png); +#endif +#ifdef HAVE_GIF + IIFORMAT_VALID_CONSOLE (x, gif); +#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 + /* button widget */ + INITIALIZE_DEVICE_IIFORMAT (x, button); + IIFORMAT_HAS_DEVMETHOD (x, button, property); + IIFORMAT_HAS_DEVMETHOD (x, button, instantiate); + + 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, instantiate); + /* text field */ + INITIALIZE_DEVICE_IIFORMAT (x, edit_field); + IIFORMAT_HAS_DEVMETHOD (x, edit_field, instantiate); +#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 + /* 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); +#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); + /* label */ + INITIALIZE_DEVICE_IIFORMAT (x, label); + IIFORMAT_HAS_DEVMETHOD (x, label, instantiate); +#endif INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font"); + IIFORMAT_VALID_CONSOLE (x, cursor_font); IIFORMAT_HAS_METHOD (cursor_font, validate); IIFORMAT_HAS_METHOD (cursor_font, possible_dest_types); @@ -2352,25 +2840,15 @@ image_instantiator_format_create_glyphs_x (void) IIFORMAT_HAS_METHOD (font, validate); IIFORMAT_HAS_METHOD (font, possible_dest_types); IIFORMAT_HAS_METHOD (font, instantiate); + IIFORMAT_VALID_CONSOLE (x, font); IIFORMAT_VALID_KEYWORD (font, Q_data, check_valid_string); IIFORMAT_VALID_KEYWORD (font, Q_foreground, check_valid_string); IIFORMAT_VALID_KEYWORD (font, Q_background, check_valid_string); #ifdef HAVE_XFACE - INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xface, "xface"); - - IIFORMAT_HAS_METHOD (xface, validate); - IIFORMAT_HAS_METHOD (xface, normalize); - IIFORMAT_HAS_METHOD (xface, possible_dest_types); - IIFORMAT_HAS_METHOD (xface, instantiate); - - IIFORMAT_VALID_KEYWORD (xface, Q_data, check_valid_string); - IIFORMAT_VALID_KEYWORD (xface, Q_file, check_valid_string); - IIFORMAT_VALID_KEYWORD (xface, Q_hotspot_x, check_valid_int); - IIFORMAT_VALID_KEYWORD (xface, Q_hotspot_y, check_valid_int); - IIFORMAT_VALID_KEYWORD (xface, Q_foreground, check_valid_string); - IIFORMAT_VALID_KEYWORD (xface, Q_background, check_valid_string); + INITIALIZE_DEVICE_IIFORMAT (x, xface); + IIFORMAT_HAS_DEVMETHOD (x, xface, instantiate); #endif INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (autodetect, @@ -2380,6 +2858,7 @@ image_instantiator_format_create_glyphs_x (void) IIFORMAT_HAS_METHOD (autodetect, normalize); IIFORMAT_HAS_METHOD (autodetect, possible_dest_types); IIFORMAT_HAS_METHOD (autodetect, instantiate); + IIFORMAT_VALID_CONSOLE (x, autodetect); IIFORMAT_VALID_KEYWORD (autodetect, Q_data, check_valid_string); } @@ -2387,10 +2866,6 @@ image_instantiator_format_create_glyphs_x (void) void vars_of_glyphs_x (void) { -#ifdef HAVE_XFACE - Fprovide (Qxface); -#endif - DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path /* A list of the directories in which X bitmap files may be found. If nil, this is initialized from the "*bitmapFilePath" resource.