1 /* X-specific Lisp objects.
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc.
3 Copyright (C) 1995 Board of Trustees, University of Illinois.
4 Copyright (C) 1995 Tinker Systems
5 Copyright (C) 1995, 1996 Ben Wing
6 Copyright (C) 1995 Sun Microsystems
8 This file is part of XEmacs.
10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with XEmacs; see the file COPYING. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* Synched up with: Not in FSF. */
27 /* Original author: Jamie Zawinski for 19.8
28 font-truename stuff added by Jamie Zawinski for 19.10
29 subwindow support added by Chuck Thompson
30 additional XPM support added by Chuck Thompson
31 initial X-Face support added by Stig
32 rewritten/restructured by Ben Wing for 19.12/19.13
33 GIF/JPEG support added by Ben Wing for 19.14
34 PNG support added by Bill Perry for 19.14
35 Improved GIF/JPEG support added by Bill Perry for 19.14
36 Cleanup/simplification of error handling by Ben Wing for 19.14
37 Pointer/icon overhaul, more restructuring by Ben Wing for 19.14
38 GIF support changed to external GIFlib 3.1 by Jareth Hein for 21.0
39 Many changes for color work and optimizations by Jareth Hein for 21.0
40 Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0
41 TIFF code by Jareth Hein for 21.0
42 GIF/JPEG/PNG/TIFF code moved to new glyph-eimage.c for 21.0
43 Gtk version by William Perry for 21.1
46 Support the GrayScale, StaticColor and StaticGray visual classes.
47 Convert images.el to C and stick it in here?
53 #include "console-gtk.h"
55 #include "glyphs-gtk.h"
56 #include "objects-gtk.h"
74 #include "file-coding.h"
78 # define FOUR_BYTE_TYPE unsigned int
80 # define FOUR_BYTE_TYPE unsigned long
82 # define FOUR_BYTE_TYPE unsigned short
84 #error What kind of strange-ass system are we running on?
87 DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing);
88 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string);
89 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
90 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit);
92 DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
95 DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff);
98 DECLARE_IMAGE_INSTANTIATOR_FORMAT (png);
101 DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif);
105 DEFINE_DEVICE_IIFORMAT (gtk, xface);
110 DEFINE_DEVICE_IIFORMAT (gtk, xpm);
113 DEFINE_DEVICE_IIFORMAT (gtk, xbm);
114 DEFINE_DEVICE_IIFORMAT (gtk, subwindow);
116 DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font);
117 Lisp_Object Qcursor_font;
119 DEFINE_IMAGE_INSTANTIATOR_FORMAT (font);
121 DEFINE_IMAGE_INSTANTIATOR_FORMAT (autodetect);
124 DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
125 DEFINE_DEVICE_IIFORMAT (gtk, widget);
126 DEFINE_DEVICE_IIFORMAT (gtk, native_layout);
127 DEFINE_DEVICE_IIFORMAT (gtk, button);
128 DEFINE_DEVICE_IIFORMAT (gtk, progress_gauge);
129 DEFINE_DEVICE_IIFORMAT (gtk, edit_field);
130 DEFINE_DEVICE_IIFORMAT (gtk, combo_box);
131 DEFINE_DEVICE_IIFORMAT (gtk, tab_control);
132 DEFINE_DEVICE_IIFORMAT (gtk, label);
135 static void update_widget_face (GtkWidget *w, Lisp_Image_Instance *ii,
137 static void cursor_font_instantiate (Lisp_Object image_instance,
138 Lisp_Object instantiator,
139 Lisp_Object pointer_fg,
140 Lisp_Object pointer_bg,
144 static gint cursor_name_to_index (const char *name);
146 #ifndef BitmapSuccess
147 #define BitmapSuccess 0
148 #define BitmapOpenFailed 1
149 #define BitmapFileInvalid 2
150 #define BitmapNoMemory 3
155 DEFINE_IMAGE_INSTANTIATOR_FORMAT (gtk_resource);
156 Lisp_Object Q_resource_type, Q_resource_id;
157 Lisp_Object Qgtk_resource;
159 Lisp_Object Qgtk_widget_instantiate_internal, Qgtk_widget_property_internal;
160 Lisp_Object Qgtk_widget_redisplay_internal, Qgtk_widget_set_style;
166 /************************************************************************/
167 /* image instance methods */
168 /************************************************************************/
170 /************************************************************************/
171 /* convert from a series of RGB triples to an XImage formated for the */
173 /************************************************************************/
175 convert_EImage_to_GDKImage (Lisp_Object device, int width, int height,
176 unsigned char *pic, unsigned long **pixtbl,
182 int depth, byte_cnt, i, j;
184 unsigned char *data, *ip, *dp = NULL;
185 quant_table *qtable = NULL;
191 cmap = DEVICE_GTK_COLORMAP (XDEVICE(device));
192 vis = DEVICE_GTK_VISUAL (XDEVICE(device));
193 depth = DEVICE_GTK_DEPTH(XDEVICE(device));
195 if (vis->type == GDK_VISUAL_GRAYSCALE || vis->type == GDK_VISUAL_STATIC_COLOR ||
196 vis->type == GDK_VISUAL_STATIC_GRAY)
198 /* #### Implement me!!! */
202 if (vis->type == GDK_VISUAL_PSEUDO_COLOR)
204 /* Quantize the image and get a histogram while we're at it.
205 Do this first to save memory */
206 qtable = build_EImage_quantable(pic, width, height, 256);
207 if (qtable == NULL) return NULL;
210 /* The first parameter (GdkWindow *) is allowed to be NULL if we
211 ** specify the depth */
212 outimg = gdk_image_new (GDK_IMAGE_FASTEST, vis, width, height);
214 if (!outimg) return NULL;
216 byte_cnt = outimg->bpp;
218 data = (unsigned char *) outimg->mem;
222 gdk_image_destroy (outimg);
226 if (vis->type == GDK_VISUAL_PSEUDO_COLOR)
228 unsigned long pixarray[256];
230 /* use our quantize table to allocate the colors */
232 *pixtbl = xnew_array (unsigned long, pixcount);
235 /* ### should implement a sort by popularity to assure proper allocation */
237 for (i = 0; i < qtable->num_active_colors; i++)
242 color.red = qtable->rm[i] ? qtable->rm[i] << 8 : 0;
243 color.green = qtable->gm[i] ? qtable->gm[i] << 8 : 0;
244 color.blue = qtable->bm[i] ? qtable->bm[i] << 8 : 0;
245 res = allocate_nearest_color (cmap, vis, &color);
246 if (res > 0 && res < 3)
248 DO_REALLOC(*pixtbl, pixcount, n+1, unsigned long);
249 (*pixtbl)[n] = color.pixel;
252 pixarray[i] = color.pixel;
256 for (i = 0; i < height; i++)
258 dp = data + (i * outimg->bpl);
259 for (j = 0; j < width; j++)
264 conv.val = pixarray[QUANT_GET_COLOR(qtable,rd,gr,bl)];
266 if (outimg->byte_order == GDK_MSB_FIRST)
267 for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q];
269 for (q = 3; q >= 4-byte_cnt; q--) *dp++ = conv.cp[q];
271 if (outimg->byte_order == GDK_MSB_FIRST)
272 for (q = byte_cnt-1; q >= 0; q--) *dp++ = conv.cp[q];
274 for (q = 0; q < byte_cnt; q++) *dp++ = conv.cp[q];
280 unsigned long rshift,gshift,bshift,rbits,gbits,bbits,junk;
281 junk = vis->red_mask;
283 while ((junk & 0x1) == 0)
294 junk = vis->green_mask;
296 while ((junk & 0x1) == 0)
307 junk = vis->blue_mask;
309 while ((junk & 0x1) == 0)
321 for (i = 0; i < height; i++)
323 dp = data + (i * outimg->bpl);
324 for (j = 0; j < width; j++)
327 rd = *ip++ << (rbits - 8);
329 rd = *ip++ >> (8 - rbits);
331 gr = *ip++ << (gbits - 8);
333 gr = *ip++ >> (8 - gbits);
335 bl = *ip++ << (bbits - 8);
337 bl = *ip++ >> (8 - bbits);
339 conv.val = (rd << rshift) | (gr << gshift) | (bl << bshift);
341 if (outimg->byte_order == GDK_MSB_FIRST)
342 for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q];
344 for (q = 3; q >= 4-byte_cnt; q--) *dp++ = conv.cp[q];
346 if (outimg->byte_order == GDK_MSB_FIRST)
347 for (q = byte_cnt-1; q >= 0; q--) *dp++ = conv.cp[q];
349 for (q = 0; q < byte_cnt; q++) *dp++ = conv.cp[q];
358 gtk_print_image_instance (struct Lisp_Image_Instance *p,
359 Lisp_Object printcharfun,
364 switch (IMAGE_INSTANCE_TYPE (p))
366 case IMAGE_MONO_PIXMAP:
367 case IMAGE_COLOR_PIXMAP:
369 sprintf (buf, " (0x%lx", (unsigned long) IMAGE_INSTANCE_GTK_PIXMAP (p));
370 write_c_string (buf, printcharfun);
371 if (IMAGE_INSTANCE_GTK_MASK (p))
373 sprintf (buf, "/0x%lx", (unsigned long) IMAGE_INSTANCE_GTK_MASK (p));
374 write_c_string (buf, printcharfun);
376 write_c_string (")", printcharfun);
379 case IMAGE_SUBWINDOW:
380 /* #### implement me */
388 gtk_finalize_image_instance (struct Lisp_Image_Instance *p)
393 if (DEVICE_LIVE_P (XDEVICE (p->device)))
398 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET)
400 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
402 gtk_widget_destroy (IMAGE_INSTANCE_SUBWINDOW_ID (p));
404 /* We can release the callbacks again. */
406 /* ungcpro_popup_callbacks (...); */
408 /* IMAGE_INSTANCE_GTK_WIDGET_ID (p) = 0; */
409 IMAGE_INSTANCE_GTK_CLIPWIDGET (p) = 0;
413 else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
420 if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
421 disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
423 if (IMAGE_INSTANCE_GTK_MASK (p) &&
424 IMAGE_INSTANCE_GTK_MASK (p) != IMAGE_INSTANCE_GTK_PIXMAP (p))
425 gdk_pixmap_unref (IMAGE_INSTANCE_GTK_MASK (p));
426 IMAGE_INSTANCE_PIXMAP_MASK (p) = 0;
428 if (IMAGE_INSTANCE_GTK_PIXMAP_SLICES (p))
430 for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++)
431 if (IMAGE_INSTANCE_GTK_PIXMAP_SLICE (p,i))
433 gdk_pixmap_unref (IMAGE_INSTANCE_GTK_PIXMAP_SLICE (p,i));
434 IMAGE_INSTANCE_GTK_PIXMAP_SLICE (p, i) = 0;
436 xfree (IMAGE_INSTANCE_GTK_PIXMAP_SLICES (p));
437 IMAGE_INSTANCE_GTK_PIXMAP_SLICES (p) = 0;
440 if (IMAGE_INSTANCE_GTK_CURSOR (p))
442 gdk_cursor_destroy (IMAGE_INSTANCE_GTK_CURSOR (p));
443 IMAGE_INSTANCE_GTK_CURSOR (p) = 0;
449 if (IMAGE_INSTANCE_GTK_NPIXELS (p) != 0)
452 IMAGE_INSTANCE_GTK_COLORMAP (p),
453 IMAGE_INSTANCE_GTK_PIXELS (p),
454 IMAGE_INSTANCE_GTK_NPIXELS (p), 0);
455 IMAGE_INSTANCE_GTK_NPIXELS (p) = 0;
460 if (IMAGE_INSTANCE_TYPE (p) != IMAGE_WIDGET
461 && IMAGE_INSTANCE_TYPE (p) != IMAGE_SUBWINDOW
462 && IMAGE_INSTANCE_GTK_PIXELS (p))
464 xfree (IMAGE_INSTANCE_GTK_PIXELS (p));
465 IMAGE_INSTANCE_GTK_PIXELS (p) = 0;
473 gtk_image_instance_equal (struct Lisp_Image_Instance *p1,
474 struct Lisp_Image_Instance *p2, int depth)
476 switch (IMAGE_INSTANCE_TYPE (p1))
478 case IMAGE_MONO_PIXMAP:
479 case IMAGE_COLOR_PIXMAP:
481 if (IMAGE_INSTANCE_GTK_COLORMAP (p1) != IMAGE_INSTANCE_GTK_COLORMAP (p2) ||
482 IMAGE_INSTANCE_GTK_NPIXELS (p1) != IMAGE_INSTANCE_GTK_NPIXELS (p2))
485 case IMAGE_SUBWINDOW:
486 /* #### implement me */
497 gtk_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
499 switch (IMAGE_INSTANCE_TYPE (p))
501 case IMAGE_MONO_PIXMAP:
502 case IMAGE_COLOR_PIXMAP:
504 return IMAGE_INSTANCE_GTK_NPIXELS (p);
506 case IMAGE_SUBWINDOW:
507 /* #### implement me */
515 /* Set all the slots in an image instance structure to reasonable
516 default values. This is used somewhere within an instantiate
517 method. It is assumed that the device slot within the image
518 instance is already set -- this is the case when instantiate
519 methods are called. */
522 gtk_initialize_pixmap_image_instance (struct Lisp_Image_Instance *ii,
524 enum image_instance_type type)
526 ii->data = xnew_and_zero (struct gtk_image_instance_data);
527 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices;
528 IMAGE_INSTANCE_GTK_PIXMAP_SLICES (ii) =
529 xnew_array_and_zero (GdkPixmap *, slices);
530 IMAGE_INSTANCE_TYPE (ii) = type;
531 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
532 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
533 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
534 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
535 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
536 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
540 /************************************************************************/
541 /* pixmap file functions */
542 /************************************************************************/
544 /* Where bitmaps are; initialized from resource database */
545 Lisp_Object Vgtk_bitmap_file_path;
548 #define BITMAPDIR "/usr/include/X11/bitmaps"
551 /* Given a pixmap filename, look through all of the "standard" places
552 where the file might be located. Return a full pathname if found;
553 otherwise, return Qnil. */
556 gtk_locate_pixmap_file (Lisp_Object name)
558 /* This function can GC if IN_REDISPLAY is false */
560 /* Check non-absolute pathnames with a directory component relative to
561 the search path; that's the way Xt does it. */
562 /* #### Unix-specific */
563 if (XSTRING_BYTE (name, 0) == '/' ||
564 (XSTRING_BYTE (name, 0) == '.' &&
565 (XSTRING_BYTE (name, 1) == '/' ||
566 (XSTRING_BYTE (name, 1) == '.' &&
567 (XSTRING_BYTE (name, 2) == '/')))))
569 if (!NILP (Ffile_readable_p (name)))
575 if (NILP (Vdefault_gtk_device))
576 /* This may occur during intialization. */
579 if (NILP (Vgtk_bitmap_file_path))
581 Vgtk_bitmap_file_path = nconc2 (Vgtk_bitmap_file_path,
582 (decode_path (BITMAPDIR)));
587 if (locate_file (Vgtk_bitmap_file_path, name, Qnil, &found, R_OK) < 0)
589 Lisp_Object temp = list1 (Vdata_directory);
593 locate_file (temp, name, Qnil, &found, R_OK);
602 locate_pixmap_file (Lisp_Object name)
604 return gtk_locate_pixmap_file (name);
608 /************************************************************************/
609 /* cursor functions */
610 /************************************************************************/
612 /* Check that this server supports cursors of size WIDTH * HEIGHT. If
613 not, signal an error. INSTANTIATOR is only used in the error
617 check_pointer_sizes (unsigned int width, unsigned int height,
618 Lisp_Object instantiator)
620 /* #### BILL!!! There is no way to call XQueryBestCursor from Gdk! */
622 unsigned int best_width, best_height;
623 if (! XQueryBestCursor (DisplayOfScreen (xs), RootWindowOfScreen (xs),
624 width, height, &best_width, &best_height))
625 /* this means that an X error of some sort occurred (we trap
626 these so they're not fatal). */
627 signal_simple_error ("XQueryBestCursor() failed?", instantiator);
629 if (width > best_width || height > best_height)
630 error_with_frob (instantiator,
631 "pointer too large (%dx%d): "
632 "server requires %dx%d or smaller",
633 width, height, best_width, best_height);
638 generate_cursor_fg_bg (Lisp_Object device, Lisp_Object *foreground,
639 Lisp_Object *background, GdkColor *xfg, GdkColor *xbg)
641 if (!NILP (*foreground) && !COLOR_INSTANCEP (*foreground))
643 Fmake_color_instance (*foreground, device,
644 encode_error_behavior_flag (ERROR_ME));
645 if (COLOR_INSTANCEP (*foreground))
646 *xfg = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (*foreground));
650 xfg->red = xfg->green = xfg->blue = 0;
653 if (!NILP (*background) && !COLOR_INSTANCEP (*background))
655 Fmake_color_instance (*background, device,
656 encode_error_behavior_flag (ERROR_ME));
657 if (COLOR_INSTANCEP (*background))
658 *xbg = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (*background));
662 xbg->red = xbg->green = xbg->blue = ~0;
667 maybe_recolor_cursor (Lisp_Object image_instance, Lisp_Object foreground,
668 Lisp_Object background)
672 Lisp_Object device = XIMAGE_INSTANCE_DEVICE (image_instance);
675 generate_cursor_fg_bg (device, &foreground, &background, &xfg, &xbg);
676 if (!NILP (foreground) || !NILP (background))
678 XRecolorCursor (DEVICE_X_DISPLAY (XDEVICE (device)),
679 XIMAGE_INSTANCE_GTK_CURSOR (image_instance),
681 XIMAGE_INSTANCE_PIXMAP_FG (image_instance) = foreground;
682 XIMAGE_INSTANCE_PIXMAP_BG (image_instance) = background;
685 /* stderr_out ("Don't know how to recolor cursors in Gtk!\n"); */
690 /************************************************************************/
691 /* color pixmap functions */
692 /************************************************************************/
694 /* Initialize an image instance from an XImage.
696 DEST_MASK specifies the mask of allowed image types.
698 PIXELS and NPIXELS specify an array of pixels that are used in
699 the image. These need to be kept around for the duration of the
700 image. When the image instance is freed, XFreeColors() will
701 automatically be called on all the pixels specified here; thus,
702 you should have allocated the pixels yourself using XAllocColor()
703 or the like. The array passed in is used directly without
704 being copied, so it should be heap data created with xmalloc().
705 It will be freed using xfree() when the image instance is
708 If this fails, signal an error. INSTANTIATOR is only used
709 in the error message.
711 #### This should be able to handle conversion into `pointer'.
712 Use the same code as for `xpm'. */
715 init_image_instance_from_gdk_image (struct Lisp_Image_Instance *ii,
719 unsigned long *pixels,
722 Lisp_Object instantiator)
724 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
729 if (!DEVICE_GTK_P (XDEVICE (device)))
730 signal_simple_error ("Not a Gtk device", device);
732 d = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (device)));
734 if (!(dest_mask & IMAGE_COLOR_PIXMAP_MASK))
735 incompatible_image_types (instantiator, dest_mask,
736 IMAGE_COLOR_PIXMAP_MASK);
738 pixmap = gdk_pixmap_new (d, gdk_image->width, gdk_image->height, gdk_image->depth);
740 signal_simple_error ("Unable to create pixmap", instantiator);
742 gc = gdk_gc_new (pixmap);
745 gdk_pixmap_unref (pixmap);
746 signal_simple_error ("Unable to create GC", instantiator);
749 gdk_draw_image (GDK_DRAWABLE (pixmap), gc, gdk_image,
750 0, 0, 0, 0, gdk_image->width, gdk_image->height);
754 gtk_initialize_pixmap_image_instance (ii, slices, IMAGE_COLOR_PIXMAP);
756 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
757 find_keyword_in_vector (instantiator, Q_file);
759 IMAGE_INSTANCE_GTK_PIXMAP (ii) = pixmap;
760 IMAGE_INSTANCE_GTK_MASK (ii) = 0;
761 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = gdk_image->width;
762 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = gdk_image->height;
763 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = gdk_image->depth;
764 IMAGE_INSTANCE_GTK_COLORMAP (ii) = cmap;
765 IMAGE_INSTANCE_GTK_PIXELS (ii) = pixels;
766 IMAGE_INSTANCE_GTK_NPIXELS (ii) = npixels;
770 void init_image_instance_from_gdk_pixmap (struct Lisp_Image_Instance *ii,
771 struct device *device,
772 GdkPixmap *gdk_pixmap,
774 Lisp_Object instantiator)
777 gint width, height, depth;
779 if (!DEVICE_GTK_P (device))
782 IMAGE_INSTANCE_DEVICE (ii) = device;
783 IMAGE_INSTANCE_TYPE (ii) = IMAGE_COLOR_PIXMAP;
785 d = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (device));
787 if (!(dest_mask & IMAGE_COLOR_PIXMAP_MASK))
788 incompatible_image_types (instantiator, dest_mask,
789 IMAGE_COLOR_PIXMAP_MASK);
791 gtk_initialize_pixmap_image_instance (ii, IMAGE_COLOR_PIXMAP);
793 gdk_window_get_geometry (gdk_pixmap, NULL, NULL, &width, &height, &depth);
795 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
796 IMAGE_INSTANCE_GTK_PIXMAP (ii) = gdk_pixmap;
797 IMAGE_INSTANCE_GTK_MASK (ii) = 0;
798 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
799 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
800 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = depth;
801 IMAGE_INSTANCE_GTK_COLORMAP (ii) = gdk_window_get_colormap (gdk_pixmap);
802 IMAGE_INSTANCE_GTK_PIXELS (ii) = 0;
803 IMAGE_INSTANCE_GTK_NPIXELS (ii) = 0;
808 image_instance_add_gdk_image (Lisp_Image_Instance *ii,
811 Lisp_Object instantiator)
813 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
818 d = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (device)));
820 pixmap = gdk_pixmap_new (d, gdk_image->width, gdk_image->height, gdk_image->depth);
823 signal_simple_error ("Unable to create pixmap", instantiator);
825 gc = gdk_gc_new (pixmap);
829 gdk_pixmap_unref (pixmap);
830 signal_simple_error ("Unable to create GC", instantiator);
833 gdk_draw_image (GDK_DRAWABLE (pixmap), gc, gdk_image, 0, 0, 0, 0,
834 gdk_image->width, gdk_image->height);
838 IMAGE_INSTANCE_GTK_PIXMAP_SLICE (ii, slice) = pixmap;
842 gtk_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
843 int width, int height,
845 unsigned char *eimage,
847 Lisp_Object instantiator,
850 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
851 GdkColormap *cmap = DEVICE_GTK_COLORMAP (XDEVICE(device));
852 unsigned long *pixtbl = NULL;
858 for (slice = 0; slice < slices; slice++)
860 gdk_image = convert_EImage_to_GDKImage (device, width, height, eimage,
864 if (pixtbl) xfree (pixtbl);
865 signal_image_error("EImage to GdkImage conversion failed", instantiator);
869 /* Now create the pixmap and set up the image instance */
870 init_image_instance_from_gdk_image (ii, gdk_image, dest_mask,
871 cmap, pixtbl, npixels, slices,
874 image_instance_add_gdk_image (ii, gdk_image, slice, instantiator);
878 gdk_image_destroy (gdk_image);
884 /* Given inline data for a mono pixmap, create and return the
885 corresponding X object. */
888 pixmap_from_xbm_inline (Lisp_Object device, int width, int height,
889 /* Note that data is in ext-format! */
892 return (gdk_bitmap_create_from_data (GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (device))),
893 (char *) bits, width, height));
896 /* Given inline data for a mono pixmap, initialize the given
897 image instance accordingly. */
900 init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii,
901 int width, int height,
902 /* Note that data is in ext-format! */
904 Lisp_Object instantiator,
905 Lisp_Object pointer_fg,
906 Lisp_Object pointer_bg,
909 Lisp_Object mask_filename)
911 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
912 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
913 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
916 enum image_instance_type type;
917 GdkWindow *draw = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (device)));
918 GdkColormap *cmap = DEVICE_GTK_COLORMAP (XDEVICE(device));
922 gdk_color_black(cmap, &black);
923 gdk_color_white(cmap, &white);
925 if (!DEVICE_GTK_P (XDEVICE (device)))
926 signal_simple_error ("Not a Gtk device", device);
928 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
929 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
931 if (!NILP (foreground) || !NILP (background))
932 type = IMAGE_COLOR_PIXMAP;
934 type = IMAGE_MONO_PIXMAP;
936 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
937 type = IMAGE_MONO_PIXMAP;
938 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
939 type = IMAGE_COLOR_PIXMAP;
940 else if (dest_mask & IMAGE_POINTER_MASK)
941 type = IMAGE_POINTER;
943 incompatible_image_types (instantiator, dest_mask,
944 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
945 | IMAGE_POINTER_MASK);
947 gtk_initialize_pixmap_image_instance (ii, 1, type);
948 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
949 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
950 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
951 find_keyword_in_vector (instantiator, Q_file);
955 case IMAGE_MONO_PIXMAP:
957 IMAGE_INSTANCE_GTK_PIXMAP (ii) =
958 pixmap_from_xbm_inline (device, width, height, (Extbyte *) bits);
962 case IMAGE_COLOR_PIXMAP:
964 gint d = DEVICE_GTK_DEPTH (XDEVICE(device));
966 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
968 Fmake_color_instance (foreground, device,
969 encode_error_behavior_flag (ERROR_ME));
971 if (COLOR_INSTANCEP (foreground))
972 fg = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (foreground));
974 if (!NILP (background) && !COLOR_INSTANCEP (background))
976 Fmake_color_instance (background, device,
977 encode_error_behavior_flag (ERROR_ME));
979 if (COLOR_INSTANCEP (background))
980 bg = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (background));
982 /* We used to duplicate the pixels using XAllocColor(), to protect
983 against their getting freed. Just as easy to just store the
984 color instances here and GC-protect them, so this doesn't
986 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
987 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
988 IMAGE_INSTANCE_GTK_PIXMAP (ii) =
989 gdk_pixmap_create_from_data (draw, (char *) bits, width, height, d, &fg, &bg);
990 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = d;
996 GdkColor fg_color, bg_color;
999 check_pointer_sizes (width, height, instantiator);
1001 source = gdk_pixmap_create_from_data (draw, (char *) bits, width, height, 1, &black, &white);
1003 if (NILP (foreground))
1004 foreground = pointer_fg;
1005 if (NILP (background))
1006 background = pointer_bg;
1007 generate_cursor_fg_bg (device, &foreground, &background,
1008 &fg_color, &bg_color);
1010 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1011 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1012 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) =
1013 find_keyword_in_vector (instantiator, Q_hotspot_x);
1014 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) =
1015 find_keyword_in_vector (instantiator, Q_hotspot_y);
1016 IMAGE_INSTANCE_GTK_CURSOR (ii) =
1017 gdk_cursor_new_from_pixmap (source, mask, &fg_color, &bg_color,
1018 !NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)) ?
1019 XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)) : 0,
1020 !NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)) ?
1021 XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)) : 0);
1031 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1032 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1033 int dest_mask, int width, int height,
1034 /* Note that data is in ext-format! */
1037 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1038 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1039 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1040 GdkPixmap *mask = 0;
1041 CONST char *gcc_may_you_rot_in_hell;
1043 if (!NILP (mask_data))
1045 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (mask_data))),
1046 C_STRING_ALLOCA, gcc_may_you_rot_in_hell,
1049 pixmap_from_xbm_inline (IMAGE_INSTANCE_DEVICE (ii),
1050 XINT (XCAR (mask_data)),
1051 XINT (XCAR (XCDR (mask_data))),
1052 (CONST unsigned char *)
1053 gcc_may_you_rot_in_hell);
1056 init_image_instance_from_xbm_inline (ii, width, height, bits,
1057 instantiator, pointer_fg, pointer_bg,
1058 dest_mask, mask, mask_file);
1061 /* Instantiate method for XBM's. */
1064 gtk_xbm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1065 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1066 int dest_mask, Lisp_Object domain)
1068 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1069 CONST char *gcc_go_home;
1071 assert (!NILP (data));
1073 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (data))),
1074 C_STRING_ALLOCA, gcc_go_home,
1077 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1078 pointer_bg, dest_mask, XINT (XCAR (data)),
1079 XINT (XCAR (XCDR (data))), gcc_go_home);
1084 /**********************************************************************
1086 **********************************************************************/
1088 write_lisp_string_to_temp_file (Lisp_Object string, char *filename_out)
1090 Lisp_Object instream, outstream;
1091 Lstream *istr, *ostr;
1092 char tempbuf[1024]; /* some random amount */
1095 static Extbyte_dynarr *conversion_out_dynarr;
1096 Bytecount bstart, bend;
1097 struct gcpro gcpro1, gcpro2;
1099 Lisp_Object conv_out_stream;
1101 struct gcpro gcpro3;
1104 /* This function can GC */
1105 if (!conversion_out_dynarr)
1106 conversion_out_dynarr = Dynarr_new (Extbyte);
1108 Dynarr_reset (conversion_out_dynarr);
1110 /* Create the temporary file ... */
1111 sprintf (filename_out, "/tmp/emacs%d.XXXXXX", (int) getpid ());
1112 mktemp (filename_out);
1113 tmpfil = fopen (filename_out, "w");
1118 int old_errno = errno;
1120 unlink (filename_out);
1123 report_file_error ("Creating temp file",
1124 list1 (build_string (filename_out)));
1127 CHECK_STRING (string);
1128 get_string_range_byte (string, Qnil, Qnil, &bstart, &bend,
1129 GB_HISTORICAL_STRING_BEHAVIOR);
1130 instream = make_lisp_string_input_stream (string, bstart, bend);
1131 istr = XLSTREAM (instream);
1132 /* setup the out stream */
1133 outstream = make_dynarr_output_stream((unsigned_char_dynarr *)conversion_out_dynarr);
1134 ostr = XLSTREAM (outstream);
1136 /* setup the conversion stream */
1137 conv_out_stream = make_encoding_output_stream (ostr, Fget_coding_system(Qbinary));
1138 costr = XLSTREAM (conv_out_stream);
1139 GCPRO3 (instream, outstream, conv_out_stream);
1141 GCPRO2 (instream, outstream);
1144 /* Get the data while doing the conversion */
1147 int size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
1150 /* It does seem the flushes are necessary... */
1152 Lstream_write (costr, tempbuf, size_in_bytes);
1153 Lstream_flush (costr);
1155 Lstream_write (ostr, tempbuf, size_in_bytes);
1157 Lstream_flush (ostr);
1158 if (fwrite ((unsigned char *)Dynarr_atp(conversion_out_dynarr, 0),
1159 Dynarr_length(conversion_out_dynarr), 1, tmpfil) != 1)
1164 /* reset the dynarr */
1165 Lstream_rewind(ostr);
1168 if (fclose (tmpfil) != 0)
1170 Lstream_close (istr);
1172 Lstream_close (costr);
1174 Lstream_close (ostr);
1177 Lstream_delete (istr);
1178 Lstream_delete (ostr);
1180 Lstream_delete (costr);
1184 report_file_error ("Writing temp file",
1185 list1 (build_string (filename_out)));
1194 static struct color_symbol*
1195 extract_xpm_color_names (Lisp_Object device,
1197 Lisp_Object color_symbol_alist,
1200 /* This function can GC */
1202 Lisp_Object results = Qnil;
1204 struct color_symbol *colortbl;
1205 struct gcpro gcpro1, gcpro2;
1207 GCPRO2 (results, device);
1209 /* We built up results to be (("name" . #<color>) ...) so that if an
1210 error happens we don't lose any malloc()ed data, or more importantly,
1211 leave any pixels allocated in the server. */
1213 LIST_LOOP (rest, color_symbol_alist)
1215 Lisp_Object cons = XCAR (rest);
1216 Lisp_Object name = XCAR (cons);
1217 Lisp_Object value = XCDR (cons);
1220 if (STRINGP (value))
1222 Fmake_color_instance
1223 (value, device, encode_error_behavior_flag (ERROR_ME_NOT));
1226 assert (COLOR_SPECIFIERP (value));
1227 value = Fspecifier_instance (value, domain, Qnil, Qnil);
1231 results = noseeum_cons (noseeum_cons (name, value), results);
1234 UNGCPRO; /* no more evaluation */
1237 if (i == 0) return 0;
1239 colortbl = xnew_array_and_zero (struct color_symbol, i);
1243 Lisp_Object cons = XCAR (results);
1245 * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
1247 colortbl[j].name = (char *) XSTRING_DATA (XCAR (cons));
1248 free_cons (XCONS (cons));
1250 results = XCDR (results);
1251 free_cons (XCONS (cons));
1257 gtk_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1258 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1259 int dest_mask, Lisp_Object domain)
1261 /* This function can GC */
1262 char temp_file_name[1024];
1263 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1264 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1265 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1270 GdkPixmap *mask = 0;
1271 GdkWindow *window = 0;
1272 int nsymbols = 0, i = 0;
1273 struct color_symbol *color_symbols = NULL;
1274 GdkColor *transparent_color = NULL;
1275 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator,
1277 enum image_instance_type type;
1281 if (!DEVICE_GTK_P (XDEVICE (device)))
1282 signal_simple_error ("Not a Gtk device", device);
1284 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1285 type = IMAGE_COLOR_PIXMAP;
1286 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
1287 type = IMAGE_MONO_PIXMAP;
1288 else if (dest_mask & IMAGE_POINTER_MASK)
1289 type = IMAGE_POINTER;
1291 incompatible_image_types (instantiator, dest_mask,
1292 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
1293 | IMAGE_POINTER_MASK);
1294 force_mono = (type != IMAGE_COLOR_PIXMAP);
1296 window = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (device)));
1297 cmap = DEVICE_GTK_COLORMAP (XDEVICE (device));
1298 depth = DEVICE_GTK_DEPTH (XDEVICE (device));
1299 visual = DEVICE_GTK_VISUAL (XDEVICE (device));
1301 gtk_initialize_pixmap_image_instance (ii, 1, type);
1303 assert (!NILP (data));
1305 /* Need to get the transparent color here */
1306 color_symbols = extract_xpm_color_names (device, domain, color_symbol_alist, &nsymbols);
1307 for (i = 0; i < nsymbols; i++)
1309 if (!strcasecmp ("BgColor", color_symbols[i].name) ||
1310 !strcasecmp ("None", color_symbols[i].name))
1312 transparent_color = &color_symbols[i].color;
1316 write_lisp_string_to_temp_file (data, temp_file_name);
1317 pixmap = gdk_pixmap_create_from_xpm (window, &mask, transparent_color, temp_file_name);
1318 unlink (temp_file_name);
1320 if (color_symbols) xfree (color_symbols);
1324 signal_image_error ("Error reading pixmap", data);
1327 gdk_window_get_geometry (pixmap, NULL, NULL, &w, &h, &depth);
1329 IMAGE_INSTANCE_GTK_PIXMAP (ii) = pixmap;
1330 IMAGE_INSTANCE_GTK_MASK (ii) = mask;
1331 IMAGE_INSTANCE_GTK_COLORMAP (ii) = cmap;
1332 IMAGE_INSTANCE_GTK_PIXELS (ii) = 0;
1333 IMAGE_INSTANCE_GTK_NPIXELS (ii) = 0;
1334 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = w;
1335 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = h;
1336 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
1337 find_keyword_in_vector (instantiator, Q_file);
1341 case IMAGE_MONO_PIXMAP:
1344 case IMAGE_COLOR_PIXMAP:
1346 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = depth;
1353 unsigned int xhot, yhot;
1355 /* #### Gtk does not give us access to the hotspots of a pixmap */
1357 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), xhot);
1358 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), yhot);
1360 check_pointer_sizes (w, h, instantiator);
1362 /* If the loaded pixmap has colors allocated (meaning it came from an
1363 XPM file), then use those as the default colors for the cursor we
1364 create. Otherwise, default to pointer_fg and pointer_bg.
1368 warn_when_safe (Qunimplemented, Qnotice,
1369 "GTK does not support XPM cursors...\n");
1370 IMAGE_INSTANCE_GTK_CURSOR (ii) = gdk_cursor_new (GDK_COFFEE_MUG);
1374 generate_cursor_fg_bg (device, &pointer_fg, &pointer_bg,
1376 IMAGE_INSTANCE_PIXMAP_FG (ii) = pointer_fg;
1377 IMAGE_INSTANCE_PIXMAP_BG (ii) = pointer_bg;
1378 IMAGE_INSTANCE_GTK_CURSOR (ii) = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, xhot, yhot);
1388 #endif /* HAVE_XPM */
1393 /**********************************************************************
1395 **********************************************************************/
1397 /* This is about to get redefined! */
1400 /* We have to define SYSV32 so that compface.h includes string.h
1401 instead of strings.h. */
1406 #include <compface.h>
1410 /* JMP_BUF cannot be used here because if it doesn't get defined
1411 to jmp_buf we end up with a conflicting type error with the
1412 definition in compface.h */
1413 extern jmp_buf comp_env;
1417 gtk_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1418 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1419 int dest_mask, Lisp_Object domain)
1421 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1423 char *p, *bits, *bp;
1424 CONST char * volatile emsg = 0;
1425 CONST char * volatile dstring;
1427 assert (!NILP (data));
1429 LISP_STRING_TO_EXTERNAL (data, dstring, Qbinary);
1431 if ((p = strchr (dstring, ':')))
1436 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */
1437 if (!(stattis = setjmp (comp_env)))
1439 UnCompAll ((char *) dstring);
1446 emsg = "uncompface: internal error";
1449 emsg = "uncompface: insufficient or invalid data";
1452 emsg = "uncompface: excess data ignored";
1457 signal_simple_error_2 (emsg, data, Qimage);
1459 bp = bits = (char *) alloca (PIXELS / 8);
1461 /* the compface library exports char F[], which uses a single byte per
1462 pixel to represent a 48x48 bitmap. Yuck. */
1463 for (i = 0, p = F; i < (PIXELS / 8); ++i)
1466 /* reverse the bit order of each byte... */
1467 for (b = n = 0; b < 8; ++b)
1474 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1475 pointer_bg, dest_mask, 48, 48, bits);
1478 #endif /* HAVE_XFACE */
1480 /**********************************************************************
1482 **********************************************************************/
1485 gtk_resource_validate (Lisp_Object instantiator)
1487 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
1489 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
1491 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
1492 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
1497 gtk_resource_normalize (Lisp_Object inst, Lisp_Object console_type, Lisp_Object dest_mask)
1499 /* This function can call lisp */
1500 Lisp_Object file = Qnil;
1501 struct gcpro gcpro1, gcpro2;
1502 Lisp_Object alist = Qnil;
1504 GCPRO2 (file, alist);
1506 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
1509 if (CONSP (file)) /* failure locating filename */
1510 signal_double_file_error ("Opening pixmap file",
1511 "no such file or directory",
1514 if (NILP (file)) /* no conversion necessary */
1515 RETURN_UNGCPRO (inst);
1517 alist = tagged_vector_to_alist (inst);
1520 alist = remassq_no_quit (Q_file, alist);
1521 alist = Fcons (Fcons (Q_file, file), alist);
1525 Lisp_Object result = alist_to_tagged_vector (Qgtk_resource, alist);
1527 RETURN_UNGCPRO (result);
1532 gtk_resource_possible_dest_types (void)
1534 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
1537 extern guint symbol_to_enum (Lisp_Object, GtkType);
1539 static guint resource_name_to_resource (Lisp_Object name, int type)
1541 if (type == IMAGE_POINTER)
1542 return (symbol_to_enum (name, GTK_TYPE_GDK_CURSOR_TYPE));
1548 resource_symbol_to_type (Lisp_Object data)
1550 if (EQ (data, Qcursor))
1551 return IMAGE_POINTER;
1553 else if (EQ (data, Qicon))
1555 else if (EQ (data, Qbitmap))
1556 return IMAGE_BITMAP;
1563 gtk_resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1564 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1565 int dest_mask, Lisp_Object domain)
1567 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1568 GdkCursor *c = NULL;
1569 unsigned int type = 0;
1570 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1571 Lisp_Object resource_type = find_keyword_in_vector (instantiator, Q_resource_type);
1572 Lisp_Object resource_id = find_keyword_in_vector (instantiator, Q_resource_id);
1574 if (!DEVICE_GTK_P (XDEVICE (device)))
1575 signal_simple_error ("Not a GTK device", device);
1577 type = resource_symbol_to_type (resource_type);
1580 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_POINTER_MASK)
1581 iitype = IMAGE_POINTER;
1582 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1583 iitype = IMAGE_COLOR_PIXMAP;
1585 incompatible_image_types (instantiator, dest_mask,
1586 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
1589 /* mess with the keyword info we were provided with */
1590 gtk_initialize_pixmap_image_instance (ii, 1, type);
1591 c = gdk_cursor_new (resource_name_to_resource (resource_id, type));
1592 IMAGE_INSTANCE_GTK_CURSOR (ii) = c;
1593 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = resource_id;
1594 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = 10;
1595 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = 10;
1596 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1600 check_valid_resource_symbol (Lisp_Object data)
1602 CHECK_SYMBOL (data);
1603 if (!resource_symbol_to_type (data))
1604 signal_simple_error ("invalid resource type", data);
1608 check_valid_resource_id (Lisp_Object data)
1610 if (!resource_name_to_resource (data, IMAGE_POINTER)
1612 !resource_name_to_resource (data, IMAGE_COLOR_PIXMAP)
1615 !resource_name_to_resource (data, IMAGE_BITMAP)
1618 signal_simple_error ("invalid resource identifier", data);
1623 check_valid_string_or_int (Lisp_Object data)
1626 CHECK_STRING (data);
1633 /**********************************************************************
1635 **********************************************************************/
1638 autodetect_validate (Lisp_Object instantiator)
1640 data_must_be_present (instantiator);
1644 autodetect_normalize (Lisp_Object instantiator,
1645 Lisp_Object console_type,
1646 Lisp_Object dest_mask)
1648 Lisp_Object file = find_keyword_in_vector (instantiator, Q_data);
1649 Lisp_Object filename = Qnil;
1650 Lisp_Object data = Qnil;
1651 struct gcpro gcpro1, gcpro2, gcpro3;
1652 Lisp_Object alist = Qnil;
1654 GCPRO3 (filename, data, alist);
1656 if (NILP (file)) /* no conversion necessary */
1657 RETURN_UNGCPRO (instantiator);
1659 alist = tagged_vector_to_alist (instantiator);
1661 filename = locate_pixmap_file (file);
1662 if (!NILP (filename))
1665 /* #### Apparently some versions of XpmReadFileToData, which is
1666 called by pixmap_to_lisp_data, don't return an error value
1667 if the given file is not a valid XPM file. Instead, they
1668 just seg fault. It is definitely caused by passing a
1669 bitmap. To try and avoid this we check for bitmaps first. */
1671 data = bitmap_to_lisp_data (filename, &xhot, &yhot, 1);
1675 alist = remassq_no_quit (Q_data, alist);
1676 alist = Fcons (Fcons (Q_file, filename),
1677 Fcons (Fcons (Q_data, data), alist));
1679 alist = Fcons (Fcons (Q_hotspot_x, make_int (xhot)),
1682 alist = Fcons (Fcons (Q_hotspot_y, make_int (yhot)),
1685 alist = xbm_mask_file_munging (alist, filename, Qnil, console_type);
1688 Lisp_Object result = alist_to_tagged_vector (Qxbm, alist);
1690 RETURN_UNGCPRO (result);
1695 data = pixmap_to_lisp_data (filename, 1);
1699 alist = remassq_no_quit (Q_data, alist);
1700 alist = Fcons (Fcons (Q_file, filename),
1701 Fcons (Fcons (Q_data, data), alist));
1702 alist = Fcons (Fcons (Q_color_symbols,
1703 evaluate_xpm_color_symbols ()),
1706 Lisp_Object result = alist_to_tagged_vector (Qxpm, alist);
1708 RETURN_UNGCPRO (result);
1714 /* If we couldn't convert it, just put it back as it is.
1715 We might try to further frob it later as a cursor-font
1716 specification. (We can't do that now because we don't know
1717 what dest-types it's going to be instantiated into.) */
1719 Lisp_Object result = alist_to_tagged_vector (Qautodetect, alist);
1721 RETURN_UNGCPRO (result);
1726 autodetect_possible_dest_types (void)
1729 IMAGE_MONO_PIXMAP_MASK |
1730 IMAGE_COLOR_PIXMAP_MASK |
1731 IMAGE_POINTER_MASK |
1736 autodetect_instantiate (Lisp_Object image_instance,
1737 Lisp_Object instantiator,
1738 Lisp_Object pointer_fg,
1739 Lisp_Object pointer_bg,
1740 int dest_mask, Lisp_Object domain)
1742 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1743 struct gcpro gcpro1, gcpro2, gcpro3;
1744 Lisp_Object alist = Qnil;
1745 Lisp_Object result = Qnil;
1746 int is_cursor_font = 0;
1748 GCPRO3 (data, alist, result);
1750 alist = tagged_vector_to_alist (instantiator);
1751 if (dest_mask & IMAGE_POINTER_MASK)
1753 CONST char *name_ext;
1755 TO_EXTERNAL_FORMAT (LISP_STRING, data,
1756 C_STRING_ALLOCA, name_ext,
1759 if (cursor_name_to_index (name_ext) != -1)
1761 result = alist_to_tagged_vector (Qcursor_font, alist);
1766 if (!is_cursor_font)
1767 result = alist_to_tagged_vector (Qstring, alist);
1771 cursor_font_instantiate (image_instance, result, pointer_fg,
1772 pointer_bg, dest_mask, domain);
1774 string_instantiate (image_instance, result, pointer_fg,
1775 pointer_bg, dest_mask, domain);
1781 /**********************************************************************
1783 **********************************************************************/
1786 font_validate (Lisp_Object instantiator)
1788 data_must_be_present (instantiator);
1792 font_possible_dest_types (void)
1794 return IMAGE_POINTER_MASK;
1798 font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1799 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1800 int dest_mask, Lisp_Object domain)
1802 /* This function can GC */
1803 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1804 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1805 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1807 GdkFont *source, *mask;
1808 char source_name[MAXPATHLEN], mask_name[MAXPATHLEN], dummy;
1809 int source_char, mask_char;
1811 Lisp_Object foreground, background;
1813 if (!DEVICE_GTK_P (XDEVICE (device)))
1814 signal_simple_error ("Not a Gtk device", device);
1816 if (!STRINGP (data) ||
1817 strncmp ("FONT ", (char *) XSTRING_DATA (data), 5))
1818 signal_simple_error ("Invalid font-glyph instantiator",
1821 if (!(dest_mask & IMAGE_POINTER_MASK))
1822 incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK);
1824 foreground = find_keyword_in_vector (instantiator, Q_foreground);
1825 if (NILP (foreground))
1826 foreground = pointer_fg;
1827 background = find_keyword_in_vector (instantiator, Q_background);
1828 if (NILP (background))
1829 background = pointer_bg;
1831 generate_cursor_fg_bg (device, &foreground, &background, &fg, &bg);
1833 count = sscanf ((char *) XSTRING_DATA (data),
1834 "FONT %s %d %s %d %c",
1835 source_name, &source_char,
1836 mask_name, &mask_char, &dummy);
1837 /* Allow "%s %d %d" as well... */
1838 if (count == 3 && (1 == sscanf (mask_name, "%d %c", &mask_char, &dummy)))
1839 count = 4, mask_name[0] = 0;
1841 if (count != 2 && count != 4)
1842 signal_simple_error ("invalid cursor specification", data);
1843 source = gdk_font_load (source_name);
1845 signal_simple_error_2 ("couldn't load font",
1846 build_string (source_name),
1850 else if (!mask_name[0])
1854 mask = gdk_font_load (mask_name);
1857 Fsignal (Qerror, list3 (build_string ("couldn't load font"),
1858 build_string (mask_name), data));
1863 /* #### call XQueryTextExtents() and check_pointer_sizes() here. */
1865 gtk_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER);
1867 IMAGE_INSTANCE_GTK_CURSOR (ii) = NULL;
1870 /* #### BILL!!! There is no way to call this function from Gdk */
1871 XCreateGlyphCursor (dpy, source, mask, source_char, mask_char,
1874 XIMAGE_INSTANCE_PIXMAP_FG (image_instance) = foreground;
1875 XIMAGE_INSTANCE_PIXMAP_BG (image_instance) = background;
1877 gdk_font_unref (source);
1878 if (mask && mask != source) gdk_font_unref (mask);
1882 /**********************************************************************
1884 **********************************************************************/
1887 cursor_font_validate (Lisp_Object instantiator)
1889 data_must_be_present (instantiator);
1893 cursor_font_possible_dest_types (void)
1895 return IMAGE_POINTER_MASK;
1898 static char *__downcase (const char *name)
1900 char *converted = strdup(name);
1901 char *work = converted;
1905 *work = tolower(*work);
1911 /* This is basically the equivalent of XmuCursorNameToIndex */
1913 cursor_name_to_index (const char *name)
1916 static char *the_gdk_cursors[GDK_NUM_GLYPHS];
1918 if (!the_gdk_cursors[GDK_BASED_ARROW_UP])
1920 /* Need to initialize the array */
1921 /* Supposedly since this array is static it should be
1922 initialized to NULLs for us, but I'm very paranoid. */
1923 for (i = 0; i < GDK_NUM_GLYPHS; i++)
1925 the_gdk_cursors[i] = NULL;
1928 #define FROB_CURSOR(x) the_gdk_cursors[GDK_##x] = __downcase(#x)
1929 FROB_CURSOR(ARROW); FROB_CURSOR(BASED_ARROW_DOWN);
1930 FROB_CURSOR(BASED_ARROW_UP); FROB_CURSOR(BOAT);
1931 FROB_CURSOR(BOGOSITY); FROB_CURSOR(BOTTOM_LEFT_CORNER);
1932 FROB_CURSOR(BOTTOM_RIGHT_CORNER); FROB_CURSOR(BOTTOM_SIDE);
1933 FROB_CURSOR(BOTTOM_TEE); FROB_CURSOR(BOX_SPIRAL);
1934 FROB_CURSOR(CENTER_PTR); FROB_CURSOR(CIRCLE);
1935 FROB_CURSOR(CLOCK); FROB_CURSOR(COFFEE_MUG);
1936 FROB_CURSOR(CROSS); FROB_CURSOR(CROSS_REVERSE);
1937 FROB_CURSOR(CROSSHAIR); FROB_CURSOR(DIAMOND_CROSS);
1938 FROB_CURSOR(DOT); FROB_CURSOR(DOTBOX);
1939 FROB_CURSOR(DOUBLE_ARROW); FROB_CURSOR(DRAFT_LARGE);
1940 FROB_CURSOR(DRAFT_SMALL); FROB_CURSOR(DRAPED_BOX);
1941 FROB_CURSOR(EXCHANGE); FROB_CURSOR(FLEUR);
1942 FROB_CURSOR(GOBBLER); FROB_CURSOR(GUMBY);
1943 FROB_CURSOR(HAND1); FROB_CURSOR(HAND2);
1944 FROB_CURSOR(HEART); FROB_CURSOR(ICON);
1945 FROB_CURSOR(IRON_CROSS); FROB_CURSOR(LEFT_PTR);
1946 FROB_CURSOR(LEFT_SIDE); FROB_CURSOR(LEFT_TEE);
1947 FROB_CURSOR(LEFTBUTTON); FROB_CURSOR(LL_ANGLE);
1948 FROB_CURSOR(LR_ANGLE); FROB_CURSOR(MAN);
1949 FROB_CURSOR(MIDDLEBUTTON); FROB_CURSOR(MOUSE);
1950 FROB_CURSOR(PENCIL); FROB_CURSOR(PIRATE);
1951 FROB_CURSOR(PLUS); FROB_CURSOR(QUESTION_ARROW);
1952 FROB_CURSOR(RIGHT_PTR); FROB_CURSOR(RIGHT_SIDE);
1953 FROB_CURSOR(RIGHT_TEE); FROB_CURSOR(RIGHTBUTTON);
1954 FROB_CURSOR(RTL_LOGO); FROB_CURSOR(SAILBOAT);
1955 FROB_CURSOR(SB_DOWN_ARROW); FROB_CURSOR(SB_H_DOUBLE_ARROW);
1956 FROB_CURSOR(SB_LEFT_ARROW); FROB_CURSOR(SB_RIGHT_ARROW);
1957 FROB_CURSOR(SB_UP_ARROW); FROB_CURSOR(SB_V_DOUBLE_ARROW);
1958 FROB_CURSOR(SHUTTLE); FROB_CURSOR(SIZING);
1959 FROB_CURSOR(SPIDER); FROB_CURSOR(SPRAYCAN);
1960 FROB_CURSOR(STAR); FROB_CURSOR(TARGET);
1961 FROB_CURSOR(TCROSS); FROB_CURSOR(TOP_LEFT_ARROW);
1962 FROB_CURSOR(TOP_LEFT_CORNER); FROB_CURSOR(TOP_RIGHT_CORNER);
1963 FROB_CURSOR(TOP_SIDE); FROB_CURSOR(TOP_TEE);
1964 FROB_CURSOR(TREK); FROB_CURSOR(UL_ANGLE);
1965 FROB_CURSOR(UMBRELLA); FROB_CURSOR(UR_ANGLE);
1966 FROB_CURSOR(WATCH); FROB_CURSOR(XTERM);
1967 FROB_CURSOR(X_CURSOR);
1971 for (i = 0; i < GDK_NUM_GLYPHS; i++)
1973 if (!the_gdk_cursors[i]) continue;
1974 if (!strcmp (the_gdk_cursors[i], name))
1983 cursor_font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1984 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1985 int dest_mask, Lisp_Object domain)
1987 /* This function can GC */
1988 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1989 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1990 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1992 CONST char *name_ext;
1993 Lisp_Object foreground, background;
1995 if (!DEVICE_GTK_P (XDEVICE (device)))
1996 signal_simple_error ("Not a Gtk device", device);
1998 if (!(dest_mask & IMAGE_POINTER_MASK))
1999 incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK);
2001 TO_EXTERNAL_FORMAT (LISP_STRING, data,
2002 C_STRING_ALLOCA, name_ext,
2005 if ((i = cursor_name_to_index (name_ext)) == -1)
2006 signal_simple_error ("Unrecognized cursor-font name", data);
2008 gtk_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER);
2009 IMAGE_INSTANCE_GTK_CURSOR (ii) = gdk_cursor_new (i);
2010 foreground = find_keyword_in_vector (instantiator, Q_foreground);
2011 if (NILP (foreground))
2012 foreground = pointer_fg;
2013 background = find_keyword_in_vector (instantiator, Q_background);
2014 if (NILP (background))
2015 background = pointer_bg;
2016 maybe_recolor_cursor (image_instance, foreground, background);
2020 gtk_colorize_image_instance (Lisp_Object image_instance,
2021 Lisp_Object foreground, Lisp_Object background);
2024 /************************************************************************/
2025 /* subwindow and widget support */
2026 /************************************************************************/
2028 /* unmap the image if it is a widget. This is used by redisplay via
2029 redisplay_unmap_subwindows */
2031 gtk_unmap_subwindow (Lisp_Image_Instance *p)
2033 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
2035 /* We don't support subwindows, but we do support widgets... */
2038 else /* must be a widget */
2040 /* Since we are being unmapped we want the enclosing frame to
2041 get focus. The losing with simple scrolling but is the safest
2043 if (IMAGE_INSTANCE_GTK_CLIPWIDGET (p))
2044 gtk_widget_unmap (IMAGE_INSTANCE_GTK_CLIPWIDGET (p));
2048 /* map the subwindow. This is used by redisplay via
2049 redisplay_output_subwindow */
2051 gtk_map_subwindow (Lisp_Image_Instance *p, int x, int y,
2052 struct display_glyph_area* dga)
2054 assert (dga->width > 0 && dga->height > 0);
2056 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
2058 /* No subwindow support... */
2061 else /* must be a widget */
2063 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
2064 GtkWidget *wid = IMAGE_INSTANCE_GTK_CLIPWIDGET (p);
2069 a.x = x + IMAGE_INSTANCE_GTK_WIDGET_XOFFSET (p);
2070 a.y = y + IMAGE_INSTANCE_GTK_WIDGET_YOFFSET (p);
2071 a.width = dga->width;
2072 a.height = dga->height;
2074 if ((a.width != wid->allocation.width) ||
2075 (a.height != wid->allocation.height))
2077 gtk_widget_size_allocate (IMAGE_INSTANCE_GTK_CLIPWIDGET (p), &a);
2080 /* #### FIXME DAMMIT */
2081 if ((wid->allocation.x != -dga->xoffset) ||
2082 (wid->allocation.y != -dga->yoffset))
2084 guint32 old_flags = GTK_WIDGET_FLAGS (FRAME_GTK_TEXT_WIDGET (f));
2086 /* Fucking GtkFixed widget queues a resize when you add a widget.
2087 ** But only if it is visible.
2090 GTK_WIDGET_FLAGS(FRAME_GTK_TEXT_WIDGET (f)) &= ~GTK_VISIBLE;
2091 if (IMAGE_INSTANCE_GTK_ALREADY_PUT(p))
2093 gtk_fixed_move (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)),
2095 -dga->xoffset, -dga->yoffset);
2099 IMAGE_INSTANCE_GTK_ALREADY_PUT(p) = TRUE;
2100 gtk_fixed_put (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)),
2102 -dga->xoffset, -dga->yoffset);
2104 GTK_WIDGET_FLAGS(FRAME_GTK_TEXT_WIDGET (f)) = old_flags;
2107 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
2109 gtk_widget_map (wid);
2112 gtk_widget_draw (wid, NULL);
2116 /* when you click on a widget you may activate another widget this
2117 needs to be checked and all appropriate widgets updated */
2119 gtk_redisplay_subwindow (Lisp_Image_Instance *p)
2121 /* Update the subwindow size if necessary. */
2122 if (IMAGE_INSTANCE_SIZE_CHANGED (p))
2125 XResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
2126 IMAGE_INSTANCE_X_SUBWINDOW_ID (p),
2127 IMAGE_INSTANCE_WIDTH (p),
2128 IMAGE_INSTANCE_HEIGHT (p));
2133 /* Update all attributes that have changed. */
2135 gtk_redisplay_widget (Lisp_Image_Instance *p)
2137 /* This function can GC if IN_REDISPLAY is false. */
2139 if (!IMAGE_INSTANCE_GTK_CLIPWIDGET (p))
2143 /* First get the items if they have changed since this is a
2144 structural change. As such it will nuke all added values so we
2145 need to update most other things after the items have changed.*/
2146 gtk_widget_show_all (IMAGE_INSTANCE_GTK_CLIPWIDGET (p));
2147 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
2149 Lisp_Object image_instance;
2151 XSETIMAGE_INSTANCE (image_instance, p);
2153 /* Need to update GtkArgs that might have changed... */
2159 /* No items changed, so do nothing, right? */
2162 /* Possibly update the colors and font */
2163 if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
2165 /* #### This is not sufficient because it will not cope with widgets
2166 that are not currently visible. Once redisplay has done the
2167 visible ones it will clear this flag so that when new ones
2168 become visible they will not be updated. */
2169 XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed
2171 XFRAME (IMAGE_INSTANCE_FRAME (p))->frame_changed
2173 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
2175 /* #### Write this function BILL! */
2176 update_widget_face (NULL, p, IMAGE_INSTANCE_FRAME (p));
2179 /* Possibly update the text. */
2180 if (IMAGE_INSTANCE_TEXT_CHANGED (p))
2183 Lisp_Object val = IMAGE_INSTANCE_WIDGET_TEXT (p);
2184 LISP_STRING_TO_EXTERNAL (val, str, Qnative);
2186 /* #### Need to special case each type of GtkWidget here! */
2189 /* Possibly update the size. */
2190 if (IMAGE_INSTANCE_SIZE_CHANGED (p)
2192 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)
2194 IMAGE_INSTANCE_TEXT_CHANGED (p))
2196 assert (IMAGE_INSTANCE_GTK_WIDGET_ID (p) &&
2197 IMAGE_INSTANCE_GTK_CLIPWIDGET (p)) ;
2199 /* #### Resize the widget! */
2200 /* gtk_widget_size_allocate () */
2203 /* Adjust offsets within the frame. */
2204 if (XFRAME (IMAGE_INSTANCE_FRAME (p))->size_changed)
2206 /* I don't think we need to do anything for Gtk here... */
2209 /* now modify the widget */
2213 /* instantiate and gtk type subwindow */
2215 gtk_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2216 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2217 int dest_mask, Lisp_Object domain)
2219 /* This function can GC */
2220 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2221 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
2222 Lisp_Object frame = DOMAIN_FRAME (domain);
2224 if (!DEVICE_GTK_P (XDEVICE (device)))
2225 signal_simple_error ("Not a GTK device", device);
2227 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
2229 ii->data = xnew_and_zero (struct gtk_subwindow_data);
2231 /* Create a window for clipping */
2232 IMAGE_INSTANCE_GTK_CLIPWINDOW (ii) = NULL;
2234 /* Now put the subwindow inside the clip window. */
2235 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void *) NULL;
2240 /************************************************************************/
2242 /************************************************************************/
2244 update_widget_face (GtkWidget *w, Lisp_Image_Instance *ii,
2249 GtkStyle *style = gtk_widget_get_style (w);
2250 Lisp_Object pixel = Qnil;
2251 GdkColor *fcolor, *bcolor;
2253 style = gtk_style_copy (style);
2255 /* Update the foreground. */
2256 pixel = FACE_FOREGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), domain);
2257 fcolor = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (pixel));
2259 /* Update the background. */
2260 pixel = FACE_BACKGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), domain);
2261 bcolor = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (pixel));
2263 /* Update the font */
2264 /* #### FIXME!!! Need to copy the widgets style, dick with it, and
2265 ** set the widgets style to the new style...
2267 gtk_widget_set_style (w, style);
2269 /* #### Megahack - but its just getting too complicated to do this
2270 in the right place. */
2272 if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qtab_control))
2273 update_tab_widget_face (wv, ii, domain);
2280 update_tab_widget_face (GtkWidget *w, Lisp_Image_Instance *ii,
2285 widget_value* val = wv->contents, *cur;
2287 /* Give each child label the correct foreground color. */
2288 Lisp_Object pixel = FACE_FOREGROUND
2289 (IMAGE_INSTANCE_WIDGET_FACE (ii),
2291 XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
2292 lw_add_widget_value_arg (val, XtNtabForeground, fcolor.pixel);
2293 wv->change = VISIBLE_CHANGE;
2294 val->change = VISIBLE_CHANGE;
2296 for (cur = val->next; cur; cur = cur->next)
2298 cur->change = VISIBLE_CHANGE;
2301 lw_copy_widget_value_args (val, cur);
2309 gtk_widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
2310 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2313 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2314 Lisp_Object widget = Qnil;
2316 GtkWidget *w = NULL;
2317 struct gcpro gcpro1;
2319 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET;
2321 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2323 LISP_STRING_TO_EXTERNAL (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm, Qnative);
2326 ii->data = xnew_and_zero (struct gtk_subwindow_data);
2328 /* Create a clipping widget */
2329 IMAGE_INSTANCE_GTK_CLIPWIDGET (ii) = NULL;
2330 IMAGE_INSTANCE_GTK_ALREADY_PUT(ii) = FALSE;
2332 /* Create the actual widget */
2334 widget = call5 (Qgtk_widget_instantiate_internal,
2335 image_instance, instantiator,
2336 pointer_fg, pointer_bg,
2341 CHECK_GTK_OBJECT (widget);
2342 w = GTK_WIDGET (XGTK_OBJECT (widget)->object);
2346 stderr_out ("Lisp-level creation of widget failed... falling back\n");
2347 w = gtk_label_new ("Widget Creation Failed...");
2352 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void *) w;
2354 /* #### HACK!!!! We should make this do the right thing if we
2355 ** really need a clip widget!
2357 IMAGE_INSTANCE_GTK_CLIPWIDGET (ii) = w;
2363 gtk_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2364 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2365 int dest_mask, Lisp_Object domain)
2367 call_with_suspended_errors ((lisp_fn_t) gtk_widget_instantiate_1,
2370 image_instance, instantiator,
2376 /* get properties of a control */
2378 gtk_widget_property (Lisp_Object image_instance, Lisp_Object prop)
2380 /* Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); */
2382 /* get the text from a control */
2383 if (EQ (prop, Q_text))
2390 #define FAKE_GTK_WIDGET_INSTANTIATOR(x) \
2392 gtk_##x##_instantiate (Lisp_Object image_instance, \
2393 Lisp_Object instantiator, \
2394 Lisp_Object pointer_fg, \
2395 Lisp_Object pointer_bg, \
2396 int dest_mask, Lisp_Object domain) \
2398 gtk_widget_instantiate (image_instance, instantiator, pointer_fg, \
2399 pointer_bg, dest_mask, domain); \
2402 FAKE_GTK_WIDGET_INSTANTIATOR(native_layout);
2403 FAKE_GTK_WIDGET_INSTANTIATOR(button);
2404 FAKE_GTK_WIDGET_INSTANTIATOR(progress_gauge);
2405 FAKE_GTK_WIDGET_INSTANTIATOR(edit_field);
2406 FAKE_GTK_WIDGET_INSTANTIATOR(combo_box);
2407 FAKE_GTK_WIDGET_INSTANTIATOR(tab_control);
2408 FAKE_GTK_WIDGET_INSTANTIATOR(label);
2410 /* Update a button's clicked state. */
2412 gtk_button_redisplay (Lisp_Object image_instance)
2414 /* This function can GC if IN_REDISPLAY is false. */
2415 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
2416 GtkWidget *w = IMAGE_INSTANCE_GTK_CLIPWIDGET (p);
2418 if (GTK_WIDGET_TYPE (w) == gtk_button_get_type ())
2421 else if (GTK_WIDGET_TYPE (w) == gtk_check_button_get_type ())
2424 else if (GTK_WIDGET_TYPE (w) == gtk_radio_button_get_type ())
2429 /* Unknown button type... */
2434 /* get properties of a button */
2436 gtk_button_property (Lisp_Object image_instance, Lisp_Object prop)
2438 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2440 /* check the state of a button */
2441 if (EQ (prop, Q_selected))
2443 if (GTK_WIDGET_HAS_FOCUS (IMAGE_INSTANCE_SUBWINDOW_ID (ii)))
2451 /* set the properties of a progress gauge */
2453 gtk_progress_gauge_redisplay (Lisp_Object image_instance)
2455 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2457 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
2462 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value;
2463 f = XFLOATINT (val);
2465 gtk_progress_set_value (GTK_PROGRESS (IMAGE_INSTANCE_SUBWINDOW_ID (ii)),
2470 /* Set the properties of a tab control */
2472 gtk_tab_control_redisplay (Lisp_Object image_instance)
2474 /* #### Convert this to GTK baby! */
2475 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2477 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) ||
2478 IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii))
2480 /* If only the order has changed then simply select the first
2481 one of the pending set. This stops horrendous rebuilding -
2482 and hence flicker - of the tabs each time you click on
2484 if (tab_control_order_only_changed (image_instance))
2486 Lisp_Object rest, selected =
2487 gui_item_list_find_selected
2488 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ?
2489 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) :
2490 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
2492 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2494 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0))
2496 Lisp_Object old_selected =gui_item_list_find_selected
2497 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
2499 /* Need to focus on the widget... */
2500 stderr_out ("Hey, change the tab-focus you boob...\n");
2502 /* Pick up the new selected item. */
2503 XGUI_ITEM (old_selected)->selected =
2504 XGUI_ITEM (XCAR (rest))->selected;
2505 XGUI_ITEM (XCAR (rest))->selected =
2506 XGUI_ITEM (selected)->selected;
2507 /* We're not actually changing the items anymore. */
2508 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
2509 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
2516 /* More than just the order has changed... let's get busy! */
2517 GtkNotebook *nb = GTK_NOTEBOOK (IMAGE_INSTANCE_GTK_CLIPWIDGET (ii));
2518 guint num_pages = g_list_length (nb->children);
2524 for (i = num_pages; i >= 0; --i)
2526 gtk_notebook_remove_page (nb, i);
2530 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2532 Lisp_Gui_Item *pgui = XGUI_ITEM (XCAR (rest));
2533 char *c_name = NULL;
2535 if (!STRINGP (pgui->name))
2536 pgui->name = Feval (pgui->name);
2538 CHECK_STRING (pgui->name);
2540 TO_EXTERNAL_FORMAT (LISP_STRING, pgui->name,
2541 C_STRING_ALLOCA, c_name,
2544 gtk_notebook_append_page (nb,
2545 gtk_vbox_new (FALSE, 3),
2546 gtk_label_new (c_name));
2549 /* Show all the new widgets we just added... */
2550 gtk_widget_show_all (GTK_WIDGET (nb));
2554 /* Possibly update the face. */
2556 if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii)
2558 XFRAME (IMAGE_INSTANCE_FRAME (ii))->faces_changed
2560 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
2562 update_tab_widget_face (wv, ii,
2563 IMAGE_INSTANCE_FRAME (ii));
2567 #endif /* HAVE_WIDGETS */
2570 /************************************************************************/
2571 /* initialization */
2572 /************************************************************************/
2574 syms_of_glyphs_gtk (void)
2576 defkeyword (&Q_resource_id, ":resource-id");
2577 defkeyword (&Q_resource_type, ":resource-type");
2579 defsymbol (&Qgtk_widget_instantiate_internal, "gtk-widget-instantiate-internal");
2580 defsymbol (&Qgtk_widget_property_internal, "gtk-widget-property-internal");
2581 defsymbol (&Qgtk_widget_redisplay_internal, "gtk-widget-redisplay-internal");
2582 defsymbol (&Qgtk_widget_set_style, "gtk-widget-set-style");
2587 console_type_create_glyphs_gtk (void)
2590 CONSOLE_HAS_METHOD (gtk, print_image_instance);
2591 CONSOLE_HAS_METHOD (gtk, finalize_image_instance);
2592 CONSOLE_HAS_METHOD (gtk, image_instance_equal);
2593 CONSOLE_HAS_METHOD (gtk, image_instance_hash);
2594 CONSOLE_HAS_METHOD (gtk, colorize_image_instance);
2595 CONSOLE_HAS_METHOD (gtk, init_image_instance_from_eimage);
2596 CONSOLE_HAS_METHOD (gtk, locate_pixmap_file);
2597 CONSOLE_HAS_METHOD (gtk, unmap_subwindow);
2598 CONSOLE_HAS_METHOD (gtk, map_subwindow);
2599 CONSOLE_HAS_METHOD (gtk, redisplay_widget);
2600 CONSOLE_HAS_METHOD (gtk, redisplay_subwindow);
2604 image_instantiator_format_create_glyphs_gtk (void)
2606 IIFORMAT_VALID_CONSOLE (gtk, nothing);
2607 IIFORMAT_VALID_CONSOLE (gtk, string);
2609 IIFORMAT_VALID_CONSOLE (gtk, layout);
2611 IIFORMAT_VALID_CONSOLE (gtk, formatted_string);
2612 IIFORMAT_VALID_CONSOLE (gtk, inherit);
2614 INITIALIZE_DEVICE_IIFORMAT (gtk, xpm);
2615 IIFORMAT_HAS_DEVMETHOD (gtk, xpm, instantiate);
2618 IIFORMAT_VALID_CONSOLE (gtk, jpeg);
2621 IIFORMAT_VALID_CONSOLE (gtk, tiff);
2624 IIFORMAT_VALID_CONSOLE (gtk, png);
2627 IIFORMAT_VALID_CONSOLE (gtk, gif);
2630 INITIALIZE_DEVICE_IIFORMAT (gtk, subwindow);
2631 IIFORMAT_HAS_DEVMETHOD (gtk, subwindow, instantiate);
2635 INITIALIZE_DEVICE_IIFORMAT (gtk, native_layout);
2636 IIFORMAT_HAS_DEVMETHOD (gtk, native_layout, instantiate);
2639 INITIALIZE_DEVICE_IIFORMAT (gtk, button);
2640 IIFORMAT_HAS_DEVMETHOD (gtk, button, property);
2641 IIFORMAT_HAS_DEVMETHOD (gtk, button, instantiate);
2642 IIFORMAT_HAS_DEVMETHOD (gtk, button, redisplay);
2643 /* general widget methods. */
2644 INITIALIZE_DEVICE_IIFORMAT (gtk, widget);
2645 IIFORMAT_HAS_DEVMETHOD (gtk, widget, property);
2647 /* progress gauge */
2648 INITIALIZE_DEVICE_IIFORMAT (gtk, progress_gauge);
2649 IIFORMAT_HAS_DEVMETHOD (gtk, progress_gauge, redisplay);
2650 IIFORMAT_HAS_DEVMETHOD (gtk, progress_gauge, instantiate);
2652 INITIALIZE_DEVICE_IIFORMAT (gtk, edit_field);
2653 IIFORMAT_HAS_DEVMETHOD (gtk, edit_field, instantiate);
2654 INITIALIZE_DEVICE_IIFORMAT (gtk, combo_box);
2655 IIFORMAT_HAS_DEVMETHOD (gtk, combo_box, instantiate);
2656 IIFORMAT_HAS_SHARED_DEVMETHOD (gtk, combo_box, redisplay, tab_control);
2657 /* tab control widget */
2658 INITIALIZE_DEVICE_IIFORMAT (gtk, tab_control);
2659 IIFORMAT_HAS_DEVMETHOD (gtk, tab_control, instantiate);
2660 IIFORMAT_HAS_DEVMETHOD (gtk, tab_control, redisplay);
2662 INITIALIZE_DEVICE_IIFORMAT (gtk, label);
2663 IIFORMAT_HAS_DEVMETHOD (gtk, label, instantiate);
2666 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font");
2667 IIFORMAT_VALID_CONSOLE (gtk, cursor_font);
2669 IIFORMAT_HAS_METHOD (cursor_font, validate);
2670 IIFORMAT_HAS_METHOD (cursor_font, possible_dest_types);
2671 IIFORMAT_HAS_METHOD (cursor_font, instantiate);
2673 IIFORMAT_VALID_KEYWORD (cursor_font, Q_data, check_valid_string);
2674 IIFORMAT_VALID_KEYWORD (cursor_font, Q_foreground, check_valid_string);
2675 IIFORMAT_VALID_KEYWORD (cursor_font, Q_background, check_valid_string);
2677 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (font, "font");
2678 IIFORMAT_VALID_CONSOLE (gtk, font);
2680 IIFORMAT_HAS_METHOD (font, validate);
2681 IIFORMAT_HAS_METHOD (font, possible_dest_types);
2682 IIFORMAT_HAS_METHOD (font, instantiate);
2684 IIFORMAT_VALID_KEYWORD (font, Q_data, check_valid_string);
2685 IIFORMAT_VALID_KEYWORD (font, Q_foreground, check_valid_string);
2686 IIFORMAT_VALID_KEYWORD (font, Q_background, check_valid_string);
2689 INITIALIZE_DEVICE_IIFORMAT (gtk, xpm);
2690 IIFORMAT_HAS_DEVMETHOD (gtk, xpm, instantiate);
2694 INITIALIZE_DEVICE_IIFORMAT (gtk, xface);
2695 IIFORMAT_HAS_DEVMETHOD (gtk, xface, instantiate);
2698 INITIALIZE_DEVICE_IIFORMAT (gtk, xbm);
2699 IIFORMAT_HAS_DEVMETHOD (gtk, xbm, instantiate);
2700 IIFORMAT_VALID_CONSOLE (gtk, xbm);
2702 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gtk_resource, "gtk-resource");
2703 IIFORMAT_VALID_CONSOLE (gtk, gtk_resource);
2705 IIFORMAT_HAS_METHOD (gtk_resource, validate);
2706 IIFORMAT_HAS_METHOD (gtk_resource, normalize);
2707 IIFORMAT_HAS_METHOD (gtk_resource, possible_dest_types);
2708 IIFORMAT_HAS_METHOD (gtk_resource, instantiate);
2710 IIFORMAT_VALID_KEYWORD (gtk_resource, Q_resource_type, check_valid_resource_symbol);
2711 IIFORMAT_VALID_KEYWORD (gtk_resource, Q_resource_id, check_valid_resource_id);
2712 IIFORMAT_VALID_KEYWORD (gtk_resource, Q_file, check_valid_string);
2714 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (autodetect, "autodetect");
2715 IIFORMAT_VALID_CONSOLE (gtk, autodetect);
2717 IIFORMAT_HAS_METHOD (autodetect, validate);
2718 IIFORMAT_HAS_METHOD (autodetect, normalize);
2719 IIFORMAT_HAS_METHOD (autodetect, possible_dest_types);
2720 IIFORMAT_HAS_METHOD (autodetect, instantiate);
2722 IIFORMAT_VALID_KEYWORD (autodetect, Q_data, check_valid_string);
2726 vars_of_glyphs_gtk (void)
2732 DEFVAR_LISP ("gtk-bitmap-file-path", &Vgtk_bitmap_file_path /*
2733 A list of the directories in which X bitmap files may be found.
2734 If nil, this is initialized from the "*bitmapFilePath" resource.
2735 This is used by the `make-image-instance' function (however, note that if
2736 the environment variable XBMLANGPATH is set, it is consulted first).
2738 Vgtk_bitmap_file_path = Qnil;
2742 complex_vars_of_glyphs_gtk (void)
2744 #define BUILD_GLYPH_INST(variable, name) \
2745 Fadd_spec_to_specifier \
2746 (GLYPH_IMAGE (XGLYPH (variable)), \
2747 vector3 (Qxbm, Q_data, \
2748 list3 (make_int (name##_width), \
2749 make_int (name##_height), \
2750 make_ext_string (name##_bits, \
2751 sizeof (name##_bits), \
2753 Qglobal, Qgtk, Qnil)
2755 BUILD_GLYPH_INST (Vtruncation_glyph, truncator);
2756 BUILD_GLYPH_INST (Vcontinuation_glyph, continuer);
2757 BUILD_GLYPH_INST (Vxemacs_logo, xemacs);
2758 BUILD_GLYPH_INST (Vhscroll_glyph, hscroll);
2760 #undef BUILD_GLYPH_INST
2764 /* Ripped off from glyphs-msw.c */
2766 * The data returned by the following routine is always in left-most byte
2767 * first and left-most bit first. If it doesn't return BitmapSuccess then
2768 * its arguments won't have been touched. This routine should look as much
2769 * like the Xlib routine XReadBitmapfile as possible.
2771 #define MAX_SIZE 1024
2773 /* shared data for the image read/parse logic */
2774 static short hexTable[256]; /* conversion value */
2775 static int initialized = FALSE; /* easier to fill in at run time */
2778 * Table index for the hex values. Initialized once, first time.
2779 * Used for translation value or delimiter significance lookup.
2781 static void initHexTable()
2784 * We build the table at run time for several reasons:
2786 * 1. portable to non-ASCII machines.
2787 * 2. still reentrant since we set the init flag after setting table.
2788 * 3. easier to extend.
2789 * 4. less prone to bugs.
2791 hexTable['0'] = 0; hexTable['1'] = 1;
2792 hexTable['2'] = 2; hexTable['3'] = 3;
2793 hexTable['4'] = 4; hexTable['5'] = 5;
2794 hexTable['6'] = 6; hexTable['7'] = 7;
2795 hexTable['8'] = 8; hexTable['9'] = 9;
2796 hexTable['A'] = 10; hexTable['B'] = 11;
2797 hexTable['C'] = 12; hexTable['D'] = 13;
2798 hexTable['E'] = 14; hexTable['F'] = 15;
2799 hexTable['a'] = 10; hexTable['b'] = 11;
2800 hexTable['c'] = 12; hexTable['d'] = 13;
2801 hexTable['e'] = 14; hexTable['f'] = 15;
2803 /* delimiters of significance are flagged w/ negative value */
2804 hexTable[' '] = -1; hexTable[','] = -1;
2805 hexTable['}'] = -1; hexTable['\n'] = -1;
2806 hexTable['\t'] = -1;
2812 * read next hex value in the input stream, return -1 if EOF
2814 static int NextInt ( FILE *fstream )
2821 /* loop, accumulate hex value until find delimiter */
2822 /* skip any initial delimiters found in read stream */
2830 /* trim high bits, check type and accumulate */
2832 if (isascii(ch) && isxdigit(ch)) {
2833 value = (value << 4) + hexTable[ch];
2835 } else if ((hexTable[ch]) < 0 && gotone)
2842 int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot)
2843 FILE *fstream; /* handle on file */
2844 unsigned int *width, *height; /* RETURNED */
2845 unsigned char **datap; /* RETURNED */
2846 int *x_hot, *y_hot; /* RETURNED */
2848 unsigned char *data = NULL; /* working variable */
2849 char line[MAX_SIZE]; /* input line from file */
2850 int size; /* number of bytes of data */
2851 char name_and_type[MAX_SIZE]; /* an input line */
2852 char *type; /* for parsing */
2853 int value; /* from an input line */
2854 int version10p; /* boolean, old format */
2855 int padding; /* to handle alignment */
2856 int bytes_per_line; /* per scanline of data */
2857 unsigned int ww = 0; /* width */
2858 unsigned int hh = 0; /* height */
2859 int hx = -1; /* x hotspot */
2860 int hy = -1; /* y hotspot */
2862 #define Xmalloc(size) malloc(size)
2864 /* first time initialization */
2865 if (initialized == FALSE) initHexTable();
2867 /* error cleanup and return macro */
2868 #define RETURN(code) { if (data) free (data); return code; }
2870 while (fgets(line, MAX_SIZE, fstream)) {
2871 if (strlen(line) == MAX_SIZE-1) {
2872 RETURN (BitmapFileInvalid);
2874 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
2875 if (!(type = strrchr(name_and_type, '_')))
2876 type = name_and_type;
2880 if (!strcmp("width", type))
2881 ww = (unsigned int) value;
2882 if (!strcmp("height", type))
2883 hh = (unsigned int) value;
2884 if (!strcmp("hot", type)) {
2885 if (type-- == name_and_type || type-- == name_and_type)
2887 if (!strcmp("x_hot", type))
2889 if (!strcmp("y_hot", type))
2895 if (sscanf(line, "static short %s = {", name_and_type) == 1)
2897 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
2899 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
2904 if (!(type = strrchr(name_and_type, '_')))
2905 type = name_and_type;
2909 if (strcmp("bits[]", type))
2913 RETURN (BitmapFileInvalid);
2915 if ((ww % 16) && ((ww % 16) < 9) && version10p)
2920 bytes_per_line = (ww+7)/8 + padding;
2922 size = bytes_per_line * hh;
2923 data = (unsigned char *) Xmalloc ((unsigned int) size);
2925 RETURN (BitmapNoMemory);
2931 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
2932 if ((value = NextInt(fstream)) < 0)
2933 RETURN (BitmapFileInvalid);
2935 if (!padding || ((bytes+2) % bytes_per_line))
2936 *(ptr++) = value >> 8;
2942 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
2943 if ((value = NextInt(fstream)) < 0)
2944 RETURN (BitmapFileInvalid);
2952 RETURN (BitmapFileInvalid);
2959 if (x_hot) *x_hot = hx;
2960 if (y_hot) *y_hot = hy;
2962 RETURN (BitmapSuccess);
2966 int read_bitmap_data_from_file (CONST char *filename, unsigned int *width,
2967 unsigned int *height, unsigned char **datap,
2968 int *x_hot, int *y_hot)
2973 if ((fstream = fopen (filename, "r")) == NULL) {
2974 return BitmapOpenFailed;
2976 rval = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
2981 /* X specific crap */
2982 #include <gdk/gdkx.h>
2983 /* #### Should remove all this X specific stuff when GTK/GDK matures a
2984 bit more and provides an abstraction for it. */
2986 gtk_colorize_image_instance (Lisp_Object image_instance,
2987 Lisp_Object foreground, Lisp_Object background)
2989 struct Lisp_Image_Instance *p;
2991 p = XIMAGE_INSTANCE (image_instance);
2993 switch (IMAGE_INSTANCE_TYPE (p))
2995 case IMAGE_MONO_PIXMAP:
2996 IMAGE_INSTANCE_TYPE (p) = IMAGE_COLOR_PIXMAP;
2997 /* Make sure there aren't two pointers to the same mask, causing
2998 it to get freed twice. */
2999 IMAGE_INSTANCE_GTK_MASK (p) = 0;
3007 GdkWindow *draw = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (IMAGE_INSTANCE_DEVICE (p))));
3008 GdkPixmap *new_pxmp = gdk_pixmap_new (draw,
3009 IMAGE_INSTANCE_PIXMAP_WIDTH (p),
3010 IMAGE_INSTANCE_PIXMAP_HEIGHT (p),
3011 DEVICE_GTK_DEPTH (XDEVICE (IMAGE_INSTANCE_DEVICE (p))));
3015 gcv.foreground = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (foreground));
3016 gcv.background = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (background));
3017 gc = gdk_gc_new_with_values (new_pxmp, &gcv, GDK_GC_BACKGROUND | GDK_GC_FOREGROUND);
3019 XCopyPlane (GDK_WINDOW_XDISPLAY (draw),
3020 GDK_WINDOW_XWINDOW (IMAGE_INSTANCE_GTK_PIXMAP (p)),
3021 GDK_WINDOW_XWINDOW (new_pxmp),
3022 GDK_GC_XGC (gc), 0, 0,
3023 IMAGE_INSTANCE_PIXMAP_WIDTH (p),
3024 IMAGE_INSTANCE_PIXMAP_HEIGHT (p),
3027 gdk_gc_destroy (gc);
3028 IMAGE_INSTANCE_GTK_PIXMAP (p) = new_pxmp;
3029 IMAGE_INSTANCE_PIXMAP_DEPTH (p) = DEVICE_GTK_DEPTH (XDEVICE (IMAGE_INSTANCE_DEVICE (p)));
3030 IMAGE_INSTANCE_PIXMAP_FG (p) = foreground;
3031 IMAGE_INSTANCE_PIXMAP_BG (p) = background;