[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] Patch: Deadkey support



Ok, this is the first time I submit any kind of patches to this list, so maintainers - please bear with me ;-)

First of all, I'm not sure how well tested things must be before submitted. I have been using this for about a week with no problems. It works when no keyboard tables are loaded, when keyboard tables with no deadkeys are loaded and when tables with deadkeys are loaded.

Also, I'm still not sure about how my coding style fits, but I tried to adapt to the style used by Draco and Ozk.

And finally, I know almost nothing about diff. I used the guide Vincent posted about a week ago, but I see that there are some absolute paths in the patch that perhaps shouldn't be there.

CVS entry:

Added support for deadkeys. Two keystrokes can be combined to produce an accented character, depending on the loaded keyboard table. The keyboard table file format is extended with a NULL-terminated 'deadkey'-table. This extended table can still be built with mktbl.


Jo Even

Common subdirectories: /e/Prosjekt/freemint.cvs/sys/.compile_mil and ./.compile_mil
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/CVS and ./CVS
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/adi and ./adi
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/arch and ./arch
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/buildinfo and ./buildinfo
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/gen-syscall and ./gen-syscall
diff -auN /e/Prosjekt/freemint.cvs/sys/key_tables.h ./key_tables.h
--- /e/Prosjekt/freemint.cvs/sys/key_tables.h	Sun Jul 25 04:35:44 2004
+++ ./key_tables.h	Tue Dec 15 21:09:34 2009
@@ -115,6 +115,9 @@
 	0x00,
 
 /* Alternate Gr */
+	0x00,
+
+/* Deadkeys */
 	0x00
 };
 
@@ -128,7 +131,8 @@
 	(uchar *)usa_kbd + 384,
 	(uchar *)usa_kbd + 385,
 	(uchar *)usa_kbd + 386,
-	(uchar *)usa_kbd + 387
+	(uchar *)usa_kbd + 387,
+	(uchar *)usa_kbd + 388
 };
 
 # endif
diff -auN /e/Prosjekt/freemint.cvs/sys/keyboard.c ./keyboard.c
--- /e/Prosjekt/freemint.cvs/sys/keyboard.c	Fri Jul 13 23:32:48 2007
+++ ./keyboard.c	Tue Dec 15 22:21:20 2009
@@ -33,12 +33,20 @@
  * - Ozk: 4 June 2005.
  *        Moved handling of keyboard delay/repeat from VBL interrupt to
  *        roottimeouts.
+ * - joska: 15 December 2009.
+ *        Added handling of deadkeys.
  *
  * UNRESOLVED:
  * - Ozk: Since we cannot completely take over the keyboard interrupt when
  *   running on Milan hardware, and that Milan TOS calls ikbdsys vector
  *   for each repeated key, we cannot control those things by ourselves.
  *   So, we need to pass calls to Kbrate() to the ROM.
+ * - joska: I'm not 100% sure what Ozk really means here. Milan TOS does
+ *   not call anything when a key is repeated - the PS/2 keyboard handles
+ *   key repeat itself so the Milan actually doesn't know the difference
+ *   between a normal keypress and a repeated one. On Milan, Kbrate() informs
+ *   the keyboard of the new repeat-rate. I don't see any need to change
+ *   this.
  *
  */
 
@@ -144,7 +152,6 @@
 short	kbd_pc_style_caps = 0;	/* PC-style vs. Atari-style for Caps operation */
 short	kbd_mpixels = 8;	/* mouse pixel steps */
 short	kbd_mpixels_fine = 1;	/* mouse pixel steps in 'fine' mode */
-short	kbd_deadkey = -1;	/* ASCII code for deadkey */
 struct	cad_def cad[3];		/* for halt, warm and cold resp. */
 #define MAKES_BLEN	16
 static char makes[MAKES_BLEN + 1 * 2];
@@ -153,7 +160,6 @@
 static	short cad_lock;		/* semaphore to avoid scheduling shutdown() twice */
 static	short kbd_lock;		/* semaphore to temporarily block the keyboard processing */
 static	long hz_ticks;		/* place for saving the hz_200 timer value */
-//static	short dead_lock;	/* flag for deakdey processing */
 
 /* Alt/numpad */
 static	uchar numin[8];		/* buffer for storing ASCII code typed in via numpad */
