Fw: [hatari-devel] Hatari and keymap

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


 Hi JM Vic!

I just noticed that you've sent this mail only to me ... Please
always send patches to the list, and not individual developers. I'm
forwarding it to hatari-devel in case Nicolas or Eero or somebody
else want to have a look at the patch... 

Some things I noticed after having a quick look:

+# Syntaxe : <SDL Key>[-<SDL Key Mod>],<ST Scancode>[-<ST Scancode>[...]]

"Syntax" is written with "e" in english ... and what about that "@"
character that you use in your examples? You don't mention it in the
description there?

+#define MAX_KEYSYM_VALUE 255

The keysyms are definitily not limited to 255 in SDL2, so that sounds
wrong.

+typedef struct s_STScanCodeList

Please no "s_" prefixes for structs (or "t_" prefixes for typedefs) -
we don't use that anywhere in the Hatari sources, so that looks odd.

+static t_ModList *addMod(t_ModList **ModList)
+{
+	t_ModList **iter = ModList;
+
+	for(;;)
+	{
+		if (*iter == NULL)
+		{
+			*iter = malloc(sizeof(t_ModList));
+			memset(*iter, 0, sizeof(t_ModList));
+			return *iter;
+		}
+		iter = &((*iter)->next);
+	}
+}

Maybe better:

static t_ModList *addMod(t_ModList **ModList)
{
	t_ModList **iter = ModList;

	while (*iter)
		iter = &(*iter)->next;

	*iter = malloc(sizeof(t_ModList));
	memset(*iter, 0, sizeof(t_ModList));

	return *iter;
}

.... that's less indentation and easier to read. Same idea can be
applied to addSTScanCode().

+static void cleanSTScanCodeList(t_STScanCodeList **stScancodeList)
+{
+	if (*stScancodeList == NULL)
+	{
+		return;
+	}
+	t_STScanCodeList *iter = *stScancodeList, *nextIter;
+	while (iter != NULL)
+	{
+		nextIter = iter->next;
+		free(iter);
+		iter = nextIter;
+	}
+	*stScancodeList = NULL;
+}

No need for the "if (*stScancodeList == NULL)" statement here ... that
should be handled by the "while (iter != NULL)" already. Same comment
applies to cleanModList(), too.

+	static t_STScanCodeList *_stScancodeList = 0;

