diff src/xfaces.c @ 26729:f5dded41adcc

Changes for automatic remapping of X colors on terminal frames: * xfaces.c (XColor) [!HAVE_X_WINDOWS]: Provide a typedef for non-X frames. (Vface_tty_color_alist): Remove. (tty_defined_color): New function. (defined_color): Rewrite to support any type of frame. (tty_color_name): New function. (face_color_supported_p, Fface_color_gray_p, Fface_color_supported_p): Support non-X frames. (load_color): Enclose the color name in quotes, in the log messages. Remove DOS-specific version of load_color. (realize_tty_face): Take the supported colors from tty-color-alist. Support translation of X colors to the closest tty color, for both MSDOS and tty frames. [MSDOS]: Don't invert face colors if they were taken from the frame colors. (Fface_register_tty_color, Fface_clear_tty_colors): Remove. * frame.h (struct x_output) [!MSDOS, !WINDOWSNT, !HAVE_X_WINDOWS]: Define a mostly empty surrogate. (tty_display): Declare. * frame.c (make_terminal_frame) [!macintosh]: Don't use tty_display. (Fframe_parameters): Don't invert colors of non-FRAME_WINDOW_P frames when the frame's param_alist includes 'reverse. (tty_display): Define. (make_terminal_frame) [!MSDOS]: Assign &tty_display to the output_data.x member. (Fframe_parameters): Return foreground and background color names on tty frames as well, in addition to MSDOS frames. * msdos.h (DisplayWidth, DisplayHeight): Changes for Lisp_Object selected_frame. (struct x_output): Remove unused members; document who uses each member. (FRAME_PARAM_FACES, FRAME_N_PARAM_FACES, FRAME_DEFAULT_PARAM_FACE, FRAME_MODE_LINE_PARAM_FACE, FRAME_COMPUTED_FACES, FRAME_N_COMPUTED_FACES, FRAME_SIZE_COMPUTED_FACES, FRAME_DEFAULT_FACE, FRAME_MODE_LINE_FACE, unload_color): Remove unused macro definintions. * msdos.c (IT_set_frame_parameters): Don't call recompute_basic_faces, the next redisplay will, anyway. (x_current_display): Remove unused variable. Many functions: changes for Lisp_object selected_frame. (IT_set_face): If the tty_reverse_p flag is set for the face, reverse the foreground and background colors. (Fmsdos_remember_default_colors): New function. (syms_of_msdos): Defsubr it. (IT_set_frame_parameters): Use initial_screen_colors[] when creating a new frame. If the frame parameters include 'reverse, swap the foreground and background colors. (internal_terminal_init): Initialize initial_screen_colors to -1. (syms_of_msdos): Add DEFVAR_BOOL for x-stretch-cursor, to shut up cus-start.el. * Makefile.in (lisp, shortlisp): Add lisp/term/tty-colors.elc. * xfns.c (x_defined_color): Rename from defined_color. All callers changed. (Fxw_color_defined_p): Renamed from Fx_color_defined_p; all callers changed. (Fxw_color_values): Renamed from Fx_color_values; all callers changed. (Fxw_display_color_p): Renamed from Fx_display_color_p; all callers changed. (x_window_to_frame, x_any_window_to_frame, x_non_menubar_window_to_frame, x_menubar_window_to_frame, x_top_window_to_frame): Use !FRAME_X_P instead of f->output_data.nothing. * xterm.h (x_defined_color): Rename from defined_color. * w32fns.c (x_window_to_frame): Use FRAME_W32_P instead of f->output_data.nothing. (Fxw_color_defined_p): Renamed from Fx_color_defined_p; all callers changed. (Fxw_color_values): Renamed from Fx_color_values; all callers changed. (Fxw_display_color_p): Renamed from Fx_display_color_p; all callers changed. * dispextern.h (tty_color_name): Add prototype. * xmenu.c (menubar_id_to_frame): Use FRAME_WINDOW_P instead of f->output_data.nothing. * w32menu.c (menubar_id_to_frame): Likewise. * w32term.h (w32_output): Declare. * dosfns.c (Qmsdos_color_translate): Remove. (msdos_stdcolor_name): Now returns a Lisp_Object. * dosfns.h (Qmsdos_color_translate): Remove. * s/msdos.h (INTERNAL_TERMINAL): Add entries for color support.
author Eli Zaretskii <eliz@gnu.org>
date Mon, 06 Dec 1999 16:54:09 +0000
parents e23e3120d84f
children 1ecff1922462
line wrap: on
line diff
--- a/src/xfaces.c	Mon Dec 06 16:46:41 1999 +0000
+++ b/src/xfaces.c	Mon Dec 06 16:54:09 1999 +0000
@@ -255,6 +255,16 @@
 
 #define FACE_CACHE_BUCKETS_SIZE 1001
 
