Date: Tue, 12 Aug 1997 10:05:22 +0200 (CEST)
From: Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>
To: Linux/m68k <linux-m68k@phil.uni-sb.de>
Subject: Re: L68K: Video patches for 2.1.47
In-Reply-To: <Pine.LNX.3.96.970806095406.2120B-100000@mercator.cs.kuleuven.ac.be>
Sender: owner-linux-m68k@phil.uni-sb.de
Reply-To: linux-m68k@phil.uni-sb.de

On Wed, 6 Aug 1997, I wrote:
> Caveat: there's a known problem with loadable frame buffer devices and usage
> counts. If you use kerneld, it will unload the frame buffer device after some
> time while it's still in use. Any clues are welcome. The loadable low level

Frame buffer device usecounts are OK now. All frame buffer devices can be
compiled as modules, but at the moment only vfb has support for unloading. The
others just keep their usecount higher than zero to prevent theirselves from
being unloaded.

I also cleant up console.c a bit more (1K smaller!). I replaced the ABSCON
macro by two macros: DO_VISUAL and DO_VISUAL_IF_FG. The motivation here is that
the console operates on a text buffer in memory. On VGA hardware, this buffer
is the VGA screen if the current console is the foreground console. With our
abstract console driver, it's always a shadow buffer so we have to add a visual
update operation if the current console is the foreground console.

If anyone has some good suggestions to make console.c more acceptable for the
PC guys, let him/her speak up now, I'm willing to listen :-) One thing I'm
wondering: currently the abstract console code is a bit arbitrarily divided
between console.c and abscon.c. Maybe console.c should swallow abscon.c
completely?


--- linux-2.1.47/drivers/char/fbmem.c.orig	Mon Aug  4 00:24:21 1997
+++ linux-2.1.47/drivers/char/fbmem.c	Mon Aug 11 20:42:18 1997
@@ -387,7 +387,7 @@
 	fb = registered_fb[fbidx]->fbops;
 
 	if (! vidx)		/* fb?current always succeeds */ 
-		return 0;
+		return fb->fb_open(fbidx);
 	if (vidx > registered_fb[fbidx]->fbvar_num)
 		return -EINVAL;
 	if (fb_curr_open[fbidx] && fb_curr_open[fbidx] != vidx)
@@ -396,8 +396,10 @@
 		return(err);
  	if (file->f_mode & 2) /* only set parameters if opened writeable */
 		if ((err=fb->fb_set_var(&registered_fb[fbidx]->fbvar[vidx-1],
-					PROC_CONSOLE())))
+					PROC_CONSOLE()))) {
+			fb->fb_release(fbidx);
 			return err;
+		}
 	fb_curr_open[fbidx] = vidx;
 	fb_open_count[fbidx]++;
 	return 0;
@@ -408,11 +410,12 @@
 {
 	int fbidx=GET_FB_IDX(inode->i_rdev);
 	int vidx=GET_FB_VAR_IDX(inode->i_rdev);
+
+	registered_fb[fbidx]->fbops->fb_release(fbidx);
 	if (! vidx)
 		return 0;
 	if (! (--fb_open_count[fbidx]))
 		fb_curr_open[fbidx]=0;
-	registered_fb[fbidx]->fbops->fb_release(fbidx);
 	return 0;
 }
 
--- linux-2.1.47/drivers/char/console.c.orig	Mon Aug  4 20:29:02 1997
+++ linux-2.1.47/drivers/char/console.c	Mon Aug 11 23:45:21 1997
@@ -196,7 +196,8 @@
 unsigned char	video_type;		/* Type of display being used	*/
 
 #ifdef CONFIG_ABSTRACT_CONSOLE
-#define ABSCON(x)	abscon_##x
+#define DO_VISUAL(x)		abscon_##x
+#define DO_VISUAL_IF_FG(x)	if (currcons == fg_console) abscon_##x
 static char putcs_buf[256];
 
 extern int abscon_probe(unsigned long *kmem_start);
@@ -206,10 +207,20 @@
     sw->con_deinit(vc_cons[currcons].d);
 }
 
