GoboLinux Downloads Documentation Community Recipes Screenshots

GoboLinux Recipe & Package Search Tool

71 versions of Linux.

ProgramAgeSizeByWWWSummary
Linux 4.13.2-r1 879  88794 Luca...
The Linux Kernel.
Linux 4.9.16-r3 1050  100651 Luca...
The Linux Kernel.
Linux 4.9.4-r5 1106  99374 Luca...
The Linux Kernel.
Linux 4.8.2-r2 1172  89394 Luca...
The Linux Kernel.
Linux 4.7.4-r1 1242  82767 Luca...
The Linux Kernel.
Linux 4.7.0-r4 1297  82585 Luca...
The Linux Kernel.
Linux 3.13.3-r1 2177  252629 Luca...
The Linux Kernel.
Linux 3.12.6-r1 2237  238949 Luca...
The Linux Kernel.
Linux 3.9.4-r2 2432  70048 Luca...
The Linux Kernel.
Linux 3.7.1-r2 2605  67579 Luca...
The Linux Kernel.
Linux 3.5.0-r1 2756  124391 Luca...
The Linux Kernel.
Linux 3.4.4-r1 2756  124348 Luca...
The Linux Kernel.
Linux 3.3.6-r1 2756  124410 Luca...
The Linux Kernel.
Linux 3.2.12-r2 2884  124345 Luca...
The Linux Kernel.
Linux 3.2.7-r1 2914  123550 Mich...
The Linux Kernel.
Linux 3.1.1-r1 3019  122907 Mich...
The Linux Kernel.
Linux 3.0.4-r4 3080  122754 Luca...
The Linux Kernel.
Linux 2.6.36.3-r1 3303  116087 Diog...
The Linux Kernel.
Linux 2.6.32.3-r1 3681  117990 Luca...
The Linux Kernel.
Linux 2.6.32-r1 3722  117751 Luca...
The Linux Kernel.
Linux 2.6.31.6-r3 3727  126499 Luca...
The Linux Kernel.
Linux 2.6.30.5-r1 3806  166102 Jona...
The Linux Kernel.
Linux 2.6.29.1-r1 3949  117500 Luca...
The Linux Kernel.
Linux 2.6.28.7-r1 4005  115518 Giam...
The Linux Kernel.
Linux 2.6.28.1-r1 4005  115487 Giam...
The Linux Kernel.
Linux 2.6.28-r1 4005  116681 Mich...
The Linux Kernel.
Linux 2.6.27.8-r1 4005  134160 Giam...
The Linux Kernel.
Linux 2.6.27.4-r3 4005  149529 Luca...
The Linux Kernel.
Linux 2.6.25.17-r1 4005  172834 Giam...
The Linux Kernel.
Linux 2.6.25.16-r1 4005  166500 Giam...
The Linux Kernel.
Linux 2.6.25.10-r2 4005  165320 Giam...
The Linux Kernel.
Linux 2.6.25.7-r1 4005  157294 Giam...
The Linux Kernel.
Linux 2.6.25.4-r1 4005  133017 Hopp...
The Linux Kernel.
Linux 2.6.25-r1 4005  133216 Luca...
The Linux Kernel.
Linux 2.6.24.4-r5 4005  150733
The Linux Kernel.
Linux 2.6.24.3-r5 4005  150221 Luca...
The Linux Kernel.
Linux 2.6.24.2-r3 4005  146488 Giam...
The Linux Kernel.
Linux 2.6.24.1-r1 4005  146454 Giam...
The Linux Kernel.
Linux 2.6.24-r1 4005  146428 Luca...
The Linux Kernel.
Linux 2.6.23.8-r4 4005  155842 Luca...
The Linux Kernel.
Linux 2.6.22.7-r4 4005  114727 Luca...
The Linux Kernel.
Linux 2.6.22.1-r1 4005  121391 Luca...
The Linux Kernel.
Linux 2.6.21.1-r3 4005  118854 Luca...
The Linux Kernel.
Linux 2.6.20.7-r1 4005  117945 Luca...
The Linux Kernel.
Linux 2.6.20.4-r3 4005  151150 Luca...
The Linux Kernel.
view entry at GitHub | download recipe.bz2 file
01-gobohide.patch
02-unionfs-2.6.21-rc5-u1.patch
03-squashfs-3.2-r2.patch
04-vesafb-tng-1.0-rc2-2.6.20-rc2.patch
05-utf8-input-backspace.patch
06-utf8-input-kbdmode.patch
07-utf8-keyboard-capslock.patch
08-utf8-output-keep-columns-and-print-replacement-character.patch
09-utf8-output.patch
10-utf8-selection.patch
Recipe
Resources/BuildInformation
Resources/Dependencies
Resources/Description
Resources/NewDependencies
i686/Recipe
i686/dot-config
ppc/Recipe
ppc/dot-config
diff -Naur linux-2.6.20.orig/drivers/char/consolemap.c linux-2.6.20/drivers/char/consolemap.c
--- linux-2.6.20.orig/drivers/char/consolemap.c	2007-02-04 19:44:54.000000000 +0100
+++ linux-2.6.20/drivers/char/consolemap.c	2007-04-04 16:14:49.000000000 +0200
@@ -629,8 +629,10 @@
 		ucs = 0xfffd;		/* U+FFFD: REPLACEMENT CHARACTER */
 	else if (ucs < 0x20 || ucs >= 0xfffe)
 		return -1;		/* Not a printable character */