+/* A definition of XColor for non-X frames.  */
+#ifndef HAVE_X_WINDOWS
+typedef struct {
+  unsigned long pixel;
+  unsigned short red, green, blue;
+  char flags;
+  char pad;
+} XColor;
+#endif
+
 /* Keyword symbols used for face attribute names.  */
 
 Lisp_Object QCfamily, QCheight, QCweight, QCslant, QCunderline;
@@ -368,10 +378,8 @@
 static Lisp_Object *lface_id_to_name;
 static int lface_id_to_name_size;
 
-/* An alist of elements (COLOR-NAME . INDEX) mapping color names
-   to color indices for tty frames.  */
-
-Lisp_Object Vface_tty_color_alist;
+/* tty color-related functions (defined on lisp/term/tty-colors.el).  */
+Lisp_Object Qtty_color_desc, Qtty_color_by_index;
 
 /* Counter for calls to clear_face_cache.  If this counter reaches
    CLEAR_FONT_TABLE_COUNT, and a frame has more than
@@ -1067,7 +1075,113 @@
 				X Colors
  ***********************************************************************/
 
+/* A version of defined_color for non-X frames.  */
+int
+tty_defined_color (f, color_name, color_def, alloc)
+     struct frame *f;
+     char *color_name;
+     XColor *color_def;
+     int alloc;
+{
+  Lisp_Object color_desc;
+  int color_idx = FACE_TTY_DEFAULT_COLOR, red = 0, green = 0, blue = 0;
+  int status = 1;
+
+  if (*color_name && !NILP (Ffboundp (Qtty_color_desc)))
+    {
+      status = 0;
+      color_desc = call1 (Qtty_color_desc, build_string (color_name));
+      if (!NILP (color_desc) && CONSP (color_desc))
+	{
+	  color_idx = XINT (XCAR (XCDR (color_desc)));
+	  if (CONSP (XCDR (XCDR (color_desc))))
+	    {
+	      red = XINT (XCAR (XCDR (XCDR (color_desc))));
+	      green = XINT (XCAR (XCDR (XCDR (XCDR (color_desc)))));
+	      blue = XINT (XCAR (XCDR (XCDR (XCDR (XCDR (color_desc))))));
+	    }
+	  status = 1;
+	}
+      else if (NILP (Fsymbol_value (intern ("tty-color-alist"))))
+	/* We were called early during startup, and the colors are not
+	   yet set up in tty-color-alist.  Don't return a failure
+	   indication, since this produces the annoying "Unable to
+	   load color" messages in the *Messages* buffer.  */
+	status = 1;
+    }
+  color_def->pixel = (unsigned long) color_idx;
+  color_def->red = red;
+  color_def->green = green;
+  color_def->blue = blue;
+
+  return status;
+}
+
+/* Decide if color named COLOR is valid for the display associated
+   with the frame F; if so, return the rgb values in COLOR_DEF.  If
+   ALLOC is nonzero, allocate a new colormap cell.
+
+   This does the right thing for any type of frame.  */
+int
+defined_color (f, color_name, color_def, alloc)
+     struct frame *f;
+     char *color_name;
+     XColor *color_def;
+     int alloc;
+{
+  if (!FRAME_WINDOW_P (f))
+    return tty_defined_color (f, color_name, color_def, alloc);
 #ifdef HAVE_X_WINDOWS
+  else if (FRAME_X_P (f))
+    return x_defined_color (f, color_name, color_def, alloc);
+#endif
+#ifdef WINDOWSNT
+  else if (FRAME_W32_P (f))
+    /* FIXME: w32_defined_color doesn't exist!  w32fns.c defines
+       defined_color which needs to be renamed, and the declaration
+       of color_def therein should be changed.  */
+    return w32_defined_color (f, color_name, color_def, alloc);
+#endif
+#ifdef macintosh
+  else if (FRAME_MAC_P (f))
+    /* FIXME: mac_defined_color doesn't exist!  */
+    return mac_defined_color (f, color_name, color_def, alloc);
+#endif
+  else
+    abort ();
+}
+
+/* Given the index of the tty color, return its name, a Lisp string.  */
+
+Lisp_Object
+tty_color_name (f, idx)
+     struct frame *f;
+     int idx;
+{
+  char *color;
+
+  if (idx >= 0 && !NILP (Ffboundp (Qtty_color_by_index)))
+    {
+      Lisp_Object coldesc = call1 (Qtty_color_by_index, make_number (idx));
+
+      if (!NILP (coldesc))
+	return XCAR (coldesc);
+    }
+#ifdef MSDOS
+  /* We can have an MSDOG frame under -nw for a short window of
+     opportunity before internal_terminal_init is called.  DTRT.  */
+  if (FRAME_MSDOS_P (f) && !inhibit_window_system)
+    return msdos_stdcolor_name (idx);
+#endif
+
+#ifdef WINDOWSNT
+  /* FIXME: When/if w32 supports colors in non-window mode, there should
+     be a call here to a w32-specific function that returns the color
+     by index using the default color mapping on a Windows console.  */
+#endif
+
+  return Qunspecified;
+}
 
 /* Return non-zero if COLOR_NAME is a shade of gray (or white or
    black) on frame F.  The algorithm is taken from 20.2 faces.el.  */
