objective-cmacoskernelmouseiokit

How to change mouse settings programmatically in macOS using IOKit


The functions IOHIDGetAccelerationWithKey and IOHIDSetAccelerationWithKey are deprecated since macOS 10.12, therefore I am trying to implement the same using other IO*-methods.

I have never worked with IOKit, thus, all I can do is google for functions and try to get it to work. Now I found this: Can't edit IORegistryEntry which has an example of how to change TrackpadThreeFingerSwipe property, however it is using a function which is not defined for me: getEVSHandle. Googling for it reveals only that it should be Found in the MachineSettings framework, however I can't seem to add any "MachineSettings" framework in Xcode 11.

What should I do? Current code is like:

#import <Foundation/Foundation.h>
#import <IOKit/hidsystem/IOHIDLib.h>

int main(int argc, const char * argv[]) {
   @autoreleasepool {
      NSInteger value = -65536;
      CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberNSIntegerType, &value);
      CFMutableDictionaryRef propertyDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, NULL, NULL);
      CFDictionarySetValue(propertyDict, @"HIDMouseAcceleration", number);

      io_connect_t connect = getEVSHandle(); // ???

      if (!connect)
      {
          NSLog(@"Unable to get EVS handle");
      }

      res = IOConnectSetCFProperties(connect, propertyDict);

      if (res != KERN_SUCCESS)
      {
         NSLog(@"Failed to set mouse acceleration (%d)", res);
      }

      IOObjectRelease(service);

      CFRelease(propertyDict);
   }
   return 0;
}


Solution

  • The following works (tested with Xcode 11.2 / macOS 10.15)

    #import <Foundation/Foundation.h>
    #import <IOKit/hidsystem/IOHIDLib.h>
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            io_service_t service = IORegistryEntryFromPath(kIOMasterPortDefault, 
                kIOServicePlane ":/IOResources/IOHIDSystem");
    
            NSDictionary *parameters = (__bridge NSDictionary *)IORegistryEntryCreateCFProperty(service, 
                CFSTR(kIOHIDParametersKey), kCFAllocatorDefault, kNilOptions);
            NSLog(@"%@", parameters);
    
            NSMutableDictionary *newParameters = [parameters mutableCopy];
            newParameters[@"HIDMouseAcceleration"] = @(12345);
    
            kern_return_t result = IORegistryEntrySetCFProperty(service,  
                CFSTR(kIOHIDParametersKey), (__bridge CFDictionaryRef)newParameters);
            NSLog(kIOReturnSuccess == result ? @"Updated" : @"Failed");
    
            IOObjectRelease(service);
        }
        return 0;
    }