Please don't use "_" as prefix for variables. We don't do that in the
Hatari source code.

 	/* Check for keypad first so we can handle numlock */
 	if (ConfigureParams.Keyboard.nKeymapType != KEYMAP_LOADED)
 	{
+		if (pKeySym == 0)
+		{
+			return -1;
+		}
....
+		STScanCode = Keymap_RemapKeyToSTScanCode(0);

Why can pKeySym be 0 now? ... this definitely needs some more comments.
Anyway, for NULL pointer checks, please use "NULL" and not "0".

-			if (szString[0] == ';' || szString[0] == '#')
+			if ( (szString[0]==';') || (szString[0]=='#') ) continue;

Please don't add unnecessary parentheses. And put the "continue" on a
new line.

All in all, I'm also still having a hard time to read your new code.
Maybe you could split it up logically in multiple patches? Or at least
refactor the parts with a lot of indentation into new functions?

 Thomas


Forwarded message:

Datum: Thu, 16 Apr 2020 15:57:42 +0200
Von: "jmvic@xxxxxxxxxxx" <jmvic@xxxxxxxxxxx>
An: Thomas Huth <th.huth@xxxxxxxxx>
Betreff: Re: [hatari-devel] Fwd: Fwd: Hatari and keymap


Hello,


Le 14/04/2020 à 06:22, Thomas Huth a écrit :
>  Hi!
> 
> Am Mon, 13 Apr 2020 12:02:28 +0200
> schrieb "jmvic@xxxxxxxxxxx" <jmvic@xxxxxxxxxxx>:
> [...]  
>> Now, with the patch, I can add in the keymap file this entry :
>>
>> **** BEGIN
>> # '{'
>> @33-0x200,0x2A-0x38-0x1A
>> **** END  
> 
> Your patch is hughe - you changed the indendation of "case" statements
> in lots of places. Please don't do that. Could you please resend your
> patch without changes to the indentation in that file, so that it
> clearer what you really changed?  

Of course.

>   
>> PS : checkkeys utility uses SDL (not SDL2)! But, Hatari uses SDL2!
>> Scancode & mod are differents between SDL & SDL2.  
> 
> Hatari can currently be compiled with both, SDL1 and SDL2.
> Please have a look at tests/keymap/makefile to see how to compile this
> tool for SDL2 instead.  

Sorry,
Indeed, in the makefile, there are these comments :

# SDL v1 build: "make SDL=sdl"
# SDL v2 build: "make SDL=sdl2"
By default => sdl
But when I compile hatari i guess sdl2 was chosen by default.

> 
>  Thomas
>   
diff --git a/doc/keymap-azerty-fr.txt b/doc/keymap-azerty-fr.txt
new file mode 100644
index 00000000..434a8572
--- /dev/null
+++ b/doc/keymap-azerty-fr.txt
@@ -0,0 +1,133 @@
+# This is an example for a keyboard mapping file that can be used in Hatari
+# by loading it from the keyboard setup dialog.
+#
+# Lines starting with a '#' or with a ';' are comments. All other lines
+# should contain exactly one key name and a scancode, separated by a comma.
+# Comment characters can be quoted with '\#' and '\;'.
+#
+# The key name is the libSDL symbolic name of the key, see the following
+# URL for a list: https://wiki.libsdl.org/SDL_Keycode
+# You can also use the symbolic keycode value instead of the name,
+# which you can get with the "--trace keymap" output from Hatari, for
+# example, but note that the values are different between SDL1 and SDL2
+# and thus they are not portable.
+#
+# The given host key will be mapped to the ST key which is specified by
+# second number - the ST scan code of the key.  "--trace keymap" output
+# shows the already mapped scan code.
+#
+# All numbers can be given as decimals or hexadecimals (with "0x" prefix).
+#
+# Syntaxe : <SDL Key>[-<SDL Key Mod>],<ST Scancode>[-<ST Scancode>[...]]
+#   <SDL Key>=<SDL Key Name> or <SDL Key SYMbole Code> or <SDL Key POSition/SCANCODE>
+#   Note:
+#     <ST Scancode> are playing in the given order; it's important!
+#     So, must be in first place, LShift(0x2A), LAlt(0x38), ...
+#
+# Scan codes for Atari keyboard key positions can be seen here:
+#   http://eerott.mbnet.fi/hatari/img/st-keymap.png
+#
+# tests/keymap/ directory contains programs to discover/test the PC SDL
+# and Atari scan code values.  Hatari's default PC key code -> ST scan
+# code mappings are in src/keymap.c source file.
+#
+# Example 1: If you want to get the 'y' and 'z' keys right with a german TOS
+# ROM, you can use the following two lines to map the PC keys to the right
+# ST scan codes:
+#Y,44
+#Z,21
+#
+# Example 2: Layout for Atari STF with AZERTY French Keyboard
+# 'q': @4=Position of key "q/Q" on an AZERTY French Keyboard
+#      => So, lower case letter "q" is targeted.
+#      30=ST Scancode of key "q/Q"
+@4,30
+# 'Q': @4=SDL Scancode; Position of key "q/Q" on an AZERTY French Keyboard
+#      -1=SDL Modifiers; Here, when LSHIFT is pressed
+#      => So, upper case letter "Q" is targeted.
+#      0x2A=ST Scancode of key LSHIFT
+#        30=ST Scancode of key "q/Q"
+@4-1,0x2A-30
+# ','
+@16,0x32
+# '?'
+@16-1,0x2A-0x32
+# 'a'
+@20,16
+# 'A'
+@20-1,0x2A-16
+# 'z'
+@26,17
+# 'Z'
+@26-1,0x2A-17
+# 'w'
+@29,44
+# 'W'
+@29-1,0x2A-44
+# '1'
+@30-1,0x2A-2
+# '2'
+@31-1,0x2A-3
+# '3'
+@32-1,0x2A-4
+# '#'
+@32-0x200,0x2B
+# '4'
+@33-1,0x2A-5
+# '{'
+@33-0x200,0x2A-0x38-0x1A
+# '5'
+@34-1,0x2A-6
+# '['
+@34-0x200,0x38-0x1A
+# '-'
+@35,13
+# '6'
+@35-1,0x2A-7
+# '|'
+@35-0x200,0x2A-0x2B
+# '7'
+@36-1,0x2A-8
+# '`'
+@36-0x200,0x29
+# '_'
+@37,0x2A-13
+# '8'
+@37-1,0x2A-9
+# '\'
+@37-0x200,0x38-0x28
+# '9'
+@38-1,0x2A-10
+# '^'
+@38-0x200,0x1A
+# '0'
+@39-1,0x2A-11
+# '@'
+@39-0x200,0x38-0x2B
+# '°'
+@45-1,0x2A-0x0C
+# ']'
+@45-0x200,0x38-0x1B
+# '='
+@46,0x35
+# '+'
+@46-1,0x2A-0x35
+# '}'
+@46-0x200,0x2A-0x38-0x1B
+# 'm'
+@51,0x27
+# 'M'
+@51-1,0x2A-0x27
+# 'ù'
+@52,0x28
+# '%'
+@52-1,0x2A-0x28
+# ";"
+@54,0x33
+# '.'
+@54-1,0x2A-0x33
+# '/'
+@55-1,0x2A-0x34
+# '>'
+@100-1,0x2A-0x60
+
diff --git a/src/keymap.c b/src/keymap.c
index 89833e17..0643f7f9 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -21,6 +21,104 @@ const char Keymap_fileid[] = "Hatari keymap.c : " __DATE__ " " __TIME__;
 #include "debugui.h"
 #include "log.h"
 
+#define MAX_KEYSYM_VALUE 255
+#define SIZEOF_KEYSYM_ARRAY (MAX_KEYSYM_VALUE + 1)
+#define SIZEOF_KEYPOS_ARRAY 256
+/* LoadedKeySym */
+typedef struct s_STScanCodeList
+{
+	char stScancode;
+	struct s_STScanCodeList *next;
+} t_STScanCodeList;
+
+typedef struct s_ModList
+{
+	int Mod;
+	struct s_STScanCodeList *stScancodeList;
+	struct s_ModList *next;
+} t_ModList;
+
+static t_ModList *findMod(t_ModList *ModList, int Mod)
+{
+	t_ModList *iter = ModList;
+	while (iter != NULL)
+	{
+		/* printf("iter->Mod=%d (expected %d)\n", iter->Mod, Mod); */
+		if (iter->Mod == Mod)
+		{
+			return iter;
+		}
+		iter = iter->next;
+	}
+	return NULL;
+}
+
+static t_ModList *addMod(t_ModList **ModList)
+{
+	t_ModList **iter = ModList;
+
+	for(;;)
+	{
+		if (*iter == NULL)
+		{
+			*iter = malloc(sizeof(t_ModList));
+			memset(*iter, 0, sizeof(t_ModList));
+			return *iter;
+		}
+		iter = &((*iter)->next);
+	}
+}
+
+static t_STScanCodeList *addSTScanCode(t_STScanCodeList **stScancodeList)
+{
+	t_STScanCodeList **iter = stScancodeList;
+
+	for(;;)
+	{
+		if (*iter == NULL)
+		{
+			*iter = malloc(sizeof(t_STScanCodeList));
+			memset(*iter, 0, sizeof(t_STScanCodeList));
+			return *iter;
+		}
+		iter = &((*iter)->next);
+	}
+}
+
+static void cleanSTScanCodeList(t_STScanCodeList **stScancodeList)
+{
+	if (*stScancodeList == NULL)
+	{
+		return;
+	}
+	t_STScanCodeList *iter = *stScancodeList, *nextIter;
+	while (iter != NULL)
+	{
+		nextIter = iter->next;
+		free(iter);
+		iter = nextIter;
+	}
+	*stScancodeList = NULL;
+}
+
+static void cleanModList(t_ModList **ModList)
+{
+	if (*ModList == NULL)
+	{
+		return;
+	}
+	t_ModList *iter = *ModList, *nextIter;
+	while (iter != NULL)
+	{
+		nextIter = iter->next;
+		cleanSTScanCodeList(&(iter->stScancodeList));
+		free(iter);
+		iter = nextIter;
+	}
+	*ModList = NULL;
+}
+
+
 
 #if !WITH_SDL2
 /* This table is used to translate a symbolic keycode to the (SDL) scancode */
@@ -28,7 +126,11 @@ static Uint8 SdlSymToSdlScan[SDLK_LAST];
 #endif
 
 /* Table for loaded keys: */
-static int LoadedKeymap[KBD_MAX_SCANCODE][2];
+/*
+  sdl.event.sym -> LoadedKeySym[sdl.event.sym] -> list(<sdl.event.mod, list(stscancode)>)
+*/
+static t_ModList *LoadedKeySym[SIZEOF_KEYSYM_ARRAY];
+static t_ModList *LoadedKeyPos[SIZEOF_KEYPOS_ARRAY];
 
 /* List of ST scan codes to NOT de-bounce when running in maximum speed */
 static const char DebounceExtendedKeys[] =
@@ -578,9 +680,14 @@ static char Keymap_GetKeyPadScanCode(SDL_keysym* pKeySym)
  */
 static char Keymap_RemapKeyToSTScanCode(SDL_keysym* pKeySym)
 {
+	static t_STScanCodeList *_stScancodeList = 0;
 	/* Check for keypad first so we can handle numlock */
 	if (ConfigureParams.Keyboard.nKeymapType != KEYMAP_LOADED)
 	{
+		if (pKeySym == 0)
+		{
+			return -1;
+		}
 		if (pKeySym->sym >= SDLK_KP1 && pKeySym->sym <= SDLK_KP9)
 		{
 			return Keymap_GetKeyPadScanCode(pKeySym);
@@ -590,21 +697,71 @@ static char Keymap_RemapKeyToSTScanCode(SDL_keysym* pKeySym)
 	/* Remap from PC scancodes? */
 	if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_SCANCODE)
 	{
+		if (pKeySym == 0)
+		{
+			return -1;
+		}
 		return Keymap_PcToStScanCode(pKeySym);
 	}
 
 	/* Use loaded keymap? */
 	if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_LOADED)
 	{
-		int i;
-		for (i = 0; i < KBD_MAX_SCANCODE && LoadedKeymap[i][1] != 0; i++)
+		if (pKeySym != 0)
 		{
-			if (pKeySym->sym == (SDLKey)LoadedKeymap[i][0])
-				return LoadedKeymap[i][1];
+			t_ModList *modList = NULL;
+			_stScancodeList = 0;
+			if (pKeySym->sym < SIZEOF_KEYSYM_ARRAY)
+			{
+				modList = LoadedKeySym[pKeySym->sym];
+			}
+			if (modList == NULL)
+			{
+				if (pKeySym->scancode < SIZEOF_KEYPOS_ARRAY)
+				{
+					modList = LoadedKeyPos[pKeySym->scancode];
+				}
+			}
+			if (modList != NULL)
+			{
+				Log_Printf(LOG_DEBUG, "1) Find for SDL.Sym=%d modList=%p\n", pKeySym->sym, (void *)modList);
+				modList = findMod(modList, pKeySym->mod & ~KMOD_NUM);
+				Log_Printf(LOG_DEBUG, "2) Find for SDL.Sym=%d SDL.mod=%d. modList=%p\n", pKeySym->sym, pKeySym->mod & ~KMOD_NUM, (void *)modList);
+				if (modList != NULL)
+				{
+					_stScancodeList = modList->stScancodeList;
+					if (_stScancodeList != NULL)
+					{
+						Log_Printf(LOG_DEBUG, "Find (1st) for SDL.Sym=%d stScancode=%d\n", pKeySym->sym, _stScancodeList->stScancode);
+						return _stScancodeList->stScancode;
+					}
+				}
+			}
+		}
+		else
+		{
+			/* printf("x2\n"); */
+			if (_stScancodeList == 0)
+			{
+				return -1;
+			}
+			/* printf("x3\n"); */
+			_stScancodeList = _stScancodeList->next;
+			/* printf("x4\n"); */
+			if (_stScancodeList == 0)
+			{
+				return -1;
+			}
+			Log_Printf(LOG_DEBUG, "Find (-) stScancode=%d\n", _stScancodeList->stScancode);
+			return _stScancodeList->stScancode;
 		}
 	}
-
+      
 	/* Use symbolic mapping */
+	if (pKeySym == 0)
+	{
+		return -1;
+	}
 	return Keymap_SymbolicToStScanCode(pKeySym);
 }
 
@@ -615,13 +772,43 @@ static char Keymap_RemapKeyToSTScanCode(SDL_keysym* pKeySym)
  */
 void Keymap_LoadRemapFile(char *pszFileName)
 {
+	static int _initialized = 0;
 	char szString[1024];
-	int STScanCode, PCKeyCode;
+	char szSTScanCode[1024];
+	char szPCKeyCode[1024];
+	int stScancode;
 	FILE *in;
-	int idx = 0;
+	int sdlPos = 0;
+	int sdlSym = 0;
+	int sdlMod = 0;
+	char *part = 0;
+	t_ModList *modList = 0;
+	t_STScanCodeList *iter = 0;
+	t_STScanCodeList **iter2 = 0;
 
 	/* Initialize table with default values */
-	memset(LoadedKeymap, 0, sizeof(LoadedKeymap));
+   
+	Log_Printf(LOG_DEBUG, "KBD_MAX_SCANCODE=%d\n", KBD_MAX_SCANCODE);
+	Log_Printf(LOG_DEBUG, "sizeof(LoadedKeySym)=%ld\n", sizeof(LoadedKeySym));
+	Log_Printf(LOG_DEBUG, "sizeof(LoadedKeySym[0])=%ld\n", sizeof(LoadedKeySym[0]));
+	if (_initialized)
+	{
+		int i = 0;
+		for (i = 0; i < SIZEOF_KEYSYM_ARRAY; i++)
+		{
+			cleanModList(&LoadedKeySym[i]);
+		}
+		for (i = 0; i < SIZEOF_KEYPOS_ARRAY; i++)
+		{
+			cleanModList(&LoadedKeyPos[i]);
+		}
+	}
+	else
+	{
+		memset(LoadedKeySym, 0, sizeof(LoadedKeySym));
+		memset(LoadedKeyPos, 0, sizeof(LoadedKeyPos));
+		_initialized = -1;
+	}
 
 	if (!*pszFileName)
 		return;
@@ -640,7 +827,7 @@ void Keymap_LoadRemapFile(char *pszFileName)
 		return;
 	}
 
-	while (!feof(in) && idx < KBD_MAX_SCANCODE)
+	while (!feof(in))
 	{
 		/* Read line from file */
 		if (fgets(szString, sizeof(szString), in) == NULL)
@@ -649,47 +836,117 @@ void Keymap_LoadRemapFile(char *pszFileName)
 		Str_Trim(szString);
 		if (strlen(szString)>0)
 		{
-			char *p;
+			int first_char_pos = 0;
 			/* Is a comment? */
-			if (szString[0] == ';' || szString[0] == '#')
+			if ( (szString[0]==';') || (szString[0]=='#') ) continue;
+			/* Read values */
+			if (szString[0]=='@')
+			{
+				first_char_pos=1;
+			}
+			part = strtok(&szString[first_char_pos], ",");
+			if (part == 0)
+			{
+				Log_Printf(LOG_WARN, "(1) This line is ignored: %s.\n", szString);
 				continue;
-			/* Cut out the values */
-			p = strtok(szString, ",");
-			if (!p)
+			}
+			strncpy(szPCKeyCode, part, sizeof(szPCKeyCode) - 1);
+			part = strtok(0, " ");
+			if (part == 0)
+			{
+				Log_Printf(LOG_WARN, "(2) This line is ignored: %s.\n", szString);
 				continue;
-			Str_Trim(szString);
-			PCKeyCode = atoi(szString);    /* Direct key code? */
-			if (PCKeyCode < 10)
+			}
+			strncpy(szSTScanCode, part, sizeof(szSTScanCode) - 1);
+			Log_Printf(LOG_DEBUG, "szPCKeyCode=%s szSTScanCode=%s\n", szPCKeyCode, szSTScanCode);
+
+			sdlMod = 0;
+			if (first_char_pos == 1)
 			{
-				/* If it's not a valid number >= 10, then
-				 * assume we've got a symbolic key name
-				 */
-				int offset = 0;
-				/* quoted character (e.g. comment line char)? */
-				if (*szString == '\\' && strlen(szString) == 2)
-					offset = 1;
-				PCKeyCode = Keymap_GetKeyFromName(szString+offset);
+				/* Part 1 (before ','): <SDL.evt.scancode>-<SDL.evt.mod> */
+				if (
+					(sscanf(szPCKeyCode, "%i-%i", &sdlPos, &sdlMod) != 2) && 
+					(sscanf(szPCKeyCode, "%i", &sdlPos) != 1)                ) 
+				{
+					Log_Printf(LOG_ERROR, "Bad syntaxe! This PCKeyCode can't be retrieved: '%s'", szPCKeyCode);
+					continue;
+				}
+				if (sdlPos >= SIZEOF_KEYPOS_ARRAY)
+				{
+					Log_Printf(LOG_ERROR, "KeyPos (%d>%d) overflow!", sdlPos, SIZEOF_KEYPOS_ARRAY);
+					continue;
+				}
+				modList = findMod(LoadedKeyPos[sdlPos], sdlMod);
 			}
-			p = strtok(NULL, "\n");
-			if (!p)
+			else
+			{
+				/* Part 1 (before ','): <SDL.evt.sym>-<SDL.evt.mod> */
+				sdlSym = Keymap_GetKeyFromName(szPCKeyCode);
+				if ((sdlSym == 0) &&
+					(sscanf(szPCKeyCode, "%i-%i", &sdlSym, &sdlMod) != 2) && 
+					(sscanf(szPCKeyCode, "%i", &sdlSym) != 1)                ) 
+				{
+					Log_Printf(LOG_ERROR, "Bad syntaxe! This PCKeyCode can't be retrieved: '%s'", szPCKeyCode);
+					continue;
+				}
+				if (sdlSym >= SIZEOF_KEYSYM_ARRAY)
+				{
+					Log_Printf(LOG_ERROR, "KeySym (%d>%d) overflow!", sdlPos, SIZEOF_KEYSYM_ARRAY);
+					continue;
+				}
+				modList = findMod(LoadedKeySym[sdlSym], sdlMod);
+			}
+			/* printf("Register SDL.Sym=%d SDL.Mod=%d...\n", sdlSym, sdlMod); */
+			if (modList != NULL)
+			{
+				Log_Printf(LOG_WARN, "Pair (sdlSym-sdlMod=%d-%d) is already registered.\n", sdlSym, sdlMod);
 				continue;
-			STScanCode = atoi(p);
-			/* Store into remap table, check both value within range */
-			if (STScanCode > 0 && STScanCode <= KBD_MAX_SCANCODE
-			    && PCKeyCode >= 8)
+			}
+			/* printf("Add... 0x%08X\n", (void *)LoadedKeySym[sdlSym]); */
+			if (first_char_pos == 1)
 			{
-				LOG_TRACE(TRACE_KEYMAP,
-				          "keymap from file: sym=%i --> scan=%i\n",
-				          PCKeyCode, STScanCode);
-				LoadedKeymap[idx][0] = PCKeyCode;
-				LoadedKeymap[idx][1] = STScanCode;
-				idx += 1;
+				modList = addMod(&LoadedKeyPos[sdlPos]);
 			}
 			else
 			{
-				Log_Printf(LOG_WARN, "Could not parse keymap file:"
-				           " '%s' (%d >= 8), '%s' (0 > %d <= %d)\n",
-					   szString, PCKeyCode, p, STScanCode, KBD_MAX_SCANCODE);
+				modList = addMod(&LoadedKeySym[sdlSym]);
+			}
+			modList->Mod = sdlMod;
+			/* Part 2 (after ','): <STScanCode 1>[-<STScanCode 2>[...]] */
+			part = strtok(szSTScanCode, "-");
+			iter = 0;
+			iter2 = &modList->stScancodeList;
+			while (part != NULL)
+			{
+				if (sscanf(part, "%i", &stScancode) != 1)
+				{
+					continue;
+				}
+				if (stScancode >= 0 && stScancode <= KBD_MAX_SCANCODE)
+				{
+					if (first_char_pos == 1)
+					{
+						LOG_TRACE(TRACE_KEYMAP,
+								  "keymap from file: '%s' pos=%i Mod=%i --> '%s' scan=%i\n",
+								  szPCKeyCode, sdlPos, sdlMod, szSTScanCode, stScancode);
+					}
+					else
+					{
+						LOG_TRACE(TRACE_KEYMAP,
+								  "keymap from file: '%s' sym=%i Mod=%i --> '%s' scan=%i\n",
+								  szPCKeyCode, sdlSym, sdlMod, szSTScanCode, stScancode);
+					}
+					iter = addSTScanCode(iter2);
+					iter->stScancode = stScancode;
+					part = strtok(0, "-");
+					iter2 = &(iter->next);
+				}
+				else
+				{
+					Log_Printf(LOG_WARN, "Could not parse keymap file:"
+							   " '%s' (%d >= 8), '%s' (0 > %d <= %d)\n",
+							   szString, sdlSym, part, stScancode, KBD_MAX_SCANCODE);
+				}
 			}
 		}
 	}
@@ -774,8 +1031,8 @@ void Keymap_KeyDown(SDL_keysym *sdlkey)
 	int symkey = sdlkey->sym;
 	int modkey = sdlkey->mod;
 
-	LOG_TRACE(TRACE_KEYMAP, "key down: sym=%i scan=%i mod=0x%x name='%s'\n",
-	          symkey, sdlkey->scancode, modkey, Keymap_GetKeyName(symkey));
+	LOG_TRACE(TRACE_KEYMAP, "key down: sym=%i scan=%i(0x%x) mod=%i(0x%x) name='%s'\n",
+			  symkey, sdlkey->scancode, sdlkey->scancode, modkey, modkey, Keymap_GetKeyName(symkey));
 
 	if (ShortCut_CheckKeys(modkey, symkey, true))
 		return;
@@ -795,7 +1052,7 @@ void Keymap_KeyDown(SDL_keysym *sdlkey)
 
 	STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
 	LOG_TRACE(TRACE_KEYMAP, "key map: sym=0x%x to ST-scan=0x%02x\n", symkey, STScanCode);
-	if (STScanCode != (uint8_t)-1)
+	while (STScanCode != (uint8_t)-1)
 	{
 		if (!Keyboard.KeyStates[STScanCode])
 		{
@@ -803,6 +1060,7 @@ void Keymap_KeyDown(SDL_keysym *sdlkey)
 			Keyboard.KeyStates[STScanCode] = true;
 			IKBD_PressSTKey(STScanCode, true);
 		}
+		STScanCode = Keymap_RemapKeyToSTScanCode(0);
 	}
 }
 