@@ -1267,8 +1273,70 @@
 		 */
 		if (make)
 		{
+			/* Deadkeys.
+			 * The deadkey table structure is as follows:
+			 * dd,bb,aa,dd,bb,aa,...,aa,bb,aa,0
+			 * Where dd is the deadkey character, aa is the base
+			 * character and aa the accented character.
+			 * So '^','a','?' means that '^' followed by 'a' results
+			 * in an '?'.
+			 */
+			uchar *vec = user_keytab->deadkeys;
 			ascii = scan2asc((uchar)scan);
-			put_key_into_buf(iorec, shift, (uchar)scan, 0, ascii);
+	
+			if (vec)
+			{
+				static unsigned int last_deadkey_scan = 0;
+				static uchar last_deadkey = 0;
+				uchar deadkey, base, accented = 0;
+				int is_deadkey = 0;
+
+				while (*vec)
+				{
+					deadkey = *vec++;
+					base = *vec++;
+					accented = *vec++;
+					
+					if (ascii == deadkey)
+					{
+						is_deadkey = 1;
+						accented = 0;
+						break;
+					}
+					
+					if (deadkey == last_deadkey && ascii == base)
+						break;
+					
+					accented = 0;
+				}
+				
+				if (last_deadkey)
+				{
+					if (accented)
+						put_key_into_buf(iorec, shift, (uchar)scan, 0, accented);
+					else
+					{
+						put_key_into_buf(iorec, shift, (uchar)last_deadkey_scan, 0, last_deadkey);
+
+						if (ascii && ascii != ' ' && ascii != '\t' && (ascii == last_deadkey ? 0:1))
+							put_key_into_buf(iorec, shift, (uchar)scan, 0, ascii);
+					}
+					
+					last_deadkey = 0;
+				}
+				else
+				{
+					if (is_deadkey)
+					{
+						last_deadkey = ascii;
+						last_deadkey_scan = scan;
+					}
+					else
+						put_key_into_buf(iorec, shift, (uchar)scan, 0, ascii);
+				}
+			}
+			else
+				put_key_into_buf(iorec, shift, (uchar)scan, 0, ascii);
 		}
 #ifndef MILAN
 		set_keyrepeat_timeout(make);
@@ -1445,6 +1513,9 @@
 	pointers->altcaps = tbl_scan_fwd(pointers->altshift);
 	pointers->altgr = tbl_scan_fwd(pointers->altcaps);
 
+	/* and the deadkeys */
+	pointers->deadkeys = tbl_scan_fwd(pointers->altgr);
+
 	/* Fix the _AKP cookie, gl_kbd may get changed in load_table().
 	 *
 	 * XXX must be changed for -DJAR_PRIVATE (forward to all processes).
@@ -1513,7 +1584,7 @@
 		return EFTYPE;
 	}
 
-	kbuf = kmalloc(size+1); /* Append a zero (if the table is missing the altgr part) */
+	kbuf = kmalloc(size+2); /* Append a zero (if the table is missing the altgr part) */
 	if (!kbuf)
 	{
 		DEBUG(("%s(): out of memory", __FUNCTION__));
@@ -1625,6 +1696,7 @@
 			size += strlen((char *)tos_keytab->altgr) + 1;
 		else
 			size += 2;
+		size += 2; /* For the empty deadkey table */
 	}
 	else
 		size += 16; /* a byte for each missing part plus a NUL plus some space */
@@ -1636,6 +1708,7 @@
 	size += strlen(tos_keytab->altshift) + 1;
 	size += strlen(tos_keytab->altcaps) + 1;
 	size += strlen(tos_keytab->altgr) + 1;
+	size += strlen(tos_keytab->deadkeys) + 1;
 
 	size += 8; /* add some space */
 # endif
@@ -1659,8 +1732,8 @@
 
 	assert(kbuf);
 
-
 	p = kbuf;
+	mint_bzero(p, size);
 
 	quickmove(p, tos_keytab->unshift, 128);
 	p += 128;
@@ -1713,6 +1786,10 @@
 
 	len = strlen((char *)tos_keytab->altgr) + 1;
 	quickmove(p, tos_keytab->altgr, len);
+	p += len;
+	
+	len = strlen((char *)tos_keytab->deadkeys) + 1;
+	quickmove(p, tos_keytab->deadkeys, len);
 
 	gl_kbd = default_akp;
 # endif
diff -auN /e/Prosjekt/freemint.cvs/sys/keyboard.h ./keyboard.h
--- /e/Prosjekt/freemint.cvs/sys/keyboard.h	Fri Jul 13 23:32:48 2007
+++ ./keyboard.h	Tue Dec 15 20:36:12 2009
@@ -86,6 +86,7 @@
 	uchar *altshift;	/* TOS 4.0x and above */
 	uchar *altcaps;		/* TOS 4.0x and above */
 	uchar *altgr;		/* Milan TOS */
+	uchar *deadkeys;	/* FreeMiNT 1.17 */
 };
 
 /* Struct for the default action on C/A/D
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/libkern and ./libkern
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/mint and ./mint
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/misc and ./misc
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/sockets and ./sockets
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/sys and ./sys
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/tbl and ./tbl
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/xdd and ./xdd
Common subdirectories: /e/Prosjekt/freemint.cvs/sys/xfs and ./xfs