[parisc-linux-cvs] STIcon-bugfix for #122

Helge Deller deller@gmx.de
Tue, 12 Jun 2001 02:24:49 +0200


EXTRAVERSION = -pa19
- fixed STIcon related bug #122 (export TERM=linux; vi xxx; press ESC->crash)
- added some (yet) unfinished functions which should help to make sticon a    
   _real_ console with scrollback a.s.o

Index: Makefile
===================================================================
RCS file: /home/cvs/parisc/linux/Makefile,v
retrieving revision 1.51
diff -u -r1.51 Makefile
--- Makefile	2001/06/12 02:36:10	1.51
+++ Makefile	2001/06/12 06:08:20
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -pa18
+EXTRAVERSION = -pa19
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: drivers/video/sti/sticon.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/sticon.c,v
retrieving revision 1.8
diff -u -r1.8 sticon.c
--- sticon.c	2001/06/12 01:21:37	1.8
+++ sticon.c	2001/06/12 06:08:26
@@ -41,6 +41,7 @@
 #include <linux/console_struct.h>
 #include <linux/errno.h>
 #include <linux/vt_kern.h>
+#include <linux/kd.h>
 #include <linux/selection.h>
 
 #include <asm/io.h>
@@ -48,6 +49,33 @@
 #include "sticon-bmode.h"	/* assume byte-mode ROM */
 #include "sticore.h"
 
+
+/* Software scrollback */
+
+int sticon_softback_size = 32768;
+static unsigned long softback_buf, softback_curr;
+static unsigned long softback_in;
+static unsigned long softback_top, softback_end;
+static int softback_lines;
+
+
+/* software cursor */
+
+static int cursor_drawn;
+#define CURSOR_DRAW_DELAY		(1)
+#define DEFAULT_CURSOR_BLINK_RATE	(20)
+
+static int vbl_cursor_cnt;
+static int cursor_on;
+static int cursor_blink_rate;
+
+static inline void cursor_undrawn(void)
+{
+    vbl_cursor_cnt = 0;
+    cursor_drawn = 0;
+}
+
+
 static const char *__init sticon_startup(void)
 {
     return "STI console";
@@ -65,15 +93,53 @@
 
 static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
 {
+    int unit = conp->vc_num;
+    int redraw_cursor = 0;
+
+    if (console_blanked)
+	    return;
+	    
+    if (vt_cons[unit]->vc_mode != KD_TEXT)
+    	    return;
+#if 0
+    if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) {
+	    cursor_undrawn();
+	    redraw_cursor = 1;
+    }
+#endif
+
     sti_putc(default_sti, c, ypos, xpos);
+
+    if (redraw_cursor)
+	    vbl_cursor_cnt = CURSOR_DRAW_DELAY;
 }
 
 static void sticon_putcs(struct vc_data *conp, const unsigned short *s,
 			 int count, int ypos, int xpos)
 {
+    int unit = conp->vc_num;
+    int redraw_cursor = 0;
+
+    if (console_blanked)
+	    return;
+
+    if (vt_cons[unit]->vc_mode != KD_TEXT)
+    	    return;
+
+#if 0
+    if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&
+	(p->cursor_x < (xpos + count))) {
+	    cursor_undrawn();
+	    redraw_cursor = 1;
+    }
+#endif
+
     while (count--) {
 	sti_putc(default_sti, *s++, ypos, xpos++);
     }
+
+    if (redraw_cursor)
+	    vbl_cursor_cnt = CURSOR_DRAW_DELAY;
 }
 
 static void sticon_cursor(struct vc_data *conp, int mode)
@@ -130,6 +196,16 @@
 sticon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
 	     int height, int width)
 {
+    if (!width || !height)
+	    return;
+#if 0
+    if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
+	(sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||
+	((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&
+	(dx <= p->cursor_x) && (p->cursor_x < dx+width)))
+		sticon_cursor(p, CM_ERASE /*|CM_SOFTBACK*/);
+#endif
+
     sti_bmove(default_sti, sy, sx, dy, dx, height, width);
 }
 
@@ -153,6 +229,9 @@
 static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
 			 int width)
 {
+    if (!height || !width)
+	return;
+
     sti_clear(default_sti, sy, sx, height, width, conp->vc_video_erase_char);
 }
 
