changeset 28092:ce3bf4da00a9

(vga_installed): New function, code moved from dos_set_window_size. (Qbar, Qcursor_type, outside_cursor): New variables. (syms_of_msdos): Intern and staticpro them. (dos_ttraw) [__DJGPP__ >= 2, !HAVE_X_WINDOWS]: Save the cursor shape used outside Emacs when called for the first time. (dos_ttcooked) [__DJGPP__ >= 2, !HAVE_X_WINDOWS]: Restore the cursor shape used outside Emacs. (msdos_set_cursor_shape, IT_set_cursor_type): New functions. (IT_frame_up_to_date): Call IT_set_cursor_type, in case the cursor type has changed. (IT_set_frame_parameters): Call IT_set_cursor_type if the frame parameters specify the cursor. Make qreverse a global variable (renamed to Qreverse).
author Eli Zaretskii <eliz@gnu.org>
date Sun, 12 Mar 2000 12:32:17 +0000
parents d28d789a8521
children 3e652235df91
files src/msdos.c
diffstat 1 files changed, 181 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/msdos.c	Sat Mar 11 18:47:38 2000 +0000
+++ b/src/msdos.c	Sun Mar 12 12:32:17 2000 +0000
@@ -342,6 +342,8 @@
 
 static int term_setup_done;
 
+static unsigned short outside_cursor;
+
 /* Similar to the_only_frame.  */
 struct x_output the_only_x_display;
 
@@ -356,6 +358,8 @@
 /* A flag to control how to display unibyte 8-bit characters.  */
 extern int unibyte_display_via_language_environment;
 
+Lisp_Object Qbar;
+
 #if __DJGPP__ > 1
 /* Update the screen from a part of relocated DOS/V screen buffer which
    begins at OFFSET and includes COUNT characters.  */
@@ -485,6 +489,19 @@
     }
 }
 
+/* Return non-zero if the system has a VGA adapter.  */
+static int
+vga_installed (void)
+{
+  union REGS regs;
+
+  regs.x.ax = 0x1a00;
+  int86 (0x10, &regs, &regs);
+  if (regs.h.al == 0x1a && regs.h.bl > 5 && regs.h.bl < 13)
+    return 1;
+  return 0;
+}
+
 /* Set the screen dimensions so that it can show no less than
    ROWS x COLS frame.  */
 
@@ -502,13 +519,8 @@
   if (*rows == current_rows && *cols == current_cols)
     return;
 
-  /* Do we have a VGA?  */
-  regs.x.ax = 0x1a00;
-  int86 (0x10, &regs, &regs);
-  if (regs.h.al == 0x1a && regs.h.bl > 5 && regs.h.bl < 13)
-    have_vga = 1;
-
   mouse_off ();
+  have_vga = vga_installed ();
 
   /* If the user specified a special video mode for these dimensions,
      use that mode.  */
@@ -656,6 +668,130 @@
   mouse_off ();
 }
 
+#define DEFAULT_CURSOR_START (-1)
+#define DEFAULT_CURSOR_WIDTH (-1)
+#define BOX_CURSOR_WIDTH     (-32)
+
+/* Set cursor to begin at scan line START_LINE in the character cell
+   and extend for WIDTH scan lines.  Scan lines are counted from top
+   of the character cell, starting from zero.  */
+static void
+msdos_set_cursor_shape (struct frame *f, int start_line, int width)
+{
+#if __DJGPP__ > 1
+  unsigned desired_cursor;
+  __dpmi_regs regs;
+  int max_line, top_line, bot_line;
+
+  /* Avoid the costly BIOS call if F isn't the currently selected
+     frame.  Allow for NULL as unconditionally meaning the selected
+     frame.  */
+  if (f && f != SELECTED_FRAME())
+    return;
+
+  /* The character cell size in scan lines is stored at 40:85 in the
+     BIOS data area.  */
+  max_line = _farpeekw (_dos_ds, 0x485) - 1;
+  switch (max_line)
+    {
+      default:	/* this relies on CGA cursor emulation being ON! */
+      case 7:
+	bot_line = 7;
+	break;
+      case 9:
+	bot_line = 9;
+	break;
+      case 13:
+	bot_line = 12;
+	break;
+      case 15:
+	bot_line = 14;
+	break;
+    }
+
+  if (width < 0)
+    {
+      if (width == BOX_CURSOR_WIDTH)
+	{
+	  top_line = 0;
+	  bot_line = max_line;
+	}
+      else if (start_line != DEFAULT_CURSOR_START)
+	{
+	  top_line = start_line;
+	  bot_line = top_line - width - 1;
+	}
+      else if (width != DEFAULT_CURSOR_WIDTH)
+	{
+	  top_line = 0;
+	  bot_line = -1 - width;
+	}
+      else
+	top_line = bot_line + 1;
+    }
+  else if (width == 0)
+    {
+      /* [31, 0] seems to DTRT for all screen sizes.  */
+      top_line = 31;
+      bot_line = 0;
+    }
+  else	/* WIDTH is positive */
+    {
+      if (start_line != DEFAULT_CURSOR_START)
+	bot_line = start_line;
+      top_line = bot_line - (width - 1);
+    }
+
+  /* If the current cursor shape is already what they want, we are
+     history here.  */
+  desired_cursor = ((top_line & 0x1f) << 8) | (bot_line & 0x1f);
+  if (desired_cursor == _farpeekw (_dos_ds, 0x460))
+    return;
+
+  regs.h.ah = 1;
+  regs.x.cx = desired_cursor;
+  __dpmi_int (0x10, &regs);
+#endif /* __DJGPP__ > 1 */
+}
+
+static void
+IT_set_cursor_type (struct frame *f, Lisp_Object cursor_type)
+{
+  if (EQ (cursor_type, Qbar))
+    {
+      /* Just BAR means the normal EGA/VGA cursor.  */
+      msdos_set_cursor_shape (f, DEFAULT_CURSOR_START, DEFAULT_CURSOR_WIDTH);
+    }
+  else if (CONSP (cursor_type) && EQ (XCAR (cursor_type), Qbar))
+    {
+      Lisp_Object bar_parms = XCDR (cursor_type);
+      int width;
+
+      if (INTEGERP (bar_parms))
+	{
+	  /* Feature: negative WIDTH means cursor at the top
+	     of the character cell, zero means invisible cursor.  */
+	  width = XINT (bar_parms);
+	  msdos_set_cursor_shape (f, width >= 0 ? DEFAULT_CURSOR_START : 0,
+				  width);
+	}
+      else if (CONSP (bar_parms)
+	       && INTEGERP (XCAR (bar_parms))
+	       && INTEGERP (XCDR (bar_parms)))
+	{
+	  int start_line = XINT (XCDR (bar_parms));
+
+	  width = XINT (XCAR (bar_parms));
+	  msdos_set_cursor_shape (f, start_line, width);
+	}
+    }
+  else
+    /* Treat anything unknown as "box cursor".  This includes nil, so
+       that a frame which doesn't specify a cursor type gets a box,
+       which is the default in Emacs.  */
+    msdos_set_cursor_shape (f, 0, BOX_CURSOR_WIDTH);
+}
+
 static void
 IT_ring_bell (void)
 {
@@ -1756,6 +1892,8 @@
   FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
 }
 
