/
dinruspro
/
reference
Обзор
Документация
Войти
/
dinruspro
/
reference
Код
Запросы
0
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
LinuxFb/keymap.cpp
162 строки
4 KB
EnergonV
Справка по коду перекочевала в репозиторий (наконец-то!)
09 янв 2024, 19:20
09 янв 2024, 19:20
e333663
Код
Авторство
О чём код?
#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