Adding per-keyset editable data
[pierogi] / keysets / philips.cpp
index 4e1c711..15c1b1f 100644 (file)
@@ -1,10 +1,9 @@
 #include "philips.h"
-#include "rc5protocol.h"
-#include "rc6protocol.h"
-#include "necprotocol.h"
+#include "protocols/rc5protocol.h"
+#include "protocols/rc6protocol.h"
+#include "protocols/necprotocol.h"
 
 PhilipsTV1::PhilipsTV1(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "TV Keyset 1",
@@ -13,10 +12,39 @@ PhilipsTV1::PhilipsTV1(
 {
   addControlledDevice(Philips_Make, "HV92", TV_Device);
   addControlledDevice(Philips_Make, "15PF4121", TV_Device);
+}
+
+
+void PhilipsTV1::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
 
   threadableProtocol = new RC5Protocol(guiObject, index);
 
-  addKey("ON/OFF", Power_Key, 0x100C, 13);
+  addKey("UP", Up_Key, 0x0010, 13);
+  addKey("DOWN", Down_Key, 0x0011, 13);
+  addKey("MENU", Menu_Key, 0x0012, 13);
+  addKey("exit", Exit_Key, 0x0013, 13);
+  addKey("LEFT", Left_Key, 0x0015, 13);
+  addKey("RIGHT", Right_Key, 0x0016, 13);
+//  addKey("TELETEXT", Teletext_Key, 0x0017, 13);
+  addKey("PICTURE_SETTINGS", PictureMode_Key, 0x002B, 13);
+  addKey("SOUND_SETTINGS", SoundMode_Key, 0x002C, 13);
+  addKey("GAME", Unmapped_Key, 0x002E, 13);
+  addKey("fav", Favorites_Key, 0x0039, 13);
+  addKey("SCREEN_WIDTH", AspectRatio_Key, 0x003E, 13); // "format"
+  addKey("RED", Red_Key, 0x00C8, 13);
+  addKey("YELLOW", Yellow_Key, 0x00F1, 13); // "radio"
+  addKey(".", Unmapped_Key, 0x00F8, 13);
+  addKey("Cinema", Unmapped_Key, 0x00F9, 13);
+  addKey("GREEN", Green_Key, 0x00FB, 13);
+
+  addKey("0", Zero_Key, 0x1000, 13);
   addKey("1", One_Key, 0x1001, 13);
   addKey("2", Two_Key, 0x1002, 13);
   addKey("3", Three_Key, 0x1003, 13);
@@ -26,113 +54,123 @@ PhilipsTV1::PhilipsTV1(
   addKey("7", Seven_Key, 0x1007, 13);
   addKey("8", Eight_Key, 0x1008, 13);
   addKey("9", Nine_Key, 0x1009, 13);
-  addKey("0", Zero_Key, 0x1000, 13);
+  addKey("1-", DoubleDigit_Key, 0x100A, 13); // -/--
+  addKey("100", PlusOneHundred_Key, 0x100A, 13);
+  addKey("TV-Dash", Dash_Key, 0x100A, 13);
+  addKey("CP", Unmapped_Key, 0x100B, 13); // "C/P"
+  addKey("ON/OFF", Power_Key, 0x100C, 13);
+  addKey("MUTE", Mute_Key, 0x100D, 13);
+  addKey("pp", PrevChannel_Key, 0x100E, 13); // "GREEN"
+  addKey("INFO", Info_Key, 0x100F, 13); // "+", "OSD"
+
   addKey("VOL+", VolumeUp_Key, 0x1010, 13);
   addKey("VOL-", VolumeDown_Key, 0x1011, 13);
-  addKey("MUTE", Mute_Key, 0x100D, 13);
+  addKey("BRIGHTNESS_UP", BrightnessUp_Key, 0x1012, 13);
+  addKey("BRIGHTNESS_DOWN", BrightnessDown_Key, 0x1013, 13);
+  addKey("CONTRAST_UP", ContrastUp_Key, 0x1014, 13);
+  addKey("CONTRAST_DOWN", ContrastDown_Key, 0x1015, 13);
+  addKey("BASS_UP", BassUp_Key, 0x1016, 13);
+  addKey("BASS_DOWN", BassDown_Key, 0x1017, 13);
+  addKey("TREBLE_UP", TrebleUp_Key, 0x1018, 13);
+  addKey("TREBLE_DOWN", TrebleDown_Key, 0x1019, 13);
+  addKey("BALANCE_RIGHT", BalanceRight_Key, 0x101A, 13);
+  addKey("BALANCE_LEFT", BalanceLeft_Key, 0x101B, 13);
+  addKey("TT_OUT", Unmapped_Key, 0x101D, 13);
+  addKey("TT_PLAY", TeletextReveal_Key, 0x101E, 13);
+
   addKey("P+", ChannelUp_Key, 0x1020, 13);
   addKey("P-", ChannelDown_Key, 0x1021, 13);
-  addKey("UP", Up_Key, 0x0010, 13);
-  addKey("DOWN", Down_Key, 0x0011, 13);
-  addKey("MENU", Menu_Key, 0x0012, 13);
-  addKey("exit", Exit_Key, 0x0013, 13);
-  addKey("LEFT", Left_Key, 0x0015, 13);
-  addKey("RIGHT", Right_Key, 0x0016, 13);
-  addKey("AV", Input_Key, 0x1038, 13); // "EXT", "SOURCE"
-  addKey("TIMER", Sleep_Key, 0x1026, 13); // "POWER-OFF", "sleep"
-  addKey("TELETEXT", Teletext_Key, 0x0017, 13);
+  addKey("SURF", Unmapped_Key, 0x1022, 13);
   addKey("I/II", Audio_Key, 0x1023, 13); // "TEXT_REVEAL", "Stereo"
-  addKey("RED", Red_Key, 0x00C8, 13);
-  addKey("GREEN", Green_Key, 0x00FB, 13);
-  addKey("YELLOW", Yellow_Key, 0x00F1, 13); // "radio"
-  addKey("BLUE", Blue_Key, 0x10F9, 13);
-  addKey("CENTER", Unmapped_Key, 0x1029, 13); // "TEXT_STOP_SEQUENCE", etc.
-  addKey("MY_AUDIO", Unmapped_Key, 0x10D2, 13);
   addKey("EXPAND", Surround_Key, 0x1024, 13); // "STEREO", "spatial"
-  addKey("INFO", Info_Key, 0x100F, 13); // "+", "OSD"
-  addKey("TEXT_TV", Unmapped_Key, 0x103C, 13); // "TELETEXT"
-  addKey("SURF", Unmapped_Key, 0x1022, 13);
-  addKey("TEXT_CLOCK", TeletextTime_Key, 0x102A, 13); // "time"
+  addKey("TIMER", Sleep_Key, 0x1026, 13); // "POWER-OFF", "sleep"
+  addKey("PLAY", Play_Key, 0x1028, 13);
+//  addKey("CENTER", Unmapped_Key, 0x1029, 13); // "TEXT_STOP_SEQUENCE", etc.
+  addKey("TT_STOP", TeletextHold_Key, 0x1029, 13);
+  addKey("TEXT_CLOCK", TeletextTime_Key, 0x102A, 13); // "time", "TT_TIME"
   addKey("TEXT_ENLARGE", TeletextSize_Key, 0x102B, 13); // "Reduce_Teletext"
-  addKey("PICTURE_SETTINGS", PictureMode_Key, 0x002B, 13);
-  addKey("SOUND_SETTINGS", SoundMode_Key, 0x002C, 13);
-  addKey("GAME", Unmapped_Key, 0x002E, 13);
-  addKey("1-", DoubleDigit_Key, 0x100A, 13); // -/--
-  addKey("100", PlusOneHundred_Key, 0x100A, 13);
-  addKey("TV-Dash", Dash_Key, 0x100A, 13);
-  addKey("CP", Unmapped_Key, 0x100B, 13); // "C/P"
-  addKey("pp", PrevChannel_Key, 0x100E, 13); // "GREEN"
-  addKey("BRIGHTNESS_UP", Unmapped_Key, 0x1012, 13);
-  addKey("BRIGHTNESS_DOWN", Unmapped_Key, 0x1013, 13);
-  addKey("CONTRAST_UP", Unmapped_Key, 0x1014, 13);
-  addKey("CONTRAST_DOWN", Unmapped_Key, 0x1015, 13);
-  addKey("BASS_UP", Unmapped_Key, 0x1016, 13);
-  addKey("BASS_DOWN", Unmapped_Key, 0x1017, 13);
-  addKey("TREBLE_UP", Unmapped_Key, 0x1018, 13);
-  addKey("TREBLE_DOWN", Unmapped_Key, 0x1019, 13);
-  addKey("BALANCE_RIGHT", Unmapped_Key, 0x101A, 13);
-  addKey("BALANCE_LEFT", Unmapped_Key, 0x101B, 13);
-  addKey("TT_OUT", Unmapped_Key, 0x101D, 13);
-  addKey("TT_UPDOWN", Unmapped_Key, 0x102B, 13); // "TELETEXT_RESIZE"
-  addKey("TT_X", Unmapped_Key, 0x102D, 13); // "TELETEXT_OFF"
-  addKey("TT_TV", Unmapped_Key, 0x103F, 13);
-  addKey("TT_PLAY", Unmapped_Key, 0x101E, 13);
   addKey("TT_INFO", Unmapped_Key, 0x102C, 13); // "TELETEXT_ADDINFO"
-  addKey("TT_STOP", Unmapped_Key, 0x1029, 13);
-  addKey("TT_TIME", Unmapped_Key, 0x102A, 13);
+  addKey("TT_X", TeletextOff_Key, 0x102D, 13); // "TELETEXT_OFF"
   addKey("TT_MIX", Unmapped_Key, 0x102E, 13);
-  addKey("TELETEXT", Unmapped_Key, 0x103C, 13);
-  // The media keys are not well described!  -- config file 5373
-  addKey("RECORD", Record_Key, 0x1037, 13);
   addKey("BACK", Unmapped_Key, 0x102F, 13);
-  addKey("STOP", Stop_Key, 0x1036, 13);
-  addKey("PLAY", Play_Key, 0x1028, 13);
-  addKey("FORWARD", Unmapped_Key, 0x1035, 13);
-  addKey("REVERSE", Unmapped_Key, 0x1033, 13);
-  addKey("SKIP", Unmapped_Key, 0x1177, 13);
-  addKey("FAST_BACK", Unmapped_Key, 0x116F, 13);
-  addKey("DOWN", Unmapped_Key, 0x1176, 13);
-  addKey("PLAY_3", Unmapped_Key, 0x1168, 13);
-  addKey("FAST_FORWARD", Unmapped_Key, 0x1175, 13);
-  addKey("SCREEN_WIDTH", AspectRatio_Key, 0x003E, 13); // "format"
+
   addKey("vcr_rewind", Rewind_Key, 0x1032, 13);
+  addKey("REVERSE", Unmapped_Key, 0x1033, 13);
   addKey("vcr_fastforward", FastForward_Key, 0x1034, 13);
-  addKey("ambilight_power", Unmapped_Key, 0x10E3, 13);
-  addKey("ambilight_mode", Unmapped_Key, 0x10E4, 13);
-  addKey("fav", Favorites_Key, 0x0039, 13);
-  addKey(".", Unmapped_Key, 0x00F8, 13);
-  addKey("Cinema", Unmapped_Key, 0x00F9, 13);
+  addKey("FORWARD", Unmapped_Key, 0x1035, 13);
+  addKey("STOP", Stop_Key, 0x1036, 13);
+  addKey("RECORD", Record_Key, 0x1037, 13);
+  addKey("AV", Input_Key, 0x1038, 13); // "EXT", "SOURCE"
+  addKey("TELETEXT", Teletext_Key, 0x103C, 13);
+  addKey("TEXT_TV", TeletextAndTV_Key, 0x103C, 13); // "TELETEXT"
+//  addKey("TT_TV", TeletextAndTV_Key, 0x103F, 13);
+
+  addKey("MY_AUDIO", Unmapped_Key, 0x10D2, 13);
   addKey("PAY-TV_UP", Unmapped_Key, 0x10DC, 13);
   addKey("PAY-TV_DOWN", Unmapped_Key, 0x10DD, 13);
   addKey("RADIO_UP", Unmapped_Key, 0x10DE, 13);
   addKey("RADIO_DOWN", Unmapped_Key, 0x10DF, 13);
+  addKey("ambilight_power", Unmapped_Key, 0x10E3, 13);
+  addKey("ambilight_mode", Unmapped_Key, 0x10E4, 13);
+  addKey("BLUE", Blue_Key, 0x10F9, 13);
+
+  // The media keys are not well described!  -- config file 5373
+  addKey("FAST_BACK", Unmapped_Key, 0x116F, 13);
+  addKey("PLAY_3", Unmapped_Key, 0x1168, 13);
+  addKey("FAST_FORWARD", Unmapped_Key, 0x1175, 13);
+  addKey("DOWN", Unmapped_Key, 0x1176, 13);
+  addKey("SKIP", Unmapped_Key, 0x1177, 13);
 }
 
 
 PhilipsTV1a::PhilipsTV1a(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsTV1(guiObject, index)
+  : PhilipsTV1(index)
 {
   setKeysetName("TV Keyset 1a");
 
   addControlledDevice(Philips_Make, "17PT1563", TV_Device);
+}
+
+
+void PhilipsTV1a::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsTV1::populateProtocol(guiObject);
 
   addKey("TIMER", Sleep_Key, 0x002D, 13);
 }
 
 
 PhilipsTV1b::PhilipsTV1b(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsTV1(guiObject, index)
+  : PhilipsTV1(index)
 {
   setKeysetName("TV Keyset 1b");
 
   addControlledDevice(Philips_Make, "29PT5507", TV_Device);
+}
+
+
+void PhilipsTV1b::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsTV1::populateProtocol(guiObject);
 
-  addKey("sound", Unmapped_Key, 0x1014, 13);
   addKey("radio", Unmapped_Key, 0x00F1, 13);
+  addKey("sound", Unmapped_Key, 0x1014, 13);
   addKey("screen", Unmapped_Key, 0x1015, 13);
   addKey("rec", Record_Key, 0x002B, 13);
   addKey("rewind", Rewind_Key, 0x002C, 13);
@@ -142,11 +180,23 @@ PhilipsTV1b::PhilipsTV1b(
 
 
 PhilipsTV1c::PhilipsTV1c(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsTV1(guiObject, index)
+  : PhilipsTV1(index)
 {
   setKeysetName("TV Keyset 1c");
+}
+
+
+void PhilipsTV1c::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsTV1::populateProtocol(guiObject);
 
   addKey("spatial", Surround_Key, 0x1024, 13);
   addKey("stereo", Audio_Key, 0x1023, 13);
@@ -155,14 +205,27 @@ PhilipsTV1c::PhilipsTV1c(
 
 
 PhilipsTV1d::PhilipsTV1d(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsTV1(guiObject, index)
+  : PhilipsTV1(index)
 {
   setKeysetName("TV Keyset 1d");
 
   addControlledDevice(Philips_Make, "47PFL7603D", TV_Device);
   addControlledDevice(Philips_Make, "14PT1562/00", TV_Device);
+  addControlledDevice(Philips_Make, "32PW9528/12", TV_Device);
+}
+
+
+void PhilipsTV1d::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsTV1::populateProtocol(guiObject);
 
   addKey("NOTE_BUTTON", Unmapped_Key, 0x1014, 13); // "Tune"
   addKey("RADIO_BUTTON", Unmapped_Key, 0x00F1, 13);
@@ -180,19 +243,31 @@ PhilipsTV1d::PhilipsTV1d(
   addKey("pip_switch", PIPSwap_Key, 0x001A, 13);
   addKey("pip_prog+", PIPChannelUp_Key, 0x0026, 13);
   addKey("pip_prog-", PIPChannelDown_Key, 0x0027, 13);
-  addKey("tvtxt_index", Unmapped_Key, 0x002F, 13);
+  addKey("tvtxt_index", TeletextIndex_Key, 0x002F, 13);
 }
 
 
 PhilipsTV1e::PhilipsTV1e(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsTV1(guiObject, index)
+  : PhilipsTV1(index)
 {
   setKeysetName("TV Keyset 1e");
 
   addControlledDevice(Philips_Make, "28PT4455", TV_Device);
   addControlledDevice(Philips_Make, "21PT2265", TV_Device);
+}
+
+
+void PhilipsTV1e::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsTV1::populateProtocol(guiObject);
 
   addKey("smart_audio", SoundMode_Key, 0x10CB, 13);
   addKey("smart_video", PictureMode_Key, 0x10CA, 13);
@@ -206,13 +281,25 @@ PhilipsTV1e::PhilipsTV1e(
 
 
 PhilipsTV1f::PhilipsTV1f(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsTV1(guiObject, index)
+  : PhilipsTV1(index)
 {
   setKeysetName("TV Keyset 1f");
 
   addControlledDevice(Philips_Make, "25PT5302", TV_Device);
+}
+
+
+void PhilipsTV1f::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsTV1::populateProtocol(guiObject);
 
   addKey("SETUP", Menu_Key, 0x003A, 13);
   addKey("VOL-", VolumeDown_Key, 0x0011, 13);
@@ -231,7 +318,6 @@ PhilipsTV1f::PhilipsTV1f(
 
 
 PhilipsTV2::PhilipsTV2(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "TV Keyset 2",
@@ -241,38 +327,21 @@ PhilipsTV2::PhilipsTV2(
   addControlledDevice(Philips_Make, "28PW8506/12R", TV_Device);
   addControlledDevice(Philips_Make, "26PFL5604H", TV_Device);
   addControlledDevice(Philips_Make, "32PFL5403D", TV_Device);
+}
+
+
+void PhilipsTV2::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
 
   threadableProtocol = new RC6Protocol(guiObject, index, 0x00);
 
-  addKey("Power", Power_Key, 0x0C, 8);
-  addKey("TV", Unmapped_Key, 0x9F, 8);
-  addKey("SUBTITLE", Captions_Key, 0x4B, 8);
-  addKey("TELETEXT", Teletext_Key, 0x3C, 8);
-  addKey("SOURCE", Input_Key, 0x38, 8); // "inputselect", "external"
-  addKey("red", Red_Key, 0x6D, 8);
-  addKey("green", Green_Key, 0x6E, 8);
-  addKey("yellow", Yellow_Key, 0x6F, 8);
-  addKey("blue", Blue_Key, 0x70, 8);
-  addKey("Home", Menu_Key, 0x54, 8); // "Menu"
-  addKey("Guide", Guide_Key, 0xCC, 8); // "nextview", "EPG"
-  addKey("OPTIONS", Unmapped_Key, 0x40, 8);
-  addKey("up", Up_Key, 0x58, 8);
-  addKey("down", Down_Key, 0x59, 8);
-  addKey("left", Left_Key, 0x5A, 8);
-  addKey("right", Right_Key, 0x5B, 8);
-  addKey("OK", Select_Key, 0x5C, 8);
-  addKey("INFO", Info_Key, 0x0F, 8); // "i+"
-  addKey("<<", Rewind_Key, 0x2B, 8);
-  addKey("Play", Play_Key, 0x2C, 8);
-  addKey(">>", FastForward_Key, 0x28, 8);
-  addKey("Stop", Stop_Key, 0x31, 8); // "MHEG_Cancel"
-  addKey("Record", Record_Key, 0x37, 8);
-  addKey("Vol+", VolumeUp_Key, 0x10, 8);
-  addKey("Vol-", VolumeDown_Key, 0x11, 8);
-  addKey("Mute", Mute_Key, 0x0D, 8);
-  addKey("FORMAT", AspectRatio_Key, 0xF5, 8); // "Picture_Format", "displaymode"
-  addKey("P+", ChannelUp_Key, 0x20, 8);
-  addKey("P-", ChannelDown_Key, 0x21, 8);
+  addKey("0", Zero_Key, 0x00, 8);
   addKey("1", One_Key, 0x01, 8);
   addKey("2", Two_Key, 0x02, 8);
   addKey("3", Three_Key, 0x03, 8);
@@ -282,49 +351,110 @@ PhilipsTV2::PhilipsTV2(
   addKey("7", Seven_Key, 0x07, 8);
   addKey("8", Eight_Key, 0x08, 8);
   addKey("9", Nine_Key, 0x09, 8);
-  addKey("0", Zero_Key, 0x00, 8);
-  addKey("SOUND", SoundMode_Key, 0xF4, 8); // "smartsound"
-  addKey("PICTURE", PictureMode_Key, 0xF3, 8); // "smartdisplay"
+  addKey("Previous_channel", PrevChannel_Key, 0x0A, 8); // "PP", "AB"
+  addKey("Power", Power_Key, 0x0C, 8);
+  addKey("Mute", Mute_Key, 0x0D, 8);
+  addKey("INFO", Info_Key, 0x0F, 8); // "i+"
+
+  addKey("Vol+", VolumeUp_Key, 0x10, 8);
+  addKey("Vol-", VolumeDown_Key, 0x11, 8);
+
+  addKey("P+", ChannelUp_Key, 0x20, 8);
+  addKey("P-", ChannelDown_Key, 0x21, 8);
+  addKey(">>", FastForward_Key, 0x28, 8);
+  addKey("<<", Rewind_Key, 0x2B, 8);
+  addKey("Play", Play_Key, 0x2C, 8);
+
+  addKey("Stop", Stop_Key, 0x31, 8); // "MHEG_Cancel"
+  addKey("Record", Record_Key, 0x37, 8);
+  addKey("SOURCE", Input_Key, 0x38, 8); // "inputselect", "external"
+  addKey("TELETEXT", Teletext_Key, 0x3C, 8);
+
+  addKey("OPTIONS", Unmapped_Key, 0x40, 8);
   addKey("InstallMenu", Unmapped_Key, 0x45, 8);
+  addKey("SUBTITLE", Captions_Key, 0x4B, 8);
+  addKey("1st/2nd_language", Audio_Key, 0x4E, 8); // "monostereo"
+
+  addKey("Home", Menu_Key, 0x54, 8); // "Menu"
+  addKey("up", Up_Key, 0x58, 8);
+  addKey("down", Down_Key, 0x59, 8);
+  addKey("left", Left_Key, 0x5A, 8);
+  addKey("right", Right_Key, 0x5B, 8);
+  addKey("OK", Select_Key, 0x5C, 8);
+  addKey("Dual_Screen", PIP_Key, 0x5D, 8); // "splitdisplay"
+
+  addKey("freeze", Pause_Key, 0x67, 8); // "pause"
+  addKey("red", Red_Key, 0x6D, 8);
+  addKey("green", Green_Key, 0x6E, 8);
+  addKey("yellow", Yellow_Key, 0x6F, 8);
+  addKey("blue", Blue_Key, 0x70, 8);
   addKey("SurroundSound", Surround_Key, 0x71, 8);  // "soundselect"
   addKey("Time", Sleep_Key, 0x7F, 8); // "clock", "timer_programming"
+
   addKey("ActiveControl", Unmapped_Key, 0x96, 8);
-  addKey("Dual_Screen", PIP_Key, 0x5D, 8); // "splitdisplay"
-  addKey("Previous_channel", PrevChannel_Key, 0x0A, 8); // "PP", "AB"
-  addKey("1st/2nd_language", Audio_Key, 0x4E, 8); // "monostereo"
-  addKey("freeze", Pause_Key, 0x67, 8); // "pause"
+  addKey("TV", Unmapped_Key, 0x9F, 8);
+
+  addKey("Guide", Guide_Key, 0xCC, 8); // "nextview", "EPG"
+
   addKey("zoom", Zoom_Key, 0xE7, 8);
+  addKey("PICTURE", PictureMode_Key, 0xF3, 8); // "smartdisplay"
+  addKey("SOUND", SoundMode_Key, 0xF4, 8); // "smartsound"
+  addKey("FORMAT", AspectRatio_Key, 0xF5, 8); // "Picture_Format", "displaymode"
 }
 
 
 PhilipsTV2a::PhilipsTV2a(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsTV2(guiObject, index)
+  : PhilipsTV2(index)
 {
   setKeysetName("TV Keyset 2a");
 
   addControlledDevice(Philips_Make, "29PT8607/12", TV_Device);
+}
+
+
+void PhilipsTV2a::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsTV2::populateProtocol(guiObject);
 
-  addKey("tv-speed+", Unmapped_Key, 0x71, 8);
-  addKey("tv-speed-", Unmapped_Key, 0x6E, 8);
-  addKey("tv-play", Play_Key, 0x70, 8);
-  addKey("tv-stop", Stop_Key, 0x6F, 8);
-  addKey("tv-recording", Record_Key, 0x6D, 8);
   addKey("tv-display", Info_Key, 0x3C, 8);
   addKey("tv-teletext_submode_(J:12)", Unmapped_Key, 0x5D, 8);
+  addKey("tv-recording", Record_Key, 0x6D, 8);
+  addKey("tv-speed-", Unmapped_Key, 0x6E, 8);
+  addKey("tv-stop", Stop_Key, 0x6F, 8);
+  addKey("tv-play", Play_Key, 0x70, 8);
+  addKey("tv-speed+", Unmapped_Key, 0x71, 8);
   addKey("tv-solarization", Unmapped_Key, 0xCC, 8);
 }
 
 
 PhilipsTV2b::PhilipsTV2b(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsTV2(guiObject, index)
+  : PhilipsTV2(index)
 {
   setKeysetName("TV Keyset 2b");
 
   addControlledDevice(Philips_Make, "32PFL7532D", TV_Device);
+}
+
+
+void PhilipsTV2b::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsTV2::populateProtocol(guiObject);
 
   addKey("KEY_PLAY", Play_Key, 0xC1, 8);
   addKey("KEY_FAVORITES", Favorites_Key, 0xD2, 8);
@@ -332,7 +462,6 @@ PhilipsTV2b::PhilipsTV2b(
 
 
 PhilipsTV3::PhilipsTV3(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "TV (settop-box) keyset 3",
@@ -340,31 +469,21 @@ PhilipsTV3::PhilipsTV3(
       index)
 {
   addControlledDevice(Philips_Make, "DTX6372", TV_Device);
+}
+
+
+void PhilipsTV3::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
 
   threadableProtocol = new RC6Protocol(guiObject, index, 0x28);
 
-  addKey("power", Power_Key, 0x0C, 8);
-  addKey("text", Unmapped_Key, 0x3C, 8);
-  addKey("red", Red_Key, 0x6D, 8);
-  addKey("green", Green_Key, 0x6E, 8);
-  addKey("yellow", Yellow_Key, 0x6F, 8);
-  addKey("blue", Blue_Key, 0x70, 8);
-  addKey("menu", Menu_Key, 0x54, 8);
-  addKey("wide", AspectRatio_Key, 0xD8, 8);
-  addKey("subtitle", Captions_Key, 0x4B, 8);
-  addKey("info", Info_Key, 0x0F, 8);
-  addKey("guide", Guide_Key, 0xCC, 8);
-  addKey("select", Select_Key, 0x5C, 8);
-  addKey("exit", Exit_Key, 0x83, 8);
-  addKey("up", Up_Key, 0x58, 8);
-  addKey("left", Left_Key, 0x5A, 8);
-  addKey("right", Right_Key, 0x5B, 8);
-  addKey("down", Down_Key, 0x59, 8);
-  addKey("vol+", VolumeUp_Key, 0x10, 8);
-  addKey("vol-", VolumeDown_Key, 0x11, 8);
-  addKey("p+", ChannelUp_Key, 0x20, 8);
-  addKey("p-", ChannelDown_Key, 0x21, 8);
-  addKey("mute", Mute_Key, 0x0D, 8);
+  addKey("0", Zero_Key, 0x00, 8);
   addKey("1", One_Key, 0x01, 8);
   addKey("2", Two_Key, 0x02, 8);
   addKey("3", Three_Key, 0x03, 8);
@@ -374,13 +493,40 @@ PhilipsTV3::PhilipsTV3(
   addKey("7", Seven_Key, 0x07, 8);
   addKey("8", Eight_Key, 0x08, 8);
   addKey("9", Nine_Key, 0x09, 8);
-  addKey("0", Zero_Key, 0x00, 8);
+
+  addKey("power", Power_Key, 0x0C, 8);
+  addKey("mute", Mute_Key, 0x0D, 8);
+  addKey("info", Info_Key, 0x0F, 8);
+
+  addKey("vol+", VolumeUp_Key, 0x10, 8);
+  addKey("vol-", VolumeDown_Key, 0x11, 8);
+
+  addKey("p+", ChannelUp_Key, 0x20, 8);
+  addKey("p-", ChannelDown_Key, 0x21, 8);
+
+  addKey("text", Teletext_Key, 0x3C, 8);
+
   addKey("tv/dtv", Input_Key, 0x43, 8);
+  addKey("subtitle", Captions_Key, 0x4B, 8);
+  addKey("menu", Menu_Key, 0x54, 8);
+  addKey("up", Up_Key, 0x58, 8);
+  addKey("down", Down_Key, 0x59, 8);
+  addKey("left", Left_Key, 0x5A, 8);
+  addKey("right", Right_Key, 0x5B, 8);
+  addKey("select", Select_Key, 0x5C, 8);
+
+  addKey("red", Red_Key, 0x6D, 8);
+  addKey("green", Green_Key, 0x6E, 8);
+  addKey("yellow", Yellow_Key, 0x6F, 8);
+  addKey("blue", Blue_Key, 0x70, 8);
+  addKey("exit", Exit_Key, 0x83, 8);
+
+  addKey("guide", Guide_Key, 0xCC, 8);
+  addKey("wide", AspectRatio_Key, 0xD8, 8);
 }
 
 
 PhilipsDVD1::PhilipsDVD1(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "DVD Keyset 1",
@@ -391,28 +537,21 @@ PhilipsDVD1::PhilipsDVD1(
   addControlledDevice(Philips_Make, "DVD722", DVD_Device);
   addControlledDevice(Philips_Make, "DVD-724", DVD_Device);
   addControlledDevice(Philips_Make, "DVP 3005", DVD_Device);
+}
+
+
+void PhilipsDVD1::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
 
   threadableProtocol = new RC6Protocol(guiObject, index, 0x04);
 
-  addKey("Standby", Power_Key, 0x0C, 8);
-  addKey("Forward", FastForward_Key, 0x28, 8);
-  addKey("Rewind", Rewind_Key, 0x29, 8);
-  addKey("Stop", Stop_Key, 0x31, 8);
-  addKey("Play", Play_Key, 0x2C, 8);
-  addKey("Still", Pause_Key, 0x30, 8); // "pause"
-  addKey("Subtitle", Captions_Key, 0x4B, 8);
-  addKey("Title", DiscTitle_Key, 0x71, 8);
-  addKey("Menu", DiscMenu_Key, 0x54, 8);
-  addKey("System_Menu", Menu_Key, 0x82, 8); // "setup"
-  addKey("OK", Select_Key, 0x5C, 8);
-  addKey("Left", Left_Key, 0x5A, 8);
-  addKey("Right", Right_Key, 0x5B, 8);
-  addKey("Up", Up_Key, 0x58, 8);
-  addKey("Down", Down_Key, 0x59, 8);
-  addKey("Return", Exit_Key, 0x83, 8);
-  addKey("Skip_Right", Next_Key, 0x20, 8); // "next"
-  addKey("Skip_Left", Previous_Key, 0x21, 8); // "prev"
-  addKey("Audio", Audio_Key, 0x4E, 8);
+  addKey("0", Zero_Key, 0x00, 8);
   addKey("1", One_Key, 0x01, 8);
   addKey("2", Two_Key, 0x02, 8);
   addKey("3", Three_Key, 0x03, 8);
@@ -422,127 +561,185 @@ PhilipsDVD1::PhilipsDVD1(
   addKey("7", Seven_Key, 0x07, 8);
   addKey("8", Eight_Key, 0x08, 8);
   addKey("9", Nine_Key, 0x09, 8);
-  addKey("0", Zero_Key, 0x00, 8);
+  addKey("Standby", Power_Key, 0x0C, 8);
+  addKey("Mute", Mute_Key, 0x0D, 8);
   addKey("Display", Info_Key, 0x0F, 8);
-  addKey("Angle", Angle_Key, 0x85, 8);
-  addKey("Zoom", Zoom_Key, 0xF7, 8);
-  addKey("Repeat", Repeat_Key, 0x1D, 8);
-  addKey("Repeat_AB", RepeatAB_Key, 0x3B, 8);
+
+  addKey("dim", Unmapped_Key, 0x13, 8);
   addKey("Shuffle", Random_Key, 0x1C, 8);
+  addKey("Repeat", Repeat_Key, 0x1D, 8);
+
+  addKey("Skip_Right", Next_Key, 0x20, 8); // "next"
+  addKey("Skip_Left", Previous_Key, 0x21, 8); // "prev"
+  addKey("Forward", FastForward_Key, 0x28, 8);
+  addKey("Rewind", Rewind_Key, 0x29, 8);
   addKey("Scan", Scan_Key, 0x2A, 8);
-  addKey("Secret", Unmapped_Key, 0xEB, 8);
+  addKey("Play", Play_Key, 0x2C, 8);
+
+  addKey("Still", Pause_Key, 0x30, 8); // "pause"
+  addKey("Stop", Stop_Key, 0x31, 8);
+  addKey("Repeat_AB", RepeatAB_Key, 0x3B, 8);
+
+  addKey("open-close", Eject_Key, 0x42, 8);
+  addKey("Subtitle", Captions_Key, 0x4B, 8);
+  addKey("Audio", Audio_Key, 0x4E, 8);
+
+  addKey("sound-mode", SoundMode_Key, 0x50, 8);
+  addKey("Menu", DiscMenu_Key, 0x54, 8);
+  addKey("Up", Up_Key, 0x58, 8);
+  addKey("Down", Down_Key, 0x59, 8);
+  addKey("Left", Left_Key, 0x5A, 8);
+  addKey("Right", Right_Key, 0x5B, 8);
+  addKey("OK", Select_Key, 0x5C, 8);
+
+  addKey("Title", DiscTitle_Key, 0x71, 8);
+  addKey("System_Menu", Menu_Key, 0x82, 8); // "setup"
+  addKey("Return", Exit_Key, 0x83, 8);
+  addKey("Angle", Angle_Key, 0x85, 8);
   addKey("Preview", Unmapped_Key, 0xB5, 8);
-  addKey("Mute", Mute_Key, 0x0D, 8);
   addKey("T-C", Unmapped_Key, 0xC8, 8);
-  addKey("dim", Unmapped_Key, 0x13, 8);
+  addKey("Secret", Unmapped_Key, 0xEB, 8);
+  addKey("Zoom", Zoom_Key, 0xF7, 8);
   addKey("fts", Unmapped_Key, 0xFB, 8);
-  addKey("sound-mode", SoundMode_Key, 0x50, 8);
 }
 
 
 PhilipsDVD1a::PhilipsDVD1a(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsDVD1(guiObject, index)
+  : PhilipsDVD1(index)
 {
   setKeysetName("DVD Keyset 1a");
 
   addControlledDevice(Philips_Make, "DVP-5982", DVD_Device);
+}
+
+
+void PhilipsDVD1a::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsDVD1::populateProtocol(guiObject);
 
-  addKey("Power", Power_Key, 0xC7, 8);
   addKey("Play_Pause", Pause_Key, 0x2C, 8);
   addKey("USB", Unmapped_Key, 0x7E, 8);
+  addKey("Power", Power_Key, 0xC7, 8);
 }
 
 
 PhilipsDVD1b::PhilipsDVD1b(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsDVD1(guiObject, index)
+  : PhilipsDVD1(index)
 {
   setKeysetName("DVD Keyset 1b");
 
   addControlledDevice(Philips_Make, "DVP-642", DVD_Device);
+}
+
+
+void PhilipsDVD1b::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsDVD1::populateProtocol(guiObject);
 
-  addKey("Title", DiscTitle_Key, 0x83, 8);
   addKey("Forward", FastForward_Key, 0x20, 8);
   addKey("Reverse", Rewind_Key, 0x21, 8);
+  addKey("Title", DiscTitle_Key, 0x83, 8);
 }
 
 
 PhilipsDVD1c::PhilipsDVD1c(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsDVD1(guiObject, index)
+  : PhilipsDVD1(index)
 {
-  setKeysetName("DVD (HT) Keyset 1c");
+  setKeysetName("DVD Keyset 1c");
 
   addControlledDevice(Philips_Make, "HTS3544", DVD_Device);
   addControlledDevice(Philips_Make, "DVP5982", DVD_Device);
+  addControlledDevice(Philips_Make, "DVP5160", DVD_Device);
+}
+
+
+void PhilipsDVD1c::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsDVD1::populateProtocol(guiObject);
 
-  addKey("power", Power_Key, 0xC7, 8);
-  addKey("disc-usb", Unmapped_Key, 0x3F, 8);
-  addKey("open-close", Eject_Key, 0x42, 8);
-  addKey("program", Program_Key, 0xFB, 8);
-  addKey("menu", DiscMenu_Key, 0xD1, 8);
-  addKey("title", DiscTitle_Key, 0x83, 8);
   addKey("play-pause", Pause_Key, 0x2C, 8);
+  addKey("disc-usb", Unmapped_Key, 0x3F, 8);
   addKey("USB", Unmapped_Key, 0x7E, 8);
+  addKey("title", DiscTitle_Key, 0x83, 8);
+  addKey("power", Power_Key, 0xC7, 8);
+  addKey("menu", DiscMenu_Key, 0xD1, 8);
+  addKey("program", Program_Key, 0xFB, 8);
 }
 
 
 PhilipsDVD1d::PhilipsDVD1d(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsDVD1(guiObject, index)
+  : PhilipsDVD1(index)
 {
   setKeysetName("DVD Keyset 1d");
 
-  addControlledDevice(Philips_Make, "DVD 963sa", DVD_Device);
+  addControlledDevice(Philips_Make, "DVD 963SA", DVD_Device);
+}
+
+
+void PhilipsDVD1d::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsDVD1::populateProtocol(guiObject);
 
-  addKey("display", Info_Key, 0x48, 8);
-  addKey("ff-left", Rewind_Key, 0x21, 8);
   addKey("ff-right", FastForward_Key, 0x20, 8);
+  addKey("ff-left", Rewind_Key, 0x21, 8);
+  addKey("display", Info_Key, 0x48, 8);
 }
 
 
 PhilipsDVD2::PhilipsDVD2(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "DVD/BD Keyset 2",
       Philips_Make,
       index)
 {
+}
+
+
+void PhilipsDVD2::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
   threadableProtocol = new RC6Protocol(guiObject, index, 0x46);
 
-  addKey("power", Power_Key, 0xC7, 8);
-  addKey("topmenu", DiscTitle_Key, 0x9C, 8);
-  addKey("bonus", Unmapped_Key, 0x5D, 8);
-  addKey("repeat", Repeat_Key, 0x1D, 8);
-  addKey("hdmi", Unmapped_Key, 0xC6, 8);
-  addKey("red", Red_Key, 0x6D, 8);
-  addKey("green", Green_Key, 0x6E, 8);
-  addKey("yellow", Yellow_Key, 0x6F, 8);
-  addKey("blue", Blue_Key, 0x70, 8);
-  addKey("home", Menu_Key, 0x92, 8);
-  addKey("menu", DiscMenu_Key, 0x9A, 8);
-  addKey("options", Unmapped_Key, 0xC9, 8);
-  addKey("up", Up_Key, 0x58, 8);
-  addKey("left", Left_Key, 0x5A, 8);
-  addKey("right", Right_Key, 0x5B, 8);
-  addKey("down", Down_Key, 0x59, 8);
-  addKey("ok", Select_Key, 0x5C, 8);
-  addKey("back", Exit_Key, 0x83, 8);
-  addKey("info", Info_Key, 0x0F, 8);
-  addKey("prev", Previous_Key, 0x21, 8);
-  addKey("play", Play_Key, 0x2C, 8);
-  addKey("pause", Pause_Key, 0x30, 8);
-  addKey("next", Next_Key, 0x20, 8);
-  addKey("bwd", Rewind_Key, 0x29, 8);
-  addKey("stop", Stop_Key, 0x31, 8);
-  addKey("fwd", FastForward_Key, 0x28, 8);
-  addKey("eject", Eject_Key, 0x42, 8);
+  addKey("0", Zero_Key, 0x00, 8);
   addKey("1", One_Key, 0x01, 8);
   addKey("2", Two_Key, 0x02, 8);
   addKey("3", Three_Key, 0x03, 8);
@@ -552,14 +749,45 @@ PhilipsDVD2::PhilipsDVD2(
   addKey("7", Seven_Key, 0x07, 8);
   addKey("8", Eight_Key, 0x08, 8);
   addKey("9", Nine_Key, 0x09, 8);
-  addKey("0", Zero_Key, 0x00, 8);
+  addKey("info", Info_Key, 0x0F, 8);
+
+  addKey("repeat", Repeat_Key, 0x1D, 8);
+
+  addKey("next", Next_Key, 0x20, 8);
+  addKey("prev", Previous_Key, 0x21, 8);
+  addKey("fwd", FastForward_Key, 0x28, 8);
+  addKey("bwd", Rewind_Key, 0x29, 8);
+  addKey("play", Play_Key, 0x2C, 8);
+  addKey("pause", Pause_Key, 0x30, 8);
+  addKey("stop", Stop_Key, 0x31, 8);
+
+  addKey("eject", Eject_Key, 0x42, 8);
   addKey("subtitle", Captions_Key, 0x4B, 8);
   addKey("audio", Audio_Key, 0x4E, 8);
+
+  addKey("up", Up_Key, 0x58, 8);
+  addKey("down", Down_Key, 0x59, 8);
+  addKey("left", Left_Key, 0x5A, 8);
+  addKey("right", Right_Key, 0x5B, 8);
+  addKey("ok", Select_Key, 0x5C, 8);
+  addKey("bonus", Unmapped_Key, 0x5D, 8);
+
+  addKey("red", Red_Key, 0x6D, 8);
+  addKey("green", Green_Key, 0x6E, 8);
+  addKey("yellow", Yellow_Key, 0x6F, 8);
+  addKey("blue", Blue_Key, 0x70, 8);
+
+  addKey("back", Exit_Key, 0x83, 8);
+  addKey("home", Menu_Key, 0x92, 8);
+  addKey("menu", DiscMenu_Key, 0x9A, 8);
+  addKey("topmenu", DiscTitle_Key, 0x9C, 8);
+  addKey("hdmi", HDMIInput_Key, 0xC6, 8);
+  addKey("power", Power_Key, 0xC7, 8);
+  addKey("options", Unmapped_Key, 0xC9, 8);
 }
 
 
 PhilipsDVD3::PhilipsDVD3(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "DVD Keyset 3",
@@ -567,43 +795,20 @@ PhilipsDVD3::PhilipsDVD3(
       index)
 {
   addControlledDevice(Philips_Make, "DVDR3570H", DVD_Device);
+}
+
+
+void PhilipsDVD3::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
 
   threadableProtocol = new RC6Protocol(guiObject, index, 0x32);
 
-  addKey("Power", Power_Key, 0x0C, 8);
-  addKey("Edit", Unmapped_Key, 0xF1, 8);
-  addKey("LiveTV", LiveTV_Key, 0xEE, 8);
-  addKey("Disc", DiscMenu_Key, 0xD1, 8);
-  addKey("Select", Unmapped_Key, 0xC9, 8);
-  addKey("Cam", Unmapped_Key, 0xC3, 8);
-  addKey("TVGuide", Guide_Key, 0xC2, 8);
-  addKey("Home", Menu_Key, 0x92, 8);
-  addKey("HDDLIst", Unmapped_Key, 0x90, 8);
-  addKey("Back", Unmapped_Key, 0x83, 8);
-  addKey("Options", Unmapped_Key, 0x82, 8);
-  addKey("USB", Unmapped_Key, 0x7E, 8);
-  addKey("Blue", Blue_Key, 0x70, 8);
-  addKey("Yellow", Yellow_Key, 0x6F, 8);
-  addKey("Green", Green_Key, 0x6E, 8);
-  addKey("Red", Red_Key, 0x6D, 8);
-  addKey("OK", Select_Key, 0x5C, 8);
-  addKey("Right", Right_Key, 0x5B, 8);
-  addKey("Left", Left_Key, 0x5A, 8);
-  addKey("Down", Down_Key, 0x59, 8);
-  addKey("Up", Up_Key, 0x58, 8);
-  addKey("Audio", Audio_Key, 0x4E, 8);
-  addKey("Subtitle", Captions_Key, 0x4B, 8);
-  addKey("Scart", Unmapped_Key, 0x43, 8);
-  addKey("Rec", Record_Key, 0x37, 8);
-  addKey("Stop", Stop_Key, 0x31, 8);
-  addKey("Play", Play_Key, 0x2C, 8);
-  addKey("Rew", Rewind_Key, 0x29, 8);
-  addKey("Ffw", FastForward_Key, 0x28, 8);
-  addKey("Prev", Previous_Key, 0x21, 8);
-  addKey("Next", Next_Key, 0x20, 8);
-  addKey("Ch-", ChannelDown_Key, 0x10, 8);
-  addKey("Ch+", ChannelUp_Key, 0x11, 8);
-  addKey("Info", Info_Key, 0x0F, 8);
   addKey("0", Zero_Key, 0x00, 8);
   addKey("1", One_Key, 0x01, 8);
   addKey("2", Two_Key, 0x02, 8);
@@ -614,11 +819,95 @@ PhilipsDVD3::PhilipsDVD3(
   addKey("7", Seven_Key, 0x07, 8);
   addKey("8", Eight_Key, 0x08, 8);
   addKey("9", Nine_Key, 0x09, 8);
+  addKey("Power", Power_Key, 0x0C, 8);
+  addKey("Info", Info_Key, 0x0F, 8);
+
+  addKey("Ch-", ChannelDown_Key, 0x10, 8);
+  addKey("Ch+", ChannelUp_Key, 0x11, 8);
+  addKey("shuffle", Random_Key, 0x1C, 8);
+  addKey("repeat", Repeat_Key, 0x1D, 8);
+
+  addKey("Next", Next_Key, 0x20, 8);
+  addKey("Prev", Previous_Key, 0x21, 8);
+  addKey("Ffw", FastForward_Key, 0x28, 8);
+  addKey("Rew", Rewind_Key, 0x29, 8);
+  addKey("Play", Play_Key, 0x2C, 8);
+  addKey("Play", Pause_Key, 0x2C, 8);
+  addKey("Stop", Stop_Key, 0x31, 8);
+  addKey("Rec", Record_Key, 0x37, 8);
+
+  addKey("Scart", ScartInput_Key, 0x43, 8);
+  addKey("Subtitle", Captions_Key, 0x4B, 8);
+  addKey("Audio", Audio_Key, 0x4E, 8);
+
+  addKey("Up", Up_Key, 0x58, 8);
+  addKey("Down", Down_Key, 0x59, 8);
+  addKey("Left", Left_Key, 0x5A, 8);
+  addKey("Right", Right_Key, 0x5B, 8);
+  addKey("OK", Select_Key, 0x5C, 8);
+  addKey("inputnext", Input_Key, 0x5E, 8);
+
+  addKey("Last_ch", PrevChannel_Key, 0x6A, 8);
+  addKey("Red", Red_Key, 0x6D, 8);
+  addKey("Green", Green_Key, 0x6E, 8);
+  addKey("Yellow", Yellow_Key, 0x6F, 8);
+  addKey("Blue", Blue_Key, 0x70, 8);
+  addKey("USB", Unmapped_Key, 0x7E, 8);
+
+  addKey("Options", Unmapped_Key, 0x82, 8);
+  addKey("Back", Exit_Key, 0x83, 8); // "Exit"
+  addKey("angle", Angle_Key, 0x85, 8);
+  addKey("inoputtuner", TunerInput_Key, 0x8A, 8);
+
+  addKey("HDDList", Unmapped_Key, 0x90, 8);
+  addKey("Home", Menu_Key, 0x92, 8);
+
+  addKey("TVGuide", Guide_Key, 0xC2, 8);
+  addKey("Cam", Unmapped_Key, 0xC3, 8);
+  addKey("t/c", Unmapped_Key, 0xC8, 8); // title/chapter
+  addKey("Select", Unmapped_Key, 0xC9, 8); // "menuselect"
+
+  addKey("Disc", DiscMenu_Key, 0xD1, 8);
+  addKey("zoom", Zoom_Key, 0xD3, 8);
+  addKey("LiveTV", LiveTV_Key, 0xEE, 8);
+  addKey("Edit", Unmapped_Key, 0xF1, 8);
+  addKey("timer", Timer_Key, 0xFE, 8);
+}
+
+
+PhilipsDVD3a::PhilipsDVD3a(
+  unsigned int index)
+  : PhilipsDVD3(index)
+{
+  setKeysetName("DVD Keyset 3a");
+
+  addControlledDevice(Philips_Make, "DVDR-3455H", DVD_Device);
+}
+
+
+void PhilipsDVD3a::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsDVD3::populateProtocol(guiObject);
+
+  addKey("CH+", ChannelUp_Key, 0x1E, 8);
+  addKey("CH-", ChannelDown_Key, 0x1F, 8);
+  addKey("Menu", Menu_Key, 0x54, 8);
+  addKey("InputDVD", Unmapped_Key, 0x90, 8);
+  addKey("InputHDD", Unmapped_Key, 0x92, 8);
+  addKey("inputusb", USBInput_Key, 0xC3, 8);
+  addKey("Audio", Audio_Key, 0xD2, 8);
+  addKey("Record", Record_Key, 0xF3, 8);
 }
 
 
 PhilipsDVD4::PhilipsDVD4(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "DVD Keyset 4",
@@ -626,32 +915,21 @@ PhilipsDVD4::PhilipsDVD4(
       index)
 {
   addControlledDevice(Philips_Make, "DVDR 1000", DVD_Device);
+}
+
+
+void PhilipsDVD4::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
 
   threadableProtocol = new RC6Protocol(guiObject, index, 0x30);
 
-  addKey("Power", Power_Key, 0x0C, 8);
-  addKey("TVDVD", Input_Key, 0x43, 8);
-  addKey("STOP", Stop_Key, 0x31, 8);
-  addKey("RECORD", Record_Key, 0x37, 8);
-  addKey("PLAY", Play_Key, 0x2C, 8);
-  addKey("REWIND", Rewind_Key, 0x29, 8);
-  addKey("PAUSE", Pause_Key, 0x30, 8);
-  addKey("SLOW", Slow_Key, 0x22, 8);
-  addKey("FORWARD", FastForward_Key, 0x28, 8);
-  addKey("PREVIOUS", Previous_Key, 0x21, 8);
-  addKey("NEXT", Next_Key, 20, 8);
-  addKey("DISC", Unmapped_Key, 0x54, 8);
-  addKey("EDIT", Unmapped_Key, 0xCF, 8);
-  addKey("SYSTEM", Info_Key, 0x0F, 8);
-  addKey("UP", Up_Key, 0x58, 8);
-  addKey("DOWN", Down_Key, 0x59, 8);
-  addKey("LEFT", Left_Key, 0x5A, 8);
-  addKey("RIGHT", Right_Key, 0x5B, 8);
-  addKey("CLEAR", Clear_Key, 0x41, 8);
-  addKey("TIMER", Timer_Key, 0xFE, 8);
-  addKey("SELECT", Select_Key, 0xFA, 8);
-  addKey("PROGPLUS", ChannelUp_Key, 0x1E, 8);
-  addKey("PROGMINUS", ChannelDown_Key, 0x1F, 8);
+  addKey("0", Zero_Key, 0x00, 8);
   addKey("1", One_Key, 0x01, 8);
   addKey("2", Two_Key, 0x02, 8);
   addKey("3", Three_Key, 0x03, 8);
@@ -661,28 +939,70 @@ PhilipsDVD4::PhilipsDVD4(
   addKey("7", Seven_Key, 0x07, 8);
   addKey("8", Eight_Key, 0x08, 8);
   addKey("9", Nine_Key, 0x09, 8);
-  addKey("0", Zero_Key, 0x00, 8);
-  addKey("TC", Unmapped_Key, 0xC8, 8);
-  addKey("TUNER", Unmapped_Key, 0xEE, 8);
-  addKey("ZOOM", Zoom_Key, 0xF7, 8);
-  addKey("ANGLE", Angle_Key, 0x85, 8);
-  addKey("SUBTITLE", Captions_Key, 0x4B, 8);
-  addKey("AUDIO", Audio_Key, 0x4E, 8);
+
+  addKey("Power", Power_Key, 0x0C, 8);
+  addKey("SYSTEM", Info_Key, 0x0F, 8);
+
   addKey("DIM", Unmapped_Key, 0x13, 8);
   addKey("REPEAT", Repeat_Key, 0x1D, 8);
-  addKey("REPEATAB", RepeatAB_Key, 0x3B, 8);
+  addKey("PROGPLUS", ChannelUp_Key, 0x1E, 8);
+  addKey("PROGMINUS", ChannelDown_Key, 0x1F, 8);
+
+  addKey("NEXT", Next_Key, 0x20, 8);
+  addKey("PREVIOUS", Previous_Key, 0x21, 8);
+  addKey("SLOW", Slow_Key, 0x22, 8);
+  addKey("FORWARD", FastForward_Key, 0x28, 8);
+  addKey("REWIND", Rewind_Key, 0x29, 8);
   addKey("SCAN", Scan_Key, 0x2A, 8);
+  addKey("PLAY", Play_Key, 0x2C, 8);
+  addKey("PAUSE", Pause_Key, 0x30, 8);
+  addKey("STOP", Stop_Key, 0x31, 8);
+  addKey("RECORD", Record_Key, 0x37, 8);
+  addKey("REPEATAB", RepeatAB_Key, 0x3B, 8);
+
+  addKey("CLEAR", Clear_Key, 0x41, 8);
+  addKey("TVDVD", Input_Key, 0x43, 8);
+  addKey("SUBTITLE", Captions_Key, 0x4B, 8);
+  addKey("AUDIO", Audio_Key, 0x4E, 8);
+
+  addKey("DISC", Unmapped_Key, 0x54, 8);
+  addKey("UP", Up_Key, 0x58, 8);
+  addKey("DOWN", Down_Key, 0x59, 8);
+  addKey("LEFT", Left_Key, 0x5A, 8);
+  addKey("RIGHT", Right_Key, 0x5B, 8);
+
+  addKey("ANGLE", Angle_Key, 0x85, 8);
+
+  addKey("TC", Unmapped_Key, 0xC8, 8);
+  addKey("EDIT", Unmapped_Key, 0xCF, 8);
+
+  addKey("TUNER", TunerInput_Key, 0xEE, 8);
+
+  addKey("ZOOM", Zoom_Key, 0xF7, 8);
+  addKey("SELECT", Select_Key, 0xFA, 8);
+  addKey("TIMER", Timer_Key, 0xFE, 8);
 }
 
 
 PhilipsVCR1::PhilipsVCR1(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "VCR Keyset 1",
       Philips_Make,
       index)
 {
+}
+
+
+void PhilipsVCR1::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
   threadableProtocol = new RC5Protocol(guiObject, index);
 
   addKey("Standby", Power_Key, 0x114C, 13);
@@ -717,10 +1037,10 @@ PhilipsVCR1::PhilipsVCR1(
   addKey("-/--", DoubleDigit_Key, 0x114A, 13);
   addKey("100", PlusOneHundred_Key, 0x114A, 13);
   addKey("VCR-Dash", Dash_Key, 0x114A, 13);
-  addKey("Index", Unmapped_Key, 0x0170, 13);
+  addKey("Index", IndexSearch_Key, 0x0170, 13);
   addKey("reset", Reset_Key, 0x1171, 13); // "clear"
   addKey("play<", Unmapped_Key, 0x116F, 13);
-  addKey("x>", Unmapped_Key, 0x116A, 13); // "X2_PLAY"
+  addKey("x>", PlayX2_Key, 0x116A, 13); // "X2_PLAY"
   addKey("speed", VHSSpeed_Key, 0x117A, 13); // "SP/LP"
   addKey("Childlock", Unmapped_Key, 0x017F, 13);
   addKey("System", Unmapped_Key, 0x094A, 13);
@@ -738,13 +1058,25 @@ PhilipsVCR1::PhilipsVCR1(
 
 
 PhilipsVCR1a::PhilipsVCR1a(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsVCR1(guiObject, index)
+  : PhilipsVCR1(index)
 {
   setKeysetName("VCR Keyset 1a");
 
   addControlledDevice(Philips_Make, "VP27/55", VCR_Device);
+}
+
+
+void PhilipsVCR1a::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsVCR1::populateProtocol(guiObject);
 
   addKey("menu", Menu_Key, 0x115D, 13);
   addKey("eject", Eject_Key, 0x116D, 13);
@@ -758,11 +1090,23 @@ PhilipsVCR1a::PhilipsVCR1a(
 
 
 PhilipsVCR1b::PhilipsVCR1b(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsVCR1(guiObject, index)
+  : PhilipsVCR1(index)
 {
   setKeysetName("VCR Keyset 1b");
+}
+
+
+void PhilipsVCR1b::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsVCR1::populateProtocol(guiObject);
 
   addKey("Cassette_Eject", Eject_Key, 0x017E, 13);
   addKey("Select", Select_Key, 0x114B, 13);
@@ -771,17 +1115,29 @@ PhilipsVCR1b::PhilipsVCR1b(
   addKey("Previous", Previous_Key, 0x0171, 13);
   addKey("Next", Next_Key, 0x0170, 13);
   addKey("Monitor", Unmapped_Key, 0x017A, 13);
-  addKey("Tuner", Unmapped_Key, 0x017D, 13);
+  addKey("Tuner", TunerInput_Key, 0x017D, 13);
   addKey("Tracking", AutoTracking_Key, 0x114E, 13);
 }
 
 
 PhilipsVCR1c::PhilipsVCR1c(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsVCR1(guiObject, index)
+  : PhilipsVCR1(index)
 {
   setKeysetName("VCR Keyset 1c");
+}
+
+
+void PhilipsVCR1c::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsVCR1::populateProtocol(guiObject);
 
   addKey("TIMER_REVIEW", Unmapped_Key, 0x0168, 13);
   addKey("DATE_UP", Unmapped_Key, 0x125C, 13);
@@ -797,28 +1153,39 @@ PhilipsVCR1c::PhilipsVCR1c(
   addKey("Previous", Previous_Key, 0x0171, 13);
   addKey("Next", Next_Key, 0x0170, 13);
   addKey("SET_CLOCK", Unmapped_Key, 0x1164, 13);
-  addKey("VPS", Unmapped_Key, 0x114B, 13);
+  addKey("VPS", RecordPDC_Key, 0x114B, 13);
   addKey("Cassette", Eject_Key, 0x017E, 13);
   addKey("DECODER", Unmapped_Key, 0x0169, 13);
-  addKey("Tuner", Unmapped_Key, 0x017D, 13);
+  addKey("Tuner", TunerInput_Key, 0x017D, 13);
   addKey("Monitor", Unmapped_Key, 0x017A, 13);
   addKey("SYSTEM", Unmapped_Key, 0x014A, 13);
   addKey("REC_MODE", Unmapped_Key, 0x115E, 13);
-  addKey("SHOWVIEW", Unmapped_Key, 0x0145, 13);
+  addKey("SHOWVIEW", Unmapped_Key, 0x0145, 13); // vhsplus+, etc.
   addKey("DW", Unmapped_Key, 0x0144, 13); // "D/W"
-  addKey("SPEED-", Unmapped_Key, 0x1165, 13);
-  addKey("SPEED+", Unmapped_Key, 0x1166, 13);
+  addKey("SPEED-", SlowMinus_Key, 0x1165, 13);
+  addKey("SPEED+", SlowPlus_Key, 0x1166, 13);
 }
 
 
 PhilipsSat1::PhilipsSat1(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "Sat Keyset 1",
       Philips_Make,
       index)
 {
+}
+
+
+void PhilipsSat1::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
   threadableProtocol = new RC5Protocol(guiObject, index);
 
   addKey("Standby", Power_Key, 0x120C, 13);
@@ -868,7 +1235,6 @@ PhilipsSat1::PhilipsSat1(
 
 
 PhilipsSat2::PhilipsSat2(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "Sat Keyset 2",
@@ -876,6 +1242,17 @@ PhilipsSat2::PhilipsSat2(
       index)
 {
   addControlledDevice(Philips_Make, "DSX-5500", Sat_Device);
+}
+
+
+void PhilipsSat2::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
 
   threadableProtocol = new RC6Protocol(guiObject, index, 0x27);
 
@@ -916,13 +1293,25 @@ PhilipsSat2::PhilipsSat2(
 
 
 PhilipsSat2a::PhilipsSat2a(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsSat2(guiObject, index)
+  : PhilipsSat2(index)
 {
   setKeysetName("Sat Keyset 2a");
 
   addControlledDevice(Philips_Make, "DSX 6010/62A", Sat_Device);
+}
+
+
+void PhilipsSat2a::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsSat2::populateProtocol(guiObject);
 
   addKey("ch+", ChannelUp_Key, 0x58, 8);
   addKey("ch-", ChannelDown_Key, 0x59, 8);
@@ -938,7 +1327,6 @@ PhilipsSat2a::PhilipsSat2a(
 
 
 PhilipsSat3::PhilipsSat3(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "Sat Keyset 3",
@@ -946,16 +1334,38 @@ PhilipsSat3::PhilipsSat3(
       index)
 {
   addControlledDevice(Philips_Make, "DST5816/33", Sat_Device);
+}
+
+
+void PhilipsSat3::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
 
   threadableProtocol = new RC5Protocol(guiObject, index);
 
-  addKey("INFO", Info_Key, 0x128F, 13); // "pilot"
+  addKey("SOUNDOFF", Mute_Key, 0x0286, 13); // "mute"
   addKey("EPG", Guide_Key, 0x028F, 13); // "prog"
   addKey("UP", Up_Key, 0x0290, 13);
   addKey("DOWN", Down_Key, 0x0291, 13);
+  addKey("SERV", Unmapped_Key, 0x0292, 13);
+  addKey("BACK", Unmapped_Key, 0x0293, 13); // "av"
   addKey("LEFT", Left_Key, 0x0295, 13);
   addKey("RIGHT", Right_Key, 0x0296, 13);
   addKey("OK", Select_Key, 0x0297, 13);
+  addKey("FRONT", Unmapped_Key, 0x02A1, 13); // "twoje"
+  addKey("MENU", Menu_Key, 0x02AA, 13); // "perso"
+  addKey("A", Unmapped_Key, 0x02AB, 13);
+  addKey("B", Unmapped_Key, 0x02AC, 13);
+  addKey("C", Unmapped_Key, 0x02AD, 13);
+  addKey("D", Unmapped_Key, 0x02AE, 13);
+  addKey("E", Unmapped_Key, 0x02AF, 13);
+
+  addKey("0", Zero_Key, 0x1280, 13);
   addKey("1", One_Key, 0x1281, 13);
   addKey("2", Two_Key, 0x1282, 13);
   addKey("3", Three_Key, 0x1283, 13);
@@ -965,25 +1375,14 @@ PhilipsSat3::PhilipsSat3(
   addKey("7", Seven_Key, 0x1287, 13);
   addKey("8", Eight_Key, 0x1288, 13);
   addKey("9", Nine_Key, 0x1289, 13);
-  addKey("0", Zero_Key, 0x1280, 13);
-  addKey("FRONT", Unmapped_Key, 0x02A1, 13); // "twoje"
-  addKey("BACK", Unmapped_Key, 0x0293, 13); // "av"
-  addKey("SERV", Unmapped_Key, 0x0292, 13);
-  addKey("+", Unmapped_Key, 0x12AF, 13);
-  addKey("MENU", Menu_Key, 0x02AA, 13); // "perso"
-  addKey("A", Unmapped_Key, 0x02AB, 13);
-  addKey("B", Unmapped_Key, 0x02AC, 13);
-  addKey("C", Unmapped_Key, 0x02AD, 13);
-  addKey("D", Unmapped_Key, 0x02AE, 13);
-  addKey("E", Unmapped_Key, 0x02AF, 13);
-  addKey("SOUNDOFF", Mute_Key, 0x0286, 13); // "mute"
-  addKey("TV/SAT", Input_Key, 0x12A8, 13);
   addKey("STANDBY", Power_Key, 0x128C, 13);
+  addKey("INFO", Info_Key, 0x128F, 13); // "pilot"
+  addKey("TV/SAT", Input_Key, 0x12A8, 13);
+  addKey("+", Unmapped_Key, 0x12AF, 13);
 }
 
 
 PhilipsAudio1::PhilipsAudio1(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "Audio Keyset 1",
@@ -998,10 +1397,21 @@ PhilipsAudio1::PhilipsAudio1(
   addControlledDevice(Philips_Make, "AZ2407", Audio_Device);
   addControlledDevice(Philips_Make, "MZ7", Audio_Device);
   addControlledDevice(Philips_Make, "AS680C", Audio_Device);
+}
+
+
+void PhilipsAudio1::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
 
   threadableProtocol = new RC5Protocol(guiObject, index);
 
-  addKey("Dynamic Bass Boost", Unmapped_Key, 0x0406, 13); // "dbb"
+  addKey("Dynamic Bass Boost", EnhancedBass_Key, 0x0406, 13); // "dbb"
   addKey("Digital Sound Control", Unmapped_Key, 0x040F, 13); // "dsc"
   addKey("mute", Mute_Key, 0x140D, 13);
   addKey("Vol+", VolumeUp_Key, 0x1410, 13);
@@ -1012,7 +1422,7 @@ PhilipsAudio1::PhilipsAudio1(
   addKey("tuner_next", Next_Key, 0x1460, 13); // "presetUp"
   addKey("tuner_previous", Previous_Key, 0x1461, 13); // "presetDown"
   addKey("tuner_program", Program_Key, 0x047A, 13); // Create Preset
-  addKey("tuner", TunerBand_Key, 0x147F, 13);
+  addKey("tuner", TunerInput_Key, 0x147F, 13);
   addKey("tape_power", Unmapped_Key, 0x148C, 13);
   addKey("tape_next", Unmapped_Key, 0x14A0, 13);
   addKey("tape_previous", Unmapped_Key, 0x14A1, 13);
@@ -1036,16 +1446,16 @@ PhilipsAudio1::PhilipsAudio1(
   addKey("cd_1", One_Key, 0x1537, 13);
   addKey("cd_2", Two_Key, 0x1538, 13);
   addKey("cd_3", Three_Key, 0x1539, 13);
-  addKey("cd", Unmapped_Key, 0x153F, 13);
+  addKey("cd", CDInput_Key, 0x153F, 13);
   addKey("aux_power", Unmapped_Key, 0x154C, 13); // "power", "standby"
-  addKey("aux", Unmapped_Key, 0x157F, 13);
+  addKey("aux", AuxInput_Key, 0x157F, 13);
   addKey("DPL", Unmapped_Key, 0x1425, 13);
   addKey("SleepTimer", Sleep_Key, 0x1426, 13);
-  addKey("Rear+", Unmapped_Key, 0x0401, 13);
-  addKey("Rear-", Unmapped_Key, 0x0402, 13);
+  addKey("Rear+", RearVolumeUp_Key, 0x0401, 13);
+  addKey("Rear-", RearVolumeDown_Key, 0x0402, 13);
   addKey("TestTone", Unmapped_Key, 0x0418, 13);
-  addKey("Center+", Unmapped_Key, 0x0426, 13);
-  addKey("Center-", Unmapped_Key, 0x0427, 13);
+  addKey("Center+", CenterVolumeUp_Key, 0x0426, 13);
+  addKey("Center-", CenterVolumeDown_Key, 0x0427, 13);
   addKey("incredible_surround", Surround_Key, 0x0400, 13); // "inc_s"
   addKey("osm", Unmapped_Key, 0x042C, 13);
   addKey("vec", Unmapped_Key, 0x042B, 13);
@@ -1056,12 +1466,12 @@ PhilipsAudio1::PhilipsAudio1(
   addKey("TIMER", Timer_Key, 0x142A, 13);
   addKey("FLAT", Unmapped_Key, 0x1434, 13);
   addKey("LOUDNESS", Unmapped_Key, 0x1432, 13);
-  addKey("BASS_UP", Unmapped_Key, 0x1416, 13);
-  addKey("BASS_DOWN", Unmapped_Key, 0x1417, 13);
-  addKey("TREBLE_UP", Unmapped_Key, 0x1418, 13);
-  addKey("TREBLE_DOWN", Unmapped_Key, 0x1419, 13);
-  addKey("BALANCE_RIGHT", Right_Key, 0x141A, 13); // "BalR"
-  addKey("BALANCE_LEFT", Left_Key, 0x141B, 13); // "BalL"
+  addKey("BASS_UP", BassUp_Key, 0x1416, 13);
+  addKey("BASS_DOWN", BassDown_Key, 0x1417, 13);
+  addKey("TREBLE_UP", TrebleUp_Key, 0x1418, 13);
+  addKey("TREBLE_DOWN", TrebleDown_Key, 0x1419, 13);
+  addKey("BALANCE_RIGHT", BalanceRight_Key, 0x141A, 13); // "BalR"
+  addKey("BALANCE_LEFT", BalanceLeft_Key, 0x141B, 13); // "BalL"
   addKey("TUNER_DISPLAY", Unmapped_Key, 0x144F, 13);
   addKey("CDR", Unmapped_Key, 0x16BF, 13);
   addKey("CDR_POWER", Unmapped_Key, 0x100C, 13);
@@ -1080,13 +1490,25 @@ PhilipsAudio1::PhilipsAudio1(
 
 
 PhilipsAudio1a::PhilipsAudio1a(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsAudio1(guiObject, index)
+  : PhilipsAudio1(index)
 {
   setKeysetName("Audio Keyset 1a");
 
   addControlledDevice(Philips_Make, "C 380", Audio_Device);
+}
+
+
+void PhilipsAudio1a::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsAudio1::populateProtocol(guiObject);
 
   addKey("VOL-", VolumeDown_Key, 0x1511, 13);
   addKey("VOL+", VolumeUp_Key, 0x1510, 13);
@@ -1094,17 +1516,29 @@ PhilipsAudio1a::PhilipsAudio1a(
 
 
 PhilipsAudio1b::PhilipsAudio1b(
-  QObject *guiObject,
   unsigned int index)
-  : PhilipsAudio1(guiObject, index)
+  : PhilipsAudio1(index)
 {
   setKeysetName("Audio Keyset 1b");
 
   addControlledDevice(Philips_Make, "FW 362", Audio_Device);
+}
+
+
+void PhilipsAudio1b::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  PhilipsAudio1::populateProtocol(guiObject);
 
   addKey("tv_power", Unmapped_Key, 0x100C, 13);
-  addKey("tv_vcr", Unmapped_Key, 0x103F, 13);
-  addKey("tape1", Unmapped_Key, 0x14AC, 13);
+  addKey("tv_vcr", VCRInput_Key, 0x103F, 13);
+  addKey("tape1", TapeInput_Key, 0x14AC, 13);
   addKey("tape2", Unmapped_Key, 0x14AE, 13);
   addKey("play", Play_Key, 0x1175, 13);
   addKey("pause", Pause_Key, 0x1170, 13);
@@ -1113,12 +1547,11 @@ PhilipsAudio1b::PhilipsAudio1b(
   addKey("skip_back", Previous_Key, 0x1021, 13);
   addKey("forw", FastForward_Key, 0x1010, 13);
   addKey("back", Rewind_Key, 0x1011, 13);
-  addKey("disc_up", Unmapped_Key, 0x151E, 13);
+  addKey("disc_up", NextDisc_Key, 0x151E, 13);
 }
 
 
 PhilipsAudio2::PhilipsAudio2(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "Audio Keyset 2",
@@ -1126,16 +1559,27 @@ PhilipsAudio2::PhilipsAudio2(
       index)
 {
   addControlledDevice(Philips_Make, "FW2104", Audio_Device);
+}
 
-  threadableProtocol = new NECProtocol(guiObject, index, Extended_NEC);
+
+void PhilipsAudio2::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
+  threadableProtocol = new NECProtocol(guiObject, index, true, false);
 
 //  setPreData(0x61CA, 16);
   setPreData(0x5386, 16);
 
   addKey("POWER", Power_Key, 0x01, 8);
-  addKey("TAPE", Unmapped_Key, 0x02, 8);
-  addKey("CD", Unmapped_Key, 0x03, 8);
-  addKey("TUNER", TunerBand_Key, 0x04, 8);
+  addKey("TAPE", TapeInput_Key, 0x02, 8);
+  addKey("CD", CDInput_Key, 0x03, 8);
+  addKey("TUNER", TunerInput_Key, 0x04, 8);
   addKey("MUTE", Mute_Key, 0x06, 8);
   addKey("VOL_UP", VolumeUp_Key, 0x07, 8);
   addKey("VOL_DOWN", VolumeDown_Key, 0x08, 8);
@@ -1144,7 +1588,7 @@ PhilipsAudio2::PhilipsAudio2(
   addKey("SNOOZE", Unmapped_Key, 0x0B, 8);
   addKey("SLEEP", Sleep_Key, 0x0C, 8);
   addKey("TIMER", Timer_Key, 0x0D, 8);
-  addKey("AUX", Unmapped_Key, 0x05, 8);
+  addKey("AUX", AuxInput_Key, 0x05, 8);
   addKey("REP_A_B", RepeatAB_Key, 0x13, 8);
   addKey("MEMORY", Program_Key, 0x14, 8);
   addKey("CANCEL", Clear_Key, 0x15, 8);
@@ -1187,7 +1631,6 @@ PhilipsAudio2::PhilipsAudio2(
 // This CD control is different enough from Audio1 that I figured I should
 // give it an entirely new keyset:
 PhilipsAudio3::PhilipsAudio3(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "Audio Keyset 3",
@@ -1195,6 +1638,17 @@ PhilipsAudio3::PhilipsAudio3(
       index)
 {
   addControlledDevice(Philips_Make, "CD723", Audio_Device);
+}
+
+
+void PhilipsAudio3::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
 
   threadableProtocol = new RC5Protocol(guiObject, index);
 
@@ -1230,13 +1684,24 @@ PhilipsAudio3::PhilipsAudio3(
 
 
 PhilipsAudio4::PhilipsAudio4(
-  QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
       "Audio Keyset 4",
       Philips_Make,
       index)
 {
+}
+
+
+void PhilipsAudio4::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // If the pointer is not null, the keyset must already be populated.
+    return;
+  }
+
   threadableProtocol = new RC5Protocol(guiObject, index);
 
   addKey("EJECT", Eject_Key, 0x16AD, 13);