+static inline void abscon_scrup(int currcons, unsigned int t, unsigned int b,
+				int nr)
+{
+    sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr);
+}
+
+static inline void abscon_scrdown(int currcons, unsigned int t, unsigned int b,
+				  int nr)
+{
+    sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr);
+}
+
 static inline void abscon_erase_to_dpy_end(int currcons)
 {
-    if (currcons != fg_console)
-	return;
     /* do in two stages */
     sw->con_clear(vc_cons[currcons].d,y,x,1,video_num_columns-x);
     sw->con_clear(vc_cons[currcons].d,y+1,0,video_num_lines-y-1,
@@ -218,8 +229,6 @@
 
 static inline void abscon_erase_from_dpy_start(int currcons)
 {
-    if (currcons != fg_console)
-	return;
     /* do in two stages */
     sw->con_clear(vc_cons[currcons].d,0,0,y,video_num_columns);
     sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
@@ -227,45 +236,33 @@
 
 static inline void abscon_erase_dpy(int currcons)
 {
-    if (currcons != fg_console)
-	return;
     sw->con_clear(vc_cons[currcons].d,0,0,video_num_lines,video_num_columns);
 }
 
 static inline void abscon_erase_to_line_end(int currcons)
 {
-    if (currcons != fg_console)
-	return;
     sw->con_clear(vc_cons[currcons].d,y,x,1,video_num_columns-x);
 }
 
 static inline void abscon_erase_from_line_start(int currcons)
 {
-    if (currcons != fg_console)
-	return;
     sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
 }
 
 static inline void abscon_erase_line(int currcons)
 {
-    if (currcons != fg_console)
-	return;
     sw->con_clear(vc_cons[currcons].d,y,0,1,video_num_columns);
 }
 
 static inline void abscon_erase_next_chars(int currcons, unsigned long count)
 {
-    if (currcons == fg_console)
-	sw->con_clear(vc_cons[currcons].d,y,x,1,count);
+    sw->con_clear(vc_cons[currcons].d,y,x,1,count);
 }
 
 static inline void abscon_insert_chars(int currcons, unsigned int nr)
 {
-    unsigned short oldattr;
-    if (currcons != fg_console)
-	return;
+    unsigned short oldattr = attr;
     sw->con_bmove(vc_cons[currcons].d,y,x,y,x+nr,1,video_num_columns-x-nr);
-    oldattr = attr;
     attr = video_erase_char >> 8;
     while (nr--)
 	sw->con_putc(vc_cons[currcons].d,(video_erase_char & 0x00ff),y,x+nr);
@@ -274,11 +271,8 @@
 
 static inline void abscon_delete_chars(int currcons, unsigned int nr)
 {
-    unsigned short oldattr;
-    if (currcons != fg_console)
-	return;
+    unsigned short oldattr = attr;
     sw->con_bmove(vc_cons[currcons].d,y,x+nr,y,x,1,video_num_columns-x-nr);
-    oldattr = attr;
     attr = video_erase_char >> 8;
     while (nr--)
 	sw->con_putc(vc_cons[currcons].d,(video_erase_char & 0x00ff),y,
@@ -288,15 +282,13 @@
 
 static inline void abscon_putc(int currcons, int tc, int yy, int xx)
 {
-    if (currcons == fg_console)
-	sw->con_putc(vc_cons[currcons].d,tc,yy,xx);
+    sw->con_putc(vc_cons[currcons].d,tc,yy,xx);
 }
 
 static inline void abscon_putc_attr(int currcons, unsigned short new,
-				    int yy, int xx, unsigned short oldattr)
+				    int yy, int xx)
 {
-    if (currcons != fg_console)
-	return;
+    unsigned short oldattr = attr;
     attr = new >> 8;
     sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
     attr = oldattr;
@@ -305,8 +297,6 @@
 static inline void abscon_putc_attr_next(int currcons, unsigned short new,
 					 int *yy, int *xx)
 {
-    if (currcons != fg_console)
-	return;
     attr = new >> 8;
     sw->con_putc(vc_cons[currcons].d, new & 0xff, *yy, *xx);
     if (++(*xx) == video_num_columns)
@@ -320,8 +310,12 @@
 static inline void get_scrmem(int currcons) {}
 static inline void set_scrmem(int currcons, long offset) {}
 static inline void set_origin(int currcons) {}
+
+#define hardscroll_enabled	0
+
 #else /* !CONFIG_ABSTRACT_CONSOLE */
-#define ABSCON(x)      do {} while (0)
+#define DO_VISUAL(x)		do {} while (0)
+#define DO_VISUAL_IF_FG(x)	do {} while (0)
 extern void get_scrmem(int currcons);
 extern void set_scrmem(int currcons, long offset);
 static void set_origin(int currcons);
@@ -378,7 +372,7 @@
 		return -ENOMEM;
 	    vc_cons[currcons].d = (struct vc_data *)p;
 	    vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data));
-	    ABSCON(init(currcons));
+	    DO_VISUAL(init(currcons));
 	    q = (long)kmalloc(video_screen_size, GFP_KERNEL);
 	    if (!q) {
 		kfree_s((char *) p, structsize);
@@ -462,7 +456,7 @@
 	    if (ll < oll)
 	      ol += (oll - ll) * osr;
 
-	    ABSCON(update_attr(currcons));
+	    DO_VISUAL(update_attr(currcons));
 	    while (ol < scr_end) {
 		memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
 		if (rrem)
@@ -492,7 +486,7 @@
 
 	/* don't update in graphics mode */
 	if (currcons == fg_console && vt_cons[fg_console]->vc_mode == KD_TEXT)
-	    ABSCON(update_screen(fg_console));
+	    DO_VISUAL(update_screen(fg_console));
 
 	set_scrmem(fg_console, 0);
 	set_origin(fg_console);
@@ -596,7 +590,7 @@
 void vc_disallocate(unsigned int currcons)
 {
 	if (vc_cons_allocated(currcons)) {
-	    ABSCON(deinit(currcons));
+	    DO_VISUAL(deinit(currcons));
 	    if (kmalloced)
 	      kfree_s(vc_scrbuf[currcons], screenbuf_size);
 	    if (currcons >= MIN_NR_CONSOLES)
@@ -753,26 +747,13 @@
 
 static void scrup(int currcons, unsigned int t, unsigned int b, int nr)
 {
-#ifdef CONFIG_ABSTRACT_CONSOLE
-	unsigned short *p;
-#else /* !CONFIG_ABSTRACT_CONSOLE */
 	int hardscroll = hardscroll_enabled;
-#endif /* !CONFIG_ABSTRACT_CONSOLE */
 
 	if (t+nr >= b)
 		nr = b - t - 1;
 	if (b > video_num_lines || t >= b || nr < 1)
 		return;
-#ifdef CONFIG_ABSTRACT_CONSOLE
-	memmove((unsigned short *)video_mem_start + t * video_num_columns,
-		(unsigned short *)video_mem_start + (t + nr) * video_num_columns,
-		(b - t - nr) * video_num_columns * 2);
-	p = (unsigned short *)video_mem_start + (b - nr) * video_num_columns;
-	memsetw(p, video_erase_char, nr * video_size_row);
-	if (currcons != fg_console)
-	  return;
-	sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr);
-#else /* !CONFIG_ABSTRACT_CONSOLE */
+#ifndef CONFIG_ABSTRACT_CONSOLE
 	if (t || b != video_num_lines || nr > 1)
 		hardscroll = 0;
 	if (hardscroll) {
@@ -812,41 +793,29 @@
 			}
 		}
 		set_origin(currcons);
-	} else {
+	} else
+#endif /* !CONFIG_ABSTRACT_CONSOLE */
+	{
 		unsigned short * d = (unsigned short *) (origin+video_size_row*t);
 		unsigned short * s = (unsigned short *) (origin+video_size_row*(t+nr));
 
 		memcpyw(d, s, (b-t-nr) * video_size_row);
 		memsetw(d + (b-t-nr) * video_num_columns, video_erase_char, video_size_row*nr);
+		DO_VISUAL_IF_FG(scrup(currcons, t, b, nr));
 	}
-#endif /* !CONFIG_ABSTRACT_CONSOLE */
 }
 
 static void
 scrdown(int currcons, unsigned int t, unsigned int b, int nr)
 {
-#ifdef CONFIG_ABSTRACT_CONSOLE
-	unsigned short *p;
-#else /* !CONFIG_ABSTRACT_CONSOLE */
 	unsigned short *s;
 	unsigned int count;
 	unsigned int step;
-#endif /* !CONFIG_ABSTRACT_CONSOLE */
 
 	if (t+nr >= b)
 		nr = b - t - 1;
 	if (b > video_num_lines || t >= b || nr < 1)
 		return;
-#ifdef CONFIG_ABSTRACT_CONSOLE
-	memmove((unsigned short *)video_mem_start + (t + nr) * video_num_columns,
-		(unsigned short *)video_mem_start + t * video_num_columns,
-		(b - t - nr) * video_num_columns * 2);
-	p = (unsigned short *)video_mem_start + t * video_num_columns;
-	memsetw(p, video_erase_char, nr * video_size_row);
-	if (currcons != fg_console)
-	  return;
-	sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr);
-#else /* !CONFIG_ABSTRACT_CONSOLE */
 	s = (unsigned short *) (origin+video_size_row*(b-nr-1));
 	step = video_num_columns * nr;
 	count = b - t - nr;
@@ -854,12 +823,13 @@
 		memcpyw(s + step, s, video_size_row);
 		s -= video_num_columns;
 	}
-	while (nr--) {
+	count = nr;
+	while (count--) {
 		s += video_num_columns;
 		memsetw(s, video_erase_char, video_size_row);
 	}
 	has_scrolled = 1;
-#endif /* !CONFIG_ABSTRACT_CONSOLE */
+	DO_VISUAL_IF_FG(scrdown(currcons, t, b, nr));
 }
 
 static void lf(int currcons)
@@ -919,17 +889,17 @@
 		case 0:	/* erase from cursor to end of display */
 			count = (scr_end-pos)>>1;
 			start = (unsigned short *) pos;
-			ABSCON(erase_to_dpy_end(currcons));
+			DO_VISUAL_IF_FG(erase_to_dpy_end(currcons));
 			break;
 		case 1:	/* erase from start to cursor */
 			count = ((pos-origin)>>1)+1;
 			start = (unsigned short *) origin;
-			ABSCON(erase_from_dpy_start(currcons));
+			DO_VISUAL_IF_FG(erase_from_dpy_start(currcons));
 			break;
 		case 2: /* erase whole display */
 			count = video_num_columns * video_num_lines;
 			start = (unsigned short *) origin;
-			ABSCON(erase_dpy(currcons));
+			DO_VISUAL_IF_FG(erase_dpy(currcons));
 			break;
 		default:
 			return;
@@ -947,17 +917,17 @@
 		case 0:	/* erase from cursor to end of line */
 			count = video_num_columns-x;
 			start = (unsigned short *) pos;
-			ABSCON(erase_to_line_end(currcons));
+			DO_VISUAL_IF_FG(erase_to_line_end(currcons));
 			break;
 		case 1:	/* erase from start of line to cursor */
 			start = (unsigned short *) (pos - (x<<1));
 			count = x+1;
-			ABSCON(erase_from_line_start(currcons));
+			DO_VISUAL_IF_FG(erase_from_line_start(currcons));
 			break;
 		case 2: /* erase whole line */
 			start = (unsigned short *) (pos - (x<<1));
 			count = video_num_columns;
-			ABSCON(erase_line(currcons));
+			DO_VISUAL_IF_FG(erase_line(currcons));
 			break;
 		default:
 			return;
@@ -974,7 +944,7 @@
 		vpar++;
 	count = (vpar > video_num_columns-x) ? (video_num_columns-x) : vpar;
 
-	ABSCON(erase_next_chars(currcons, count));
+	DO_VISUAL_IF_FG(erase_next_chars(currcons, count));
 	memsetw((unsigned short *) pos, video_erase_char, 2 * count);
 	need_wrap = 0;
 }
@@ -1259,7 +1229,7 @@
 			unsigned short new = reverse_video_short(old);
 			scr_writew(new, p);
 			p++;
-			ABSCON(putc_attr_next(currcons, new, &yy, &xx));
+			DO_VISUAL_IF_FG(putc_attr_next(currcons, new, &yy, &xx));
 		}
 	else
 		while (count--) {
@@ -1267,7 +1237,7 @@
 			unsigned short new = reverse_video_short_mono(old);
 			scr_writew(new, p);
 			p++;
-			ABSCON(putc_attr_next(currcons, new, &yy, &xx));
+			DO_VISUAL_IF_FG(putc_attr_next(currcons, new, &yy, &xx));
 		}
 #ifdef CONFIG_ABSTRACT_CONSOLE
 	attr = oldattr;
@@ -1281,12 +1251,11 @@
 	static unsigned short old = 0;
 #ifdef CONFIG_ABSTRACT_CONSOLE
 	static unsigned short oldx = 0, oldy = 0;
-	unsigned short oldattr = attr;
 #endif /* CONFIG_ABSTRACT_CONSOLE */
 
 	if (p) {
 		scr_writew(old, p);
-		ABSCON(putc_attr(currcons, old, oldy, oldx, oldattr));
+		DO_VISUAL_IF_FG(putc_attr(currcons, old, oldy, oldx));
 	}
 	if (offset == -1)
 		p = NULL;
@@ -1297,15 +1266,10 @@
 #ifdef CONFIG_ABSTRACT_CONSOLE
 		oldx = (offset >> 1) % video_num_columns;
 		oldy = (offset >> 1) / video_num_columns;
-		if (can_do_color)
-			new = old ^ 0x7700;
-		else
-			new = old ^ 0x800;
-#else /* !CONFIG_ABSTRACT_CONSOLE */
-		new = old ^ 0x7700;
 #endif /* !CONFIG_ABSTRACT_CONSOLE */
+		new = complement_video_short(old);
 		scr_writew(new, p);
-		ABSCON(putc_attr(currcons, new, oldy, oldx, oldattr));
+		DO_VISUAL_IF_FG(putc_attr(currcons, new, oldy, oldx));
 	}
 }
 
@@ -1472,7 +1436,7 @@
 		p++;
 	}
 	need_wrap = 0;
