diff src/msdos.c @ 25110:4833aea1f1e7

(IT_set_face): Rewritten for the new redisplay engine. Use default frame colors if the face doesn't specify them; invert the colors if highlight is ON. (IT_write_glyphs): Rewritten for the new redisplay engine. (IT_change_line_highlight): Add (unused) parameter Y, since that's how the hook is called by term.c. (IT_copy_glyphs): New function, copies an area of the display in video RAM. (IT_insert_glyphs): Rewritten to DTRT instead of aborting, since redisplay now calls it even if char_ins_del_ok is zero. (IT_set_frame_parameters): Prototype changed. Calls the new load_color. Puts the new fore/background colors into the default face on current frame. (IT_menu_display): Rewritten to handle the new struct glyph instead of a char array. (XMenuActivate): Call lookup_derived_face to create and use special faces for the pop-up and drop-down menus.
author Eli Zaretskii <eliz@gnu.org>
date Fri, 30 Jul 1999 08:05:13 +0000
parents 2e3da138463f
children acfe5b9d7233
line wrap: on
line diff
--- a/src/msdos.c	Fri Jul 30 00:50:59 1999 +0000
+++ b/src/msdos.c	Fri Jul 30 08:05:13 1999 +0000
@@ -46,12 +46,12 @@
 #include <conio.h>	 /* for cputs */
 #endif
 
-#include "dosfns.h"
 #include "msdos.h"
 #include "systime.h"
 #include "termhooks.h"
 #include "termchar.h"
 #include "dispextern.h"
+#include "dosfns.h"
 #include "termopts.h"
 #include "charset.h"
 #include "coding.h"
@@ -658,29 +658,54 @@
     }
 }
 
+/* Given a face id FACE, extract the face parameters to be used for
+   display until the face changes.  The face parameters (actually, its
+   color) are used to construct the video attribute byte for each
+   glyph during the construction of the buffer that is then blitted to
+   the video RAM.  */
 static void
 IT_set_face (int face)
 {
-  struct face *fp;
-  extern struct face *intern_face (/* FRAME_PTR, struct face * */);
-
-  if (face == 1 || (face == 0 && highlight))
-    fp = FRAME_MODE_LINE_FACE (foo);
-  else if (face <= 0 || face >= FRAME_N_COMPUTED_FACES (foo))
-    fp = FRAME_DEFAULT_FACE (foo);
-  else
-    fp = intern_face (selected_frame, FRAME_COMPUTED_FACES (foo)[face]);
+  struct face *fp = FACE_FROM_ID (selected_frame, face);
+  unsigned long fg, bg;
+
+  if (!fp)
+    fp = FACE_FROM_ID (selected_frame, DEFAULT_FACE_ID);
+  screen_face = face;
+  fg = fp->foreground;
+  bg = fp->background;
+
+  /* Don't use invalid colors.  In particular, a color of -1 means use
+     the colors of the default face, except that if highlight is on,
+     invert the foreground and the background.  Note that we assume
+     all 16 colors to be available for the background, since Emacs
+     switches on this mode (and loses the blinking attribute) at
+     startup.  */
+  if (fg == (unsigned long)-1)
+    fg = highlight ? FRAME_BACKGROUND_PIXEL (selected_frame)
+		   : FRAME_FOREGROUND_PIXEL (selected_frame);
+  if (bg == (unsigned long)-1)
+    bg = highlight ? FRAME_FOREGROUND_PIXEL (selected_frame)
+		   : FRAME_BACKGROUND_PIXEL (selected_frame);
   if (termscript)
-    fprintf (termscript, "<FACE %d: %d/%d>",
-	     face, FACE_FOREGROUND (fp), FACE_BACKGROUND (fp));
-  screen_face = face;
-  ScreenAttrib = (FACE_BACKGROUND (fp) << 4) | FACE_FOREGROUND (fp);
+    fprintf (termscript, "<FACE %d%s: %d/%d>",
+	     face, highlight ? "H" : "", fp->foreground, fp->background);
+  if (fg >= 0 && fg < 16)
+    {
+      ScreenAttrib &= 0xf0;
+      ScreenAttrib |= fg;
+    }
+  if (bg >= 0 && bg < 16)
+    {
+      ScreenAttrib &= 0x0f;
+      ScreenAttrib |= ((bg & 0x0f) << 4);
+    }
 }
 
 Lisp_Object Vdos_unsupported_char_glyph;
 
 static void