+Lisp_Object Qcursor_type;
+
 static void
 IT_frame_up_to_date (struct frame *f)
 {
@@ -1773,6 +1911,9 @@
       UNBLOCK_INPUT;
     }
 
+  /* Set the cursor type to whatever they wanted.  */
+  IT_set_cursor_type (f, Fcdr (Fassq (Qcursor_type, f->param_alist)));
+
   IT_cmgoto (f);  /* position cursor when update is done */
 }
 
@@ -1847,6 +1988,7 @@
 
 Lisp_Object Qbackground_color;
 Lisp_Object Qforeground_color;
+Lisp_Object Qreverse;
 extern Lisp_Object Qtitle;
 
 /* IT_set_terminal_modes is called when emacs is started,
@@ -2040,9 +2182,8 @@
     = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
   Lisp_Object *values
     = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
-  Lisp_Object qreverse = intern ("reverse");
   /* Do we have to reverse the foreground and background colors?  */
-  int reverse = EQ (Fcdr (Fassq (qreverse, f->param_alist)), Qt);
+  int reverse = EQ (Fcdr (Fassq (Qreverse, f->param_alist)), Qt);
   int was_reverse = reverse;
   int redraw = 0, fg_set = 0, bg_set = 0;
   unsigned long orig_fg;
@@ -2079,7 +2220,7 @@
       Lisp_Object prop = parms[i];
       Lisp_Object val  = values[i];
 
-      if (EQ (prop, qreverse))
+      if (EQ (prop, Qreverse))
 	reverse = EQ (val, Qt);
     }
 	
@@ -2138,6 +2279,14 @@
 	  if (termscript)
 	    fprintf (termscript, "<TITLE: %s>\n", XSTRING (val)->data);
 	}
+      else if (EQ (prop, Qcursor_type))
+	{
+	  IT_set_cursor_type (f, val);
+	  if (termscript)
+	    fprintf (termscript, "<CTYPE: %s>\n",
+		     EQ (val, Qbar) || CONSP (val) && EQ (XCAR (val), Qbar)
+		     ? "bar" : "box");
+	}
       store_frame_param (f, prop, val);
     }
 
@@ -4267,6 +4416,13 @@
 	      mouse_position_hook = &mouse_get_pos;
 	      mouse_init ();
 	    }
+
+#ifndef HAVE_X_WINDOWS
+#if __DJGPP__ >= 2
+	  /* Save the cursor shape used outside Emacs.  */
+	  outside_cursor = _farpeekw (_dos_ds, 0x460);
+#endif
+#endif
 	}
 
       first_time = 0;
@@ -4312,6 +4468,16 @@
 
 #if __DJGPP__ >= 2
 
+#ifndef HAVE_X_WINDOWS
+  /* Restore the cursor shape we found on startup.  */
+  if (outside_cursor)
+    {
+      inregs.h.ah = 1;
+      inregs.x.cx = outside_cursor;
+      int86 (0x10, &inregs, &outregs);
+    }
+#endif
+
   return (setmode (fileno (stdin), stdin_stat) != -1);
 
 #else  /* not __DJGPP__ >= 2 */
@@ -4904,6 +5070,12 @@
   staticpro (&Qbackground_color);
   Qforeground_color = intern ("foreground-color");
   staticpro (&Qforeground_color);
+  Qbar = intern ("bar");
+  staticpro (&Qbar);
+  Qcursor_type = intern ("cursor-type");
+  staticpro (&Qcursor_type);
+  Qreverse = intern ("reverse");
+  staticpro (&Qreverse);
 
   DEFVAR_LISP ("dos-unsupported-char-glyph", &Vdos_unsupported_char_glyph,
    "*Glyph to display instead of chars not supported by current codepage.\n\