Mail Archives: djgpp-workers/2001/08/07/03:57:18
On Mon, 6 Aug 2001, cvs-snowball AT delorie DOT com wrote:
> + case 'v': /* Change cursor shape. DJGPP private command. */
> + switch (GET_ARG(0, 0))
> + {
> + case 0: /* Set to normal. */
> + r.x.cx = 0x0607;
> + break;
> +
> + case 1: /* Make invisible. */
> + r.x.cx = 0x2000;
> + break;
> +
> + case 2: /* Make enhanced. */
> + r.x.cx = 0x0007;
> + break;
> + }
> + r.h.ah = 1;
> + __dpmi_int(0x10, &r);
Will this DTRT no matter what screen resolution is? That is, the text
screen can be 25 lines, 28 lines, 43 lines, 50 lines, or something
else, and the above code should be tested to see if it works with all
of them, including on Windows in windowed mode. In particular, some
machine could have the CGA cursor emulation turned off.
I remember I had some difficulties when I wrote similar capability for
the upcoming Emacs 21; the result is attached below, in case it helps
you.
#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, ®s);
#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);
}
- Raw text -