Skip to contentSkip to conversation

omission in video driver

PATCH In review [email protected] 2 participants 2 messages Apr 1, 2002 – Apr 3, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 omission in video driver

Documenting the video ioctls, I noticed to my dismay that the ioctl to set the border color of the console screen is lacking.

Here part of the fix for 2.4.19:

vgacon.c renamed from linux/2.4/linux-2.4.19pre4/linux/drivers/video/vgacon.c +8 -0
@@ -244,6 +244,14 @@
 				outb_p (6, 0x3ce) ;
 				outb_p (6, 0x3cf) ;
 #endif
+				/*
+				 * Load overscan register red.
+				 */
+				inb_p(0x3da);        /* clear flipflop */
+				outb_p(0x11, 0x3c0); /* index overscan color */
+				outb_p(0x0c, 0x3c0); /* load value */
+				outb_p(0x20, 0x3c0); /* allow display memory
+							to access palette */
 
 				/*
 				 * Normalise the palette registers, to point

Andries

[this is the nontrivial part; the rest is left as an exercise]

#1 lore raw
Quoted 6 lines · [email protected] wrote:

Documenting the video ioctls, I noticed to my dismay that the ioctl to set the border color of the console screen is lacking.

Here part of the fix for 2.4.19:

...

Quoted 1 line

[this is the nontrivial part; the rest is left as an exercise]

Heh, you mean "here is the hardware information, please make a patch". But your choice of red makes it truly a "bleeding edge" kernel :)

The fact that we have been using linux for ~ 10 yrs and nobody has complained about the lack of this function yet says something...

Anyway, have a look at this and see if it is what you had in mind. I figured it would be sensible to have a per VC colour, which is the way I've done it. At end of 2.4.19pre5 patch is a $0.02 test program.

Paul.

linux/console.h renamed from linux/include/linux/console.h +1 -0
diff -ur ../linux/include/linux/console.h include/linux/console.h
@@ -41,6 +41,7 @@
 	int	(*con_blank)(struct vc_data *, int);
 	int	(*con_font_op)(struct vc_data *, struct console_font_op *);
 	int	(*con_set_palette)(struct vc_data *, unsigned char *);
+	void	(*con_border)(struct vc_data *);
 	int	(*con_scrolldelta)(struct vc_data *, int);
 	int	(*con_set_origin)(struct vc_data *);
 	void	(*con_save_screen)(struct vc_data *);
linux/console_struct.h renamed from linux/include/linux/console_struct.h +1 -0
diff -ur ../linux/include/linux/console_struct.h include/linux/console_struct.h
@@ -23,6 +23,7 @@
 	unsigned char	vc_def_color;		/* Default colors */
 	unsigned char	vc_color;		/* Foreground & background */
 	unsigned char	vc_s_color;		/* Saved foreground & background */
+	unsigned char	vc_border;		/* Border color */
 	unsigned char	vc_ulcolor;		/* Color for underline mode */
 	unsigned char	vc_halfcolor;		/* Color for half intensity mode */
 	unsigned short	vc_complement_mask;	/* [#] Xor mask for mouse pointer */
linux/kd.h renamed from linux/include/linux/kd.h +4 -1
diff -ur ../linux/include/linux/kd.h include/linux/kd.h
@@ -155,6 +155,9 @@
 
 #define KDFONTOP	0x4B72	/* font operations */
 
+#define PIO_BORDER	0x4B73	/* Border color */
+#define GIO_BORDER	0x4B74
+
 struct console_font_op {
 	unsigned int op;	/* operation code KD_FONT_OP_* */
 	unsigned int flags;	/* KD_FONT_FLAG_* */
@@ -175,6 +178,6 @@
 
 /* note: 0x4B00-0x4B4E all have had a value at some time;
    don't reuse for the time being */
-/* note: 0x4B60-0x4B6D, 0x4B70-0x4B72 used above */
+/* note: 0x4B60-0x4B6D, 0x4B70-0x4B74 used above */
 
 #endif /* _LINUX_KD_H */
linux/vt_kern.h renamed from linux/include/linux/vt_kern.h +3 -0
diff -ur ../linux/include/linux/vt_kern.h include/linux/vt_kern.h
@@ -47,12 +47,15 @@
 void vc_disallocate(unsigned int console);
 void reset_palette(int currcons);
 void set_palette(int currcons);
+void set_border(int currcons);
 void do_blank_screen(int gfx_mode);
 void unblank_screen(void);
 void poke_blanked_console(void);
 int con_font_op(int currcons, struct console_font_op *op);
 int con_set_cmap(unsigned char *cmap);
 int con_get_cmap(unsigned char *cmap);
+int con_set_border(int currcons, unsigned char *arg);
+int con_get_border(int currcons, unsigned char *arg);
 void scrollback(int);
 void scrollfront(int);
 void update_region(int currcons, unsigned long start, int count);
char/console.c renamed from linux/drivers/char/console.c +28 -0
@@ -608,6 +608,7 @@
 		set_origin(currcons);
 		update = sw->con_switch(vc_cons[currcons].d);
 		set_palette(currcons);
+		set_border(currcons);
 		if (update && vcmode != KD_GRAPHICS)
 			do_update_region(currcons, origin, screenbuf_size/2);
 	}
@@ -2425,6 +2426,7 @@
 	def_color       = 0x07;   /* white */
 	ulcolor		= 0x0f;   /* bold white */
 	halfcolor       = 0x08;   /* grey */