-	else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f))
-		return -2;			/* Zero-width space */
+//	These are handled in vt.c since their wcwidth() is 0,
+//	except for 0x200a which shouldn't be handled here originally.
+//	else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f))
+//		return -2;			/* Zero-width space */
 	/*
 	 * UNI_DIRECT_BASE indicates the start of the region in the User Zone
 	 * which always has a 1:1 mapping to the currently loaded font.  The
diff -Naur linux-2.6.20.orig/drivers/char/vt.c linux-2.6.20/drivers/char/vt.c
--- linux-2.6.20.orig/drivers/char/vt.c	2007-02-04 19:44:54.000000000 +0100
+++ linux-2.6.20/drivers/char/vt.c	2007-04-04 20:05:35.000000000 +0200
@@ -1934,6 +1934,311 @@
 char con_buf[CON_BUF_SIZE];
 DECLARE_MUTEX(con_buf_sem);
 
+/* Emulate the return values of wcwidth() of glibc 2.3.5 with an UTF-8 locale,
+   but return 1 instead of -1 for unknown characters.
+ */
+static int wcwidth(int ucs) {
+	if (ucs <= 0x0000) return 0;
+	if (ucs <= 0x02FF) return 1;
+	if (ucs <= 0x034F) return 0;
+	if (ucs <= 0x035F) return 1;
+	if (ucs <= 0x036F) return 0;
+	if (ucs <= 0x0482) return 1;
+	if (ucs <= 0x0486) return 0;
+	if (ucs <= 0x0487) return 1;
+	if (ucs <= 0x0489) return 0;
+	if (ucs <= 0x0590) return 1;
+	if (ucs <= 0x05A1) return 0;
+	if (ucs <= 0x05A2) return 1;
+	if (ucs <= 0x05B9) return 0;
+	if (ucs <= 0x05BA) return 1;
+	if (ucs <= 0x05BD) return 0;
+	if (ucs <= 0x05BE) return 1;
+	if (ucs <= 0x05BF) return 0;
+	if (ucs <= 0x05C0) return 1;
+	if (ucs <= 0x05C2) return 0;
+	if (ucs <= 0x05C3) return 1;
+	if (ucs <= 0x05C4) return 0;
+	if (ucs <= 0x064A) return 1;
+	if (ucs <= 0x0655) return 0;
+	if (ucs <= 0x066F) return 1;
+	if (ucs <= 0x0670) return 0;
+	if (ucs <= 0x06D5) return 1;
+	if (ucs <= 0x06E4) return 0;
+	if (ucs <= 0x06E6) return 1;
+	if (ucs <= 0x06E8) return 0;
+	if (ucs <= 0x06E9) return 1;
+	if (ucs <= 0x06ED) return 0;
+	if (ucs <= 0x070E) return 1;
+	if (ucs <= 0x070F) return 0;
+	if (ucs <= 0x0710) return 1;
+	if (ucs <= 0x0711) return 0;
+	if (ucs <= 0x072F) return 1;
+	if (ucs <= 0x074A) return 0;
+	if (ucs <= 0x07A5) return 1;
+	if (ucs <= 0x07B0) return 0;
+	if (ucs <= 0x0900) return 1;
+	if (ucs <= 0x0902) return 0;
+	if (ucs <= 0x093B) return 1;
+	if (ucs <= 0x093C) return 0;
+	if (ucs <= 0x0940) return 1;
+	if (ucs <= 0x0948) return 0;
+	if (ucs <= 0x094C) return 1;
+	if (ucs <= 0x094D) return 0;
+	if (ucs <= 0x0950) return 1;
+	if (ucs <= 0x0954) return 0;
+	if (ucs <= 0x0961) return 1;
+	if (ucs <= 0x0963) return 0;
+	if (ucs <= 0x0980) return 1;
+	if (ucs <= 0x0981) return 0;
+	if (ucs <= 0x09BB) return 1;
+	if (ucs <= 0x09BC) return 0;
+	if (ucs <= 0x09C0) return 1;
+	if (ucs <= 0x09C4) return 0;
+	if (ucs <= 0x09CC) return 1;
+	if (ucs <= 0x09CD) return 0;
+	if (ucs <= 0x09E1) return 1;
+	if (ucs <= 0x09E3) return 0;
+	if (ucs <= 0x0A01) return 1;
+	if (ucs <= 0x0A02) return 0;
+	if (ucs <= 0x0A3B) return 1;
+	if (ucs <= 0x0A3C) return 0;
+	if (ucs <= 0x0A40) return 1;
+	if (ucs <= 0x0A42) return 0;
+	if (ucs <= 0x0A46) return 1;
+	if (ucs <= 0x0A48) return 0;
+	if (ucs <= 0x0A4A) return 1;
+	if (ucs <= 0x0A4D) return 0;
+	if (ucs <= 0x0A6F) return 1;
+	if (ucs <= 0x0A71) return 0;
+	if (ucs <= 0x0A80) return 1;
+	if (ucs <= 0x0A82) return 0;
+	if (ucs <= 0x0ABB) return 1;
+	if (ucs <= 0x0ABC) return 0;
+	if (ucs <= 0x0AC0) return 1;
+	if (ucs <= 0x0AC5) return 0;
+	if (ucs <= 0x0AC6) return 1;
+	if (ucs <= 0x0AC8) return 0;
+	if (ucs <= 0x0ACC) return 1;
+	if (ucs <= 0x0ACD) return 0;
+	if (ucs <= 0x0B00) return 1;
+	if (ucs <= 0x0B01) return 0;
+	if (ucs <= 0x0B3B) return 1;
+	if (ucs <= 0x0B3C) return 0;
+	if (ucs <= 0x0B3E) return 1;
+	if (ucs <= 0x0B3F) return 0;
+	if (ucs <= 0x0B40) return 1;
+	if (ucs <= 0x0B43) return 0;
+	if (ucs <= 0x0B4C) return 1;
+	if (ucs <= 0x0B4D) return 0;
+	if (ucs <= 0x0B55) return 1;
+	if (ucs <= 0x0B56) return 0;
+	if (ucs <= 0x0B81) return 1;
+	if (ucs <= 0x0B82) return 0;
+	if (ucs <= 0x0BBF) return 1;
+	if (ucs <= 0x0BC0) return 0;
+	if (ucs <= 0x0BCC) return 1;
+	if (ucs <= 0x0BCD) return 0;
+	if (ucs <= 0x0C3D) return 1;
+	if (ucs <= 0x0C40) return 0;
+	if (ucs <= 0x0C45) return 1;
+	if (ucs <= 0x0C48) return 0;
+	if (ucs <= 0x0C49) return 1;
+	if (ucs <= 0x0C4D) return 0;
+	if (ucs <= 0x0C54) return 1;
+	if (ucs <= 0x0C56) return 0;
+	if (ucs <= 0x0CBE) return 1;
+	if (ucs <= 0x0CBF) return 0;
+	if (ucs <= 0x0CC5) return 1;
+	if (ucs <= 0x0CC6) return 0;
+	if (ucs <= 0x0CCB) return 1;
+	if (ucs <= 0x0CCD) return 0;
+	if (ucs <= 0x0D40) return 1;
+	if (ucs <= 0x0D43) return 0;
+	if (ucs <= 0x0D4C) return 1;
+	if (ucs <= 0x0D4D) return 0;
+	if (ucs <= 0x0DC9) return 1;
+	if (ucs <= 0x0DCA) return 0;
+	if (ucs <= 0x0DD1) return 1;
+	if (ucs <= 0x0DD4) return 0;
+	if (ucs <= 0x0DD5) return 1;
+	if (ucs <= 0x0DD6) return 0;
+	if (ucs <= 0x0E30) return 1;
+	if (ucs <= 0x0E31) return 0;
+	if (ucs <= 0x0E33) return 1;
+	if (ucs <= 0x0E3A) return 0;
+	if (ucs <= 0x0E46) return 1;
+	if (ucs <= 0x0E4E) return 0;
+	if (ucs <= 0x0EB0) return 1;
+	if (ucs <= 0x0EB1) return 0;
+	if (ucs <= 0x0EB3) return 1;
+	if (ucs <= 0x0EB9) return 0;
+	if (ucs <= 0x0EBA) return 1;
+	if (ucs <= 0x0EBC) return 0;
+	if (ucs <= 0x0EC7) return 1;
+	if (ucs <= 0x0ECD) return 0;
+	if (ucs <= 0x0F17) return 1;
+	if (ucs <= 0x0F19) return 0;
+	if (ucs <= 0x0F34) return 1;
+	if (ucs <= 0x0F35) return 0;
+	if (ucs <= 0x0F36) return 1;
+	if (ucs <= 0x0F37) return 0;
+	if (ucs <= 0x0F38) return 1;
+	if (ucs <= 0x0F39) return 0;
+	if (ucs <= 0x0F70) return 1;
+	if (ucs <= 0x0F7E) return 0;
+	if (ucs <= 0x0F7F) return 1;
+	if (ucs <= 0x0F84) return 0;
+	if (ucs <= 0x0F85) return 1;
+	if (ucs <= 0x0F87) return 0;
+	if (ucs <= 0x0F8F) return 1;
+	if (ucs <= 0x0F97) return 0;
+	if (ucs <= 0x0F98) return 1;
+	if (ucs <= 0x0FBC) return 0;
+	if (ucs <= 0x0FC5) return 1;
+	if (ucs <= 0x0FC6) return 0;
+	if (ucs <= 0x102C) return 1;
+	if (ucs <= 0x1030) return 0;
+	if (ucs <= 0x1031) return 1;
+	if (ucs <= 0x1032) return 0;
+	if (ucs <= 0x1035) return 1;
+	if (ucs <= 0x1037) return 0;
+	if (ucs <= 0x1038) return 1;
+	if (ucs <= 0x1039) return 0;
+	if (ucs <= 0x1057) return 1;
+	if (ucs <= 0x1059) return 0;
+	if (ucs <= 0x10FF) return 1;
+	if (ucs <= 0x1159) return 2;
+	if (ucs <= 0x115E) return 1;
+	if (ucs <= 0x115F) return 2;
+	if (ucs <= 0x11A2) return 0;
+	if (ucs <= 0x11A7) return 1;
+	if (ucs <= 0x11F9) return 0;
+	if (ucs <= 0x1711) return 1;
+	if (ucs <= 0x1714) return 0;
+	if (ucs <= 0x1731) return 1;
+	if (ucs <= 0x1734) return 0;
+	if (ucs <= 0x1751) return 1;
+	if (ucs <= 0x1753) return 0;
+	if (ucs <= 0x1771) return 1;
+	if (ucs <= 0x1773) return 0;
+	if (ucs <= 0x17B6) return 1;
+	if (ucs <= 0x17BD) return 0;
+	if (ucs <= 0x17C5) return 1;
+	if (ucs <= 0x17C6) return 0;
+	if (ucs <= 0x17C8) return 1;
+	if (ucs <= 0x17D3) return 0;
+	if (ucs <= 0x180A) return 1;
+	if (ucs <= 0x180E) return 0;
+	if (ucs <= 0x18A8) return 1;
+	if (ucs <= 0x18A9) return 0;
+	if (ucs <= 0x200A) return 1;
+	if (ucs <= 0x200F) return 0;
+	if (ucs <= 0x2029) return 1;
+	if (ucs <= 0x202E) return 0;
+	if (ucs <= 0x205F) return 1;
+	if (ucs <= 0x2063) return 0;
+	if (ucs <= 0x2069) return 1;
+	if (ucs <= 0x206F) return 0;
+	if (ucs <= 0x20CF) return 1;
+	if (ucs <= 0x20EA) return 0;
+	if (ucs <= 0x2328) return 1;
+	if (ucs <= 0x232A) return 2;
+	if (ucs <= 0x2E7F) return 1;
+	if (ucs <= 0x2E99) return 2;
+	if (ucs <= 0x2E9A) return 1;
+	if (ucs <= 0x2EF3) return 2;
+	if (ucs <= 0x2EFF) return 1;
+	if (ucs <= 0x2FD5) return 2;
+	if (ucs <= 0x2FEF) return 1;
+	if (ucs <= 0x2FFB) return 2;
+	if (ucs <= 0x2FFF) return 1;
+	if (ucs <= 0x3029) return 2;
+	if (ucs <= 0x302F) return 0;
+	if (ucs <= 0x303E) return 2;
+	if (ucs <= 0x3040) return 1;
+	if (ucs <= 0x3096) return 2;
+	if (ucs <= 0x3098) return 1;
+	if (ucs <= 0x309A) return 0;
+	if (ucs <= 0x30FF) return 2;
+	if (ucs <= 0x3104) return 1;
+	if (ucs <= 0x312C) return 2;
+	if (ucs <= 0x3130) return 1;
+	if (ucs <= 0x318E) return 2;
+	if (ucs <= 0x318F) return 1;
+	if (ucs <= 0x31B7) return 2;
+	if (ucs <= 0x31EF) return 1;
+	if (ucs <= 0x321C) return 2;
+	if (ucs <= 0x321F) return 1;
+	if (ucs <= 0x3243) return 2;
+	if (ucs <= 0x3250) return 1;
+	if (ucs <= 0x327B) return 2;
+	if (ucs <= 0x327E) return 1;
+	if (ucs <= 0x32CB) return 2;
+	if (ucs <= 0x32CF) return 1;
+	if (ucs <= 0x32FE) return 2;
+	if (ucs <= 0x32FF) return 1;
+	if (ucs <= 0x3376) return 2;
+	if (ucs <= 0x337A) return 1;
+	if (ucs <= 0x33DD) return 2;
+	if (ucs <= 0x33DF) return 1;
+	if (ucs <= 0x33FE) return 2;
+	if (ucs <= 0x33FF) return 1;
+	if (ucs <= 0x4DB5) return 2;
+	if (ucs <= 0x4DFF) return 1;
+	if (ucs <= 0x9FA5) return 2;
+	if (ucs <= 0x9FFF) return 1;
+	if (ucs <= 0xA48C) return 2;
+	if (ucs <= 0xA48F) return 1;
+	if (ucs <= 0xA4C6) return 2;
+	if (ucs <= 0xABFF) return 1;
+	if (ucs <= 0xD7A3) return 2;
+	if (ucs <= 0xF8EF) return 1;
+	if (ucs <= 0xF8FF) return 0;
+	if (ucs <= 0xFA2D) return 2;
+	if (ucs <= 0xFA2F) return 1;
+	if (ucs <= 0xFA6A) return 2;
+	if (ucs <= 0xFB1D) return 1;
+	if (ucs <= 0xFB1E) return 0;
+	if (ucs <= 0xFDFF) return 1;
+	if (ucs <= 0xFE0F) return 0;
+	if (ucs <= 0xFE1F) return 1;
+	if (ucs <= 0xFE23) return 0;
+	if (ucs <= 0xFE2F) return 1;
+	if (ucs <= 0xFE46) return 2;
+	if (ucs <= 0xFE48) return 1;
+	if (ucs <= 0xFE52) return 2;
+	if (ucs <= 0xFE53) return 1;
+	if (ucs <= 0xFE66) return 2;
+	if (ucs <= 0xFE67) return 1;
+	if (ucs <= 0xFE6B) return 2;
+	if (ucs <= 0xFEFE) return 1;
+	if (ucs <= 0xFEFF) return 0;
+	if (ucs <= 0xFF00) return 1;
+	if (ucs <= 0xFF60) return 2;
+	if (ucs <= 0xFFDF) return 1;
+	if (ucs <= 0xFFE6) return 2;
+	if (ucs <= 0xFFF8) return 1;
+	if (ucs <= 0xFFFB) return 0;
+	if (ucs <= 0x1D166) return 1;
+	if (ucs <= 0x1D169) return 0;
+	if (ucs <= 0x1D172) return 1;
+	if (ucs <= 0x1D182) return 0;
+	if (ucs <= 0x1D184) return 1;
+	if (ucs <= 0x1D18B) return 0;
+	if (ucs <= 0x1D1A9) return 1;
+	if (ucs <= 0x1D1AD) return 0;
+	if (ucs <= 0x1FFFF) return 1;
+	if (ucs <= 0x2A6D6) return 2;
+	if (ucs <= 0x2F7FF) return 1;
+	if (ucs <= 0x2FA1D) return 2;
+	if (ucs <= 0xE0000) return 1;
+	if (ucs <= 0xE0001) return 0;
+	if (ucs <= 0xE001F) return 1;
+	if (ucs <= 0xE007F) return 0;
+	return 1;
+}
+
 /* acquires console_sem */
 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