-IT_write_glyphs (GLYPH *str, int str_len)
+IT_write_glyphs (struct glyph *str, int str_len)
 {
   unsigned char *screen_buf, *screen_bp, *screen_buf_end, *bp;
   int unsupported_face = FAST_GLYPH_FACE (Vdos_unsupported_char_glyph);
@@ -710,9 +735,10 @@
   terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
   while (sl)
     {
-      int cf, ch, chlen, enclen;
+      int cf, chlen, enclen;
       unsigned char workbuf[4], *buf;
-      register GLYPH g = *str;
+      unsigned ch;
+      register GLYPH g = GLYPH_FROM_CHAR_GLYPH (*str);
 
       /* Find the actual glyph to display by traversing the entire
 	 aliases chain for this glyph.  */
@@ -721,7 +747,7 @@
       /* Glyphs with GLYPH_MASK_PADDING bit set are actually there
 	 only for the redisplay code to know how many columns does
          this character occupy on the screen.  Skip padding glyphs.  */
-      if ((g & GLYPH_MASK_PADDING))
+      if (CHAR_GLYPH_PADDING_P (*str))
 	{
 	  str++;
 	  sl--;
@@ -740,7 +766,7 @@
 	    ch = unibyte_char_to_multibyte (ch);
 
 	  /* Invalid characters are displayed with a special glyph.  */
-	  if (ch > MAX_CHAR)
+	  if (! GLYPH_CHAR_VALID_P (ch))
 	    {
 	      g = !NILP (Vdos_unsupported_char_glyph)
 		? Vdos_unsupported_char_glyph
@@ -773,8 +799,7 @@
 	      buf = GLYPH_STRING (tbase, g);
 	    }
 
-	  /* If the character is not multibyte, don't bother converting it.
-	     FIXME: what about "emacs --unibyte"  */
+	  /* If the character is not multibyte, don't bother converting it.  */
 	  if (chlen == 1)
 	    {
 	      *conversion_buffer = (unsigned char)ch;
@@ -1054,7 +1079,7 @@
 }
 
 static void
-IT_change_line_highlight (int new_highlight, int vpos, int first_unused_hpos)
+IT_change_line_highlight (int new_highlight, int y, int vpos, int first_unused_hpos)
 {
   highlight = new_highlight;
   IT_set_face (0); /* To possibly clear the highlighting.  */
@@ -1075,15 +1100,55 @@
 {
 }
 
-/* Insert and delete characters.  These are not supposed to be used
-   because we are supposed to turn off the feature of using them by
-   setting char_ins_del_ok to zero (see internal_terminal_init).  */
+/* Copy LEN glyphs displayed on a single line whose vertical position
+   is YPOS, beginning at horizontal position XFROM to horizontal
+   position XTO, by moving blocks in the video memory.  Used by
+   functions that insert and delete glyphs.  */
+static void
+IT_copy_glyphs (int xfrom, int xto, size_t len, int ypos)
+{
+  /* The offsets of source and destination relative to the
+     conventional memorty selector.  */
+  int from = 2 * (xfrom + screen_size_X * ypos) + ScreenPrimary;
+  int to = 2 * (xto + screen_size_X * ypos) + ScreenPrimary;
+
+  if (from == to || len <= 0)
+    return;
+
+  _farsetsel (_dos_ds);
+
+  /* The source and destination might overlap, so we need to move
+     glyphs non-destructively.  */
+  if (from > to)
+    {
+      for ( ; len; from += 2, to += 2, len--)
+	_farnspokew (to, _farnspeekw (from));
+    }
+  else
+    {
+      from += (len - 1) * 2;
+      to += (len - 1) * 2;
+      for ( ; len; from -= 2, to -= 2, len--)
+	_farnspokew (to, _farnspeekw (from));
+    }
+  if (screen_virtual_segment)
+    dosv_refresh_virtual_screen (ypos * screen_size_X * 2, screen_size_X);
+}
+
+/* Insert and delete glyphs.  */
 static void
 IT_insert_glyphs (start, len)
-     register char *start;
+     register struct glyph *start;
      register int len;
 {
-  abort ();
+  int shift_by_width = screen_size_X - (new_pos_X + len);
+
+  /* Shift right the glyphs from the nominal cursor position to the
+     end of this line.  */
+  IT_copy_glyphs (new_pos_X, new_pos_X + len, shift_by_width, new_pos_Y);
+
+  /* Now write the glyphs to be inserted.  */
+  IT_write_glyphs (start, len);
 }
 
 static void
@@ -1265,7 +1330,7 @@
 
 void
 IT_set_frame_parameters (f, alist)
-     FRAME_PTR f;
+     struct frame *f;
      Lisp_Object alist;
 {
   Lisp_Object tail;
@@ -1276,7 +1341,10 @@
   Lisp_Object *values
     = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
   int redraw;
-  extern unsigned long load_color ();
+  struct face *dflt = NULL;
+
+  if (FRAME_FACE_CACHE (f))
+    dflt = FACE_FROM_ID (f, DEFAULT_FACE_ID);
 
   redraw = 0;
 
@@ -1302,10 +1370,14 @@
 
       if (EQ (prop, Qforeground_color))
 	{
-	  unsigned long new_color = load_color (f, val);
+	  unsigned long new_color = load_color (f, NULL, val,
+						LFACE_FOREGROUND_INDEX);
 	  if (new_color != ~0)
 	    {
+	      if (!dflt)
+		abort ();
 	      FRAME_FOREGROUND_PIXEL (f) = new_color;
+	      dflt->foreground = new_color;
 	      redraw = 1;
 	      if (termscript)
 		fprintf (termscript, "<FGCOLOR %lu>\n", new_color);
@@ -1313,10 +1385,14 @@
 	}
       else if (EQ (prop, Qbackground_color))
 	{
-	  unsigned long new_color = load_color (f, val);
+	  unsigned long new_color = load_color (f, NULL, val,
+						LFACE_BACKGROUND_INDEX);
 	  if (new_color != ~0)
 	    {
+	      if (!dflt)
+		abort ();
 	      FRAME_BACKGROUND_PIXEL (f) = new_color;
+	      dflt->background = new_color;
 	      redraw = 1;
 	      if (termscript)
 		fprintf (termscript, "<BGCOLOR %lu>\n", new_color);
@@ -1332,8 +1408,12 @@
 	{
 	  unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
 
-	  FRAME_FOREGROUND_PIXEL (f) = FRAME_BACKGROUND_PIXEL (f);
+	  if (!dflt)
+	    abort ();
+	  FRAME_FOREGROUND_PIXEL (f) = FRAME_BACKGROUND_PIXEL (f); /* FIXME! */
 	  FRAME_BACKGROUND_PIXEL (f) = fg;
+	  dflt->foreground = FRAME_FOREGROUND_PIXEL (f);
+	  dflt->foreground = fg;
 	  if (termscript)
 	    fprintf (termscript, "<INVERSE-VIDEO>\n");
 	}
@@ -1343,9 +1423,6 @@
 
   if (redraw)
     {
-      extern void recompute_basic_faces (FRAME_PTR);
-      extern void redraw_frame (FRAME_PTR);
-
       recompute_basic_faces (f);
       if (f == selected_frame)
 	redraw_frame (f);
@@ -1433,8 +1510,7 @@
   set_terminal_modes_hook = IT_set_terminal_modes;
   reset_terminal_modes_hook = IT_reset_terminal_modes;
   set_terminal_window_hook = IT_set_terminal_window;
-
-  char_ins_del_ok = 0;		/* just as fast to write the line */
+  char_ins_del_ok = 0;
 #endif
 }
 
@@ -2409,14 +2485,14 @@
 IT_menu_display (XMenu *menu, int y, int x, int *faces)
 {
   int i, j, face, width;
-  GLYPH *text, *p;
+  struct glyph *text, *p;
   char *q;
   int mx, my;
   int enabled, mousehere;
   int row, col;
 
   width = menu->width;
-  text = (GLYPH *) xmalloc ((width + 2) * sizeof (GLYPH));
+  text = (struct glyph *) xmalloc ((width + 2) * sizeof (struct glyph));
   ScreenGetCursor (&row, &col);
   mouse_get_xy (&mx, &my);
   IT_update_begin (selected_frame);
@@ -2428,22 +2504,30 @@
       mousehere = (y + i == my && x <= mx && mx < x + width + 2);
       face = faces[enabled + mousehere * 2];
       p = text;
-      *p++ = FAST_MAKE_GLYPH (' ', face);
+      SET_CHAR_GLYPH (*p, ' ', face, 0);
+      p++;
       for (j = 0, q = menu->text[i]; *q; j++)
 	{
 	  if (*q > 26)
-	    *p++ = FAST_MAKE_GLYPH (*q++, face);
+	    {
+	      SET_CHAR_GLYPH (*p, *q++, face, 0);
+	      p++;
+	    }
 	  else	/* make '^x' */
 	    {
-	      *p++ = FAST_MAKE_GLYPH ('^', face);
+	      SET_CHAR_GLYPH (*p, '^', face, 0);
+	      p++;
 	      j++;
-	      *p++ = FAST_MAKE_GLYPH (*q++ + 64, face);
+	      SET_CHAR_GLYPH (*p, *q++ + 64, face, 0);
+	      p++;
 	    }
 	}
 	    
-      for (; j < width; j++)
-	*p++ = FAST_MAKE_GLYPH (' ', face);
-      *p++ = FAST_MAKE_GLYPH (menu->submenu[i] ? 16 : ' ', face);
+      for (; j < width; j++, p++)
+	SET_CHAR_GLYPH (*p, ' ', face, 0);
+
+      SET_CHAR_GLYPH (*p, menu->submenu[i] ? 16 : ' ', face, 0);
+      p++;
       IT_write_glyphs (text, width + 2);
     }
   IT_update_end (selected_frame);
@@ -2561,7 +2645,8 @@
   int statecount;
   int x, y, i, b;
   int screensize;
-  int faces[4], selectface;
+  int faces[4];
+  Lisp_Object selectface;
   int leave, result, onepane;
   int title_faces[4];		/* face to display the menu title */
   int buffers_num_deleted = 0;
@@ -2583,21 +2668,16 @@
   state = alloca (menu->panecount * sizeof (struct IT_menu_state));
   screensize = screen_size * 2;
   faces[0]
-    = compute_glyph_face (selected_frame,
-			  face_name_id_number
-			  (selected_frame,
-			   intern ("msdos-menu-passive-face")),
-			  0);
+    = lookup_derived_face (selected_frame, intern ("msdos-menu-passive-face"),
+			   CHARSET_ASCII, DEFAULT_FACE_ID);
   faces[1]
-    = compute_glyph_face (selected_frame,
-			  face_name_id_number
-			  (selected_frame,
-			   intern ("msdos-menu-active-face")),
-			  0);
-  selectface
-    = face_name_id_number (selected_frame, intern ("msdos-menu-select-face"));
-  faces[2] = compute_glyph_face (selected_frame, selectface, faces[0]);
-  faces[3] = compute_glyph_face (selected_frame, selectface, faces[1]);
+    = lookup_derived_face (selected_frame, intern ("msdos-menu-active-face"),
+			   CHARSET_ASCII, DEFAULT_FACE_ID);
+  selectface = intern ("msdos-menu-select-face");
+  faces[2] = lookup_derived_face (selected_frame, selectface,
+				  CHARSET_ASCII, faces[0]);
+  faces[3] = lookup_derived_face (selected_frame, selectface,
+				  CHARSET_ASCII, faces[1]);
 
   /* Make sure the menu title is always displayed with
      `msdos-menu-active-face', no matter where the mouse pointer is.  */