diff src/glyphs.c @ 276:6330739388db r21-0b36

Import from CVS: tag r21-0b36
author cvs
date Mon, 13 Aug 2007 10:30:37 +0200
parents c5d627a313b1
children 90d73dddcdc4
line wrap: on
line diff
--- a/src/glyphs.c	Mon Aug 13 10:29:43 2007 +0200
+++ b/src/glyphs.c	Mon Aug 13 10:30:37 2007 +0200
@@ -33,11 +33,16 @@
 #include "elhash.h"
 #include "faces.h"
 #include "frame.h"
+#include "insdel.h"
 #include "glyphs.h"
 #include "objects.h"
 #include "redisplay.h"
 #include "window.h"
 
+#ifdef HAVE_XPM
+#include <X11/xpm.h>
+#endif
+
 Lisp_Object Qimage_conversion_error;
 
 Lisp_Object Qglyphp, Qcontrib_p, Qbaseline;
@@ -67,6 +72,22 @@
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string);
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
 
+#ifdef HAVE_XPM
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (xpm);
+Lisp_Object Qxpm;
+Lisp_Object Q_color_symbols;
+void x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+						Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+						int dest_mask, Lisp_Object domain);
+void mswindows_xpm_instantiate (Lisp_Object image_instance, 
+				Lisp_Object instantiator,
+				Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+				int dest_mask, Lisp_Object domain);
+Lisp_Object x_xpm_normalize (Lisp_Object inst, Lisp_Object console_type);
+Lisp_Object mswindows_xpm_normalize (Lisp_Object inst,
+									 Lisp_Object console_type);
+#endif
+
 typedef struct image_instantiator_format_entry image_instantiator_format_entry;
 struct image_instantiator_format_entry
 {
@@ -586,8 +607,7 @@
 	  write_c_string (" @", printcharfun);
 	  if (!NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)))
 	    {
-	      sprintf (buf, "%ld",
-		       (long) XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)));
+	      long_to_string (buf, XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)));
 	      write_c_string (buf, printcharfun);
 	    }
 	  else
@@ -595,8 +615,7 @@
 	  write_c_string (",", printcharfun);
 	  if (!NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)))
 	    {
-	      sprintf (buf, "%ld",
-		       (long) XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)));
+	      long_to_string (buf, XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)));
 	      write_c_string (buf, printcharfun);
 	    }
 	  else
@@ -1277,6 +1296,23 @@
 }
 
 
+/************************************************************************/
+/*                              error helpers                           */
+/************************************************************************/
+DOESNT_RETURN
+signal_image_error (CONST char *reason, Lisp_Object frob)
+{
+  signal_error (Qimage_conversion_error,
+		list2 (build_translated_string (reason), frob));
+}
+
+DOESNT_RETURN
+signal_image_error_2 (CONST char *reason, Lisp_Object frob0, Lisp_Object frob1)
+{
+  signal_error (Qimage_conversion_error,
+		list3 (build_translated_string (reason), frob0, frob1));
+}
+
 /****************************************************************************
  *                                  nothing                                 *
  ****************************************************************************/
@@ -1414,6 +1450,126 @@
 }
 
 
