[PATCH] devc-con: software block cursor for console

bridged with qdn.public.qnxrtp.x86
Post Reply
Guest

[PATCH] devc-con: software block cursor for console

Post by Guest » Thu Mar 27, 2003 7:39 pm

Block cursor has much better visibility than the
default underline cursor, but setting VGA hardware cursor
in block mode isn't pretty, as it blinks too fast.

This modification against devc-con will add a software rendered
block cursor which won't blink (just like FreeBSD console?).

(The blinking hardware cursor is still enabled in underline mode,
in case you lost it in a reverseful screen.)

* The source for devc-con to patch is in 6.1 CDROM, Character DDK.
--
kabe

Index: devc/con/tto.c
===================================================================
RCS file: /root6.1/CVSroot/devc-con-jp/devc/con/tto.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.2.1
diff -u -r1.1.1.1 -r1.1.2.1
--- devc/con/tto.c 2002/12/18 18:31:41 1.1.1.1
+++ devc/con/tto.c 2003/03/27 19:05:00 1.1.2.1
@@ -192,6 +192,12 @@
static int Screen_color = 1;
static int disable_color;

+/* software cursor */
+#if 1 /*SOFTCURSOR*/
+enum softcur_onoff_t { CUR_OFF=0, CUR_ON=1 };
+static int softcur_show(struct state_entry *stp, enum softcur_onoff_t set);
+#endif
+
/*
* Protocol emulation flags
* The low byte will be sent out with a qnx_ioctl()
@@ -698,7 +704,7 @@
break;
case '|':
gr = s->g[s->gr = 3];
- break;
+ break; /*{*/
case '}':
gr = s->g[s->gr = 2];
break;
@@ -770,10 +776,10 @@
s->attr &= ~UNDERLINE;
s->attribute = map_attr( s->attr, s->colour, s );
break;
- case '{': /* Blink on */
+ case '{': /* Blink on } */
s->attr |= BLINK;
s->attribute |= 0x80;
- break;
+ break; /*{*/
case '}': /* Blink off */
s->attr &= ~BLINK;
s->attribute &= ~0x80;
@@ -1782,6 +1788,9 @@
}

if(cur) {
+ /*erase softcursor first*/
+ softcur_show(cur, CUR_OFF);
+
/*
* Limit QNX cursor to visible screen, even if BIOS moves it off screen
* (which on an IBM PC makes the cursor disappear)
@@ -1833,7 +1842,10 @@
* Restore new screen contents
*/
new->screen = screen;
+ softcur_show(new, CUR_OFF);
memcpy( new->screen, new->buffer, new->buffer_size);
+ softcur_show(new, CUR_ON);
+
}

invisible = be_invisible;
@@ -1856,8 +1868,10 @@

static int con_put_char_attr( char row, char col, char C, char attr, int n,
struct state_entry *stp ) {
+ /*XXXoptimize*/softcur_show(stp, CUR_OFF);
memsetw( (unsigned short *)(stp->screen + ((((unsigned)row) * stp->screen_width) + col) * 2),
(attr << 8) | C, n );
+ /*XXXoptimize*/softcur_show(stp, CUR_ON);
return(0);
}

@@ -1866,10 +1880,12 @@
unsigned char *screen = stp->screen;

screen += ((((unsigned)row) * stp->screen_width) + col) * 2;
+ /*XXXoptimize*/softcur_show(stp, CUR_OFF);
while( n-- ) {
*screen++ = *str++;
*screen++ = attr;
}
+ /*XXXoptimize*/softcur_show(stp, CUR_ON);
return(0);
}

@@ -1886,12 +1902,47 @@
return(0);
}

