Skip to content

Instantly share code, notes, and snippets.

@Orangenhain
Created June 25, 2012 12:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Orangenhain/2988387 to your computer and use it in GitHub Desktop.
Save Orangenhain/2988387 to your computer and use it in GitHub Desktop.
small tool to check modifier key state on the command-line (CLI, Mac only)
// Usage:
// Basically, there are two ways to use this, either just invoke it via
// modifierKeyState
// and the exit code will be a bit mask for the state of the modifier keys,
// or:
// modifierKeyState command
// modifierKeyState shift alt
// exit code 0 means the specified keys (and only those!) have been found
// exit code 1 means the key was either not pressed, or other keys have been pressed as well
// Lastly:
// modifierKeyState null
// will check if NO modifier key has been pressed (exit code will be either 0 or 1, in contrast to invoking w/o the argument)
// clang -framework Foundation -framework ApplicationServices -o modifierKeyState modifierKeyState.m
#import <Foundation/Foundation.h>
enum {
// EXIT_SUCCESS = 0,
// EXIT_FAILURE = 1,
EXIT_CAPSLOCK = 1 << 1,
EXIT_SHIFT = 1 << 2,
EXIT_CONTROL = 1 << 3,
EXIT_ALTERNATE = 1 << 4,
EXIT_COMMAND = 1 << 5,
EXIT_HELP = 1 << 6,
EXIT_FN = 1 << 7
};
int main(int argc, const char * argv[])
{
int exitCode = 0;
@autoreleasepool {
CGEventFlags flags = CGEventSourceFlagsState(kCGEventSourceStateHIDSystemState);
if( kCGEventFlagMaskAlphaShift & flags ) { exitCode |= EXIT_CAPSLOCK; }
if( kCGEventFlagMaskShift & flags ) { exitCode |= EXIT_SHIFT; }
if( kCGEventFlagMaskControl & flags ) { exitCode |= EXIT_CONTROL; }
if( kCGEventFlagMaskAlternate & flags ) { exitCode |= EXIT_ALTERNATE; }
if( kCGEventFlagMaskCommand & flags ) { exitCode |= EXIT_COMMAND; }
if( kCGEventFlagMaskHelp & flags ) { exitCode |= EXIT_HELP; }
if( kCGEventFlagMaskSecondaryFn & flags ) { exitCode |= EXIT_FN; }
// at this point, the exit code is a bit mask for the keyboard modifier state
NSArray *modifierNames = [NSArray arrayWithObjects:@"null", @"capslock", @"shift", @"control", @"option", @"command", @"help", @"fn", nil];
for (int i = 1; i < argc; i++) {
NSString *arg = [[[NSString alloc] initWithCString:argv[i]
encoding:NSUTF8StringEncoding] lowercaseString];
NSUInteger idx = [modifierNames indexOfObject:arg];
if (idx == 0) {
// nothing to do for "null" argument
continue;
}
if (idx == NSNotFound) {
exitCode = EXIT_FAILURE;
NSLog(@"invalid argument: %@", arg);
break;
}
// modifierNames idx matches EXIT_* bit shift, as the exitCode is a bit mask,
// the relevant bit is XOR-ed, meaning that if the bit was set (i.e. key pressed)
// it gets set to 0 -- thus, iff only the keys from the command line have been pressed
// we will end up with an exitCode of 0
exitCode ^= (1 << idx);
}
if ( (argc > 1) && (exitCode > 0) )
{
// so either a key was pressed the user did not want, or he asked for a key that wasn't pressed
exitCode = EXIT_FAILURE;
}
}
return exitCode;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment