I'm looking for application-wide access to raw keyboard events in OS X, either using the Cocoa or Carbon frameworks (or any of the underlying APIs, for that matter). I know that I can override NSApplication's sendEvent: to get raw keyboard information, but for the meta keys (command, control, alternate, shift, etc) don't show up as keystroke events. I'm looking for something analogous to Microsoft's DirectInput framework.
Thanks!
I think the equivalent to DirectInput is HID Manager. HID stands for "human interface device" and HID Manager (sometimes called HIDLib) is the low-level API to HIDs: keyboards, mice, and joysticks.
Leopard's got a new HID Manager API, documented in Technical Note TN2187. The pre-Leopard API is documented in HID Class Device Interface Guide. I wrote an Objecive-C wrapper around the older APIs, DDHidLib, which you may find useful. The Leopard API is much nicer. I'd use that directly, if you can.
The Core Graphics framework also has some useful functionality buried in it as part of the remote operation system. Look for CGRemoteOperation.h, and check out the Quartz Events reference.
You can use the Quartz Events system to install application-specific or system-wide "event taps", which let you monitor and inject keyboard and mouse events at a pretty low level. A few years ago there were some bugs with application-specific event taps, but they've hopefully been worked out by now.
I think the HID stuff is mostly for driver development, so if you're just looking for a tool for your application, HID is probably overkill.
NSResponder derived classes have a method -(void)flagsChanged: that gets called when meta-keys are held down.
You can use the RegisterHotKeyEvent Carbon function, I'm not sure if you can register for any of the meta keys explicitly though.
The blog post Program Global Hotkeys in Cocoa Easily explains how to do this.
Related
I want to write a Windows application which accesses the joystick. It is just a very simple application which reads the values and sends them to a server, so I am not using any game programming framework. However, I am confused about which API to use.
I looked at the Multimedia Joystick API, but this is described as superseded by DirectInput. So I looked at DirectInput, but this is also deprecated in favour of XInput.
However the XInput documentation talks only about Xbox360 controllers, and says it does not support "legacy DirectInput devices".
Have Microsoft consigned the entire HID Joystick usage type to the dustbin and given up on supporting them in favour of their own proprietary controller products, or am I missing something?
The most common solution is to use a combination of XInput and DirectInput so your application can properly access both type of devices. Microsoft even provides instructions on how to do this.
Please note that DirectInput is not available for Windows Store apps so if you intend to distribute through there, that's not an option.
XInput devices like the XBox 360 controller will also work with DirectInput but with some limitations. Notably, the left and right trigger will be mapped to the same axis instead of being independents, and vibration effects will not be available.
How would I go about creating a "gamepad" which appears to DirectInput applications as a normal game controller but the state of its controls is actually defined by software?
Write a device driver to pretend to be one.
Specifically, Windows device drivers handle what are called Interrupt Requests via the Interrupt Request Protocol - which boils down to a wrapped up structure and a set of buffers internally in the driver.
Now the next thing you need to know is that many drivers are actually layered, or stacked, or whichever name you want to use. So for example to write a disk driver, you might interface with the driver above it (as a disk class) but use a driver below it (scsi port, for example) to actually send commands to your devices.
That's how real devices work. Fake devices need to conform to the top level interface requirements, e.g. a disk, or a controller, or a mouse, or whatever it is. However, underneath they can do anything they like - return whatever values they like.
This opens up the possibility of controlling a driver via a user-mode application and pretending to "be" a device. To send a driver messages, you can DeviceIoControl to it; then to actually get those messages you can either:
Stuff them in the Irp that makes up that DeviceIoControl.
Have the driver read them out of your process' memory space.
Drivers can also access \\Registry\\Machine and various other, non-user-specific non-explorer registry areas, so it is possible to communicate that way.
Finally, there's no saying you can't filter existing IO, rather than make it all up via a new device. There are a great many options and ways you can go about doing this.
If you're going to do this, you'll need:
VirtualKD or an expensive debugger cable and two PCs.
You probably also want to start with the references on this blog post. You'll find that there are essentially a bazillion different names for driver code, so I'll interpret some of them:
WDM = Windows Driver Model, basically the NT driver model mixed with (some of) Windows 9x.
KMDF = Kernel mode driver framework - drivers of the above type use this, plus additionally WDF (Windows Driver Foundation) which is a set of libraries on top of WDM to make it quicker to use.
UMDF = User mode driver framework - write a driver without the danger of kernel mode. If you can, use this, as kernel mode drivers that go wrong will bluescreen (in driver parlance, bugcheck) your system.
Edit: I'm not massively knowledgeable on DirectInput - there may be a way to override the various API controls in use via DLL redirection and the like, which may be simpler than the way I've described.
There is vJoy opensource project: http://sourceforge.net/projects/vjoystick/ - can be worth looking at.
The easiest solution may be to emulate an XInput device (Xbox 360 and One). These are supported in most modern games and the set up is very simple. Here is a C++ project here that provides this without any installed drivers or external dependencies: https://github.com/shauleiz/vXboxInterface/
I know it is an old question but for anyone which is interested in this topic it is also worth looking at this project called ViGEm.
You can emulate some well known gamepads like Microsoft Xbox 360 Controller, Sony DualShock 4 Controller and Microsoft Xbox One Controller. The project offers also some API to interact with these virtual controllers. E.g. the C# API can be found here
The simplest solution I found was using vJoy and its C# wrapper.
You need to download the vJoy driver from here.
You can use the vJoy SDK for implementing a feeder program: https://github.com/njz3/vJoy/tree/master/SDK/c%23
Use the C# starter project for this, or simply add the two .dll-s to your existing project as references from the x86 or x64 folder.
You can find instructions on how to use the api in the readme.odt file.
I am currently trying to get simple keyboard input on OSX, right now I am doing it through the Leopard HID Manager object and that generally works, but since that is pretty low level I am wondering if there is an API available that has some extra functionality build it like key repetition or Unicode support (since when I catch the events on HID I/O level I think I have to write all these fancy extras from scratch). I know carbon event handlers(NewEventHandlerUPP) are capable of that but I am pretty sure that they are deprecated since you can't find anything about them in the current OSX reference and I don't want to use anything deprecated, so I am wondering if there is any alternative I didn't come across during my search!
Thanks!
No.
At the Unicode level, the official API of receiving input is NSTextInputClient protocol in Objective-C, and the official API of processing input between the keyboard and the program is the Input Method Kit.
And you can never write a sufficiently fancy extra correctly from scratch. You need to get the user's setting of the international keyboard and modify the key obtained accordingly. And you can never write an input method from scratch which turns the raw key input to Chinese or Japanese ...
So, I think the sane choices are either
Just get the raw ASCII data from the keyboard and don't aim for more, or
Use Cocoa at least around the key input handling, to get additional features.
I am about to implement simple keyboard and mouse input on osx for my engine. I want to abstract the implementation in more generic c++ classes like Keyboard and Mouse plus appropriate Listeners for portability. Anyways, I came across the Leopard HID Api (http://developer.apple.com/mac/library/technotes/tn2007/tn2187.html#TNTAG9000-SAMPLE_CODE_)which seems to be the right way to go for the osx implementation of these classes. Anyways, the examples of the HID are very complex and I can't really wrap my head around it as fast as I wished I could, so I was wondering if anybody has used it allready to get some basic mouse and keyboard input, or knows about some good examples/resources online.
Or Maybe even a totally different way to go?
thanks
I thought I was a decent programmer until I tried writing gamepad code for OS X. Now I feel deeply useless.
Does anyone know of any code that I can legally use in my (non-free) game?
Is it really this hard to talk to a gamepad on OS X? What am I missing?
Check out the HID Manager, especially the new HID Manager APIs in Leopard. It's somewhat verbose, but the essence of it is that you can get callbacks when devices are attached and detached, and get callbacks when events from those devices are enqueued.
If you're working with Cocoa, Dave Dribin has DDHidLib which provides a nicer Objective-C API atop the HID Manager, and runs on Tiger as well.
Turns out the answer was Apple's HID_Utilities, which (somewhat) simplifies the job of talking to HID Manager.
John Carmack really hit the nail on the head when he said that Apple don't care about games...
The quickest way to get gamepad events on OSX is to use SDL, the game library.
You don't have to use the whole library, you can just init the joystick subsystem
and then poll or wait for SDL_JOYAXISMOTION and SDL_JOYBUTTONUP/DOWN events.
SDL has an LGPL license, so you can dynamically link to it in your non-free game.
Easy!
No code, but communicating with gamepads and the like is pretty straightforward with the InputSprocket mechanism. What was the precise problem you had?