160 lines
4.1 KiB
Objective-C
160 lines
4.1 KiB
Objective-C
#import <Cocoa/Cocoa.h>
|
|
#import <LuaSkin/LuaSkin.h>
|
|
|
|
#import <IOKit/IOKitLib.h>
|
|
#import <IOKit/hidsystem/IOHIDLib.h>
|
|
#import <IOKit/hidsystem/IOHIDParameter.h>
|
|
#import <CoreFoundation/CoreFoundation.h>
|
|
#import <IOKit/hid/IOHIDUsageTables.h>
|
|
|
|
#define CAPSLOCK_OFF 0
|
|
#define CAPSLOCK_ON 1
|
|
#define CAPSLOCK_TOGGLE -1
|
|
#define CAPSLOCK_QUERY 9
|
|
|
|
// Source: https://discussions.apple.com/thread/7094207
|
|
|
|
static int access_capslock(int op){
|
|
kern_return_t kr = -1;
|
|
io_service_t ios;
|
|
io_connect_t ioc;
|
|
CFMutableDictionaryRef mdict;
|
|
bool state = false;
|
|
|
|
mdict = IOServiceMatching(kIOHIDSystemClass);
|
|
ios = IOServiceGetMatchingService(kIOMasterPortDefault, (CFDictionaryRef) mdict);
|
|
if (!ios)
|
|
{
|
|
// fprintf(stderr, "IOServiceGetMatchingService() failed: %x\n", kr);
|
|
return (int) kr;
|
|
}
|
|
|
|
kr = IOServiceOpen(ios, mach_task_self(), kIOHIDParamConnectType, &ioc);
|
|
IOObjectRelease(ios);
|
|
if (kr != KERN_SUCCESS)
|
|
{
|
|
// fprintf(stderr, "IOServiceOpen() failed: %x\n", kr);
|
|
return (int) kr;
|
|
}
|
|
|
|
switch (op)
|
|
{
|
|
case CAPSLOCK_ON:
|
|
case CAPSLOCK_OFF:
|
|
state = (op == CAPSLOCK_ON);
|
|
kr = IOHIDSetModifierLockState(ioc, kIOHIDCapsLockState, state);
|
|
if (kr != KERN_SUCCESS)
|
|
{
|
|
IOServiceClose(ioc);
|
|
fprintf(stderr, "IOHIDSetModifierLockState() failed: %x\n", kr);
|
|
return (int) kr;
|
|
}
|
|
break;
|
|
case CAPSLOCK_TOGGLE:
|
|
kr = IOHIDGetModifierLockState(ioc, kIOHIDCapsLockState, &state);
|
|
if (kr != KERN_SUCCESS)
|
|
{
|
|
IOServiceClose(ioc);
|
|
fprintf(stderr, "IOHIDGetModifierLockState() failed: %x\n", kr);
|
|
return (int) kr;
|
|
}
|
|
state = !state;
|
|
kr = IOHIDSetModifierLockState(ioc, kIOHIDCapsLockState, state);
|
|
if (kr != KERN_SUCCESS)
|
|
{
|
|
IOServiceClose(ioc);
|
|
fprintf(stderr, "IOHIDSetModifierLockState() failed: %x\n", kr);
|
|
return (int) kr;
|
|
}
|
|
break;
|
|
case CAPSLOCK_QUERY:
|
|
kr = IOHIDGetModifierLockState(ioc, kIOHIDCapsLockState, &state);
|
|
if (kr != KERN_SUCCESS)
|
|
{
|
|
IOServiceClose(ioc);
|
|
//fprintf(stderr, "IOHIDGetModifierLockState() failed: %x\n", kr);
|
|
return (int) kr;
|
|
}
|
|
break;
|
|
}
|
|
|
|
IOServiceClose(ioc);
|
|
return (bool) state;
|
|
}
|
|
|
|
// hs.hid.capslock.get() -> bool
|
|
// Function
|
|
// Checks the state of the caps lock via HID
|
|
static int hid_capslock_query(lua_State* L) {
|
|
bool state = access_capslock(CAPSLOCK_QUERY);
|
|
lua_pushboolean(L, state);
|
|
return 1;
|
|
}
|
|
|
|
// hs.hid.capslock.toggle() -> bool
|
|
// Function
|
|
// Toggles the state of caps lock via HID
|
|
static int hid_capslock_toggle(lua_State* L) {
|
|
bool state = access_capslock(CAPSLOCK_TOGGLE);
|
|
lua_pushboolean(L, state);
|
|
return 1;
|
|
}
|
|
|
|
// hs.hid.capslock.set(true) -> bool
|
|
// Function
|
|
// Assigns capslock to the desired state
|
|
static int hid_capslock_on(lua_State* L) {
|
|
bool state = access_capslock(CAPSLOCK_ON);
|
|
lua_pushboolean(L, state);
|
|
return 1;
|
|
}
|
|
|
|
// hs.hid.capslock.set(false) -> bool
|
|
// Function
|
|
// Assigns capslock to the desired state
|
|
static int hid_capslock_off(lua_State* L) {
|
|
bool state = access_capslock(CAPSLOCK_OFF);
|
|
lua_pushboolean(L, state);
|
|
return 1;
|
|
}
|
|
|
|
bool hidled_set(uint32 usage, long target_value);
|
|
|
|
static int hid_led_set(lua_State* L) {
|
|
LuaSkin *skin = [LuaSkin sharedWithState:L];
|
|
[skin checkArgs:LS_TSTRING, LS_TBOOLEAN, LS_TBREAK];
|
|
|
|
NSString *name = [skin toNSObjectAtIndex:1];
|
|
long target_value = lua_toboolean(L, 2);
|
|
bool ret = false;
|
|
|
|
if ([name isEqualToString:@"caps"]) {
|
|
ret = hidled_set(kHIDUsage_LED_CapsLock, target_value);
|
|
} else if ([name isEqualToString:@"scroll"]) {
|
|
ret = hidled_set(kHIDUsage_LED_ScrollLock, target_value);
|
|
} else if ([name isEqualToString:@"num"]) {
|
|
ret = hidled_set(kHIDUsage_LED_NumLock, target_value);
|
|
} else {
|
|
[skin logError:@"Unsupported LED name"];
|
|
}
|
|
|
|
lua_pushboolean(L, ret);
|
|
return 1;
|
|
}
|
|
|
|
static const luaL_Reg hid_lib[] = {
|
|
{"_capslock_query", hid_capslock_query},
|
|
{"_capslock_toggle", hid_capslock_toggle},
|
|
{"_capslock_on", hid_capslock_on},
|
|
{"_capslock_off", hid_capslock_off},
|
|
{"_led_set", hid_led_set},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
int luaopen_hs_libhid(lua_State* L) {
|
|
LuaSkin *skin = [LuaSkin sharedWithState:L];
|
|
[skin registerLibrary:"hs.hid" functions:hid_lib metaFunctions:nil];
|
|
|
|
return 1;
|
|
}
|