-	ABSCON(insert_chars(currcons, 1));
+	DO_VISUAL_IF_FG(insert_chars(currcons, 1));
 }
 
 static void insert_line(int currcons, unsigned int nr)
@@ -1493,7 +1457,7 @@
 	}
 	scr_writew(video_erase_char, p);
 	need_wrap = 0;
-	ABSCON(delete_char(currcons, 1));
+	DO_VISUAL(delete_char(currcons, 1));
 }
 #endif /* no longer used */
 
@@ -1520,7 +1484,7 @@
 	}
 	memsetw(p, video_erase_char, 2 * nr);
 	need_wrap = 0;
-	ABSCON(insert_chars(currcons, nr));
+	DO_VISUAL_IF_FG(insert_chars(currcons, nr));
 }
 
 static void csi_L(int currcons, unsigned int nr)
@@ -1549,7 +1513,7 @@
 	}
 	memsetw(p, video_erase_char, 2 * nr);
 	need_wrap = 0;
-	ABSCON(delete_chars(currcons, nr));
+	DO_VISUAL_IF_FG(delete_chars(currcons, nr));
 }
 
 static void csi_M(int currcons, unsigned int nr)
@@ -1716,7 +1680,7 @@
 
 	/* undraw cursor first */
 	if (currcons == fg_console)
-		ABSCON(hide_cursor(currcons));
+		DO_VISUAL(hide_cursor(currcons));
 
 	/* clear the selection */
 	if (currcons == sel_cons)
@@ -1896,7 +1860,7 @@
 			   ((attr & 0xf7) << 8) + ((tc & 0x100) << 3) +
 			   (tc & 0x0ff) : (attr << 8) + tc,
 			   (unsigned short *) pos);
-			ABSCON(putc(currcons, tc, y, x));
+			DO_VISUAL_IF_FG(putc(currcons, tc, y, x));
 			if (x == video_num_columns - 1)
 				need_wrap = decawm;
 			else {
@@ -2587,7 +2551,7 @@
 		kmem_start += sizeof(struct vc_data);
 		vt_cons[currcons] = (struct vt_struct *) kmem_start;
 		kmem_start += sizeof(struct vt_struct);
-		ABSCON(init(currcons));
+		DO_VISUAL(init(currcons));
 		vc_scrbuf[currcons] = (unsigned short *) kmem_start;
 		kmem_start += video_screen_size;
 		kmalloced = 0;
--- linux-2.1.47/drivers/video/vfb.c.orig	Wed Jul 30 23:25:14 1997
+++ linux-2.1.47/drivers/video/vfb.c	Mon Aug 11 20:31:15 1997
@@ -594,10 +594,8 @@
 
 void cleanup_module(void)
 {
-#if 0
-    /* Not yet supported */
     unregister_framebuffer(&fb_info);
-#endif
+    vfree(videomemory);
 }
 
 #endif /* MODULE */
--- linux-2.1.47/drivers/video/amifb.c.orig	Wed Jul 30 23:25:05 1997
+++ linux-2.1.47/drivers/video/amifb.c	Mon Aug 11 22:20:28 1997
@@ -1882,6 +1882,10 @@
 
 	printk("%s frame buffer device, using %ldK of video memory\n",
 	       fb_info.modename, videomemorysize>>10);
+
+        /* TODO: This driver cannot be unloaded yet */
+	MOD_INC_USE_COUNT;
+
 	return 0;
 }
 