@@ -1946,10 +2251,13 @@
 	}
 #endif
 
-	int c, tc, ok, n = 0, draw_x = -1;
+	int c, tc, tc2, ok, n = 0, draw_x = -1;
 	unsigned int currcons;
 	unsigned long draw_from = 0, draw_to = 0;
 	struct vc_data *vc;
+	unsigned char vc_attr;
+	int inverse;
+	int width;
 	u16 himask, charmask;
 	const unsigned char *orig_buf = NULL;
 	int orig_count;
@@ -2012,6 +2320,7 @@
 		buf++;
 		n++;
 		count--;
+		inverse = 0;
 
 		/* Do no translation at all in control states */
 		if (vc->vc_state != ESnormal) {
@@ -2021,18 +2330,32 @@
 		    /* Malformed sequences as sequences of replacement glyphs */
 rescan_last_byte:
 		    if(c > 0x7f) {
-			if (vc->vc_utf_count) {
-			       if ((c & 0xc0) == 0x80) {
+			if ((c & 0xc0) == 0x80) {
+			       if (vc->vc_utf_count) {
 				       vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
        				       if (--vc->vc_utf_count) {
 					       vc->vc_npar++;
 				   	       continue;
        				       }
 				       tc = c = vc->vc_utf_char;
+				       if (vc->vc_utf_char <= 0x0000007f ||
+					  (vc->vc_utf_char >= 0x00000080 && vc->vc_utf_char <= 0x000007ff && vc->vc_npar \
!= 0) ||
+					  (vc->vc_utf_char >= 0x00000800 && vc->vc_utf_char <= 0x0000ffff && vc->vc_npar \
!= 1) ||
+					  (vc->vc_utf_char >= 0x00010000 && vc->vc_utf_char <= 0x001fffff && vc->vc_npar \
!= 2) ||
+					  (vc->vc_utf_char >= 0x00200000 && vc->vc_utf_char <= 0x03ffffff && vc->vc_npar \
!= 3) ||
+					  (vc->vc_utf_char >= 0x04000000 && vc->vc_utf_char <= 0x7fffffff && vc->vc_npar \
!= 4) ||
+					  vc->vc_utf_char > 0x7fffffff) {
+					       /* Overlong sequence caught */
+					       vc->vc_utf_count = 0;
+					       goto replacement_glyph;
+				       }
 			       } else
 				       goto replacement_glyph;
 			} else {
 				vc->vc_npar = 0;
+				if (vc->vc_utf_count) {
+				    goto replacement_glyph;
+				}
 				if ((c & 0xe0) == 0xc0) {
 				    vc->vc_utf_count = 1;
 				    vc->vc_utf_char = (c & 0x1f);
@@ -2053,6 +2376,7 @@
 				continue;
 			      }
 		    } else {
+		      vc->vc_npar = 0;
 		      if (vc->vc_utf_count)
 	  		      goto replacement_glyph;
 		      tc = c;
@@ -2061,6 +2385,11 @@
 		  tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c];
 		}
 
+		if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) {
+replacement_glyph:
+			tc = c = 0xfffd;
+		}
+
                 /* If the original code was a control character we
                  * only allow a glyph to be displayed if the code is
                  * not normally used (such as for cursor movement) or
@@ -2084,21 +2413,50 @@
 				if ( tc == -4 ) {
                                 /* If we got -4 (not found) then see if we have
                                    defined a replacement character (U+FFFD) */
-replacement_glyph:
-                                	tc = conv_uni_to_pc(vc, 0xfffd);
+				/* No! The replacement character denotes an
+				   invalid UTF-8 sequence, not a valid Unicode
+				   character missing from our font. Use a
+				   different symbol here, let's say, an
+				   inverse dot. The only exception is U+FFFD
+				   itself if it is not present in the font. */
+					inverse = 1;
+					tc = conv_uni_to_pc(vc, c == 0xfffd ? '?' : '.');
+					if (tc < 0) tc = (c == 0xfffd ? '?' : '.');
 					if (!(tc & ~charmask))
 						goto display_glyph;
                         	} else if ( tc != -3 )
                                 	continue; /* nothing to display */
                                 /* no hash table or no replacement --
 				 * hope for the best */
-				if ( c & ~charmask )
-					tc = '?';
-				else
-					tc = c;
+				inverse = 1;
+				tc = conv_uni_to_pc(vc, c == 0xfffd ? '?' : '.');
+				if (tc < 0) tc = (c == 0xfffd ? '?' : '.');
 			}
 
 display_glyph:
+			tc2 = tc;
+			/* Always print exactly as many character cells as
+			   wcwidth() tells. The first one is the character
+			   if it is found in the font, or an inverse question
+			   mark or inverse dot otherwise. Subsequent characters
+			   are spaces, keeping the previous normal or inverse
+			   state. */
+			width = wcwidth(c);
+			while (width--) {
+
+			if (!inverse) {
+				vc_attr = vc->vc_attr;
+			} else {
+				/* invert vc_attr, based on invert_screen() */
+				if (!vc->vc_can_do_color) {
+					vc_attr = (vc->vc_attr) ^ 0x08;
+				} else if (vc->vc_hi_font_mask == 0x100) {
+					vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) \
& 0x0e) << 4);
+				} else {
+					vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) \
& 0x07) << 4);
+				}
+			}
+
 			if (vc->vc_need_wrap || vc->vc_decim)
 				FLUSH
 			if (vc->vc_need_wrap) {
@@ -2108,8 +2466,8 @@
 			if (vc->vc_decim)
 				insert_char(vc, 1);
 			scr_writew(himask ?
-				     ((vc->vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) \
:
-				     (vc->vc_attr << 8) + tc,
+				     ((vc_attr << 8) & ~himask) + ((tc2 & 0x100) ? himask : 0) + (tc2 & 0xff) \
:
+				     (vc_attr << 8) + tc2,
 				   (u16 *) vc->vc_pos);
 			if (DO_UPDATE(vc) && draw_x < 0) {
 				draw_x = vc->vc_x;
@@ -2122,6 +2480,12 @@
 				vc->vc_x++;
 				draw_to = (vc->vc_pos += 2);
 			}
+
+			tc2 = conv_uni_to_pc(vc, ' '); /* print a space in the 2nd column */
+			if (tc2 < 0) tc = ' ';
+
+			} /* while (width--) */
+
 			if (vc->vc_utf_count) {
 				if (vc->vc_npar) {
 					vc->vc_npar--;
@@ -2129,6 +2493,7 @@
 				}
 				vc->vc_utf_count = 0;
 				c = orig;
+				inverse = 0;
 				goto rescan_last_byte;
 			}
 			continue;
diff -Naur linux-2.6.20.orig/drivers/char/_wcwidth.c linux-2.6.20/drivers/char/_wcwidth.c
--- linux-2.6.20.orig/drivers/char/_wcwidth.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20/drivers/char/_wcwidth.c	2007-04-04 16:15:29.000000000 +0200
@@ -0,0 +1,26 @@
+/* This utility was used to generate the kernel unicode wcwidth patch */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <wchar.h>
+#include <locale.h>
+
+int main (int argc, char *argv[])
+{
+	int i;
+	int w, prevw;
+	setlocale(LC_ALL, "en_US.UTF-8");
+	w = wcwidth(0);
+	printf("static int wcwidth(int ucs) {\n");
+	for (i = 1; i <= 0x1fffff; i++) {
+		prevw = w;
+		w = wcwidth(i);
+		if (w == -1) w = 1;
+		if (w != prevw) {
+			printf("\tif (ucs <= 0x%04X) return %d;\n", i-1, prevw);
+		}
+	}
+	printf("\treturn %d;\n", w);
+	printf("}\n");
+	return 0;
+}
Linux 2.6.20-r1 4005  106429 Luca...
The Linux Kernel.
Linux 2.6.18.3-r2 4005  111124 Luca...
The Linux Kernel.
Linux 2.6.17.11-r1 4005  164053 Luca...
The Linux Kernel.
Linux 2.6.17.3-r1 4005  165067 Luca...
The Linux Kernel.
Linux 2.6.16.20-r1 4005  133625 Luca...
The Linux Kernel.
Linux 2.6.16.14-r1 4005  168270 Luca...
The Linux Kernel.
Linux 2.6.15.5-r1 4005  224686 Jona...
The Linux Kernel.
Linux 2.6.15.2-r1 4005  177165 Carl...
The Linux Kernel.
Linux 2.6.15.1-r1 4005  149219 Jona...
The Linux Kernel.
Linux 2.6.15-r1 4005  149214 Luca...
The Linux Kernel.
Linux 2.6.14.4-r1 4005  150166 Jona...
The Linux Kernel.
Linux 2.6.14.3-r1 4005  150060 Jona...
The Linux Kernel.
Linux 2.6.14.2-r1 4005  149791 Carl...
The Linux Kernel.
Linux 2.6.13.4-r1 4005  149559 Luca...
The Linux Kernel.
Linux 2.6.13.2-r1 4005  56611 Jona...
The Linux Kernel.
Linux 2.6.13.1-r1 4005  56378 Luca...
The Linux Kernel.
Linux 2.6.12.2-r1 4005  50355 Luca...
The Linux Kernel.
Linux 2.6.11.9-r1 4005  98969 Luca...
The Linux Kernel.
Linux 2.6.11.8-r1 4005  109424 Jona...
The Linux Kernel.
Linux 2.6.11-r1 4005  99032 Luca...
The Linux Kernel.
Linux 2.6.10-r1 4005  65969 Luca...
The Linux Kernel.
Linux 2.6.9-r1 4005  278461 Luca...
The Linux Kernel.
Linux 2.6.8.1-r1 4005  35576 Luca...
The Linux Kernel.
Linux 2.6.7-r1 4005  22610 Luca...
The Linux Kernel.
Linux 2.6.6-r1 4005  21958 Luca...
The Linux Kernel.
Linux 2.4.26-r1 4005  22359 Luca...
The Linux Kernel.