3

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;
}

Cœur
  • 37,241
  • 25
  • 195
  • 267
user826955
  • 3,137
  • 2
  • 30
  • 71
  • MachineSettings is a private framework and can be found in /System/Library/PrivateFrameworks – TheNextman Oct 10 '19 at 16:25
  • Is there documentation for it? E.g. what `getEVSHandle` is doing? I also found `IORegistryEntryFromPath` in https://stackoverflow.com/questions/49679753/replacement-for-deprecated-nxopeneventstatus which works for me to _retrieve_ the mouse acceleration, but not set it. I also found `IOServiceOpen`, however I am unsure of how to use it in regards of `owningTask` and `type` parameters (which seems to be covered by whatever `getEVSHandle` does?). – user826955 Oct 11 '19 at 08:10

1 Answers1

1

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;
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • Is there a limit of how many calls you should do in say, a minute, or an hour? Will it matter? Because I want to have the program reset the acceleration every time someone else resets it (e.g. by using the prefpane mouse settings). – user826955 Dec 20 '19 at 16:56
  • 1
    No documented limitations, and I think if something happens you can control it by checking returned `result` for errors. – Asperi Dec 20 '19 at 17:01