@@ -1105,17 +1219,19 @@
      int background_p;
 {
   Lisp_Object frame;
+  XColor not_used;
 
   XSETFRAME (frame, f);
-  return (!NILP (Vwindow_system)
-	  && (!NILP (Fx_display_color_p (frame))
+  return ((FRAME_WINDOW_P (f)
+	  && (!NILP (Fxw_display_color_p (frame))
 	      || xstricmp (color_name, "black") == 0
 	      || xstricmp (color_name, "white") == 0
 	      || (background_p
 		  && face_color_gray_p (f, color_name))
 	      || (!NILP (Fx_display_grayscale_p (frame))
-		  && face_color_gray_p (f, color_name))));
-}  
+		  && face_color_gray_p (f, color_name))))
+	  || tty_defined_color (f, color_name, &not_used, 0));
+}
 
 
 DEFUN ("face-color-gray-p", Fface_color_gray_p, Sface_color_gray_p, 1, 2, 0,
@@ -1125,8 +1241,11 @@
    (color, frame)
      Lisp_Object color, frame;
 {
-  struct frame *f = check_x_frame (frame);
+  struct frame *f;
+
+  CHECK_FRAME (frame, 0);
   CHECK_STRING (color, 0);
+  f = XFRAME (frame);
   return face_color_gray_p (f, XSTRING (color)->data) ? Qt : Qnil;
 }
 
@@ -1140,8 +1259,11 @@
    (frame, color, background_p)
      Lisp_Object frame, color, background_p;
 {
-  struct frame *f = check_x_frame (frame);
+  struct frame *f;
+
+  CHECK_FRAME (frame, 0);
   CHECK_STRING (color, 0);
+  f = XFRAME (frame);
   if (face_color_supported_p (f, XSTRING (color)->data, !NILP (background_p)))
     return Qt;
   return Qnil;
@@ -1177,7 +1299,7 @@
      to the values in an existing cell. */
   if (!defined_color (f, XSTRING (name)->data, &color, 1))
     {
-      add_to_log ("Unable to load color %s", name, Qnil);
+      add_to_log ("Unable to load color \"%s\"", name, Qnil);
       
       switch (target_index)
 	{
@@ -1223,6 +1345,7 @@
   return color.pixel;
 }
 
+#ifdef HAVE_X_WINDOWS
 
 /* Load colors for face FACE which is used on frame F.  Colors are
    specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
@@ -1371,75 +1494,7 @@
       UNBLOCK_INPUT;
     }
 }
-
-#else  /* ! HAVE_X_WINDOWS */
-
-#ifdef MSDOS
-unsigned long
-load_color (f, face, name, target_index)
-     struct frame *f;
-     struct face *face;
-     Lisp_Object name;
-     enum lface_attribute_index target_index;
-{
-  Lisp_Object color;
-  int color_idx = FACE_TTY_DEFAULT_COLOR;
-
-  if (NILP (name))
-    return (unsigned long)FACE_TTY_DEFAULT_COLOR;
-
-  CHECK_STRING (name, 0);
-
-  color = Qnil;
-  if (XSTRING (name)->size && !NILP (Ffboundp (Qmsdos_color_translate)))
-    {
-      color = call1 (Qmsdos_color_translate, name);
-
-      if (INTEGERP (color))
-	return (unsigned long)XINT (color);
-
-      add_to_log ("Unable to load color %s", name, Qnil);
-      
-      switch (target_index)
-	{
-	case LFACE_FOREGROUND_INDEX:
-	  face->foreground_defaulted_p = 1;
-	  color_idx = FRAME_FOREGROUND_PIXEL (f);
-	  break;
-	  
-	case LFACE_BACKGROUND_INDEX:
-	  face->background_defaulted_p = 1;
-	  color_idx = FRAME_BACKGROUND_PIXEL (f);
-	  break;
-	  
-	case LFACE_UNDERLINE_INDEX:
-	  face->underline_defaulted_p = 1;
-	  color_idx = FRAME_FOREGROUND_PIXEL (f);
-	  break;
-	  
-	case LFACE_OVERLINE_INDEX:
-	  face->overline_color_defaulted_p = 1;
-	  color_idx = FRAME_FOREGROUND_PIXEL (f);
-	  break;
-	  
-	case LFACE_STRIKE_THROUGH_INDEX:
-	  face->strike_through_color_defaulted_p = 1;
-	  color_idx = FRAME_FOREGROUND_PIXEL (f);
-	  break;
-	  
-	case LFACE_BOX_INDEX:
-	  face->box_color_defaulted_p = 1;
-	  color_idx = FRAME_FOREGROUND_PIXEL (f);
-	  break;
-	}
-    }
-  else
-    color_idx = msdos_stdcolor_idx (XSTRING (name)->data);
-
-  return (unsigned long)color_idx;
-}
-#endif /* MSDOS */
-#endif /* ! HAVE_X_WINDOWS */
+#endif /* HAVE_X_WINDOWS */
 
 
 
@@ -2714,7 +2769,7 @@
    for split_font_name, see the comment there.  */
    
 static int
-set_lface_from_font_name (f, lface, font_name, force_p, may_fail_p)
+set_lface_from_font_name (f, lface, font_name, force_p)
      struct frame *f;
      Lisp_Object lface;
      char *font_name;
@@ -2752,10 +2807,8 @@
 	      split_font_name (f, &font, 1);
 	      have_font_p = 1;
 	    }
-	  
 	  UNBLOCK_INPUT;
 	}
-    }
 
   /* If FONT_NAME is completely bogus try to use something reasonable
      if this function must succeed.  Otherwise, give up.  */
