Closed irtemed88 closed 7 years ago
I think I've encountered this bug before, and I remember uninstalling and reinstalling the kext fixed it. Take a look at issue #4 to see how to uninstall it.
Hey @dwang733 -- Thanks for the suggestion. I uninstalled and reinstalled the latest release from the 'releases' section and still have the issue. Would it help if I uploaded my sample project?
Hmm...did you restart your computer between uninstallation and reinstallation? If not, try doing that first. If that also doesn't work, you can try sending the project and I'll see what I can do.
Ah yeah, I restarted between uninstall and reinstall just to be sure. I've attached the project to this ticket. When you run the project a window should appear with a single button. Clicking that will trigger the keystroke sequence I mentioned above after a 2 second delay. The delay is so I had enough time to switch to TextEdit and see in the keystrokes come in (I'm sure there's a more elegant means of testing, but this was the first thing that came to mind).
Typically clicking the button 3 or 4 times quickly will reproduce the error. Once it occurs the only way I could get the keyboard back into a stable state was to kill the app and force-quit 'hidd' from Activity Monitor (it'll restart as soon as you kill it).
Oh also, I'd recommend not listening to music while testing. For some reason this issue causes the volume on my mac to turn all the way up...
I think I fixed it by mallocing the keyboard on the heap rather than the stack. Try using this code for the stroke method:
struct keyboard_report_t* keyboard = malloc(sizeof(struct keyboard_report_t*));
uint32_t send_count = 4;
uint64_t send[send_count];
send[0] = (uint64_t)strdup(DEVICE_NAME); // device name
send[1] = strlen((char *)send[0]); // name length
send[2] = (uint64_t) keyboard; // keyboard struct
send[3] = sizeof(struct keyboard_report_t); // keyboard struct len
keyboard->modifier = 0;
keyboard->key_codes[0] = key_code;
kern_return_t ret = IOConnectCallScalarMethod(service_connection, FOOHID_SEND, send, send_count, NULL, 0);
if (ret != KERN_SUCCESS) {
printf("Unable to send message to HID device.\n");
}
That did it. Thanks so much! Any idea why the change was necessary?
To be honest, I'm not completely sure why it works. I know that with the old code, if you call stroke() multiple times, there's sometimes random values initialized for keyboard
rather than all 0's, so I just allocated new memory for it. Also, before I forget, add this line at the end of the stroke() method:
free(keyboard);
Don't want any memory leaks :)
Oh interesting. I actually just tried changing the struct initialization to struct keyboard_report_t keyboard = {0};
and that seems to work too.
I guess if the struct was getting random values the rest of the entries in key_codes could be causing the unknown inputs. That also explains why there would be continuous keydown events since the random inputs would never be released.
Hi! Firstly, thanks so much for creating this project. I've been working off of the keyboard.c example and encountered a behavior I can't seem to explain and was wondering if it's a fundamental misunderstanding on my part or possibly something else.
I have a modified keyboard.c that takes an arbitrary keycode via the method
stroke(uint_8 keycode)
. From my app I call this method with the desired keycode (in this case 0x04) followed by 0x00 which I assume acts as a "key up" event (I assume that because the original sample alternated between 0x04 and 0x00)? What I've noticed is while this sometimes works, I get into a state where an unknown keycode is firing nonstop. If TextEdit is in the foreground the character input is the number '8'. Also, the volume on my computer gets turned up all the way and cannot be turned back down until I restart the hid daemon.I feel like I'm missing something here, but haven't been able to figure out what exactly that is through experimentation. I'm sure you're super busy, but if you could offer some feedback on what I've done wrong with my modifications or point me in the direction of documentation that would help clear up my misunderstanding I'd appreciate it.
I'm running macOS 10.12.5. I've wired up a button in my app that makes the following c calls every time it is clicked. If you'd like to see the full project I'd be happy to zip that up and include it here as well:
stroke(0x04); stroke(0x00);
Here's my modified keyboard.c. The main difference is I broke out what I think is the one-time setup logic from the keystroke logic and made the keystroke a variable.