ultimatepp/rainbow/LinuxFb/keymap.cpp
cxl f0e42f8693 reorganizing repo
git-svn-id: svn://ultimatepp.org/upp/trunk@9214 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2015-11-22 19:53:58 +00:00

162 lines
4 KiB
C++

#include "LinuxFbLocal.h"
#define LLOG(x) //LOG(x)
NAMESPACE_UPP
dword modkeys = 0;
enum KMOD {
KMOD_NONE = 0x00,
KMOD_LSHIFT= 0x01,
KMOD_RSHIFT= 0x02,
KMOD_LCTRL = 0x04,
KMOD_RCTRL = 0x08,
KMOD_LALT = 0x10,
KMOD_RALT = 0x20,
KMOD_CAPS = 0x40,
KMOD_NUM = 0x80,
KMOD_CTRL = KMOD_LCTRL | KMOD_RCTRL,
KMOD_SHIFT = KMOD_LSHIFT | KMOD_RSHIFT,
KMOD_ALT = KMOD_LALT | KMOD_RALT,
};
#define CHFLAG(w, m, b) if(b) w |= m; else w &= ~m;
void SaveModKeys(dword keycode, dword pressed)
{
switch(keycode)
{
case SCANCODE_LEFTSHIFT: CHFLAG(modkeys, KMOD_LSHIFT, pressed) break;
case SCANCODE_RIGHTSHIFT: CHFLAG(modkeys, KMOD_RSHIFT, pressed) break;
case SCANCODE_LEFTCONTROL: CHFLAG(modkeys, KMOD_LCTRL, pressed) break;
case SCANCODE_RIGHTCONTROL: CHFLAG(modkeys, KMOD_RCTRL, pressed) break;
case SCANCODE_LEFTALT: CHFLAG(modkeys, KMOD_LALT, pressed) break;
case SCANCODE_RIGHTALT: CHFLAG(modkeys, KMOD_RALT, pressed) break;
case SCANCODE_CAPSLOCK: CHFLAG(modkeys, KMOD_CAPS, pressed) break;
case SCANCODE_NUMLOCK: CHFLAG(modkeys, KMOD_NUM, pressed) break;
}
}
bool GetShift() { return modkeys & KMOD_SHIFT; }
bool GetCtrl() { return modkeys & KMOD_CTRL; }
bool GetAlt() { return modkeys & KMOD_ALT; }
bool GetCapsLock() { return modkeys & KMOD_CAPS; }
dword fbKEYtoK(dword chr) {
if(chr == SCANCODE_TAB)
chr = K_TAB;
else
if(chr == SCANCODE_SPACE)
chr = K_SPACE;
else
if(chr == SCANCODE_ENTER)
chr = K_RETURN;
else
chr = chr + K_DELTA;
//if the mod keys themselves, no need to have CTRL+ xxx behaviour indicator
if(chr == K_ALT_KEY || chr == K_CTRL_KEY || chr == K_SHIFT_KEY)
return chr;
if(GetCtrl()) chr |= K_CTRL;
if(GetAlt()) chr |= K_ALT;
if(GetShift()) chr |= K_SHIFT;
return chr;
}
END_UPP_NAMESPACE
//kernel defines conflict with some upp K_ enums, like K_SHIFT, K_ALT, K_CTRL
//so we separate as much as possible
#include <linux/keyboard.h>
NAMESPACE_UPP
//The kernel copy of translation tables
//from a console keycode in MEDIUMRAW to unicode
static uint16 kmap[MAX_NR_KEYMAPS][NR_KEYS];
void dupkmap(int fd)
{
struct kbentry entry;
if(fd < 0) return;
for(int m=0; m<MAX_NR_KEYMAPS; ++m) {
memset(kmap[m], 0, NR_KEYS*sizeof(uint16));
for(int i=0; i<NR_KEYS; ++i) {
entry.kb_table = m; entry.kb_index = i;
if(ioctl(fd, KDGKBENT, &entry) < 0)
{
fprintf(stderr, "Error: reading keymap\n");
return;
}
if(entry.kb_value == K_ENTER ) entry.kb_value = K(KT_ASCII,13);
//correct numpad
if(KTYP(entry.kb_value) == KT_PAD) {
switch(entry.kb_value) {
case K_P0:
case K_P1:
case K_P2:
case K_P3:
case K_P4:
case K_P5:
case K_P6:
case K_P7:
case K_P8:
case K_P9:
kmap[m][i]=entry.kb_value;
kmap[m][i]+= '0';
break;
case K_PPLUS: kmap[m][i]=K(KT_ASCII,'+'); break;
case K_PMINUS: kmap[m][i]=K(KT_ASCII,'-'); break;
case K_PSTAR: kmap[m][i]=K(KT_ASCII,'*'); break;
case K_PSLASH: kmap[m][i]=K(KT_ASCII,'/'); break;
case K_PENTER: kmap[m][i]=K(KT_ASCII,'\r'); break;
case K_PCOMMA: kmap[m][i]=K(KT_ASCII,','); break;
case K_PDOT: kmap[m][i]=K(KT_ASCII,'.'); break;
default: break;
}
}
if((KTYP(entry.kb_value) == KT_LATIN)
|| (KTYP(entry.kb_value) == KT_ASCII)
|| (KTYP(entry.kb_value) == KT_LETTER)
)
kmap[m][i] = entry.kb_value;
}
}
}
dword TranslateUnicode(dword keycode)
{
int m = 0;
if(modkeys & KMOD_SHIFT) m |= (1<<KG_SHIFT);
if(modkeys & KMOD_CTRL) m |= (1<<KG_CTRL);
if(modkeys & KMOD_LALT) m |= (1<<KG_ALT);
if(modkeys & KMOD_RALT) m |= (1<<KG_ALTGR);
//CAPS changes shift meaning in both directions
if((modkeys & KMOD_CAPS)
&& KTYP(kmap[m][keycode]) == KT_LETTER
)
m ^= (1<<KG_SHIFT);
//num pad handling stays same so far
if((modkeys & KMOD_NUM)
&& KTYP(kmap[m][keycode]) == KT_PAD
)
return KVAL(kmap[m][keycode]);
else
return KVAL(kmap[m][keycode]);
}
END_UPP_NAMESPACE