@@ -5628,12 +5681,7 @@
 	LFACE_FOREGROUND (lface) = XCDR (color);
       else if (FRAME_X_P (f))
 	return 0;
-      else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
-	/* Frame parameters for terminal frames usually don't contain
-	   a color.  Use an empty string to indicate that the face
-	   should use the (unknown) default color of the terminal.  */
-	LFACE_FOREGROUND (lface) = build_string ("");
-      else
+      else if (!FRAME_TERMCAP_P (f) && !FRAME_MSDOS_P (f))
 	abort ();
     }
   
@@ -5646,12 +5694,7 @@
 	LFACE_BACKGROUND (lface) = XCDR (color);
       else if (FRAME_X_P (f))
 	return 0;
-      else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
-	/* Frame parameters for terminal frames usually don't contain
-	   a color.  Use an empty string to indicate that the face
-	   should use the (unknown) default color of the terminal.  */
-	LFACE_BACKGROUND (lface) = build_string ("");
-      else
+      else if (!FRAME_TERMCAP_P (f) && !FRAME_MSDOS_P (f))
 	abort ();
     }
   
@@ -6006,6 +6049,8 @@
   struct face *face;
   int weight, slant;
   Lisp_Object color;
+  Lisp_Object tty_color_alist = Fsymbol_value (intern ("tty-color-alist"));
+  int face_colors_defaulted = 0;
 
   /* Frame must be a termcap frame.  */
   xassert (FRAME_TERMCAP_P (c->f) || FRAME_MSDOS_P (c->f));
