Mac OS X Porting - Apple Remote implementation

From Apache OpenOffice Wiki
Jump to: navigation, search

Apple Remote Implementation for Aqua on Mac OS X



The remote, on the above picture, allows to drive applications in fullscreen mode, or in windowed mode, for playing presentations, photos slideshows, play music .. and so on, with the latests computers Apple ships, including Intel processors, but not only.

The most known application running with the remote, is Front Row

There is at least one model running PowerPC processor, the iMac G5 iSight, who is shipped with a remote too.

More information : Apple Remote on Wikipedia


Make the Apple Remote work on Mac OS X, using Impress application with Aqua

Several steps are scheduled (appleremote01, appleremote02 and appleremote03)


Task started early june 2008

CWS name State Date milestone comment Owner QA resp.
appleremote01 ready for QA 21st September 2008 ericb Florian Heckl done
appleremote01 integrated 27th October 2008 DEV300_m35 Apple Remote will be in 3.1 ericb Florian Heckl done
appleremote02 created 28th October 2008 DEV300_m37 replace keyCodes,
using MEDIA_COMMAND_* instead
ericb done
appleremote02 Ready for QA January 2009 DEV300_m38 ericb Wolfram Garten done
appleremote02 Integrated January 2009
(should be in 3.1)

ericb Wolfram Garten
appleremote03 planned 14th December 2008 Try to use the
contextual menu
in presentation mode
(preliminary step)
ericb done
appleremote03 created 14th January 2009 DEV300_m39(rebased m38->m39) ericb done
appleremote03 Ready for QA undefined planned : DEV300_mxx ericb

Source Code authors

Initial code who allows the Apple Remote control use, has been written by from Martin Kahr, under the MIT License. This code, who has been put in the new apple_remote module, has been adapted to by Eric Bachard, under the same license.

For further informations, please see : Martin Khar website

Important: to make it work with , the initial code in the cws has been modified a lot. Please use the original code if you want to see the diffs

Note: the existing code allows to use the Keyspan remote device. If you have such device, please provide us feedback and help us to make it work

Modes (definitions)

The current implementation is described below. If you have a better idea (not too complicated though), please tell us.

1) Mode not presenting

(Normal Mode kUIModeNormal -> see MacApplication.h)

This mode means, windows and frames are displayed.

If you have choosen to run the prosentation in Windowed mode, the remote works like if you are in fullscreen (since appleremote02)

Else, just play will work, and start the presentation in fullscreen.

2) Mode Presentation

(fullscreen aka kUIModeAllHidden)

Starting point: fullscreen, slide 1 is displayed, presentation paused (default). From presentation mode, can be reached any slide, using the menu (used as a right click)

Or :

The current window has been extended in all the screen (using CTRL+shift +J), just hidding the window , borders,the menubar and the dock.

This is a window-less mode, aka fullscreen mode, known as the usual mode for presentation.

3) LIST_MODE (will be implemented in appleremote03)


What follows is just a draft: means there is no guarantee it will work as expected, and will need a lot of tests.

Expected behavior: in list mode or in menu mode: [right], [left], [+] or [-] buttons allow to browse the contextual menu

Important : this feature works in parallel with other events from mouse or keyboard

To trigger the contextual menu :

Hit menu key when on fullscreen (during the presentation) :

  • pauses the presentation
  • makes the contextual menu appear

Hit the menu key entry again or escape :

  • removes the contextual menu
  • resumes, and the presentation continues

To navigate :

Hit the - key goes down in the menu when possible

Hit the +key goes up in the menu when possible

Hit the right (forward) key goes right in the menu when possible

Hit the left (backward) key goes left in the menu when possible

To validate an item :

Hit the key play/pause, in LIST_MODE, means when a menu appears, or type enter  :

  • validates the highlighted menu item, when corresponding to an existing possibility

4) Other mode : Presenter Screen extension

So nice, that you must install it :-)

This is not a mode, but more a feature, allowing you to read your notes on the laptop, while the slides are displayed .. etc

Download the extension, install it, and in the diaporama properties, don't forget to choose screen 2 for the presentation screen (else you'll see the presenter screen on the public screen and the presentation on your laptop / screen :-)

Other definitions

short key stroke: short key hit, inferior to 0,4 second

long key stroke: obtained when the key is maintained hit more than 0,4 second

Detailed behavior after appleremote02 will be integrated (Draft)

Mode not presenting (aka Windowed mode)

Either :

One Impress window is in front (active window)

and if the Windowed mode is selected in the preferences :

=> Hit |> || symbol (namely: play /pause button) starts the presentation,
and every button of the remote work in Windowed mode (excepted the play/pause button).
Hold Play button quits the presentation

else :

Hit the Play button will start the presentation at the current slide (common use)


Another application is focused (is the active Window) :
Writer, or Calc or Draw, or Base document is focused and is in NOT in fullscreen :
=> hit any button on the remote does nothing, the keyboard works as usual


Writer document is focused and is in fullscreen (using CMD+shift+J) :
CMD+shift+J gives a "fullscreen like" document
=> hit any button on the remote does nothing, the keyboard works as usual


