modifier keys

This commit is contained in:
Adam D. Ruppe 2013-10-05 23:20:01 -04:00
parent 0b8ddc2470
commit 67757c74a7
1 changed files with 104 additions and 12 deletions

View File

@ -1330,7 +1330,6 @@ struct RealTimeConsoleInput {
e.eventType = ev.bKeyDown ? CharacterEvent.Type.Pressed : CharacterEvent.Type.Released; e.eventType = ev.bKeyDown ? CharacterEvent.Type.Pressed : CharacterEvent.Type.Released;
ne.eventType = ev.bKeyDown ? NonCharacterKeyEvent.Type.Pressed : NonCharacterKeyEvent.Type.Released; ne.eventType = ev.bKeyDown ? NonCharacterKeyEvent.Type.Pressed : NonCharacterKeyEvent.Type.Released;
// FIXME standardize
e.modifierState = ev.dwControlKeyState; e.modifierState = ev.dwControlKeyState;
ne.modifierState = ev.dwControlKeyState; ne.modifierState = ev.dwControlKeyState;
@ -1406,16 +1405,17 @@ struct RealTimeConsoleInput {
InputEvent(CharacterEvent(CharacterEvent.Type.Released, character, 0)), InputEvent(CharacterEvent(CharacterEvent.Type.Released, character, 0)),
]; ];
} }
InputEvent[] keyPressAndRelease(NonCharacterKeyEvent.Key key) { InputEvent[] keyPressAndRelease(NonCharacterKeyEvent.Key key, uint modifiers = 0) {
return [ return [
InputEvent(NonCharacterKeyEvent(NonCharacterKeyEvent.Type.Pressed, key, 0)), InputEvent(NonCharacterKeyEvent(NonCharacterKeyEvent.Type.Pressed, key, modifiers)),
InputEvent(NonCharacterKeyEvent(NonCharacterKeyEvent.Type.Released, key, 0)), InputEvent(NonCharacterKeyEvent(NonCharacterKeyEvent.Type.Released, key, modifiers)),
]; ];
} }
char[30] sequenceBuffer;
// this assumes you just read "\033[" // this assumes you just read "\033["
char[] readEscapeSequence() { char[] readEscapeSequence(char[] sequence) {
char[30] sequence;
int sequenceLength = 2; int sequenceLength = 2;
sequence[0] = '\033'; sequence[0] = '\033';
sequence[1] = '['; sequence[1] = '[';
@ -1514,7 +1514,7 @@ struct RealTimeConsoleInput {
if(n == '\033') { if(n == '\033') {
n = nextRaw(); n = nextRaw();
if(n == '[') { if(n == '[') {
auto esc = readEscapeSequence(); auto esc = readEscapeSequence(sequenceBuffer);
if(esc == "\033[201~") { if(esc == "\033[201~") {
// complete! // complete!
break; break;
@ -1566,7 +1566,7 @@ struct RealTimeConsoleInput {
m.buttons = 1 << (buttonNumber - 1); // I prefer flags so that's how we do it m.buttons = 1 << (buttonNumber - 1); // I prefer flags so that's how we do it
m.x = x; m.x = x;
m.y = y; m.y = y;
m.modifierState = modifiers; // FIXME, standardize m.modifierState = modifiers;
return [InputEvent(m)]; return [InputEvent(m)];
break; break;
@ -1575,6 +1575,79 @@ struct RealTimeConsoleInput {
auto cap = terminal.findSequenceInTermcap(sequence); auto cap = terminal.findSequenceInTermcap(sequence);
if(cap !is null) if(cap !is null)
return translateTermcapName(cap); return translateTermcapName(cap);
else {
if(terminal.terminalInFamily("xterm")) {
import std.conv, std.string;
auto terminator = sequence[$ - 1];
auto parts = sequence[2 .. $ - 1].split(";");
// parts[0] and terminator tells us the key
// parts[1] tells us the modifierState
uint modifierState;
int modGot = to!int(parts[1]);
mod_switch: switch(modGot) {
case 2: modifierState |= ModifierState.shift; break;
case 3: modifierState |= ModifierState.alt; break;
case 4: modifierState |= ModifierState.shift | ModifierState.alt; break;
case 5: modifierState |= ModifierState.control; break;
case 6: modifierState |= ModifierState.shift | ModifierState.control; break;
case 7: modifierState |= ModifierState.alt | ModifierState.control; break;
case 8: modifierState |= ModifierState.shift | ModifierState.alt | ModifierState.control; break;
case 9:
..
case 16:
modifierState |= ModifierState.meta;
if(modGot != 9) {
modGot -= 8;
goto mod_switch;
}
break;
default:
}
switch(terminator) {
case 'A': return keyPressAndRelease(NonCharacterKeyEvent.Key.UpArrow, modifierState);
case 'B': return keyPressAndRelease(NonCharacterKeyEvent.Key.DownArrow, modifierState);
case 'C': return keyPressAndRelease(NonCharacterKeyEvent.Key.RightArrow, modifierState);
case 'D': return keyPressAndRelease(NonCharacterKeyEvent.Key.LeftArrow, modifierState);
case 'H': return keyPressAndRelease(NonCharacterKeyEvent.Key.Home, modifierState);
case 'F': return keyPressAndRelease(NonCharacterKeyEvent.Key.End, modifierState);
case 'P': return keyPressAndRelease(NonCharacterKeyEvent.Key.F1, modifierState);
case 'Q': return keyPressAndRelease(NonCharacterKeyEvent.Key.F2, modifierState);
case 'R': return keyPressAndRelease(NonCharacterKeyEvent.Key.F3, modifierState);
case 'S': return keyPressAndRelease(NonCharacterKeyEvent.Key.F4, modifierState);
case '~': // others
switch(parts[0]) {
case "5": return keyPressAndRelease(NonCharacterKeyEvent.Key.PageUp, modifierState);
case "6": return keyPressAndRelease(NonCharacterKeyEvent.Key.PageDown, modifierState);
case "2": return keyPressAndRelease(NonCharacterKeyEvent.Key.Insert, modifierState);
case "3": return keyPressAndRelease(NonCharacterKeyEvent.Key.Delete, modifierState);
case "15": return keyPressAndRelease(NonCharacterKeyEvent.Key.F5, modifierState);
case "17": return keyPressAndRelease(NonCharacterKeyEvent.Key.F6, modifierState);
case "18": return keyPressAndRelease(NonCharacterKeyEvent.Key.F7, modifierState);
case "19": return keyPressAndRelease(NonCharacterKeyEvent.Key.F8, modifierState);
case "20": return keyPressAndRelease(NonCharacterKeyEvent.Key.F9, modifierState);
case "21": return keyPressAndRelease(NonCharacterKeyEvent.Key.F10, modifierState);
case "23": return keyPressAndRelease(NonCharacterKeyEvent.Key.F11, modifierState);
case "24": return keyPressAndRelease(NonCharacterKeyEvent.Key.F12, modifierState);
default:
}
break;
default:
}
} else if(terminal.terminalInFamily("rxvt")) {
// FIXME: figure these out
} else {
// maybe we could do more terminals, but linux doesn't even send it and screen just seems to pass through, so i don't think so; xterm prolly covers most them anyway
// so this space is semi-intentionally left blank
}
}
} }
return null; return null;
@ -1588,7 +1661,7 @@ struct RealTimeConsoleInput {
// escape sequence // escape sequence
c = nextRaw(); c = nextRaw();
if(c == '[') { // CSI, ends on anything >= 'A' if(c == '[') { // CSI, ends on anything >= 'A'
return doEscapeSequence(readEscapeSequence()); return doEscapeSequence(readEscapeSequence(sequenceBuffer));
} else if(c == 'O') { } else if(c == 'O') {
// could be xterm function key // could be xterm function key
auto n = nextRaw(); auto n = nextRaw();
@ -1631,7 +1704,7 @@ struct CharacterEvent {
Type eventType; /// . Type eventType; /// .
dchar character; /// . dchar character; /// .
uint modifierState; /// . uint modifierState; /// Don't depend on this to be available for character events
} }
struct NonCharacterKeyEvent { struct NonCharacterKeyEvent {
@ -1672,7 +1745,7 @@ struct NonCharacterKeyEvent {
} }
Key key; /// . Key key; /// .
uint modifierState; /// . uint modifierState; /// A mask of ModifierState. Always use by checking modifierState & ModifierState.something, the actual value differs across platforms
} }
@ -1705,7 +1778,7 @@ struct MouseEvent {
uint buttons; /// A mask of Button uint buttons; /// A mask of Button
int x; /// 0 == left side int x; /// 0 == left side
int y; /// 0 == top int y; /// 0 == top
uint modifierState; /// shift, ctrl, alt, meta, altgr uint modifierState; /// shift, ctrl, alt, meta, altgr. Not always available. Always check by using modifierState & ModifierState.something
} }
/// . /// .
@ -1721,6 +1794,25 @@ struct UserInterruptionEvent {}
interface CustomEvent {} interface CustomEvent {}
version(Windows)
enum ModifierState : uint {
shift = 4,
ctrl = 8,
// i'm not sure if the next two are available
alt = 256,
// windows = 512,
meta = 4096, // FIXME sanity
}
else
enum ModifierState : uint {
shift = 4,
alt = 2,
control = 16,
meta = 8
}
/// GetNextEvent returns this. Check the type, then use get to get the more detailed input /// GetNextEvent returns this. Check the type, then use get to get the more detailed input
struct InputEvent { struct InputEvent {
/// . /// .