@@ -6033,109 +6078,78 @@
   face->foreground = face->background = FACE_TTY_DEFAULT_COLOR;
 
   color = attrs[LFACE_FOREGROUND_INDEX];
-  if (XSTRING (color)->size
-      && (color = Fassoc (color, Vface_tty_color_alist),
+  if (STRINGP (color)
+      && XSTRING (color)->size
+      && !NILP (tty_color_alist)
+      && (color = Fassoc (color, tty_color_alist),
 	  CONSP (color)))
-    face->foreground = XINT (XCDR (color));
-
-#ifdef MSDOS
-  if (FRAME_MSDOS_P (c->f) && face->foreground == FACE_TTY_DEFAULT_COLOR)
+    /* Associations in tty-color-alist are of the form
+       (NAME INDEX R G B).  We need the INDEX part.  */
+    face->foreground = XINT (XCAR (XCDR (color)));
+
+  if (face->foreground == FACE_TTY_DEFAULT_COLOR
+      && STRINGP (attrs[LFACE_FOREGROUND_INDEX]))
     {
       face->foreground = load_color (c->f, face,
 				     attrs[LFACE_FOREGROUND_INDEX],
 				     LFACE_FOREGROUND_INDEX);
+#ifdef MSDOS
       /* If the foreground of the default face is the default color,
 	 use the foreground color defined by the frame.  */
-      if (face->foreground == FACE_TTY_DEFAULT_COLOR)
+      if (FRAME_MSDOS_P (c->f) && face->foreground == FACE_TTY_DEFAULT_COLOR)
 	{
 	  face->foreground = FRAME_FOREGROUND_PIXEL (f);
 	  attrs[LFACE_FOREGROUND_INDEX] =
-	    build_string (msdos_stdcolor_name (face->foreground));
+	    msdos_stdcolor_name (face->foreground);
+	  face_colors_defaulted = 1;
 	}
-    }
 #endif
+    }
 
   color = attrs[LFACE_BACKGROUND_INDEX];
-  if (XSTRING (color)->size
-      && (color = Fassoc (color, Vface_tty_color_alist),
+  if (STRINGP (color)
+      && XSTRING (color)->size
+      && !NILP (tty_color_alist)
+      && (color = Fassoc (color, tty_color_alist),
 	  CONSP (color)))
-    face->background = XINT (XCDR (color));
-
-#ifdef MSDOS
-  if (FRAME_MSDOS_P (c->f) && face->background == FACE_TTY_DEFAULT_COLOR)
+    /* Associations in tty-color-alist are of the form
+       (NAME INDEX R G B).  We need the INDEX part.  */
+    face->background = XINT (XCAR (XCDR (color)));
+
+  if (face->background == FACE_TTY_DEFAULT_COLOR
+      && STRINGP (attrs[LFACE_BACKGROUND_INDEX]))
     {
       face->background = load_color (c->f, face,
 				     attrs[LFACE_BACKGROUND_INDEX],
 				     LFACE_BACKGROUND_INDEX);
+#ifdef MSDOS
       /* If the background of the default face is the default color,
 	 use the background color defined by the frame.  */
-      if (face->background == FACE_TTY_DEFAULT_COLOR)
+      if (FRAME_MSDOS_P (c->f) && face->background == FACE_TTY_DEFAULT_COLOR)
 	{
 	  face->background = FRAME_BACKGROUND_PIXEL (f);
 	  attrs[LFACE_BACKGROUND_INDEX] =
-	    build_string (msdos_stdcolor_name (face->background));
+	    msdos_stdcolor_name (face->background);
+	  face_colors_defaulted = 1;
 	}
-    }
-
-  /* Swap colors if face is inverse-video.  */
-  if (face->tty_reverse_p)
+#endif
+    }
+
+  /* Swap colors if face is inverse-video.  If the colors are taken
+     from the frame colors, they are already inverted, since the
+     frame-creation function calls x-handle-reverse-video.  */
+  if (face->tty_reverse_p && !face_colors_defaulted)
     {
       unsigned long tem = face->foreground;
 
       face->foreground = face->background;
       face->background = tem;
     }
-#endif
 
   return face;
 }
 
 
-DEFUN ("face-register-tty-color", Fface_register_tty_color,
-       Sface_register_tty_color, 2, 2, 0,
-  "Say that COLOR is color number NUMBER on the terminal.\n\
-COLOR is a string, the color name.  Value is COLOR.")
-  (color, number)
-     Lisp_Object color, number;
-{
-  Lisp_Object entry;
-  
-  CHECK_STRING (color, 0);
-  CHECK_NUMBER (number, 1);
-  entry = Fassoc (color, Vface_tty_color_alist);
-  if (NILP (entry))
-    Vface_tty_color_alist = Fcons (Fcons (color, number),
-				   Vface_tty_color_alist);
-  else
-    Fsetcdr (entry, number);
-  return color;
-}
-
-
-DEFUN ("face-clear-tty-colors", Fface_clear_tty_colors,
-       Sface_clear_tty_colors, 0, 0, 0,
-  "Unregister all registered tty colors.")
-  ()
-{
-  return Vface_tty_color_alist = Qnil;
-}
-
-
-DEFUN ("tty-defined-colors", Ftty_defined_colors,
-       Stty_defined_colors, 0, 0, 0,
-  "Return a list of registered tty colors.")
-  ()
-{
-  Lisp_Object list, colors;
-
-  colors = Qnil;
-  for (list = Vface_tty_color_alist; CONSP (list); list = XCDR (list))
-    colors = Fcons (XCAR (XCAR (list)), colors);
-
-  return colors;
-}
-
-
 
 /***********************************************************************
 			   Computing Faces
@@ -6625,6 +6639,10 @@
   staticpro (&Qborder);
   Qmouse = intern ("mouse");
   staticpro (&Qmouse);
+  Qtty_color_desc = intern ("tty-color-desc");
+  staticpro (&Qtty_color_desc);
+  Qtty_color_by_index = intern ("tty-color-by-index");
+  staticpro (&Qtty_color_by_index);
 
   defsubr (&Sinternal_make_lisp_face);
   defsubr (&Sinternal_lisp_face_p);
@@ -6696,11 +6714,4 @@
   defsubr (&Sx_family_fonts);
   defsubr (&Sx_font_family_list);
 #endif /* HAVE_X_WINDOWS */
-
-  /* TTY face support.  */
-  defsubr (&Sface_register_tty_color);
-  defsubr (&Sface_clear_tty_colors);
-  defsubr (&Stty_defined_colors);
-  Vface_tty_color_alist = Qnil;
-  staticpro (&Vface_tty_color_alist);
 }