1
0
Fork 0
fgdata/Nasal/keyboard.nas

443 lines
7.8 KiB
Text

PrintableKeys = {
0: 0x30,
1: 0x31,
2: 0x32,
3: 0x33,
4: 0x34,
5: 0x35,
6: 0x36,
7: 0x37,
8: 0x38,
9: 0x39,
A: 0x61,
a: 0x61,
B: 0x62,
b: 0x62,
C: 0x63,
c: 0x63,
D: 0x64,
d: 0x64,
E: 0x65,
e: 0x65,
F: 0x66,
f: 0x66,
G: 0x67,
g: 0x67,
H: 0x68,
h: 0x68,
I: 0x69,
i: 0x69,
J: 0x6a,
j: 0x6a,
K: 0x6b,
k: 0x6b,
L: 0x6c,
l: 0x6c,
M: 0x6d,
m: 0x6d,
N: 0x6e,
n: 0x6e,
O: 0x6f,
o: 0x6f,
P: 0x70,
p: 0x70,
Q: 0x71,
q: 0x71,
R: 0x72,
r: 0x72,
S: 0x73,
s: 0x73,
T: 0x74,
t: 0x74,
U: 0x75,
u: 0x75,
V: 0x76,
v: 0x76,
W: 0x77,
w: 0x77,
X: 0x78,
x: 0x78,
Y: 0x79,
y: 0x79,
Z: 0x7a,
z: 0x7a,
"!": 0x21,
Exclaim: 0x21,
'"': 0x22,
DoubleQuote: 0x22,
"#": 0x23,
Hash: 0x23,
"$": 0x24,
Dollar: 0x24,
"&": 0x26,
Ampersand: 0x26,
"'": 0x27,
SingleQuote: 0x27,
"(": 0x28,
OpeningParenthesis: 0x28,
")": 0x29,
ClosingParenthesis: 0x29,
"*": 0x2a,
Asterisk: 0x2A,
"+": 0x2b,
Plus: 0x2B,
",": 0x2c,
Comma: 0x2C,
"-": 0x2d,
Minus: 0x2D,
".": 0x2e,
Period: 0x2E,
"/": 0x2f,
Slash: 0x2F,
",": 0x3a,
Colon: 0x3A,
";": 0x3b,
SemiColon: 0x3B,
"<": 0x3c,
Less: 0x3C,
"=": 0x3d,
Equals: 0x3D,
">": 0x3e,
Greater: 0x3E,
"?": 0x3f,
Question: 0x3F,
"@": 0x40,
At: 0x40,
"[": 0x5b,
OpeningBracket: 0x5B,
"\\": 0x5c,
BackSlash: 0x5C,
"]": 0x5d,
ClosingBracket: 0x5D,
"^": 0x5e,
Caret: 0x5E,
"_": 0x5f,
Underscore: 0x5F,
"`": 0x60,
BackQuote: 0x60,
};
FunctionKeys = {
Space: 0x20,
Backspace: 0xFF08,
Tab: 0xFF09,
Linefeed: 0xFF0A,
Clear: 0xFF0B,
Return: 0xFF0D,
Pause: 0xFF13,
Sys_Req: 0xFF15,
"Esc": 0xff1b,
Escape: 0xFF1B,
"Del": 0xffff,
Delete: 0xFFFF,
Home: 0xFF50,
Left: 0xFF51,
Up: 0xFF52,
Right: 0xFF53,
Down: 0xFF54,
Prior: 0xFF55,
Page_Up: 0xFF55,
Next: 0xFF56,
Page_Down: 0xFF56,
End: 0xFF57,
Begin: 0xFF58,
Select: 0xFF60,
Print: 0xFF61,
Execute: 0xFF62,
Insert: 0xFF63,
Undo: 0xFF65,
Redo: 0xFF66,
Menu: 0xFF67,
Find: 0xFF68,
Cancel: 0xFF69,
Help: 0xFF6A,
Break: 0xFF6B,
# Any key binding using these would be pretty confusing …
Mode_switch: 0xFF7E,
Script_switch: 0xFF7E,
Num_Lock: 0xFF7F,
Scroll_Lock: 0xFF14,
# Keypad keys probably should not be used because their normal key equivalent will be passed by OSG AFAIK
KP_Space: 0xFF80,
KP_Tab: 0xFF89,
KP_Enter: 0xFF8D,
KP_F1: 0xFF91,
KP_F2: 0xFF92,
KP_F3: 0xFF93,
KP_F4: 0xFF94,
KP_Home: 0xFF95,
KP_Left: 0xFF96,
KP_Up: 0xFF97,
KP_Right: 0xFF98,
KP_Down: 0xFF99,
KP_Prior: 0xFF9A,
KP_Page_Up: 0xFF9A,
KP_Next: 0xFF9B,
KP_Page_Down: 0xFF9B,
KP_End: 0xFF9C,
KP_Begin: 0xFF9D,
KP_Insert: 0xFF9E,
KP_Delete: 0xFF9F,
KP_Equal: 0xFFBD,
KP_Multiply: 0xFFAA,
KP_Add: 0xFFAB,
KP_Separator: 0xFFAC,
KP_Subtract: 0xFFAD,
KP_Decimal: 0xFFAE,
KP_Divide: 0xFFAF,
KP_0: 0xFFB0,
KP_1: 0xFFB1,
KP_2: 0xFFB2,
KP_3: 0xFFB3,
KP_4: 0xFFB4,
KP_5: 0xFFB5,
KP_6: 0xFFB6,
KP_7: 0xFFB7,
KP_8: 0xFFB8,
KP_9: 0xFFB9,
F1: 0xFFBE,
F2: 0xFFBF,
F3: 0xFFC0,
F4: 0xFFC1,
F5: 0xFFC2,
F6: 0xFFC3,
F7: 0xFFC4,
F8: 0xFFC5,
F9: 0xFFC6,
F10: 0xFFC7,
F11: 0xFFC8,
# most keyboards only have F1 - F11, so better not use any of the below FunctionKeys
F12: 0xFFC9,
F13: 0xFFCA,
F14: 0xFFCB,
F15: 0xFFCC,
F16: 0xFFCD,
F17: 0xFFCE,
F18: 0xFFCF,
F19: 0xFFD0,
F20: 0xFFD1,
F21: 0xFFD2,
F22: 0xFFD3,
F23: 0xFFD4,
F24: 0xFFD5,
F25: 0xFFD6,
F26: 0xFFD7,
F27: 0xFFD8,
F28: 0xFFD9,
F29: 0xFFDA,
F30: 0xFFDB,
F31: 0xFFDC,
F32: 0xFFDD,
F33: 0xFFDE,
F34: 0xFFDF,
F35: 0xFFE0,
# Do not use the below keys !
Shift_L: 0xFFE1,
Shift_R: 0xFFE2,
Control_L: 0xFFE3,
Control_R: 0xFFE4,
Caps_Lock: 0xFFE5,
Shift_Lock: 0xFFE6,
Meta_L: 0xFFE7,
Meta_R: 0xFFE8,
Alt_L: 0xFFE9,
Alt_R: 0xFFEA,
#Super_L: 0xFFEB,
#Super_R: 0xFFEC,
#Hyper_L: 0xFFED,
#Hyper_R: 0xFFEE,
};
ModifierKeys = {
Shift_L: 0x0001,
Shift_R: 0x0002,
Control_L: 0x0004,
Control_R: 0x0008,
Alt_L: 0x0010,
Alt_R: 0x0020,
Meta_L: 0x0040,
Meta_R: 0x0080,
# These do not seem to be available in OSG events
#Super_L: 0x0100,
#Super_R: 0x0200,
#Hyper_L: 0x0400,
#Hyper_R: 0x0800,
#Num_Lock: 0x1000,
Caps_Lock: 0x2000,
};
# Only use the below keys !
ModifierKeys.Ctrl = (ModifierKeys.Control_L | ModifierKeys.Control_R);
ModifierKeys.Shift = (ModifierKeys.Shift_L | ModifierKeys.Shift_R);
ModifierKeys.Alt = (ModifierKeys.Alt_L | ModifierKeys.Alt_R);
ModifierKeys.Meta = (ModifierKeys.Meta_L | ModifierKeys.Meta_R);
# These do not seem to be available in OSG events
#ModifierKeys.Super = (ModifierKeys.Super_L | ModifierKeys.Super_R);
#ModifierKeys.Hyper = (ModifierKeys.Hyper_L | ModifierKeys.Hyper_R);
var Shortcut = {
new: func(modifiers, keys...) {
var m = {
parents: [Shortcut],
modifiers: modifiers,
keys: keys,
};
if (m.modifiers == nil) {
m.modifiers = [];
m.keys = [];
} elsif (isa(m.modifiers, Shortcut)) {
var shortcut = m.modifiers;
m.modifiers = shortcut.modifiers;
m.keys = shortcut.keys;
} elsif (typeof(m.modifiers) == "scalar") {
var res = m.parseString(m.modifiers);
if (typeof(res) == "scalar") {
logprint(LOG_ALERT, "keyboard.Shortcut.parseString failed parsing '" ~ m.modifiers ~ "' with the following reason:");
logprint(LOG_ALERT, "\t" ~ res);
m.modifiers = [];
m.keys = [];
} else {
m.modifiers = res[0];
m.keys = res[1];
}
}
return m;
},
parseString: func(s) {
if (size(s) == 0) {
return "shortcut string is empty";
}
var found = [];
var modifiers = [];
var input = split("+", s);
foreach (var key; input) {
if (string.match(key, "<*>")) {
append(modifiers, substr(key, 1, size(key) - 2));
} else {
append(found, key);
}
}
var newmodifiers = [];
foreach (var mod; modifiers) {
if (ModifierKeys[mod] == nil) {
return "Unknown modifier key '" ~ mod ~ "' !";
} else {
append(newmodifiers, ModifierKeys[mod]);
}
}
var newfound = [];
foreach (var key; found) {
if (PrintableKeys[key] == nil) {
if (FunctionKeys[key] == nil) {
return "Unknown key '" ~ key ~ "' !";
} else {
append(newfound, FunctionKeys[key]);
}
} else {
append(newfound, PrintableKeys[key]);
}
}
return [newmodifiers, newfound];
},
match: func(keys, shift=0, ctrl=0, alt=0, meta=0) {
if (!me.modifiers and !me.keys) {
return 0;
}
var match = 1;
match &= contains(me.modifiers, ModifierKeys["Shift"]) == shift;
match &= contains(me.modifiers, ModifierKeys["Ctrl"]) == ctrl;
match &= contains(me.modifiers, ModifierKeys["Alt"]) == alt;
match &= contains(me.modifiers, ModifierKeys["Meta"]) == meta;
match &= size(keys) == size(me.keys);
if (!match) {
return 0;
}
for (var i = 0; i < size(keys); i += 1) {
match &= keys[i] == me.keys[i];
}
return match;
},
repr: func {
if (!me.modifiers and !me.keys) {
return "";
}
var names = [];
foreach (var mod; me.modifiers) {
append(names, findKeyName(mod));
}
foreach (var key; me.keys) {
append(names, findKeyName(key));
}
return string.join(" + ", names);
},
equals: func(other) {
return me.modifiers == other.modifiers and me.keys == other.keys;
},
};
var findKeyName = func(key) {
foreach (var mod; keys(ModifierKeys)) {
if (ModifierKeys[mod] == key) {
return mod;
}
}
foreach (var printable; keys(PrintableKeys)) {
if (PrintableKeys[printable] == key) {
return printable;
}
}
foreach (var function; keys(FunctionKeys)) {
if (FunctionKeys[function] == key) {
return function;
}
}
return nil;
};
var namesToKeys = func(strings...) {
var res = [];
foreach (var s; strings) {
var key = ModifierKeys[s] or PrintableKeys[s] or FunctionKeys[s];
if (!key) {
logprint(LOG_ALERT, "keyboard.namesToKeys: unknown key '" ~ key ~ "' - skipping !");
continue;
}
append(res, key);
}
return res;
};
var Binding = {
new: func(shortcut, f) {
var m = {
parents: [Binding],
f: f,
shortcut: shortcut,
};
return m;
},
fire: func(e) {
debug.dump(e);
if (isfunc(me.f)) {
me.f(e);
}
}
};