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

Re: [MiNT] Patch: Deadkey support



Vincent Rivière skreiv:
Jo Even Skarstein wrote:
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.

You forgot the "r" in the options, for "recursive".

Is this necessary when all the touched files are in the same directory?

But as your tree contain CVS dirs (used for internal CVS machinery), they must be excluded.

So your diff command line should be:
diff -aurN -x CVS olddir newdir

Ok, tried again.

1. 'make distclean' on the modified tree (to get rid of object-files and executables).
2. cd to the parent directory of these two trees.
3. 'diff -aurN -x CVS -x tools freemint.cvs freemint > deadkeys.patch'
'freemint.cvs' is identical to my last CVS checkout. 'freemint' is a copy of 'freemint.cvs' with my modified sources.

Let's hope that it's OK this time. I obviously has a lot to learn.

I hope I will be able to use the deadkeys on my French keyboard :-)
There are only 2 deadkeys: ^ and ¨
¨ is actually obtained with Shift+^
Will this work ?

Yes. The deadkeys works with ASCII-codes, not scan-codes. So if you need to type 'ö' you first press '¨' (using whatever key combo you need) followed by 'o'. However, you must first specify this in the keytable file.

Did you update KeyEdit for the new deadkey table ?

Not yet, but I will if the patch is accepted.

Jo Even
diff -aurN -x CVS -x tools freemint.cvs/sys/key_tables.h freemint/sys/key_tables.h
--- freemint.cvs/sys/key_tables.h	Sun Jul 25 04:35:44 2004
+++ freemint/sys/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 -aurN -x CVS -x tools freemint.cvs/sys/keyboard.c freemint/sys/keyboard.c
--- freemint.cvs/sys/keyboard.c	Fri Jul 13 23:32:48 2007
+++ freemint/sys/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 -aurN -x CVS -x tools freemint.cvs/sys/keyboard.h freemint/sys/keyboard.h
--- freemint.cvs/sys/keyboard.h	Fri Jul 13 23:32:48 2007
+++ freemint/sys/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