@@ -3356,9 +3360,8 @@
 
 void cleanup_module(void)
 {
-#if 0
-    /* Not yet supported */
+    /* Not reached because the usecount will never be decremented to zero */
     unregister_framebuffer(&fb_info);
-#endif
+    /* TODO: clean up ... */
 }
 #endif /* MODULE */
--- linux-2.1.47/drivers/video/atafb.c.orig	Wed Jul 30 23:25:06 1997
+++ linux-2.1.47/drivers/video/atafb.c	Mon Aug 11 22:20:33 1997
@@ -2847,6 +2847,10 @@
 	do_install_cmap(0);
 	printk("%s frame buffer device, using %dK of video memory\n",
 	       fb_info.modename, screen_len>>10);
+
+        /* TODO: This driver cannot be unloaded yet */
+	MOD_INC_USE_COUNT;
+
 	return 0;
 }
 
@@ -3121,3 +3125,18 @@
 		;
 	}
 }
+
+
+#ifdef MODULE
+int init_module(void)
+{
+    return(atari_fb_init(NULL));
+}
+
+void cleanup_module(void)
+{
+    /* Not reached because the usecount will never be decremented to zero */
+    unregister_framebuffer(&fb_info);
+    /* TODO: clean up ... */
+}
+#endif /* MODULE */
--- linux-2.1.47/drivers/video/cyberfb.c.orig	Sun Aug  3 23:57:23 1997
+++ linux-2.1.47/drivers/video/cyberfb.c	Mon Aug 11 22:20:38 1997
@@ -1012,6 +1012,10 @@
 
    printk("%s frame buffer device, using %ldK of video memory\n",
 	  fb_info.modename, CyberSize>>10);
