1 module iota.controls.keyboard; 2 3 public import iota.controls.types; 4 5 version (Windows) { 6 import core.sys.windows.windows; 7 import core.sys.windows.wtypes; 8 } 9 /** 10 * Defines keyboard modifiers. 11 */ 12 public enum KeyboardModifiers : ubyte { 13 init, 14 Shift = 1<<0, 15 Ctrl = 1<<1, 16 Alt = 1<<2, 17 Meta = 1<<3, 18 NumLock = 1<<4, 19 CapsLock= 1<<5, 20 ScrollLock= 1<<6, 21 Aux = 1<<7, 22 } 23 /** 24 * Defines keyboard locklight flags. 25 * Both `Compose` and `Kana` exist within USB HID specifications, however they not necessarily are implemented whithin 26 * OS API. Same with the now obsolete Scroll Lock. 27 */ 28 public enum KeyboardLocklights : ubyte { 29 NumLock = 1<<0, 30 CapsLock= 1<<1, 31 ScrollLock= 1<<2, 32 Compose = 1<<3, 33 Kana = 1<<4, 34 } 35 /** 36 * Implements keyboard I/O. 37 */ 38 public class Keyboard : InputDevice { 39 ///Defines keyboard-specific flags. 40 enum KeyboardFlags : ushort { 41 TextInput = 1<<8, ///Set if text input is enabled. 42 IgnoreLLMods = 1<<9, ///Set if lock light modifiers are to be ignored. 43 } 44 package this() nothrow { 45 _type = InputDeviceType.Keyboard; 46 status |= StatusFlags.IsConnected; 47 } 48 /** 49 * Polls the device for events. 50 * Params: 51 * output = InputEvents outputted by the 52 * Returns: 1 if there's still events to be polled, 0 if no events left. Other values are error codes. 53 */ 54 public override int poll(ref InputEvent output) @nogc nothrow { 55 version (Windows) { 56 //Since Windows is a bit weird when it comes to inputs, so inputs are polled from system. 57 //This class mainly exists here to provide context and other interfaces 58 return 0; 59 } else { 60 return 0; 61 } 62 } 63 /** 64 * Returns true if the text input has been enabled. 65 */ 66 public final bool isTextInputEn() @property @nogc @safe pure nothrow const { 67 return (status & KeyboardFlags.TextInput) != 0; 68 } 69 /** 70 * Sets whether the text input is enabled or not, then 71 */ 72 public bool setTextInput(bool val) @property @nogc @safe pure nothrow { 73 if (val) 74 status |= KeyboardFlags.TextInput; 75 else 76 status &= ~KeyboardFlags.TextInput; 77 return isTextInputEn(); 78 } 79 public final bool isIgnoringLockLights() @property @nogc @safe pure nothrow const { 80 return (status & KeyboardFlags.IgnoreLLMods) != 0; 81 } 82 public bool setIgnoreLockLights(bool val) @property @nogc @safe pure nothrow { 83 if (val) 84 status |= KeyboardFlags.IgnoreLLMods; 85 else 86 status &= ~KeyboardFlags.IgnoreLLMods; 87 return isIgnoringLockLights(); 88 } 89 public ubyte getModifiers() @nogc nothrow { 90 ubyte result; 91 version (Windows) { 92 if (GetKeyState(VK_SHIFT)) 93 result |= KeyboardModifiers.Shift; 94 if (GetKeyState(VK_CONTROL)) 95 result |= KeyboardModifiers.Ctrl; 96 if (GetKeyState(VK_MENU)) 97 result |= KeyboardModifiers.Alt; 98 if (GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) 99 result |= KeyboardModifiers.Meta; 100 if (!isIgnoringLockLights()) { 101 if (GetKeyState(VK_NUMLOCK)) 102 result |= KeyboardModifiers.NumLock; 103 if (GetKeyState(VK_CAPITAL)) 104 result |= KeyboardModifiers.CapsLock; 105 if (GetKeyState(VK_SCROLL)) 106 result |= KeyboardModifiers.ScrollLock; 107 } 108 } 109 return result; 110 } 111 }