Hacking AirClick USB (for Mac)
If you’re interested in adding additional functionality to your AirClick without all the mucking about in property lists and what not, you may want to look at this, otherwise, read on.
Quite a while back I wrote a little blurb suggesting that people interested in customizing their AirClick USB software contact me for an explanation. What I should have really done was taken the time to write up as nice little HOWTO instead of setting myself up to write several individual HOWTOs. That is something we shall have to remedy.
A few notes before we get started. Though I work for Griffin (we’ll see for how much longer after this post) this article is by no means endorsed or supported by Griffin Technology. In other words if you go mucking around inside AirClick package and break something, don’t expect much sympathy from the guys in support. Me either for that matter. If you accidently rm -rfv / please don’t come crying to me (by the way, I did that once, it made me sad). Please make a backup copy of the application, your hard drive, make sure the batteries are good in your smoke alarm, etc., etc. That being said, if you’re still interested, read on.
In order to make this easy on yourself, you should probably have installed Apple’s developer tools. You don’t need to compile anything, but you’ll find that Property List Editor, found in /Developer/Applications/Utilities will make life much easier. You should also be familiar with AppleScript.
First let’s take a look inside the AirClick package and see how things are put together. Control-click the AirClick application and select Show Package Contents from the contextual menu. Notice the various scripts in Contents/Resources. You’ll also see a file called functions.plist. Open this file with Property List Editor or your favorite text editor and follow along by navigating through the items in the as they are explained.
The top level is an array of dictionaries. Each of these dictionaries represents a group of functions that can be selected in the AirClick menu. Within each group are two entries: an array named “Functions” and a string named “Name”. The “Name” appears in the AirClick menu which is used to select the active group of functions. “Functions” is an array of dictionaries that describes each of the functions in this group and the rules required to execute each script.
A function dictionary contains the following:
- Button (Number): A code indicating which button will trigger this function. The button codes are:
- Play: 1
- Volume Up: 2
- Volume Down: 4
- Next: 8
- Previous: 16
- Modifiers (Number): A mask indicating which additional buttons need to be pressed to trigger this function. Uses the same codes as described above. Use 0 to indicate no required modifiers.
- Name (String): The human readable name of this function. Not currently used, but you never know.
- OnRelease (Boolean): YES if this function executes when “Button”
is released. Otherwise executed when pressed.
- Repeats (Boolean): YES if this function repeats until the state of
- Scriptname (String): The file name of the AppleScript to be executed.
- SetLogic [optional] (Dictionary): Contains optional parameters used to set internal variables. Defined as:
- Value (Number): The value to set the variable to.
- VarName (String): The name of the variable to set.
- TestLogic [optional] (Dictionary): Contains optional parameters used to query internal variables. The function will only execute if the test
evaluates true. Defined as:
- Value (Number): The value to compare the variable to.
- VarName (String): The name of the variable to compare.
- Time (Number): Time in seconds the state must remain true before the function executes. 0.0 indicates that the function should execute immediately.
So now you know what all of the various property describe, let’s take a look at a few examples. First look in the first (or zero-ith if you like) function group (Name: DVD Player) in the first function. The properties are:
Translated that means when the Play button is released (and no other buttons are pressed) immediately execute the script named dvd_playpause.scpt once. That’s a fairly straightforward example.
A slightly more complicated example is emulating an iPod’s next and previous buttons. These buttons when pressed and released quickly go to the next or previous track. If held the track will fast-forward or rewind respectively. However when the button is released, it should not trigger the next / previous track function. The DVD Player remote works the same way. Consider these two functions:
The first function will execute the dvd_fforward.scpt script once the Next button has been held for 0.5 seconds. Furthermore it will set a variable named DidFF equal to 1. This variable is key because the next function says execute when the Next button is released if the variable DidFF evaluates to 0. A third function is actually required to reset this variable when the button is released if necessary. But you get the idea. You can create some pretty non-trivial functions if needed.
This is pretty straightforward. Create your AppleScript and test it in Script Editor, or AppleScript Studio etc, and save it into the Contents/Resources folder along with all the others. There is one tiny wrinkle however. You must make sure your script is saved as a text file and not a script. The software expects, at this point in time, to find a text file at the location specified in the function definition.
Additionally, the AirClick AppleScript suite provides several commands for such things as an on screen display which can include a message, assorted icons and a level meter. Also the ability to simulate a user key press and a means of adjusting the system volume. This commands are all documented in the AirClick dictionary and there are plenty of examples in the scripts provided in the AirClick package so there really isn’t a need to dive into them here.
Where to go from here
I would encourage you to examine the built-in functions and scripts until you feel comfortable enough to construct your own group of functions. It’s really pretty straightforward I think. And so I think that pretty much covers things. Hopefully someone finds this useulf and if there’s something that’s unclear or something I’ve forgotten just leave a comment.