@@ -817,8 +1075,8 @@ void Keymap_KeyUp(SDL_keysym *sdlkey)
 	int symkey = sdlkey->sym;
 	int modkey = sdlkey->mod;
 
-	LOG_TRACE(TRACE_KEYMAP, "key up: sym=%i scan=%i mod=0x%x name='%s'\n",
-	          symkey, sdlkey->scancode, modkey, Keymap_GetKeyName(symkey));
+	LOG_TRACE(TRACE_KEYMAP, "key up: sym=%i scan=%i(0x%x) mod=%i(0x%x) name='%s'\n",
+			  symkey, sdlkey->scancode, sdlkey->scancode, modkey, modkey, Keymap_GetKeyName(symkey));
 
 	/* Ignore short-cut keys here */
 	if (ShortCut_CheckKeys(modkey, symkey, false))
@@ -839,13 +1097,14 @@ void Keymap_KeyUp(SDL_keysym *sdlkey)
 
 	STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
 	/* Release key (only if was pressed) */
-	if (STScanCode != (uint8_t)-1)
+	while (STScanCode != (uint8_t)-1)
 	{
 		if (Keyboard.KeyStates[STScanCode])
 		{
 			IKBD_PressSTKey(STScanCode, false);
 			Keyboard.KeyStates[STScanCode] = false;
 		}
+		STScanCode = Keymap_RemapKeyToSTScanCode(0);
 	}
 }
 


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/