+#if 1 /*SOFTCURSOR {*/
+/* Emulates a "hardware" cursor; thus there's
+ * only one of it and exists across virtual screens.
+ */
+static struct softcur_t {
+ int prev_row, prev_col;
+ enum softcur_onoff_t onoff;
+} softcur = {
+ 24, 3, /* initial weirdplace debug;
+ * if this place reverses, something is wrong */
+ CUR_OFF /* initial state */
+};
+/* reversevideo a position in physical screen */
+/* TODO: shouldn't do anything if "invisible" (non-text mode) */
+static int scr_inverse1( unsigned char row, unsigned char col, struct state_entry *stp)
+{
+ register unsigned char *p = screen + ((((unsigned)row) * stp->screen_width) + col) * 2 + 1;
+ /* if (invisible) return 0; */
+ *p = (*p & 0x88) | (((*p & 0x07) << 4) | ((*p & 0x70) >> 4));
+ return 0;
+}
+/*
+ * show/hide the softcursor.
+ * When modifying a screen buffer,
+ * you must sandwich it with CUR_OFF and CUR_ON call to avoid
+ * cursor corruption.
+ */
+static int softcur_show(struct state_entry *stp, enum softcur_onoff_t set)
+{
+ if (softcur.onoff == set) return 0;
+ softcur.onoff = !softcur.onoff;
+ return scr_inverse1(stp->cursor_y, stp->cursor_x, stp);
+}
+#endif /*}*/
+
static int con_set_curs_type( unsigned type, char hidden ) {
unsigned cursor;
unsigned port;
unsigned ctype[] = {
0x0f00, /* off */
- 0x0d0e, /* underline */
+ 0x0e0f, /* underline at bottom */
0x000e /* block */
};

@@ -1906,6 +1957,7 @@
* Keep BIOS up to date
*/
*((unsigned short *)(bios + 0x60)) = cursor;
+ /* set VGA hardware cursor size */
port = *((unsigned char *)(bios + 0x63)) | (*((unsigned char *)(bios + 0x64)) << 8);
out8( port, 10 );
out8( port+1, cursor >> 8 );
@@ -1927,13 +1979,21 @@
*((unsigned char *)(bios + 0x50)) = col;
*((unsigned char *)(bios + 0x51)) = row;

- offset = ((unsigned) row) * stp->screen_width + col + Screen_origin / 2;
+ if (softcur.onoff == CUR_ON /*&& softcur.blink*/) {
+ /* erase & draw */
+ scr_inverse1(softcur.prev_row, softcur.prev_col, stp);
+ scr_inverse1(row, col, stp);
+ }
+ softcur.prev_row=row; softcur.prev_col=col;

+ /* set VGA hardware cursor location */
+ offset = ((unsigned) row) * stp->screen_width + col + Screen_origin / 2;
port = *((unsigned char *)(bios + 0x63)) | (*((unsigned char *)(bios + 0x64)) << 8);
out8( port, 14 );
out8( port+1, offset >> 8 );
out8( port, 15 );
out8( port+1, offset & 0xFF );
+
return(0);
}

@@ -1941,8 +2001,10 @@
unsigned char *screen = stp->screen;

screen += ((((unsigned)row) * stp->screen_width) + col) * 2;
+ /*XXXoptimize*/softcur_show(stp, CUR_OFF);
memmove( screen, screen + 2, n*2);
*((unsigned short *)(screen + (n*2))) = (fill << 8) | ' ';
+ /*XXXoptimize*/softcur_show(stp, CUR_ON);
return(0);
}

@@ -1950,8 +2012,10 @@
unsigned char *screen = stp->screen;

screen += ((((unsigned)row) * stp->screen_width) + col) * 2;
+ /*XXXoptimize*/softcur_show(stp, CUR_OFF);
memmove( screen + 2, screen, n*2);
*((unsigned short *)screen) = (fill << 8) | ' ';
+ /*XXXoptimize*/softcur_show(stp, CUR_ON);
return(0);
}

@@ -1981,8 +2045,10 @@
}
#endif
addr = screen + (top * stp->screen_width*2);
+ /*XXXoptimize*/softcur_show(stp, CUR_OFF);
memmove( addr + stp->screen_width*2, addr, (bottom-top) * stp->screen_width*2);
memsetw( (unsigned short *)(screen + (top * stp->screen_width*2)), (fill << 8) | ' ', stp->screen_width );
+ /*XXXoptimize*/softcur_show(stp, CUR_ON);
return(0);
}

@@ -2010,8 +2076,10 @@
}
#endif
addr = screen + (top * stp->screen_width*2);
+ /*XXXoptimize*/softcur_show(stp, CUR_OFF);
memmove( addr, addr + stp->screen_width*2, (bottom-top) * stp->screen_width*2);
memsetw( (unsigned short *)(screen + (bottom * stp->screen_width*2)), (fill << 8) | ' ', stp->screen_width );
+ /*XXXoptimize*/softcur_show(stp, CUR_ON);
return(0);
}

@@ -2056,7 +2124,6 @@
stp->esc_flag = STATE_NONE;

if(first) {
- first = 0;
stp->cursor_x = *(unsigned char *)(bios + 0x50);
stp->cursor_y = *(unsigned char *)(bios + 0x51);
stp->screen = screen;
@@ -2076,6 +2143,13 @@
}

reset_term(stp);
+ if (first) {
+ con_set_curs_pos( stp->cursor_y, stp->cursor_x, 0, stp ); /*init softcur.prev_x */
+ con_set_curs_type( stp->cursor_type & 0x07, 0 );
+ softcur_show(stp, CUR_ON); /* showit */
+ }
+
+ if (first) first=0;
}

Post Reply

Return to “qdn.public.qnxrtp.x86”