User: ben
Date: 05/09/27 07:48:35
Modified: xemacs/src ChangeLog glyphs.c glyphs-eimage.c glyphs-x.c
glyphs-gtk.c glyphs-msw.c console-impl.h
Log:
Implement color pixmap cursors
glyphs.c, glyphs-eimage.c, glyphs-x.c, glyphs-gtk.c, glyphs-msw.c, console-impl.h: Allow all kinds of color images (GIF, JPEG, ...) to be mouse pointers.
new -> new_, 'foo -> `foo'.
Revision Changes Path
1.863 +33 -0 XEmacs/xemacs/src/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/ChangeLog,v
retrieving revision 1.862
retrieving revision 1.863
diff -u -p -r1.862 -r1.863
--- ChangeLog 2005/09/27 05:35:24 1.862
+++ ChangeLog 2005/09/27 05:48:22 1.863
@@ -1,5 +1,38 @@
2005-09-27 Ben Wing <ben(a)xemacs.org>
+ * glyphs.c:
+ * glyphs.c (find_instantiator_differences):
+ * glyphs.c (Fvalid_image_instance_type_p):
+ * glyphs.c (Fimage_instance_type):
+ * glyphs.c (Fcolorize_image_instance):
+ * glyphs.c (Fglyph_type):
+ * glyphs.c (glyph_image_instance):
+ * glyphs.c (image_instantiator_format_create):
+ * glyphs-eimage.c:
+ * glyphs-eimage.c (jpeg_instantiate):
+ * glyphs-eimage.c (gif_instantiate):
+ * glyphs-eimage.c (png_instantiate):
+ * glyphs-eimage.c (tiff_instantiate):
+ * glyphs-x.c:
+ * glyphs-x.c (image_instance_convert_to_pointer):
+ * glyphs-x.c (init_image_instance_from_x_image):
+ * glyphs-x.c (x_init_image_instance_from_eimage):
+ * glyphs-x.c (x_xpm_instantiate):
+ * glyphs-x.c (x_colorize_image_instance):
+ * glyphs-gtk.c:
+ * glyphs-gtk.c (image_instance_convert_to_pointer):
+ * glyphs-gtk.c (init_image_instance_from_gdk_image):
+ * glyphs-gtk.c (gtk_init_image_instance_from_eimage):
+ * glyphs-gtk.c (gtk_xpm_instantiate):
+ * glyphs-msw.c:
+ * glyphs-msw.c (mswindows_init_image_instance_from_eimage):
+ * console-impl.h:
+ * console-impl.h (struct console_methods):
+ Allow all kinds of color images (GIF, JPEG, ...) to be mouse pointers.
+ new -> new_, 'foo -> `foo'.
+
+2005-09-27 Ben Wing <ben(a)xemacs.org>
+
* Makefile.in.in (cppflags):
Always include SRC, so <config.h> in lib-src always works.
1.53 +51 -32 XEmacs/xemacs/src/glyphs.c
Index: glyphs.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/glyphs.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -p -r1.52 -r1.53
--- glyphs.c 2005/04/08 23:11:26 1.52
+++ glyphs.c 2005/09/27 05:48:25 1.53
@@ -1,7 +1,7 @@
/* Generic glyph/image implementation + display tables
Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
Copyright (C) 1995 Tinker Systems
- Copyright (C) 1995, 1996, 2000, 2001, 2002, 2004 Ben Wing
+ Copyright (C) 1995, 1996, 2000, 2001, 2002, 2004, 2005 Ben Wing
Copyright (C) 1995 Sun Microsystems
Copyright (C) 1998, 1999, 2000 Andy Piper
@@ -24,9 +24,25 @@ Boston, MA 02111-1307, USA. */
/* Synched up with: Not in FSF. */
-/* Written by Ben Wing and Chuck Thompson. Heavily modified /
- rewritten by Andy Piper. */
+/* This file mostly written by Ben Wing, with some code by Chuck Thompson.
+ Heavily modified / rewritten by Andy Piper.
+ Earliest glyph support, Jamie Zawinski for 19.8?
+ subwindow support added by Chuck Thompson
+ additional XPM support added by Chuck Thompson
+ initial X-Face support added by Stig
+ Majorly rewritten/restructured by Ben Wing, including creation of
+ glyph and image-instance objects, for 19.12/19.13
+ GIF/JPEG/etc. support originally in this file -- see glyph-eimage.c
+ Pointer/icon overhaul, more restructuring by Ben Wing for 19.14
+ 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
+ Generalization for ms-windows by Andy Piper for 21.0
+ TODO:
+ Convert images.el to C and stick it in here?
+ */
+
#include <config.h>
#include "lisp.h"
@@ -232,12 +248,12 @@ Given an IMAGE-INSTANTIATOR-FORMAT, retu
If LOCALE is non-nil then the format is checked in that locale.
If LOCALE is nil the current console is used.
-Valid formats are some subset of 'nothing, 'string, 'formatted-string,
-'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font,
-'autodetect, 'subwindow, 'inherit, 'mswindows-resource, 'bmp,
-'native-layout, 'layout, 'label, 'tab-control, 'tree-view,
-'progress-gauge, 'scrollbar, 'combo-box, 'edit-field, 'button,
-'widget, 'pointer, and 'text, depending on how XEmacs was compiled.
+Valid formats are some subset of `nothing', `string', `formatted-string',
+`xpm', `xbm', `xface', `gif', `jpeg', `png', `tiff', `cursor-font', `font',
+`autodetect', `subwindow', `inherit', `mswindows-resource', `bmp',
+`native-layout', `layout', `label', `tab-control', `tree-view',
+`progress-gauge', `scrollbar', `combo-box', `edit-field', `button',
+`widget', `pointer', and `text', depending on how XEmacs was compiled.
*/
(image_instantiator_format, locale))
{
@@ -437,12 +453,12 @@ find_keyword_in_vector (Lisp_Object vect
}
static Lisp_Object
-find_instantiator_differences (Lisp_Object new, Lisp_Object old)
+find_instantiator_differences (Lisp_Object new_, Lisp_Object old)
{
Lisp_Object alist = Qnil;
- Lisp_Object *elt = XVECTOR_DATA (new);
+ Lisp_Object *elt = XVECTOR_DATA (new_);
Lisp_Object *old_elt = XVECTOR_DATA (old);
- int len = XVECTOR_LENGTH (new);
+ int len = XVECTOR_LENGTH (new_);
struct gcpro gcpro1;
/* If the vector length has changed then consider everything
@@ -450,7 +466,7 @@ find_instantiator_differences (Lisp_Obje
disappeared or been added, but this code is only used as an
optimization anyway so lets not bother. */
if (len != XVECTOR_LENGTH (old))
- return new;
+ return new_;
GCPRO1 (alist);
@@ -1450,8 +1466,9 @@ valid_image_instance_type_p (Lisp_Object
DEFUN ("valid-image-instance-type-p", Fvalid_image_instance_type_p, 1, 1, 0, /*
Given an IMAGE-INSTANCE-TYPE, return non-nil if it is valid.
-Valid types are some subset of 'nothing, 'text, 'mono-pixmap, 'color-pixmap,
-'pointer, 'subwindow, and 'widget, depending on how XEmacs was compiled.
+Valid types are some subset of `nothing', `text', `mono-pixmap',
+`color-pixmap', `pointer', `subwindow', and `widget', depending on how
+XEmacs was compiled.
*/
(image_instance_type))
{
@@ -1550,27 +1567,27 @@ DATA is an image instantiator, which des
DEST-TYPES should be a list of allowed image instance types that can
be generated. The recognized image instance types are
-'nothing
+`nothing'
Nothing is displayed.
-'text
+`text'
Displayed as text. The foreground and background colors and the
font of the text are specified independent of the pixmap. Typically
these attributes will come from the face of the surrounding text,
unless a face is specified for the glyph in which the image appears.
-'mono-pixmap
+`mono-pixmap'
Displayed as a mono pixmap (a pixmap with only two colors where the
foreground and background can be specified independent of the pixmap;
typically the pixmap assumes the foreground and background colors of
the text around it, unless a face is specified for the glyph in which
the image appears).
-'color-pixmap
+`color-pixmap'
Displayed as a color pixmap.
-'pointer
+`pointer'
Used as the mouse pointer for a window.
-'subwindow
+`subwindow'
A child window that is treated as an image. This allows (e.g.)
another program to be responsible for drawing into the window.
-'widget
+`widget'
A child window that contains a window-system widget, e.g. a push
button, text field, or slider.
@@ -1648,8 +1665,8 @@ Return non-nil if OBJECT is an image ins
DEFUN ("image-instance-type", Fimage_instance_type, 1, 1, 0, /*
Return the type of the given image instance.
-The return value will be one of 'nothing, 'text, 'mono-pixmap,
-'color-pixmap, 'pointer, 'subwindow, or 'widget.
+The return value will be one of `nothing', `text', `mono-pixmap',
+`color-pixmap', `pointer', `subwindow', or `widget'.
*/
(image_instance))
{
@@ -1964,7 +1981,7 @@ instance is a mono pixmap; otherwise, th
*/
(image_instance, foreground, background))
{
- Lisp_Object new;
+ Lisp_Object new_;
Lisp_Object device;
CHECK_IMAGE_INSTANCE (image_instance);
@@ -1978,20 +1995,20 @@ instance is a mono pixmap; otherwise, th
/* #### There should be a copy_image_instance(), which calls a
device-specific method to copy the window-system subobject. */
- new = allocate_image_instance (XIMAGE_INSTANCE_DOMAIN (image_instance),
+ new_ = allocate_image_instance (XIMAGE_INSTANCE_DOMAIN (image_instance),
Qnil, Qnil);
#ifdef MC_ALLOC
- copy_lrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance));
+ copy_lrecord (XIMAGE_INSTANCE (new_), XIMAGE_INSTANCE (image_instance));
#else /* not MC_ALLOC */
- copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance));
+ copy_lcrecord (XIMAGE_INSTANCE (new_), XIMAGE_INSTANCE (image_instance));
#endif /* not MC_ALLOC */
/* note that if this method returns non-zero, this method MUST
copy any window-system resources, so that when one image instance is
freed, the other one is not hosed. */
- if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground,
+ if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new_, foreground,
background)))
return image_instance;
- return new;
+ return new_;
}
@@ -3942,7 +3959,7 @@ information.
DEFUN ("glyph-type", Fglyph_type, 1, 1, 0, /*
Return the type of the given glyph.
-The return value will be one of 'buffer, 'pointer, or 'icon.
+The return value will be one of `buffer', `pointer', or `icon'.
*/
(glyph))
{
@@ -3962,7 +3979,7 @@ glyph_image_instance (Lisp_Object glyph,
{
Lisp_Object specifier = GLYPH_IMAGE (XGLYPH (glyph));
- /* This can never return Qunbound. All glyphs have 'nothing as
+ /* This can never return Qunbound. All glyphs have `nothing' as
a fallback. */
Lisp_Object image_instance = specifier_instance (specifier, Qunbound,
domain, errb, no_quit, 0,
@@ -5401,6 +5418,8 @@ image_instantiator_format_create (void)
IIFORMAT_VALID_KEYWORD (xface, Q_data, check_valid_string);
IIFORMAT_VALID_KEYWORD (xface, Q_file, check_valid_string);
+ IIFORMAT_VALID_KEYWORD (xface, Q_mask_data, check_valid_xbm_inline);
+ IIFORMAT_VALID_KEYWORD (xface, Q_mask_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);
1.26 +13 -22 XEmacs/xemacs/src/glyphs-eimage.c
Index: glyphs-eimage.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/glyphs-eimage.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -p -r1.25 -r1.26
--- glyphs-eimage.c 2005/02/04 03:01:21 1.25
+++ glyphs-eimage.c 2005/09/27 05:48:25 1.26
@@ -2,7 +2,7 @@
Copyright (C) 1993, 1994, 1998 Free Software Foundation, Inc.
Copyright (C) 1995 Board of Trustees, University of Illinois.
Copyright (C) 1995 Tinker Systems
- Copyright (C) 1995, 1996, 2001, 2002, 2004 Ben Wing
+ Copyright (C) 1995, 1996, 2001, 2002, 2004, 2005 Ben Wing
Copyright (C) 1995 Sun Microsystems
This file is part of XEmacs.
@@ -24,22 +24,16 @@ Boston, MA 02111-1307, USA. */
/* Synched up with: Not in FSF. */
-/* Original author: Jamie Zawinski for 19.8
- font-truename stuff added by Jamie Zawinski for 19.10
- subwindow support added by Chuck Thompson
- additional XPM support added by Chuck Thompson
- initial X-Face support added by Stig
- rewritten/restructured by Ben Wing for 19.12/19.13
+/* Originally part of glyphs.c.
+
GIF/JPEG support added by Ben Wing for 19.14
PNG support added by Bill Perry for 19.14
Improved GIF/JPEG support added by Bill Perry for 19.14
Cleanup/simplification of error handling by Ben Wing for 19.14
- Pointer/icon overhaul, more restructuring by Ben Wing for 19.14
GIF support changed to external Gifreader lib by Jareth Hein for 21.0
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
- Generalization for ms-windows by Andy Piper for 21.0
TODO:
Convert images.el to C and stick it in here?
*/
@@ -325,8 +319,7 @@ my_jpeg_output_message (j_common_ptr cin
source code and from gif_instantiate() */
static void
jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
- Lisp_Object UNUSED (pointer_fg),
- Lisp_Object UNUSED (pointer_bg),
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
int dest_mask, Lisp_Object domain)
{
Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
@@ -500,7 +493,7 @@ jpeg_instantiate (Lisp_Object image_inst
init_image_instance_from_eimage,
(ii, cinfo.output_width, cinfo.output_height, 1,
unwind.eimage, dest_mask,
- instantiator, domain));
+ instantiator, pointer_fg, pointer_bg, domain));
/* Step 7: Finish decompression */
@@ -614,8 +607,7 @@ gif_error_func (const Extbyte *err_str,
static void
gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
- Lisp_Object UNUSED (pointer_fg),
- Lisp_Object UNUSED (pointer_bg),
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
int dest_mask, Lisp_Object domain)
{
Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
@@ -729,8 +721,9 @@ gif_instantiate (Lisp_Object image_insta
/* now instantiate */
MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
init_image_instance_from_eimage,
- (ii, width, height, unwind.giffile->ImageCount, unwind.eimage, dest_mask,
- instantiator, domain));
+ (ii, width, height, unwind.giffile->ImageCount,
+ unwind.eimage, dest_mask, instantiator, pointer_fg,
+ pointer_bg, domain));
}
/* We read the gif successfully. If we have more than one slice then
@@ -864,8 +857,7 @@ png_instantiate_unwind (Lisp_Object unwi
static void
png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
- Lisp_Object UNUSED (pointer_fg),
- Lisp_Object UNUSED (pointer_bg),
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
int dest_mask, Lisp_Object domain)
{
Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
@@ -1046,7 +1038,7 @@ png_instantiate (Lisp_Object image_insta
MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
init_image_instance_from_eimage,
(ii, width, height, 1, unwind.eimage, dest_mask,
- instantiator, domain));
+ instantiator, pointer_fg, pointer_bg, domain));
/* This will clean up everything else. */
unbind_to (speccount);
@@ -1242,8 +1234,7 @@ tiff_warning_func (const char *module, c
static void
tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
- Lisp_Object UNUSED (pointer_fg),
- Lisp_Object UNUSED (pointer_bg),
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
int dest_mask, Lisp_Object domain)
{
Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
@@ -1336,7 +1327,7 @@ tiff_instantiate (Lisp_Object image_inst
MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
init_image_instance_from_eimage,
(ii, width, height, 1, unwind.eimage, dest_mask,
- instantiator, domain));
+ instantiator, pointer_fg, pointer_bg, domain));
unbind_to (speccount);
}
1.83 +196 -157 XEmacs/xemacs/src/glyphs-x.c
Index: glyphs-x.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/glyphs-x.c,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -p -r1.82 -r1.83
--- glyphs-x.c 2005/01/24 23:33:58 1.82
+++ glyphs-x.c 2005/09/27 05:48:26 1.83
@@ -2,7 +2,7 @@
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
Copyright (C) 1995 Board of Trustees, University of Illinois.
Copyright (C) 1995 Tinker Systems
- Copyright (C) 1995, 1996, 2001, 2002, 2003, 2004 Ben Wing
+ Copyright (C) 1995, 1996, 2001, 2002, 2003, 2004, 2005 Ben Wing
Copyright (C) 1995 Sun Microsystems
Copyright (C) 1999, 2000, 2002 Andy Piper
@@ -724,6 +724,159 @@ maybe_recolor_cursor (Lisp_Object image_
/* color pixmap functions */
/************************************************************************/
+/* Create a pointer from a color pixmap. */
+
+static void
+image_instance_convert_to_pointer (Lisp_Image_Instance *ii,
+ Lisp_Object instantiator,
+ Lisp_Object pointer_fg,
+ Lisp_Object pointer_bg)
+{
+ Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+ Display *dpy = DEVICE_X_DISPLAY (XDEVICE (device));
+ Screen *xs = DefaultScreenOfDisplay (dpy);
+ int npixels = IMAGE_INSTANCE_X_NPIXELS (ii);
+ unsigned long *pixels = IMAGE_INSTANCE_X_PIXELS (ii);
+ Pixmap pixmap = IMAGE_INSTANCE_X_PIXMAP (ii);
+ Pixmap mask = (Pixmap) IMAGE_INSTANCE_PIXMAP_MASK (ii);
+ Colormap cmap;
+ XColor fg, bg;
+ int i;
+ int xhot = 0, yhot = 0;
+ int w, h;
+
+ if (INTP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)))
+ xhot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii));
+ if (INTP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)))
+ yhot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii));
+ w = IMAGE_INSTANCE_PIXMAP_WIDTH (ii);
+ h = IMAGE_INSTANCE_PIXMAP_HEIGHT (ii);
+
+#if 1
+ /* Although I haven't found it documented yet, it appears that pointers are
+ always colored via the default window colormap... Sigh. */
+ cmap = DefaultColormap (dpy, DefaultScreen (dpy));
+ IMAGE_INSTANCE_X_COLORMAP (ii) = cmap;
+#else
+ cmap = IMAGE_INSTANCE_X_COLORMAP (ii);
+#endif
+
+ check_pointer_sizes (xs, w, h, instantiator);
+
+ /* If the loaded pixmap has colors allocated (meaning it came from an
+ XPM file), then use those as the default colors for the cursor we
+ create. Otherwise, default to pointer_fg and pointer_bg.
+ */
+ if (npixels >= 2)
+ {
+ /* With an XBM file, it's obvious which bit is foreground
+ and which is background, or rather, it's implicit: in
+ an XBM file, a 1 bit is foreground, and a 0 bit is
+ background.
+
+ XCreatePixmapCursor() assumes this property of the
+ pixmap it is called with as well; the `foreground'
+ color argument is used for the 1 bits.
+
+ With an XPM file, it's tricker, since the elements of
+ the pixmap don't represent FG and BG, but are actual
+ pixel values. So we need to figure out which of those
+ pixels is the foreground color and which is the
+ background. We do it by comparing RGB and assuming
+ that the darker color is the foreground. This works
+ with the result of xbmtopbm|ppmtoxpm, at least.
+
+ It might be nice if there was some way to tag the
+ colors in the XPM file with whether they are the
+ foreground - perhaps with logical color names somehow?
+
+ Once we have decided which color is the foreground, we
+ need to ensure that that color corresponds to a `1' bit
+ in the Pixmap. The XPM library wrote into the (1-bit)
+ pixmap with XPutPixel, which will ignore all but the
+ least significant bit.
+
+ This means that a 1 bit in the image corresponds to
+ `fg' only if `fg.pixel' is odd.
+
+ (This also means that the image will be all the same
+ color if both `fg' and `bg' are odd or even, but we can
+ safely assume that that won't happen if the XPM file is
+ sensible I think.)
+
+ The desired result is that the image use `1' to
+ represent the foreground color, and `0' to represent
+ the background color. So, we may need to invert the
+ image to accomplish this; we invert if fg is
+ odd. (Remember that WhitePixel and BlackPixel are not
+ necessarily 1 and 0 respectively, though I think it
+ might be safe to assume that one of them is always 1
+ and the other is always 0. We also pretty much need to
+ assume that one is even and the other is odd.)
+ */
+
+ fg.pixel = pixels[0]; /* pick a pixel at random. */
+ bg.pixel = fg.pixel;
+ for (i = 1; i < npixels; i++) /* Look for an "other" pixel value.*/
+ {
+ bg.pixel = pixels[i];
+ if (fg.pixel != bg.pixel)
+ break;
+ }
+
+ /* If (fg.pixel == bg.pixel) then probably something has
+ gone wrong, but I don't think signalling an error would
+ be appropriate. */
+
+ XQueryColor (dpy, cmap, &fg);
+ XQueryColor (dpy, cmap, &bg);
+
+ /* If the foreground is lighter than the background, swap them.
+ (This occurs semi-randomly, depending on the ordering of the
+ color list in the XPM file.)
+ */
+ {
+ unsigned short fg_total = ((fg.red / 3) + (fg.green / 3)
+ + (fg.blue / 3));
+ unsigned short bg_total = ((bg.red / 3) + (bg.green / 3)
+ + (bg.blue / 3));
+ if (fg_total > bg_total)
+ {
+ XColor swap;
+ swap = fg;
+ fg = bg;
+ bg = swap;
+ }
+ }
+
+ /* If the fg pixel corresponds to a `0' in the bitmap, invert it.
+ (This occurs (only?) on servers with Black=0, White=1.)
+ */
+ if ((fg.pixel & 1) == 0)
+ {
+ XGCValues gcv;
+ GC gc;
+ gcv.function = GXxor;
+ gcv.foreground = 1;
+ gc = XCreateGC (dpy, pixmap, (GCFunction | GCForeground),
+ &gcv);
+ XFillRectangle (dpy, pixmap, gc, 0, 0, w, h);
+ XFreeGC (dpy, gc);
+ }
+ }
+ else
+ {
+ generate_cursor_fg_bg (device, &pointer_fg, &pointer_bg,
+ &fg, &bg);
+ IMAGE_INSTANCE_PIXMAP_FG (ii) = pointer_fg;
+ IMAGE_INSTANCE_PIXMAP_BG (ii) = pointer_bg;
+ }
+
+ IMAGE_INSTANCE_X_CURSOR (ii) =
+ XCreatePixmapCursor
+ (dpy, pixmap, mask, &fg, &bg, xhot, yhot);
+}
+
/* Initialize an image instance from an XImage.
DEST_MASK specifies the mask of allowed image types.
@@ -740,9 +893,7 @@ maybe_recolor_cursor (Lisp_Object image_
If this fails, signal an error. INSTANTIATOR is only used
in the error message.
-
- #### This should be able to handle conversion into `pointer'.
- Use the same code as for `xpm'. */
+*/
static void
init_image_instance_from_x_image (Lisp_Image_Instance *ii,
@@ -752,23 +903,31 @@ init_image_instance_from_x_image (Lisp_I
unsigned long *pixels,
int npixels,
int slices,
- Lisp_Object instantiator)
+ Lisp_Object instantiator,
+ Lisp_Object pointer_fg,
+ Lisp_Object pointer_bg)
{
Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
Display *dpy;
GC gc;
Drawable d;
Pixmap pixmap;
+ enum image_instance_type type;
if (!DEVICE_X_P (XDEVICE (device)))
gui_error ("Not an X device", device);
dpy = DEVICE_X_DISPLAY (XDEVICE (device));
- d = XtWindow(DEVICE_XT_APP_SHELL (XDEVICE (device)));
+ d = XtWindow (DEVICE_XT_APP_SHELL (XDEVICE (device)));
- if (!(dest_mask & IMAGE_COLOR_PIXMAP_MASK))
+ if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
+ type = IMAGE_COLOR_PIXMAP;
+ else if (dest_mask & IMAGE_POINTER_MASK)
+ type = IMAGE_POINTER;
+ else
incompatible_image_types (instantiator, dest_mask,
- IMAGE_COLOR_PIXMAP_MASK);
+ IMAGE_COLOR_PIXMAP_MASK
+ | IMAGE_POINTER_MASK);
pixmap = XCreatePixmap (dpy, d, ximage->width,
ximage->height, ximage->depth);
@@ -802,6 +961,10 @@ init_image_instance_from_x_image (Lisp_I
IMAGE_INSTANCE_X_COLORMAP (ii) = cmap;
IMAGE_INSTANCE_X_PIXELS (ii) = pixels;
IMAGE_INSTANCE_X_NPIXELS (ii) = npixels;
+
+ if (type == IMAGE_POINTER)
+ image_instance_convert_to_pointer (ii, instantiator, pointer_fg,
+ pointer_bg);
}
static void
@@ -846,6 +1009,8 @@ x_init_image_instance_from_eimage (Lisp_
Binbyte *eimage,
int dest_mask,
Lisp_Object instantiator,
+ Lisp_Object pointer_fg,
+ Lisp_Object pointer_bg,
Lisp_Object UNUSED (domain))
{
Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
@@ -864,14 +1029,16 @@ x_init_image_instance_from_eimage (Lisp_
{
if (pixtbl)
xfree (pixtbl, unsigned long *);
- signal_image_error("EImage to XImage conversion failed", instantiator);
+ signal_image_error ("EImage to XImage conversion failed",
+ 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);
+ instantiator, pointer_fg,
+ pointer_bg);
else
image_instance_add_x_image (ii, ximage, slice, instantiator);
@@ -1236,20 +1403,20 @@ x_xpm_instantiate (Lisp_Object image_ins
always colored via the default window colormap... Sigh. */
if (type == IMAGE_POINTER)
{
- cmap = DefaultColormap(dpy, DefaultScreen(dpy));
+ cmap = DefaultColormap (dpy, DefaultScreen (dpy));
depth = DefaultDepthOfScreen (xs);
visual = DefaultVisualOfScreen (xs);
}
else
{
- cmap = DEVICE_X_COLORMAP (XDEVICE(device));
- depth = DEVICE_X_DEPTH (XDEVICE(device));
- visual = DEVICE_X_VISUAL (XDEVICE(device));
+ cmap = DEVICE_X_COLORMAP (XDEVICE (device));
+ depth = DEVICE_X_DEPTH (XDEVICE (device));
+ visual = DEVICE_X_VISUAL (XDEVICE (device));
}
#else
- cmap = DEVICE_X_COLORMAP (XDEVICE(device));
- depth = DEVICE_X_DEPTH (XDEVICE(device));
- visual = DEVICE_X_VISUAL (XDEVICE(device));
+ cmap = DEVICE_X_COLORMAP (XDEVICE (device));
+ depth = DEVICE_X_DEPTH (XDEVICE (device));
+ visual = DEVICE_X_VISUAL (XDEVICE (device));
#endif
x_initialize_pixmap_image_instance (ii, 1, type);
@@ -1382,145 +1549,17 @@ x_xpm_instantiate (Lisp_Object image_ins
break;
case IMAGE_COLOR_PIXMAP:
- {
- IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = depth;
- }
+ IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = depth;
break;
case IMAGE_POINTER:
- {
- int npixels = xpmattrs.npixels;
- Pixel *pixels = xpmattrs.pixels;
- XColor fg, bg;
- int i;
- int xhot = 0, yhot = 0;
-
- if (xpmattrs.valuemask & XpmHotspot)
- {
- xhot = xpmattrs.x_hotspot;
- IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int (xpmattrs.x_hotspot);
- }
- if (xpmattrs.valuemask & XpmHotspot)
- {
- yhot = xpmattrs.y_hotspot;
- IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int (xpmattrs.y_hotspot);
- }
- check_pointer_sizes (xs, w, h, instantiator);
-
- /* If the loaded pixmap has colors allocated (meaning it came from an
- XPM file), then use those as the default colors for the cursor we
- create. Otherwise, default to pointer_fg and pointer_bg.
- */
- if (npixels >= 2)
- {
- /* With an XBM file, it's obvious which bit is foreground
- and which is background, or rather, it's implicit: in
- an XBM file, a 1 bit is foreground, and a 0 bit is
- background.
-
- XCreatePixmapCursor() assumes this property of the
- pixmap it is called with as well; the `foreground'
- color argument is used for the 1 bits.
-
- With an XPM file, it's tricker, since the elements of
- the pixmap don't represent FG and BG, but are actual
- pixel values. So we need to figure out which of those
- pixels is the foreground color and which is the
- background. We do it by comparing RGB and assuming
- that the darker color is the foreground. This works
- with the result of xbmtopbm|ppmtoxpm, at least.
-
- It might be nice if there was some way to tag the
- colors in the XPM file with whether they are the
- foreground - perhaps with logical color names somehow?
-
- Once we have decided which color is the foreground, we
- need to ensure that that color corresponds to a `1' bit
- in the Pixmap. The XPM library wrote into the (1-bit)
- pixmap with XPutPixel, which will ignore all but the
- least significant bit.
-
- This means that a 1 bit in the image corresponds to
- `fg' only if `fg.pixel' is odd.
-
- (This also means that the image will be all the same
- color if both `fg' and `bg' are odd or even, but we can
- safely assume that that won't happen if the XPM file is
- sensible I think.)
-
- The desired result is that the image use `1' to
- represent the foreground color, and `0' to represent
- the background color. So, we may need to invert the
- image to accomplish this; we invert if fg is
- odd. (Remember that WhitePixel and BlackPixel are not
- necessarily 1 and 0 respectively, though I think it
- might be safe to assume that one of them is always 1
- and the other is always 0. We also pretty much need to
- assume that one is even and the other is odd.)
- */
-
- fg.pixel = pixels[0]; /* pick a pixel at random. */
- bg.pixel = fg.pixel;
- for (i = 1; i < npixels; i++) /* Look for an "other" pixel value.*/
- {
- bg.pixel = pixels[i];
- if (fg.pixel != bg.pixel)
- break;
- }
-
- /* If (fg.pixel == bg.pixel) then probably something has
- gone wrong, but I don't think signalling an error would
- be appropriate. */
-
- XQueryColor (dpy, cmap, &fg);
- XQueryColor (dpy, cmap, &bg);
-
- /* If the foreground is lighter than the background, swap them.
- (This occurs semi-randomly, depending on the ordering of the
- color list in the XPM file.)
- */
- {
- unsigned short fg_total = ((fg.red / 3) + (fg.green / 3)
- + (fg.blue / 3));
- unsigned short bg_total = ((bg.red / 3) + (bg.green / 3)
- + (bg.blue / 3));
- if (fg_total > bg_total)
- {
- XColor swap;
- swap = fg;
- fg = bg;
- bg = swap;
- }
- }
-
- /* If the fg pixel corresponds to a `0' in the bitmap, invert it.
- (This occurs (only?) on servers with Black=0, White=1.)
- */
- if ((fg.pixel & 1) == 0)
- {
- XGCValues gcv;
- GC gc;
- gcv.function = GXxor;
- gcv.foreground = 1;
- gc = XCreateGC (dpy, pixmap, (GCFunction | GCForeground),
- &gcv);
- XFillRectangle (dpy, pixmap, gc, 0, 0, w, h);
- XFreeGC (dpy, gc);
- }
- }
- else
- {
- generate_cursor_fg_bg (device, &pointer_fg, &pointer_bg,
- &fg, &bg);
- IMAGE_INSTANCE_PIXMAP_FG (ii) = pointer_fg;
- IMAGE_INSTANCE_PIXMAP_BG (ii) = pointer_bg;
- }
-
- IMAGE_INSTANCE_X_CURSOR (ii) =
- XCreatePixmapCursor
- (dpy, pixmap, mask, &fg, &bg, xhot, yhot);
- }
-
+ if (xpmattrs.valuemask & XpmHotspot)
+ IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int (xpmattrs.x_hotspot);
+ if (xpmattrs.valuemask & XpmHotspot)
+ IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int (xpmattrs.y_hotspot);
+
+ image_instance_convert_to_pointer (ii, instantiator, pointer_fg,
+ pointer_bg);
break;
default:
@@ -1986,7 +2025,7 @@ x_colorize_image_instance (Lisp_Object i
Display *dpy = DEVICE_X_DISPLAY (XDEVICE (IMAGE_INSTANCE_DEVICE (p)));
Drawable draw = XtWindow(DEVICE_XT_APP_SHELL (XDEVICE (IMAGE_INSTANCE_DEVICE (p))));
Dimension d = DEVICE_X_DEPTH (XDEVICE (IMAGE_INSTANCE_DEVICE (p)));
- Pixmap new = XCreatePixmap (dpy, draw,
+ Pixmap new_ = XCreatePixmap (dpy, draw,
IMAGE_INSTANCE_PIXMAP_WIDTH (p),
IMAGE_INSTANCE_PIXMAP_HEIGHT (p), d);
XColor color;
@@ -1996,13 +2035,13 @@ x_colorize_image_instance (Lisp_Object i
gcv.foreground = color.pixel;
color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (background));
gcv.background = color.pixel;
- gc = XCreateGC (dpy, new, GCBackground|GCForeground, &gcv);
- XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP (p), new, gc, 0, 0,
+ gc = XCreateGC (dpy, new_, GCBackground|GCForeground, &gcv);
+ XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP (p), new_, gc, 0, 0,
IMAGE_INSTANCE_PIXMAP_WIDTH (p),
IMAGE_INSTANCE_PIXMAP_HEIGHT (p),
0, 0, 1);
XFreeGC (dpy, gc);
- IMAGE_INSTANCE_X_PIXMAP (p) = new;
+ IMAGE_INSTANCE_X_PIXMAP (p) = new_;
IMAGE_INSTANCE_PIXMAP_DEPTH (p) = d;
IMAGE_INSTANCE_PIXMAP_FG (p) = foreground;
IMAGE_INSTANCE_PIXMAP_BG (p) = background;
1.31 +72 -37 XEmacs/xemacs/src/glyphs-gtk.c
Index: glyphs-gtk.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/glyphs-gtk.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -p -r1.30 -r1.31
--- glyphs-gtk.c 2005/01/26 10:22:26 1.30
+++ glyphs-gtk.c 2005/09/27 05:48:26 1.31
@@ -2,7 +2,7 @@
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
Copyright (C) 1995 Board of Trustees, University of Illinois.
Copyright (C) 1995 Tinker Systems
- Copyright (C) 1995, 1996, 2001, 2002, 2004 Ben Wing
+ Copyright (C) 1995, 1996, 2001, 2002, 2004, 2005 Ben Wing
Copyright (C) 1995 Sun Microsystems
This file is part of XEmacs.
@@ -677,6 +677,51 @@ maybe_recolor_cursor (Lisp_Object UNUSED
/* color pixmap functions */
/************************************************************************/
+/* Create a pointer from a color pixmap. */
+
+static void
+image_instance_convert_to_pointer (Lisp_Image_Instance *ii,
+ Lisp_Object instantiator,
+ Lisp_Object pointer_fg,
+ Lisp_Object pointer_bg)
+{
+ Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+ GdkPixmap *pixmap = IMAGE_INSTANCE_X_PIXMAP (ii);
+ GdkPixmap *mask = (GdkPixmap *) IMAGE_INSTANCE_PIXMAP_MASK (ii);
+ GdkColor fg, bg;
+ int xhot = 0, yhot = 0;
+ int w, h;
+
+ if (INTP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)))
+ xhot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii));
+ if (INTP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)))
+ yhot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii));
+ w = IMAGE_INSTANCE_PIXMAP_WIDTH (ii);
+ h = IMAGE_INSTANCE_PIXMAP_HEIGHT (ii);
+
+ check_pointer_sizes (w, h, instantiator);
+
+ /* If the loaded pixmap has colors allocated (meaning it came from an
+ XPM file), then use those as the default colors for the cursor we
+ create. Otherwise, default to pointer_fg and pointer_bg.
+ */
+ if (DEVICE_GTK_DEPTH (XDEVICE (device)) > 1)
+ {
+ warn_when_safe (Qunimplemented, Qnotice,
+ "GTK does not support XPM cursors...\n");
+ IMAGE_INSTANCE_GTK_CURSOR (ii) = gdk_cursor_new (GDK_COFFEE_MUG);
+ }
+ else
+ {
+ generate_cursor_fg_bg (device, &pointer_fg, &pointer_bg,
+ &fg, &bg);
+ IMAGE_INSTANCE_PIXMAP_FG (ii) = pointer_fg;
+ IMAGE_INSTANCE_PIXMAP_BG (ii) = pointer_bg;
+ IMAGE_INSTANCE_GTK_CURSOR (ii) =
+ gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, xhot, yhot);
+ }
+}
+
/* Initialize an image instance from an XImage.
DEST_MASK specifies the mask of allowed image types.
@@ -705,21 +750,29 @@ init_image_instance_from_gdk_image (stru
unsigned long *pixels,
int npixels,
int slices,
- Lisp_Object instantiator)
+ Lisp_Object instantiator,
+ Lisp_Object pointer_fg,
+ Lisp_Object pointer_bg)
{
Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
GdkGC *gc;
GdkWindow *d;
GdkPixmap *pixmap;
+ enum image_instance_type type;
if (!DEVICE_GTK_P (XDEVICE (device)))
gui_error ("Not a Gtk device", device);
d = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (device)));
- if (!(dest_mask & IMAGE_COLOR_PIXMAP_MASK))
+ if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
+ type = IMAGE_COLOR_PIXMAP;
+ else if (dest_mask & IMAGE_POINTER_MASK)
+ type = IMAGE_POINTER;
+ else
incompatible_image_types (instantiator, dest_mask,
- IMAGE_COLOR_PIXMAP_MASK);
+ IMAGE_COLOR_PIXMAP_MASK
+ | IMAGE_POINTER_MASK);
pixmap = gdk_pixmap_new (d, gdk_image->width, gdk_image->height, gdk_image->depth);
if (!pixmap)
@@ -750,6 +803,10 @@ init_image_instance_from_gdk_image (stru
IMAGE_INSTANCE_GTK_COLORMAP (ii) = cmap;
IMAGE_INSTANCE_GTK_PIXELS (ii) = pixels;
IMAGE_INSTANCE_GTK_NPIXELS (ii) = npixels;
+
+ if (type == IMAGE_POINTER)
+ image_instance_convert_to_pointer (ii, instantiator, pointer_fg,
+ pointer_bg);
}
#if 0
@@ -831,6 +888,8 @@ gtk_init_image_instance_from_eimage (str
unsigned char *eimage,
int dest_mask,
Lisp_Object instantiator,
+ Lisp_Object pointer_fg,
+ Lisp_Object pointer_bg,
Lisp_Object UNUSED (domain))
{
Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
@@ -856,7 +915,8 @@ gtk_init_image_instance_from_eimage (str
/* Now create the pixmap and set up the image instance */
init_image_instance_from_gdk_image (ii, gdk_image, dest_mask,
cmap, pixtbl, npixels, slices,
- instantiator);
+ instantiator, pointer_fg,
+ pointer_bg);
else
image_instance_add_gdk_image (ii, gdk_image, slice, instantiator);
@@ -1269,38 +1329,13 @@ gtk_xpm_instantiate (Lisp_Object image_i
break;
case IMAGE_POINTER:
- {
- GdkColor fg, bg;
- unsigned int xhot, yhot;
-
- /* #### Gtk does not give us access to the hotspots of a pixmap */
- xhot = yhot = 1;
- IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int (xhot);
- IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int (yhot);
-
- check_pointer_sizes (w, h, instantiator);
-
- /* If the loaded pixmap has colors allocated (meaning it came from an
- XPM file), then use those as the default colors for the cursor we
- create. Otherwise, default to pointer_fg and pointer_bg.
- */
- if (depth > 1)
- {
- warn_when_safe (Qunimplemented, Qnotice,
- "GTK does not support XPM cursors...\n");
- IMAGE_INSTANCE_GTK_CURSOR (ii) = gdk_cursor_new (GDK_COFFEE_MUG);
- }
- else
- {
- generate_cursor_fg_bg (device, &pointer_fg, &pointer_bg,
- &fg, &bg);
- IMAGE_INSTANCE_PIXMAP_FG (ii) = pointer_fg;
- IMAGE_INSTANCE_PIXMAP_BG (ii) = pointer_bg;
- IMAGE_INSTANCE_GTK_CURSOR (ii) =
- gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, xhot, yhot);
- }
- }
-
+ if (xpmattrs.valuemask & XpmHotspot)
+ IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int (xpmattrs.x_hotspot);
+ if (xpmattrs.valuemask & XpmHotspot)
+ IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int (xpmattrs.y_hotspot);
+
+ image_instance_convert_to_pointer (ii, instantiator, pointer_fg,
+ pointer_bg);
break;
default:
1.56 +3 -1 XEmacs/xemacs/src/glyphs-msw.c
Index: glyphs-msw.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/glyphs-msw.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -p -r1.55 -r1.56
--- glyphs-msw.c 2005/01/24 23:33:57 1.55
+++ glyphs-msw.c 2005/09/27 05:48:26 1.56
@@ -1,6 +1,6 @@
/* mswindows-specific glyph objects.
Copyright (C) 1998, 1999, 2000 Andy Piper.
- Copyright (C) 2001, 2002, 2003, 2004 Ben Wing.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005 Ben Wing.
This file is part of XEmacs.
@@ -436,6 +436,8 @@ mswindows_init_image_instance_from_eimag
Binbyte *eimage,
int dest_mask,
Lisp_Object instantiator,
+ Lisp_Object UNUSED (pointer_fg),
+ Lisp_Object UNUSED (pointer_bg),
Lisp_Object domain)
{
Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1.11 +3 -1 XEmacs/xemacs/src/console-impl.h
Index: console-impl.h
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/console-impl.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -p -r1.10 -r1.11
--- console-impl.h 2005/06/26 18:05:03 1.10
+++ console-impl.h 2005/09/27 05:48:27 1.11
@@ -1,5 +1,5 @@
/* Define console object for XEmacs.
- Copyright (C) 1996, 2002, 2003 Ben Wing
+ Copyright (C) 1996, 2002, 2003, 2005 Ben Wing
This file is part of XEmacs.
@@ -252,6 +252,8 @@ struct console_methods
unsigned char *eimage,
int dest_mask,
Lisp_Object instantiator,
+ Lisp_Object pointer_fg,
+ Lisp_Object pointer_bg,
Lisp_Object domain);
Lisp_Object (*locate_pixmap_file_method) (Lisp_Object file_method);
int (*colorize_image_instance_method) (Lisp_Object image_instance,