40EX503Remote

Some of the default mappings from my Bravia seemed a little odd and a couple of buttons were not mapped at all, so I took to customising them, a process which isn't as simple as it could be due to there being multiple levels of abstraction by the time you try to configure what a button press does in XBMC – in simple terms XBMC handles CEC support by converting the CEC commands into button presses on an imaginary IR remote, so you need to know two things:

  1. What is the CEC command that your remote control's button causes to be sent to XBMC
  2. What is the button on the imaginary IR remote that XBMC maps that CEC command back to

Example …

PeripheralCecAdapter maps all the supported CEC commands to a button on the XBMC remote control.  For example CEC command "right" is mapped to "right" on the remote control.  Simple enough in this case:

case CEC_USER_CONTROL_CODE_RIGHT:
  xbmcKey.iButton = XINPUT_IR_REMOTE_RIGHT;
  PushCecKeypress(xbmcKey);
  break;

Thus, the CEC "right" command sent from my TV is mapped to the "right" button on the remote control (code 168), as defined in XBIRRemote.

#define XINPUT_IR_REMOTE_RIGHT 168

In ButtonTranslator I can see the mapping from the button labels XBMC uses in the key map config to the XBIRRemote codes.  All that's left to do is find the CEC command you want to map — in my case I would like to use the unmapped audio button on my remote.  To find out what CEC command is sent by this button I simple enable debugging and tail the log.  When I press the button the following is logged in XBMC:

15:43:59 T:2967913536 DEBUG: CecLogMessage - >> TV (0) -> Recorder 1 (1): user control pressed (33)
15:43:59 T:2967913536 DEBUG: CecLogMessage - key pressed: sound select (33)
15:43:59 T:2967913536 DEBUG: PushCecKeypress - received key 2d duration 0
15:43:59 T:3037818880 DEBUG: OnKey: minus (2d) pressed, action is

The first thing I need to work out is what XBMC button string is mapped to the CEC "sound select" command.  To do this I look in PeripheralCecAdapter which tells me that this command is mapped to the IR_REMOTE_LANGUAGE button.

Secondly, in ButtonTranslator I can see that the IR_REMOTE_LANGUAGE button is mapped to the string language, which is what I need to use in the keymap config file.  Finally, elsewhere in ButtonTranslator I can see the list of possible actions that I can assign to this button press

        {"hidesubmenu"       , ACTION_OSD_HIDESUBMENU},
        {"screenshot"        , ACTION_TAKE_SCREENSHOT},
        {"rename"            , ACTION_RENAME_ITEM},
        {"togglewatched"     , ACTION_TOGGLE_WATCHED},
        {"scanitem"          , ACTION_SCAN_ITEM},
        {"reloadkeymaps"     , ACTION_RELOAD_KEYMAPS},

.I'm going to map the audio button to a toggle for the watched flag, all I need to do is create /home/pi/.xbmc/userdata/keymaps/bravia.xml with the following content:

<keymap>
  <global>
    <remote>
      <language>togglewatched</language>
    </remote>
  </global>
</keymap>

Now (after rebooting XBMC to reload the key map), I can see the following in the logs:

18:34:52 T:2967913536 DEBUG: CecLogMessage - >> 01:44:33
18:34:52 T:2967913536 DEBUG: CecLogMessage - >> TV (0) -> Recorder 1 (1): user control pressed (44)
18:34:52 T:2967913536 DEBUG: CecLogMessage - key pressed: sound select (33)
18:34:52 T:2967913536 DEBUG: PushCecKeypress - received key 2d duration 0
18:34:52 T:3038273536 DEBUG: OnKey: minus (2d) pressed, action is togglewatched

For reference, the complete list of CEC enabled buttons on my Bravia 40EX503's remote, & their corresponding XBMC labels, are listed below:

Button XBMC Button Label
Select <select>
Right <right>
Left <left>
Up <up>
Down <down>
Guide <guide>
Options <title>
Home <menu>
Return <back>
Red <red>
Green <green>
Yellow <yellow>
Blue <blue>
Rewind <reverse>
Play <play>
Forward <forward>
Skip Back <skipminus>
Stop <stop>
Skip Forward <skipplus>
Exit <back>
… (Channel Recall) <subtitle>
Audio <language>