@@ -178,13 +257,54 @@
 
 static u16 *sticon_screen_pos(struct vc_data *conp, int offset)
 {
-    return NULL;
+    int line;
+    unsigned long p;
+
+    if (conp->vc_num != fg_console || !softback_lines)
+    	return (u16 *)(conp->vc_origin + offset);
+    line = offset / conp->vc_size_row;
+    if (line >= softback_lines)
+    	return (u16 *)(conp->vc_origin + offset - softback_lines * 
conp->vc_size_row);
+    p = softback_curr + offset;
+    if (p >= softback_end)
+    	p += softback_buf - softback_end;
+    return (u16 *)p;
 }
 
 static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos,
 				  int *px, int *py)
 {
-    return 0;
+    int x, y;
+    unsigned long ret;
+    if (pos >= conp->vc_origin && pos < conp->vc_scr_end) {
+    	unsigned long offset = (pos - conp->vc_origin) / 2;
+    	
+    	x = offset % conp->vc_cols;
+    	y = offset / conp->vc_cols;
+    	if (conp->vc_num == fg_console)
+    	    y += softback_lines;
+    	ret = pos + (conp->vc_cols - x) * 2;
+    } else if (conp->vc_num == fg_console && softback_lines) {
+    	unsigned long offset = pos - softback_curr;
+    	
+    	if (pos < softback_curr)
+    	    offset += softback_end - softback_buf;
+    	offset /= 2;
+    	x = offset % conp->vc_cols;
+    	y = offset / conp->vc_cols;
+	ret = pos + (conp->vc_cols - x) * 2;
+	if (ret == softback_end)
+	    ret = softback_buf;
+	if (ret == softback_in)
+	    ret = conp->vc_origin;
+    } else {
+    	/* Should not happen */
+    	x = y = 0;
+    	ret = conp->vc_origin;
+    }
+    if (px) *px = x;
+    if (py) *py = y;
+    return ret;
 }
 
 static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens,
@@ -200,6 +320,45 @@
     return attr;
 }
 
+void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
+{
+#if 0
+    int col = 1; /* vga_can_do_color; */
+
+    while (count--) {
+	u16 a = scr_readw(p);
+
+	if (col)
+		a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
+	else
+		a = ((a & 0x0700) == 0x0100) ? 0x7000 : 0x7700;
+
+	scr_writew(a, p++);
+    }
+#endif
+}
+
+void sticon_save_screen(struct vc_data *conp)
+{
+    static int bootup_console = 0;
+
+    if (!bootup_console) {
+	/* This is a gross hack, but here is the only place we can
+	 * set bootup console parameters without messing up generic
+	 * console initialization routines.
+	 */
+	bootup_console = 1;
+	conp->vc_x = 0; /* ORIG_X; ORIG_Y; */
+	conp->vc_y = 0;
+    }
+    
+    /* TODO?: fill conp->vc_screenbuf with pdccons's bootup messages */
+    /*
+    if (!vga_is_gfx)
+	scr_memcpyw_from((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, 
c->vc_screenbuf_size);
+    */
+}
+
 struct consw sti_con = {
     con_startup:	sticon_startup,
     con_init:		sticon_init,
@@ -216,9 +375,9 @@
     con_set_palette:	sticon_set_palette,
     con_scrolldelta:	sticon_scrolldelta,
     con_set_origin:	sticon_set_origin,
-    con_save_screen:	NULL,
+    con_save_screen:	sticon_save_screen, 
     con_build_attr:	sticon_build_attr,
-    con_invert_region:	NULL,
+    con_invert_region:	sticon_invert_region, 
     con_screen_pos:	sticon_screen_pos,
     con_getxy:		sticon_getxy,
 };