Calc Document is focused and is in fullscreen (using CMD+shift+J):
=> hit any button on the remote does nothing, the keyboard works as usual

Base document:


Draw document:


Mode Presentation

  • Hit Page backward ( |<< symbol ) or + button ( Volume down) gives Previous page (if existing)
  • Hit Page forward ( >>| symbol) or - button (Volume up) gives Next page (if existing)
  • longHit Page backward ( |<< symbol ) gives First page
  • long Hit Page forward ( >>| symbol) gives Last page
  • Hold Menu ends the presentation
  • Play : toggle play/pause button can play pause automatic presentation


NOT YET IMPLEMENTED (will be in appleremote03 cws)

1) + / - button can increase / decrease sound volume (very unsure, because some Apple black magic seems to lock that buttons)

2) Hit menu key simulates right click -> gives the contextual menu in presentation mode => opens the LIST MODE

3) hold play (long hit) allows to choose a list of presentations, in some default dir (like Front Row does) )

4) in LIST_MODE (available in presentation mode only)

  • normal stroke: [right], [left], [+] or [-] browses the contextual menu
  • play validates the choice ( ends the LIST_MODE )
  • stroke menu : simulates escape and ends the LIST_MODE

Note: go to the first/last slide can be achieved using the contextual menu

Technical part

FIXME: the information below needs important cleanup

Make it buildable

