303 lines
5.8 KiB
C
303 lines
5.8 KiB
C
//
|
|
// keymap.c
|
|
//
|
|
// USPi - An USB driver for Raspberry Pi written in C
|
|
// Copyright (C) 2014-2016 R. Stange <rsta2@o2online.de>
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
#include <uspi/keymap.h>
|
|
#include <uspi/usbhid.h>
|
|
#include <uspi/util.h>
|
|
#include <uspi/assert.h>
|
|
#include <uspios.h>
|
|
|
|
#define KEYPAD_FIRST 0x53
|
|
#define KEYPAD_LAST 0x63
|
|
|
|
// order must match TSpecialKey beginning at KeySpace
|
|
static const char *s_KeyStrings[KeyMaxCode-KeySpace] =
|
|
{
|
|
" ", // KeySpace
|
|
"\x1b", // KeyEscape
|
|
"\x7f", // KeyBackspace
|
|
"\t", // KeyTabulator
|
|
"\n", // KeyReturn
|
|
"\x1b[2~", // KeyInsert
|
|
"\x1b[1~", // KeyHome
|
|
"\x1b[5~", // KeyPageUp
|
|
"\x1b[3~", // KeyDelete
|
|
"\x1b[4~", // KeyEnd
|
|
"\x1b[6~", // KeyPageDown
|
|
"\x1b[A", // KeyUp
|
|
"\x1b[B", // KeyDown
|
|
"\x1b[D", // KeyLeft
|
|
"\x1b[C", // KeyRight
|
|
"\x1b[[A", // KeyF1
|
|
"\x1b[[B", // KeyF2
|
|
"\x1b[[C", // KeyF3
|
|
"\x1b[[D", // KeyF4
|
|
"\x1b[[E", // KeyF5
|
|
"\x1b[17~", // KeyF6
|
|
"\x1b[18~", // KeyF7
|
|
"\x1b[19~", // KeyF8
|
|
"\x1b[20~", // KeyF9
|
|
0, // KeyF10
|
|
0, // KeyF11
|
|
0, // KeyF12
|
|
0, // KeyApplication
|
|
0, // KeyCapsLock
|
|
0, // KeyPrintScreen
|
|
0, // KeyScrollLock
|
|
0, // KeyPause
|
|
0, // KeyNumLock
|
|
"/", // KeyKP_Divide
|
|
"*", // KeyKP_Multiply
|
|
"-", // KeyKP_Subtract
|
|
"+", // KeyKP_Add
|
|
"\n", // KeyKP_Enter
|
|
"1", // KeyKP_1
|
|
"2", // KeyKP_2
|
|
"3", // KeyKP_3
|
|
"4", // KeyKP_4
|
|
"5", // KeyKP_5
|
|
"6", // KeyKP_6
|
|
"7", // KeyKP_7
|
|
"8", // KeyKP_8
|
|
"9", // KeyKP_9
|
|
"0", // KeyKP_0
|
|
"\x1b[G", // KeyKP_Center
|
|
",", // KeyKP_Comma
|
|
"." // KeyKP_Period
|
|
};
|
|
|
|
#define C(chr) ((u16) (u8) (chr))
|
|
|
|
static const u16 s_DefaultMap[PHY_MAX_CODE+1][K_ALTSHIFTTAB+1] =
|
|
{
|
|
#if defined (USPI_DEFAULT_KEYMAP_DE)
|
|
#include "keymap_de.h"
|
|
#elif defined (USPI_DEFAULT_KEYMAP_ES)
|
|
#include "keymap_es.h"
|
|
#elif defined (USPI_DEFAULT_KEYMAP_FR)
|
|
#include "keymap_fr.h"
|
|
#elif defined (USPI_DEFAULT_KEYMAP_IT)
|
|
#include "keymap_it.h"
|
|
#elif defined (USPI_DEFAULT_KEYMAP_UK)
|
|
#include "keymap_uk.h"
|
|
#elif defined (USPI_DEFAULT_KEYMAP_US)
|
|
#include "keymap_us.h"
|
|
#else
|
|
{KeyNone}
|
|
#endif
|
|
};
|
|
|
|
void KeyMap (TKeyMap *pThis)
|
|
{
|
|
assert (pThis != 0);
|
|
|
|
pThis->m_bCapsLock = FALSE;
|
|
pThis->m_bNumLock = TRUE;
|
|
pThis->m_bScrollLock = FALSE;
|
|
|
|
assert (sizeof pThis->m_KeyMap == sizeof s_DefaultMap);
|
|
memcpy (pThis->m_KeyMap, s_DefaultMap, sizeof pThis->m_KeyMap);
|
|
}
|
|
|
|
void _KeyMap (TKeyMap *pThis)
|
|
{
|
|
}
|
|
|
|
boolean KeyMapClearTable (TKeyMap *pThis, u8 nTable)
|
|
{
|
|
assert (pThis != 0);
|
|
|
|
if (nTable > K_ALTSHIFTTAB)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
for (unsigned nPhyCode = 0; nPhyCode <= PHY_MAX_CODE; nPhyCode++)
|
|
{
|
|
pThis->m_KeyMap[nPhyCode][nTable] = KeyNone;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
boolean KeyMapSetEntry (TKeyMap *pThis, u8 nTable, u8 nPhyCode, u16 nValue)
|
|
{
|
|
assert (pThis != 0);
|
|
|
|
if ( nTable > K_ALTSHIFTTAB
|
|
|| nPhyCode == 0
|
|
|| nPhyCode > PHY_MAX_CODE
|
|
|| nValue >= KeyMaxCode)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
pThis->m_KeyMap[nPhyCode][nTable] = nValue;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
u16 KeyMapTranslate (TKeyMap *pThis, u8 nPhyCode, u8 nModifiers)
|
|
{
|
|
assert (pThis != 0);
|
|
|
|
if ( nPhyCode == 0
|
|
|| nPhyCode > PHY_MAX_CODE)
|
|
{
|
|
return KeyNone;
|
|
}
|
|
|
|
u16 nLogCodeNorm = pThis->m_KeyMap[nPhyCode][K_NORMTAB];
|
|
|
|
if ( nLogCodeNorm == KeyDelete
|
|
&& (nModifiers & (LCTRL | RCTRL))
|
|
&& (nModifiers & ALT))
|
|
{
|
|
return ActionShutdown;
|
|
}
|
|
|
|
if ( (KeyF1 <= nLogCodeNorm && nLogCodeNorm <= KeyF12)
|
|
&& (nModifiers & ALT))
|
|
{
|
|
return ActionSelectConsole1 + (nLogCodeNorm - KeyF1);
|
|
}
|
|
|
|
if (nModifiers & (ALT | LWIN | RWIN))
|
|
{
|
|
return KeyNone;
|
|
}
|
|
|
|
unsigned nTable = K_NORMTAB;
|
|
|
|
// TODO: hard-wired to keypad
|
|
if (KEYPAD_FIRST <= nPhyCode && nPhyCode <= KEYPAD_LAST)
|
|
{
|
|
if (pThis->m_bNumLock)
|
|
{
|
|
nTable = K_SHIFTTAB;
|
|
}
|
|
}
|
|
else if (nModifiers & ALTGR)
|
|
{
|
|
if (nModifiers & (LSHIFT | RSHIFT))
|
|
{
|
|
nTable = K_ALTSHIFTTAB;
|
|
}
|
|
else
|
|
{
|
|
nTable = K_ALTTAB;
|
|
}
|
|
}
|
|
else if (nModifiers & (LSHIFT | RSHIFT))
|
|
{
|
|
nTable = K_SHIFTTAB;
|
|
}
|
|
|
|
u16 nLogCode = pThis->m_KeyMap[nPhyCode][nTable];
|
|
|
|
switch (nLogCode)
|
|
{
|
|
case KeyCapsLock:
|
|
pThis->m_bCapsLock = !pThis->m_bCapsLock;
|
|
return ActionSwitchCapsLock;
|
|
|
|
case KeyNumLock:
|
|
pThis->m_bNumLock = !pThis->m_bNumLock;
|
|
return ActionSwitchNumLock;
|
|
|
|
case KeyScrollLock:
|
|
pThis->m_bScrollLock = !pThis->m_bScrollLock;
|
|
return ActionSwitchScrollLock;
|
|
}
|
|
|
|
return nLogCode;
|
|
}
|
|
|
|
const char *KeyMapGetString (TKeyMap *pThis, u16 nKeyCode, u8 nModifiers, char Buffer[2])
|
|
{
|
|
assert (pThis != 0);
|
|
|
|
if ( nKeyCode <= ' '
|
|
|| nKeyCode >= KeyMaxCode)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (KeySpace <= nKeyCode && nKeyCode < KeyMaxCode)
|
|
{
|
|
return s_KeyStrings[nKeyCode-KeySpace];
|
|
}
|
|
|
|
char chChar = (char) nKeyCode;
|
|
|
|
if (nModifiers & (LCTRL | RCTRL))
|
|
{
|
|
chChar -= 'a';
|
|
if ('\0' <= chChar && chChar <= 'z'-'a')
|
|
{
|
|
Buffer[0] = chChar + 1;
|
|
Buffer[1] = '\0';
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
if (pThis->m_bCapsLock)
|
|
{
|
|
if ('A' <= chChar && chChar <= 'Z')
|
|
{
|
|
chChar += 'a'-'A';
|
|
}
|
|
else if ('a' <= chChar && chChar <= 'z')
|
|
{
|
|
chChar -= 'a'-'A';
|
|
}
|
|
}
|
|
|
|
Buffer[0] = chChar;
|
|
Buffer[1] = '\0';
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
u8 KeyMapGetLEDStatus (TKeyMap *pThis)
|
|
{
|
|
assert (pThis != 0);
|
|
|
|
u8 nResult = 0;
|
|
|
|
if (pThis->m_bCapsLock)
|
|
{
|
|
nResult |= LED_CAPS_LOCK;
|
|
}
|
|
|
|
if (pThis->m_bNumLock)
|
|
{
|
|
nResult |= LED_NUM_LOCK;
|
|
}
|
|
|
|
if (pThis->m_bScrollLock)
|
|
{
|
|
nResult |= LED_SCROLL_LOCK;
|
|
}
|
|
|
|
return nResult;
|
|
}
|