+#ifdef HAVE_XPM
+
+/**********************************************************************
+ *                             XPM                                    *
+ **********************************************************************/
+
+static void
+check_valid_xpm_color_symbols (Lisp_Object data)
+{
+  Lisp_Object rest;
+
+  for (rest = data; !NILP (rest); rest = XCDR (rest))
+    {
+      if (!CONSP (rest) ||
+	  !CONSP (XCAR (rest)) ||
+	  !STRINGP (XCAR (XCAR (rest))) ||
+	  (!STRINGP (XCDR (XCAR (rest))) &&
+	   !COLOR_SPECIFIERP (XCDR (XCAR (rest)))))
+	signal_simple_error ("Invalid color symbol alist", data);
+    }
+}
+
+static void
+xpm_validate (Lisp_Object instantiator)
+{
+  file_or_data_must_be_present (instantiator);
+}
+
+Lisp_Object Vxpm_color_symbols;
+
+Lisp_Object
+evaluate_xpm_color_symbols (void)
+{
+  Lisp_Object rest, results = Qnil;
+  struct gcpro gcpro1, gcpro2;
+
+  GCPRO2 (rest, results);
+  for (rest = Vxpm_color_symbols; !NILP (rest); rest = XCDR (rest))
+    {
+      Lisp_Object name, value, cons;
+
+      CHECK_CONS (rest);
+      cons = XCAR (rest);
+      CHECK_CONS (cons);
+      name = XCAR (cons);
+      CHECK_STRING (name);
+      value = XCDR (cons);
+      CHECK_CONS (value);
+      value = XCAR (value);
+      value = Feval (value);
+      if (NILP (value))
+	continue;
+      if (!STRINGP (value) && !COLOR_SPECIFIERP (value))
+	signal_simple_error
+	  ("Result from xpm-color-symbols eval must be nil, string, or color",
+	   value);
+      results = Fcons (Fcons (name, value), results);
+    }
+  UNGCPRO;			/* no more evaluation */
+  return results;
+}
+
+static Lisp_Object
+xpm_normalize (Lisp_Object inst, Lisp_Object console_type)
+{
+#ifdef HAVE_X_WINDOWS
+  if (CONSOLE_TYPESYM_X_P (console_type))
+	return x_xpm_normalize (inst, console_type);
+  else
+#endif
+#ifdef HAVE_MS_WINDOWS
+  if (CONSOLE_TYPESYM_MSWINDOWS_P (console_type))
+	return mswindows_xpm_normalize (inst, console_type);
+  else
+#endif
+	signal_image_error ("Can't display XPM images on this console",
+						console_type);
+}
+
+static int
+xpm_possible_dest_types (void)
+{
+  return
+    IMAGE_MONO_PIXMAP_MASK  |
+    IMAGE_COLOR_PIXMAP_MASK |
+    IMAGE_POINTER_MASK;
+}
+
+static void
+xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+		 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+		 int dest_mask, Lisp_Object domain)
+{
+  Lisp_Object device= IMAGE_INSTANCE_DEVICE (XIMAGE_INSTANCE (image_instance));
+#ifdef HAVE_X_WINDOWS
+  if (DEVICE_X_P (XDEVICE (device)))
+	{
+	  x_xpm_instantiate (image_instance, instantiator, 
+						 pointer_fg, pointer_bg, 
+						 dest_mask, domain);
+	  return;
+	}
+  else
+#endif
+#ifdef HAVE_MS_WINDOWS
+  if (DEVICE_MSWINDOWS_P (XDEVICE (device)))
+	{
+      mswindows_xpm_instantiate (image_instance, instantiator, 
+								 pointer_fg, pointer_bg, 
+								 dest_mask, domain);
+	  return;
+	}
+  else
+#endif
+	signal_image_error ("Can't display XPM images on this device", device);
+}
+
+#endif /* HAVE_XPM */
+
+
 /****************************************************************************
  *                         Image Specifier Object                           *
  ****************************************************************************/
@@ -2653,6 +2809,10 @@
   defkeyword (&Q_data, ":data");
   defkeyword (&Q_face, ":face");
 
+#ifdef HAVE_XPM
+  defkeyword (&Q_color_symbols, ":color-symbols");
+#endif
+
   /* image specifiers */
 
   DEFSUBR (Fimage_specifier_p);
@@ -2783,6 +2943,19 @@
   IIFORMAT_HAS_METHOD (formatted_string, instantiate);
 
   IIFORMAT_VALID_KEYWORD (formatted_string, Q_data, check_valid_string);
+
+#ifdef HAVE_XPM
+  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xpm, "xpm");
+
+  IIFORMAT_HAS_METHOD (xpm, validate);
+  IIFORMAT_HAS_METHOD (xpm, normalize);
+  IIFORMAT_HAS_METHOD (xpm, possible_dest_types);
+  IIFORMAT_HAS_METHOD (xpm, instantiate);
+
+  IIFORMAT_VALID_KEYWORD (xpm, Q_data, check_valid_string);
+  IIFORMAT_VALID_KEYWORD (xpm, Q_file, check_valid_string);
+  IIFORMAT_VALID_KEYWORD (xpm, Q_color_symbols, check_valid_xpm_color_symbols);
+#endif
 }
 
 void
@@ -2830,6 +3003,23 @@
 What to display at the beginning of horizontally scrolled lines.
 */);
   Vhscroll_glyph = allocate_glyph (GLYPH_BUFFER, redisplay_glyph_changed);
+
+#ifdef HAVE_XPM
+  Fprovide (Qxpm);
+
+  DEFVAR_LISP ("xpm-color-symbols", &Vxpm_color_symbols /*
+Definitions of logical color-names used when reading XPM files.
+Elements of this list should be of the form (COLOR-NAME FORM-TO-EVALUATE).
+The COLOR-NAME should be a string, which is the name of the color to define;
+the FORM should evaluate to a `color' specifier object, or a string to be
+passed to `make-color-instance'.  If a loaded XPM file references a symbolic
+color called COLOR-NAME, it will display as the computed color instead.
+
+The default value of this variable defines the logical color names
+\"foreground\" and \"background\" to be the colors of the `default' face.
+*/ );
+  Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */
+#endif
 }
 
 void