Done. With the current code, no warnings, everything is delivered as expected.

  • in apple_remote module (build triggered in postprocess)
  • in vcl : apple_remote module has been added as a dependancy
  • in scp2 ( libAppleRemotemx{i | p}.dylib has been added in the package

Integrate the code in for Mac OS X

Done :

Concerned modules :

  • external (Apple Remote code will be there due to the MIT License )
  • scp2 : libAppleRemotemxi.dylib has to be packaged
  • vcl : MainControler object and notifications are detected by the NSApplication in all its life + add apple_remote module as dependancy
  • postprocess : build apple_remote module
  • sd : implement the MEDIA_COMMAND part, add the eventListener, remove it, and add missing features

Code :

  • created external/apple_remote tree. To check out the module (until it is integrated) : cvs co apple_remote
  • created the makefile, links against IOKit framework
  • modified prj/build.lst to build external/AppleRemote
  • modified prj/d.lst to deliver the headers in the solver (vcl will need them) and deliver libAppleRemotemxi.dylib
  • build is ok : no warning (fixed the static issue, and all the other warnings , made the code more robust)
  • in vcl : modified the makefile ( linking against libAppleRemotemxi.dylib ), added mpMainController member in SalData ( saldata.hxx ),

initialized mpMainController in the SalData Ctor, added the MainController initialization in initNSApp() (salinst.cxx)

  • release mpMainController in saltada destructor
  • Packaging works as expected, and works fine with the new lib included in the archive

Done :

Remote Control initialized, and reports finely all events.

Global Keyboard works

Multi click should work too

Current logs :

Reading symbols for shared libraries . done
System Version 1049
Stored System Version 1049
2008-08-13 11:27:49.513 soffice.bin[13926] RemoteControl initWithDelegate ok
2008-08-13 11:27:49.513 soffice.bin[13926] RemoteControlContainer initWithDelegate ok
2008-08-13 11:27:49.514 soffice.bin[13926] RemoteControl initWithDelegate ok
2008-08-13 11:27:49.516 soffice.bin[13926] [container instantiateAndAddRemoteControlDeviceWithClass: [AppleRemote class]] successfull
2008-08-13 11:27:49.517 soffice.bin[13926] RemoteControlContainer instantiateAndAddRemoteControlDeviceWithClass failed
2008-08-13 11:27:49.518 soffice.bin[13926] [container instantiateAndAddRemoteControlDeviceWithClass: [KeyspanFrontRowControl class]] failed
2008-08-13 11:27:49.518 soffice.bin[13926] RemoteControl initWithDelegate ok
2008-08-13 11:27:49.519 soffice.bin[13926] [container instantiateAndAddRemoteControlDeviceWithClass: [GlobalKeyboardDevice class]] successfull
2008-08-13 11:27:49.519 soffice.bin[13926] MainController init done


The remote is active when one window has the focus. Using the Finder ( Apple + TAB ) deactivates it, and then Front Row becomes again available. The application no longer receives the events when Front Row is active.

Select another application gives :

2008-08-13 11:30:00.241 soffice.bin[13927] stopListening to events... 
2008-08-13 11:30:00.242 soffice.bin[13927] key = RemoteControlDeviceName 
2008-08-13 11:30:00.242 soffice.bin[13927] key = CFBundleIdentifier 
2008-08-13 11:30:00.242 soffice.bin[13927] value = AppleIRController 
2008-08-13 11:30:00.242 soffice.bin[13927] value = org.openoffice.script 
2008-08-13 11:30:00.242 soffice.bin[13927] sendDistributedNotification ...
2008-08-13 11:30:00.242 soffice.bin[13927] Notification posted...
2008-08-13 11:30:00.242 soffice.bin[13927] sendFinishedNotifcationForAppIdentifier ...

Note: the keys are extracted from the userInfo dictionary

Select again in front gives:

2008-08-13 11:32:23.231 soffice.bin[13927] startListening to events... 
2008-08-13 11:32:23.239 soffice.bin[13927] reset... (after listening to remote)
2008-08-13 11:32:23.239 soffice.bin[13927] Apple Remote will become active - Using remote controls


  • alias for apple_remote in external created by Martin Hollmichel (see issue 92739 )
  • code commited
  • cws appleremote01 created ( Florian Heckl will QA it)
  • all known issues fixed. Remains: better keycode mapping
  • final design for final implementation in progress


  • infos about contextual menu emulation
  • feedback for the Keyspan remote
  • feedback for the current Design

Intercept events with the remote, and trace

Adding some NSLog at the right place, we have the numerical values returned by the remote:

  • + as value "2"
  • - is seen as value "4"
  • Menu button is seen as the value "8"
  • |> || (play pause) as value "16"
  • >>| is seen as value "32"
  • <<| is seen as "64"
  • long hold with key Menu (kRemoteButtonMenu_Hold) is seen as value "512"
  • long hold with key Play (kRemoteButtonPlay_Hold) is seen as value "1024"
  • long hold with key Backward (kRemoteButtonLeft_Hold) is seen as value "2048"
  • long hold with key Forward (kRemoteButtonRight_Hold) is seen as value "4096"

Important: when in Front Row mode, the events are seen too, and accordingly to the link below, there is a way to programaticaly enable / disable it.

Do not work :

  • long hold with key Plus (kRemoteButtonPlus_Hold) is seen as value "128"
  • long hold with key Minus (kRemoteButtonMinus_Hold) is seen as value "256"

Added kRemoteButtonNone, for button initialization

Started :

vcl bindin using ImplHandleAppCommand()

Missing (to be added ?) :

// Missing : case kRemoteButtonMenu:

case kRemoteButtonMenu_Hold:

case kRemoteButtonPlay_Hold:

case kRemoteButtonRight_Hold:

case kRemoteButtonLeft_Hold:

case kRemoteControl_Switched:


Done :

case kRemoteButtonPlay

case kRemoteButtonLeft

case kRemoteButtonRight

case kRemoteButtonMinus

case kRemoteButtonPlus


  • bind with vcl events
  • make it work
  • improve
  • make it work also with OOo Presenter extension

XSlideShowController use

  • Since another solution has been used, what follows it there for information, as developer note

Philipp Lohmann presented me Andre Fisher, the specialist of the thing. Andre kindly explained me where start :

From Andre mail :

First you need access to the XSlideShowController.  You get that from a model (document) like this

    Reference<XModel> xModel; // Given.

    Reference<XPresentationSupplier> xPS (
        xModel, UNO_QUERY_THROW);
    Reference<XPresentation2> xP (
        xPS->getPresentation(), UNO_QUERY_THROW);
    Reference<XSlideShowController> xSSC (

The XSlideShowController provides the functionality to change slides and get information about the current slide.

You can find the interfaces in com/sun/star/presentation, and the real implementation in sd/source/ui/slideshow/slideshowimpl.cxx

Usefull variables sin the interface ( XSlideShowController.idl )

boolean isRunning() -> are we in presentation mode, or not ? 

long getSlideCount(): returns the number of slides ( are we at the beggining, the end .. ) 

void gotoNextSlide()  -> kRemoteButtonRight 

void gotoPreviousSlide() -> kRemoteButtonLeft

void pause()  // needs some work

void activate() : activates the user interface of the slideshow -> can we use the FrontRow menu ? 

boolean isEndless() : demo, the presentation is running in infinite loop when true

bind with vcl events


First basic implementation works :

  • play
  • quit presentation mode
  • next slide
  • previous slide
  • first slide
  • last slide
  • up : volume up does not work with the current implementation, but is replaced with previous slide
  • down: volume down does not work with the current implementation, but is replaced with next slide

Missing :

  • contextual menus

Make it work


Create the cws and commit

DONE: file the issue, and ask mh the alias to be created. (maybe things are more easy now ?)


  • Did Apple document the API since ?
  • Document how things are working [started]
  • Does an Impress Controller API exist ?
  • Find where the events are managed in slideshow (or sd) ? [ask Thorsten]
  • Contact Andre Fisher, the specialist of the thing (following Philipp Lohmann recommandations), and see how marry the remote with the presenter screen

Code description

Files :


Using different devices

Right now the wrapper ships with support for three devices:

  • [works] AppleRemote: Apple Remote Control
  • [works] GlobalKeyboardDevice: Registers global keyboard shortcuts to provide a virtual remote control
  • [untested, no feedback yet] KeyspanFrontRowControl: Keyspan RF Remote for FrontRow



HID at

Using the Apple Remote Control

People involved

Name OOo Nickname Role
Eric Bachard ericb Development
Philipp Lohmann pl Code review (vcl, apple_remote)
Christian Lippka cl Code review (sd, MEDIA_COMMAND )
Andre Fischer af Code review (sd)
Florian Heckl fheckl QA appleremote01
Wolfram Garten wg QA appleremote02
xxxx xxxx User Experience
Eric Bachard ericb Documentation
Personal tools