+	border		= 0x00;	  /* black */
 	init_waitqueue_head(&vt_cons[currcons]->paste_wait);
 	reset_terminal(currcons, do_clear);
 }
@@ -2749,6 +2751,7 @@
 	if (console_blank_hook)
 		console_blank_hook(0);
 	set_palette(currcons);
+	set_border(currcons);
 	if (sw->con_blank(vc_cons[currcons].d, 0))
 		/* Low-level driver cannot restore -> do it ourselves */
 		update_screen(fg_console);
@@ -2838,6 +2841,31 @@
 		palette[k++] = default_blu[j];
 	}
 	set_palette(currcons);
+}
+
+/*
+ *	Borders
+ */
+
+int con_set_border(int currcons, unsigned char *arg)
+{
+	if (get_user(border, arg))
+		return -EFAULT;
+	set_border(currcons);
+	return 0;
+}
+
+int con_get_border(int currcons, unsigned char *arg)
+{
+	if (put_user(border, arg))
+		return -EFAULT;
+	return 0;
+}
+
+void set_border(int currcons)
+{
+	if (vcmode != KD_GRAPHICS && sw->con_border != NULL)
+		sw->con_border(vc_cons[currcons].d);
 }
 
 /*
char/vt.c renamed from linux/drivers/char/vt.c +9 -0
@@ -8,6 +8,7 @@
  *  Restrict VT switching via ioctl() - [email protected] - Dec 1995
  *  Some code moved for less code duplication - Andi Kleen - Mar 1997
  *  Check put/get_user, cleanups - [email protected] - Jun 2001
+ *  Get/set VT border color - Paul Gortmaker/aeb - Apr 2002
  */
 
 #include <linux/config.h>
@@ -967,6 +968,14 @@
 
 	case GIO_CMAP:
                 return con_get_cmap((char *)arg);
+
+	case PIO_BORDER:
+                if (!perm)
+			return -EPERM;
+                return con_set_border(fg_console, (unsigned char *)arg);
+
+	case GIO_BORDER:
+                return con_get_border(fg_console, (unsigned char *)arg);
 
 	case PIO_FONTX:
 	case GIO_FONTX:
video/vgacon.c renamed from linux/drivers/video/vgacon.c +18 -0
@@ -86,6 +86,7 @@
 static void vgacon_deinit(struct vc_data *c);
 static void vgacon_cursor(struct vc_data *c, int mode);
 static int vgacon_switch(struct vc_data *c);
+static void vgacon_border(struct vc_data *c);
 static int vgacon_blank(struct vc_data *c, int blank);
 static int vgacon_font_op(struct vc_data *c, struct console_font_op *op);
 static int vgacon_set_palette(struct vc_data *c, unsigned char *table);
@@ -470,6 +471,22 @@
     }
 }
 
+static void vgacon_border(struct vc_data *c)
+{
+	unsigned long flags;
+	unsigned char color = c->vc_border & 0x0f;
+
+	if (c->vc_can_do_color == 0)
+		return;
+
+	spin_lock_irqsave(&vga_lock, flags);
+	inb_p(0x3da);		/* clear flipflop */
+	outb_p(0x11, 0x3c0);	/* index overscan color reg */
+	outb_p(color, 0x3c0);	/* load color value */ 
+	outb_p(0x20, 0x3c0);	/* allow display memory */
+	spin_unlock_irqrestore(&vga_lock, flags);
+}
+
 static int vgacon_switch(struct vc_data *c)
 {
 	/*
@@ -1042,6 +1059,7 @@
 	con_scroll:		vgacon_scroll,
 	con_bmove:		DUMMY,
 	con_switch:		vgacon_switch,
+	con_border:		vgacon_border,
 	con_blank:		vgacon_blank,
 	con_font_op:		vgacon_font_op,
 	con_set_palette:	vgacon_set_palette,
char/console_macros.h renamed from linux/drivers/char/console_macros.h +1 -0
@@ -41,6 +41,7 @@
 #define color		(vc_cons[currcons].d->vc_color)
 #define s_color		(vc_cons[currcons].d->vc_s_color)
 #define def_color	(vc_cons[currcons].d->vc_def_color)
+#define border		(vc_cons[currcons].d->vc_border)
 #define foreground	(color & 0x0f)
 #define background	(color & 0xf0)
 #define charset		(vc_cons[currcons].d->vc_charset)

-----------------8<---------------8<-----------8<------------------- /*
* set VGA border colour.
*
* 0 -> 7 are blk, blu, grn, cyn, red, mag, yel, wht.
* 8 -> 15 are brighter versions (bright version of blk = grey). *
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <asm/io.h>

/* #include <linux/kd.h> */
#define PIO_BORDER 0x4B73
#define GIO_BORDER 0x4B74

int main(int argc, char** argv)

{
	unsigned char colour, oldcolour;
	int i;

	if (argc != 2) {
		fprintf(stderr,"Usage %s <colour_number>\n", argv[0]);
		exit(EINVAL);
	}

	colour = atoi(argv[1]) & 0xf;
	
	i = ioctl(0, GIO_BORDER, &oldcolour);
	if (i != 0) {
		perror("ioctl(GIO_BORDER)");
		exit(errno);
	}
	printf("Old colour was %d\n", oldcolour);

	i = ioctl(0, PIO_BORDER, &colour);
	if (i != 0) {
		perror("ioctl(PIO_BORDER)");
		exit(errno);
	}

	return 0;
}