+
+   /* TODO: This driver cannot be unloaded yet */
+   MOD_INC_USE_COUNT;
+
    return(0);
 }
 
@@ -1087,10 +1091,9 @@
 
 void cleanup_module(void)
 {
-#if 0
-    /* Not yet supported */
+    /* Not reached because the usecount will never be decremented to zero */
     unregister_framebuffer(&fb_info);
-#endif
+    /* TODO: clean up ... */
 }
 #endif /* MODULE */
 
--- linux-2.1.47/drivers/video/retz3fb.c.orig	Sun Aug  3 23:58:38 1997
+++ linux-2.1.47/drivers/video/retz3fb.c	Mon Aug 11 22:20:42 1997
@@ -1513,6 +1513,9 @@
 	printk("%s frame buffer device, using %ldK of video memory\n",
 	       fb_info.modename, z3_size>>10);
 
+	/* TODO: This driver cannot be unloaded yet */
+	MOD_INC_USE_COUNT;
+
 	return 0;
 }
 
@@ -1592,10 +1595,9 @@
 
 void cleanup_module(void)
 {
-#if 0
-    /* Not yet supported */
+    /* Not reached because the usecount will never be decremented to zero */
     unregister_framebuffer(&fb_info);
-#endif
+    /* TODO: clean up ... */
 }
 #endif /* MODULE */
 
--- linux-2.1.47/include/linux/selection.h.orig	Mon Aug 11 19:52:55 1997
+++ linux-2.1.47/include/linux/selection.h	Mon Aug 11 23:22:38 1997
@@ -66,9 +66,11 @@
    requires a self-inverse operation; moreover, the old version looks wrong */
 #ifdef CONFIG_ABSTRACT_CONSOLE
 #define reverse_video_short_mono(a)	((a) ^ 0x800)
+#define complement_video_short(a)	((a) ^ (can_do_color ? 0x7700 : 0x800))
 #else /* !CONFIG_ABSTRACT_CONSOLE */
 #define reverse_video_short_mono(a)	\
 	((a) ^ ((((a) & 0x0700) == 0x0100) ? 0x7000 : 0x7700))
+#define complement_video_short(a)	((a) ^ 0x7700)
 #endif /* !CONFIG_ABSTRACT_CONSOLE */
 
 extern void getconsxy(int currcons, char *p);

Greetings,

						Geert

--
Geert Uytterhoeven                     Geert.Uytterhoeven@cs.kuleuven.ac.be
Wavelets, Linux/m68k on Amiga          http://www.cs.kuleuven.ac.be/~geert/
Department of Computer Science -- Katholieke Universiteit Leuven -- Belgium

