Modprobe scripts now working! Plus JVC keyset.
authorJohn Pietrzak <john@pietrzak.org>
Mon, 9 Jan 2012 21:37:18 +0000 (16:37 -0500)
committerJohn Pietrzak <john@pietrzak.org>
Mon, 9 Jan 2012 21:37:18 +0000 (16:37 -0500)
Finally got the scripts to load and unload lirc_rx51 kernel module working
correctly.  This means, the app is finally ready for normal human beings to
play around with.  (If only I could get Qt to actually construct a debian
package for me now...)  Plus, a JVC keyset has been constructed, and a new
application icon created.

25 files changed:
PierogiResources.qrc
doc/about.html
doc/documentation.html
icons/PierogiIcon.png
keysets/apple.cpp
keysets/jvc.cpp [new file with mode: 0644]
keysets/jvc.h [new file with mode: 0644]
keysets/rca.cpp
keysets/westinghouse.cpp
main.cpp
mainwindow.cpp
mainwindow.h
necprotocol.cpp
necprotocol.h
pierogi.pro
pierogi.pro.user
pierogi64.png
pirkeysetmanager.cpp
pirmakenames.cpp
pirmakenames.h
pirmodprobe.cpp
pirmodprobe.h
selectionwindow.h
welcome [deleted file]
www/index.html

index af8072e..fbbcb26 100644 (file)
@@ -13,7 +13,6 @@
         <file>icons/playback_pause_icon&amp;48.png</file>
         <file>icons/playback_play_icon&amp;48.png</file>
         <file>icons/playback_prev_icon&amp;48.png</file>
-        <file>icons/playback_rec_icon&amp;48.png</file>
         <file>icons/playback_rew_icon&amp;48.png</file>
         <file>icons/playback_stop_icon&amp;48.png</file>
         <file>icons/redo_icon&amp;48.png</file>
@@ -30,8 +29,8 @@
         <file>icons/yellow_square.png</file>
         <file>icons/red_record_icon.png</file>
         <file>icons/dash.png</file>
-        <file>icons/PierogiIcon.png</file>
         <file>doc/about.html</file>
         <file>doc/documentation.html</file>
+        <file>icons/PierogiIcon.png</file>
     </qresource>
 </RCC>
index 961bc64..7e557f9 100644 (file)
@@ -5,9 +5,11 @@
 <h1 align="center"><img src="qrc:///icons/PierogiIcon.png"> Pierogi</h1>
 <h2 align="center">A Universal Infrared Remote Control</h2>
 
-<p>Copyright 2012 by John Pietrzak.  Released under the GPL version 2.0.</p>
+<p>Copyright (C) 2012 by John Pietrzak.
+Released under the GPL version 2.0 or later.</p>
 
-<p>Icons provided by <a href="http://www.gentleface.com">Gentleface</a>.</p>
+<p>Icons provided under a Creative Commons license by
+<a href="http://www.gentleface.com">Gentleface</a>.</p>
 
 <p>Please send any questions or comments to:
 <a href="mailto:jpietrzak8@gmail.com">jpietrzak8@gmail.com</a></p>
index 7d5a637..a1d2d34 100644 (file)
@@ -7,16 +7,33 @@
 
 <p>
 The Pierogi universal infrared remote controller is a single self-contained
-app capable of sending IR commands to pretty much any IR-controlled device.
+app capable of sending IR commands to a wide variety of devices.
 At the moment, it is oriented towards television, VCR, DVD, and Blu-ray
 devices, but a few other types of device have had their command sets entered.
 </p>
 
 <p>
-Commands are collected into "keysets".  As each manufacturer tends to reuse
-a given set of command encodings rather than re-invent the wheel each
-time they come out with a new product, a large number of devices can be
-controlled by a single keyset.
+In this app, each family of related infrared commands is collected into a
+"keyset".  As manufacturers commonly reuse a given set of commands rather
+than re-invent the wheel each time they come out with a new product, many
+devices can share the same keyset.
+</p>
+
+<p>
+Pierogi also follows the classic concept of a universal remote, by having
+a common set of buttons that are reused for each device.  So, for example,
+the "power" button has the same name and is located in the same position,
+no matter what keyset is currently in use -- even if that keyset has a
+different name for "power", or has no "power" command at all.  (Check out
+the <a href="http://en.wikipedia.org/wiki/Universal_remote">Universal
+Remote wiki</a> for a description of universal remote controls, which
+includes a special mention of the N900!)
+</p>
+
+<p>
+So in short, to use Pierogi, you first select an appropriate keyset, then
+press the appropriate buttons to control the target device.  More detail on
+the features of Pierogi is provided below.
 </p>
 
 <h2>Using Pierogi</h2>
@@ -109,8 +126,9 @@ return arrow at the top right of the screen).</p>
 
 <h3>Hasn't this been done before?</h3>
 
-<p>Yes, remote control software has already been written.  In particular,
-the <a href="http://irreco.garage.maemo.org/">Irreco / QtIrreco</a> project
+<p>Yes, remote control software has already been written for the N900.  In
+particular, the
+<a href="http://irreco.garage.maemo.org/">Irreco / QtIrreco</a> project
 creates beautiful virtual remote controls.  I've also used the
 <a href="http://thp.io/2010/raemote/">Raemote</a> widget to control my Apple
 computers.  But these programs have their shortcomings; in particular, they
@@ -120,18 +138,18 @@ use on all sorts of different hardware.</p>
 
 <h3>What's up with LIRC?</h3>
 
-<p>Just as Irreco and Raemote do, I want to leverage the work of the 
+<p>Just as QtIrreco and Raemote do, I want to leverage the work of the 
 <a href="http://www.lirc.org/">Linux Infrared Remote Control</a> project.
-The LIRC project is, at the moment, by far the most influential open-source
-effort working with consumer IR.  And the N900 comes with a device driver
-built specifically for use with LIRC!  But, you see, I have a problem.  I
+The LIRC project is by far the most influential open-source effort working
+with consumer IR.  And the N900 comes with a device driver made
+specifically for their server!  But, you see, I have a problem.  I
 don't want to do things the way LIRC wants to do things.</p>
 
 <p>The N900 is different from other Linux systems using IR -- rather than
 being the machine at which you point a remote control, this machine <i>is</i>
-the remote control.  Which is not what LIRC was made for; the heart of the
+the remote control.  This is not what LIRC was designed for; the heart of the
 LIRC project is a server that will sit and wait for messages to arrive from
-the IR hardware.  Although it can also broadcast IR data back out (when using
+the IR system.  Although it can also broadcast IR data back out (when using
 hardware that supports 2-way IR communication), that is not its primary
 purpose.</p>
 
@@ -151,9 +169,9 @@ multitudes.</p>
 <p>The third problem is more subtle, but really tough to crack.  You see, the
 whole point of LIRC is to take the commands it receives from the IR port and
 translate them into something recognizable.  As such, each config file provides
-a mapping from numeric commands to human-readable strings.  (These strings
-are normally based on the labels used on the remote control itself.)  This is a
-serious problem for a universal controller!  Take, for example, the "power"
+a mapping from numeric commands to human-readable strings.  This is a
+serious problem, if your interest is in finding similar commands in
+different config files!  Take, for example, the "power"
 button found on most remote controls.  In some config files, the string for
 this is "power".  Others have "Power", or "POWER".  You can also find "pwr",
 "PWR", "ON/OFF", "ON-OFF", "ONOFF", "POWER_ON_OFF", "KEY_POWER", "Operate",
@@ -165,14 +183,18 @@ know which key to map all these strings to?</p>
 
 <p>
 Pierogi attempts to answer these problems.  First, it talks directly to the
-/dev/lirc0 device, no server middleman needed.  Yes, you can halt (or even
-uninstall!) the lircd daemon, and still use Pierogi.  Second, the entire
-set of LIRC config files are being processed and combined into a small(er)
-set of related families of commands.  The third problem mentioned above is a
-bit harder to solve; I'm currently mapping each LIRC config file string by
-hand to a corresponding Pierogi key.  Naturally, this process will be fraught
-with errors; I intend to keep updating Pierogi as these errors are found and
-fixed.
+/dev/lirc0 device, no server middleman needed.  Yes, you can use Pierogi
+without the LIRC daemon running; in fact, there's no need to ever install it.
+Second, Pierogi is built
+around the concept of the "keyset"; all IR codes that can share the same
+protocol without interfering with one another are combined into a single
+family of related commands.  In short, this reduces the quantity of data
+available from LIRC config files to something much more manageable.</p>
+<p>The third problem mentioned above is a bit harder to solve; I'm currently
+mapping each LIRC string to a corresponding Pierogi key by hand.  Naturally,
+this process will be fraught with errors; I intend to keep updating Pierogi
+as these errors are found and fixed.
 </p>
 
 <h2>Internal Design Notes</h2>
@@ -249,7 +271,14 @@ sorting through a massive pile of flags, conditional statements, and some
 really funky delayed-action buffering to make everything work.  The simple act
 of splitting the code into one routine for the RC5 (biphase) protocol and
 another for the NEC (space-encoded) protocol makes it much easier to read, at
-least to my eyes.  (I haven't yet implemented the RC6 protocol.)
+least to my eyes.  (I haven't yet implemented the RC6 or other protocols.)
+</p>
+
+<p>
+In any case, I owe the LIRC authors a deep debt of gratitude for their
+efforts.  If you are one such author, thank you.  As Pierogi is more-or-less
+derived directly from their work, it is also licensed under the same terms,
+the GNU General Public License (GPL) version 2 or later.
 </p>
 
 <h2>Attribution</h2>
@@ -263,7 +292,10 @@ Find their work at <a href="http://www.gentleface.com">www.gentleface.com</a>.
 <p>A set of links to some resources I've used while writing the code.</p>
 
 <ul>
-<li><a href="http://en.wikipedia.org/wiki/Consumer_IR">Wiki page</a> with
+<li>The center of the Linux infrared world, the
+<a href="http://www.lirc.org/">Linux Infrared Remote Control</a> project.
+
+<li>A <a href="http://en.wikipedia.org/wiki/Consumer_IR">Wiki page</a> with
 general info on consumer IR
 
 <li>A <a href="http://www.sbprojects.com/knowledge/ir/index.php">good introduction</a>
@@ -271,14 +303,11 @@ to the theory and practice behind consumer IR devices
 
 <li>A <a href="http://en.wikipedia.org/wiki/RC-5">Wiki for the RC-5 protocol</a>
 
-<li><a href="http://www.sbprojects.com/knowledge/ir/nec.php">Info on the NEC protocol</a>
-
-<li><a href="http://www2.renesas.com/faq/en/mi_com/f_com_remo.html">More info on the NEC protocol</a>
+<li>Some <a href="http://www.sbprojects.com/knowledge/ir/nec.php">Info on the NEC protocol</a>
 
-<li>The heart of it all, the
-<a href="http://www.lirc.org/">Linux Infrared Remote Control</a> project.
+<li>Some <a href="http://www2.renesas.com/faq/en/mi_com/f_com_remo.html">More info on the NEC protocol</a>
 
-<li>Link to (what appears to be) the source code for the N900's
+<li>Link to (what appears to be) source code for the N900's
 <a href="http://svn.jacekowski.org/host_mode/trunk/drivers/input/lirc/lirc_rx51.c">/dev/lirc0 device driver</a>.
 <ul>
 
index 8fed1ec..cf3a282 100644 (file)
Binary files a/icons/PierogiIcon.png and b/icons/PierogiIcon.png differ
index 943da86..143de54 100644 (file)
@@ -7,9 +7,9 @@ AppleWhiteRemote::AppleWhiteRemote(
   QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
-    "White Remote",
-    Apple_Make,
-    index)
+      "White Remote",
+      Apple_Make,
+      index)
 {
   addControlledDevice(Apple_Make, "Mac Mini", Computer_Device);
 
diff --git a/keysets/jvc.cpp b/keysets/jvc.cpp
new file mode 100644 (file)
index 0000000..79f1433
--- /dev/null
@@ -0,0 +1,1100 @@
+#include "jvc.h"
+#include "necprotocol.h"
+
+JVCSat1::JVCSat1(
+  QObject *guiObject,
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "Satellite (Dish Network) Keyset 1",
+      JVC_Make,
+      index)
+{
+  NECProtocol *np = new NECProtocol(
+   guiObject,
+   index,
+   624, 1500,
+   624, 2600,
+   6000, false);
+
+  threadableProtocol = np;
+
+  np->setHeaderPair(750, 6000);
+  np->setTrailerPulse(624);
+
+  np->setFullHeadlessRepeat(true);
+
+//  np->setCarrierFrequency(56000);
+//  np->setDutyCycle(32);
+
+  addKey("power", Power_Key, 0x1EFC, 13);
+  addKey("recent", Unmapped_Key, 0x16FC, 13);
+  addKey("tvWeb", Unmapped_Key, 0x1A7C, 13);
+  addKey("scrollUp", Unmapped_Key, 0x137C, 13);
+  addKey("scrollDown", Unmapped_Key, 0x117C, 13);
+  addKey("home", Unmapped_Key, 0x15FC, 13);
+  addKey("back", Exit_Key, 0x1FFC, 13);
+  addKey("up", Up_Key, 0x12FC, 13);
+  addKey("left", Left_Key, 0x11FC, 13);
+  addKey("go", Enter_Key, 0x17FC, 13);
+  addKey("right", Right_Key, 0x13FC, 13);
+  addKey("down", Down_Key, 0x10FC, 13);
+  addKey("options", Unmapped_Key, 0x14FC, 13);
+  addKey("chDown", ChannelDown_Key, 0x187C, 13);
+  addKey("record", Record_Key, 0x107C, 13);
+  addKey("rewind", Rewind_Key, 0x1C7C, 13);
+  addKey("play", Play_Key, 0x1E7C, 13);
+  addKey("1", One_Key, 0x1DFC, 13);
+  addKey("2", Two_Key, 0x1D7C, 13);
+  addKey("3", Three_Key, 0x1CFC, 13);
+  addKey("4", Four_Key, 0x1BFC, 13);
+  addKey("5", Five_Key, 0x1B7C, 13);
+  addKey("6", Six_Key, 0x1AFC, 13);
+  addKey("7", Seven_Key, 0x19FC, 13);
+  addKey("8", Eight_Key, 0x197C, 13);
+  addKey("9", Nine_Key, 0x18FC, 13);
+  addKey("0", Zero_Key, 0x177C, 13);
+  addKey("enter", Enter_Key, 0x127C, 13);
+  addKey("pip", PIP_Key, 0x077C, 13);
+  addKey("info", Info_Key, 0x06FC, 13);
+  addKey("listings", Guide_Key, 0x07FC, 13);
+  addKey("personalTv", Unmapped_Key, 0x0CFC, 13);
+  addKey("replay", Replay_Key, 0x0EFC, 13);
+  addKey("skip", Advance_Key, 0x0E7C, 13);
+  addKey("pause", Pause_Key, 0x0DFC, 13);
+  addKey("fastForward", FastForward_Key, 0x0D7C, 13);
+  addKey("stop", Stop_Key, 0x0F7C, 13);
+  addKey("chUp", ChannelUp_Key, 0x0FFC, 13);
+  addKey("recall", PrevChannel_Key, 0x057C, 13);
+}
+
+
+JVCSat2::JVCSat2(
+  QObject *guiObject,
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "Satellite (Dish Network) Keyset 2",
+      JVC_Make,
+      index)
+{
+  NECProtocol *np = new NECProtocol(
+    guiObject,
+    index,
+    440, 2780,
+    440, 1645,
+    6115, false);
+
+  threadableProtocol = np;
+
+  np->setHeaderPair(525, 6045);
+  np->setTrailerPulse(450);
+
+  np->setPostData(0x000, 10);
+
+//  np->setMinimumRepetitions(6);
+  np->setFullHeadlessRepeat(true);
+
+  np->setCarrierFrequency(56000);
+  np->setDutyCycle(32);
+
+  addKey("info", Info_Key, 0x0, 6);
+  addKey("power_on", Unmapped_Key, 0x1, 6);
+  addKey("power", Power_Key, 0x2, 6);
+  addKey("1", One_Key, 0x4, 6);
+  addKey("2", Two_Key, 0x5, 6);
+  addKey("3", Three_Key, 0x6, 6);
+  addKey("4", Four_Key, 0x8, 6);
+  addKey("5", Five_Key, 0x9, 6);
+  addKey("6", Six_Key, 0x10, 6);
+  addKey("7", Seven_Key, 0x12, 6);
+  addKey("8", Eight_Key, 0x13, 6);
+  addKey("9", Nine_Key, 0x14, 6);
+  addKey("0", Zero_Key, 0x17, 6);
+  addKey("menu", Menu_Key, 0x11, 6);
+  addKey("select", Select_Key, 0x16, 6);
+  addKey("cancel", Exit_Key, 0x18, 6);
+  addKey("guide", Guide_Key, 0x20, 6);
+  addKey("view", Unmapped_Key, 0x22, 6);
+  addKey("tv_vcr", Input_Key, 0x23, 6);
+  addKey("right", Right_Key, 0x24, 6);
+  addKey("up", Up_Key, 0x26, 6);
+  addKey("recall", PrevChannel_Key, 0x27, 6);
+  addKey("left", Left_Key, 0x28, 6);
+  addKey("down", Down_Key, 0x30, 6);
+  addKey("record", Record_Key, 0x31, 6);
+  addKey("pause", Pause_Key, 0x32, 6);
+  addKey("stop", Stop_Key, 0x33, 6);
+  addKey("sys_info", Info_Key, 0x36, 6);
+  addKey("asterisk", Unmapped_Key, 0x37, 6);
+  addKey("pound", Unmapped_Key, 0x38, 6);
+  addKey("power_off", Unmapped_Key, 0x39, 6);
+  addKey("sat", Unmapped_Key, 0x41, 6);
+  addKey("dish_home", Unmapped_Key, 0x52, 6);
+  addKey("sys_info2", Unmapped_Key, 0x54, 6);
+  addKey("dish_home2", Unmapped_Key, 0x56, 6);
+}
+
+
+JVCVCR1::JVCVCR1(
+  QObject *guiObject,
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "VCR Keyset 1",
+      JVC_Make,
+      index)
+{
+  NECProtocol *np = new NECProtocol(
+    guiObject,
+    index,
+    600, 500,
+    600, 1600,
+    45000, true);
+
+  threadableProtocol = np;
+
+  np->setTrailerPulse(600);
+
+  np->setPreData(0xC2, 8);
+
+  addKey("power", Power_Key, 0xD0, 8);
+  addKey("play", Play_Key, 0x30, 8);
+  addKey("forward", FastForward_Key, 0x60, 8);
+  addKey("backward", Rewind_Key, 0xE0, 8);
+  addKey("stop", Stop_Key, 0xC0, 8);
+  addKey("pause", Pause_Key, 0xB0, 8);
+  addKey("menu", Menu_Key, 0xEC, 8); // "PROG"
+  addKey("ok", Select_Key, 0x3C, 8);
+  addKey("CANCEL", Exit_Key, 0x6C, 8); // "zero4x", "reset"
+  addKey("CANCEL", Clear_Key, 0x6C, 8); // "zero4x", "reset"
+  addKey("RECORD", Record_Key, 0x33, 8); // "itr"
+  addKey("pr_up", ChannelUp_Key, 0x98, 8);
+  addKey("pr_dn", ChannelDown_Key, 0x18, 8);
+  addKey("right", Next_Key, 0x28, 8); // "JOG+"
+  addKey("left", Previous_Key, 0xA8, 8); // "JOG-"
+  addKey("pr_up", Up_Key, 0x98, 8);
+  addKey("pr_dn", Down_Key, 0x18, 8);
+  addKey("right", Right_Key, 0x28, 8); // "JOG+"
+  addKey("left", Left_Key, 0xA8, 8); // "JOG-"
+  addKey("eject", Eject_Key, 0x20, 8);
+  addKey("no_1", One_Key, 0x84, 8);
+  addKey("no_2", Two_Key, 0x44, 8);
+  addKey("no_3", Three_Key, 0xC4, 8);
+  addKey("no_4", Four_Key, 0x24, 8);
+  addKey("no_5", Five_Key, 0xA4, 8);
+  addKey("no_6", Six_Key, 0x64, 8);
+  addKey("no_7", Seven_Key, 0xE4, 8);
+  addKey("no_8", Eight_Key, 0x14, 8);
+  addKey("no_9", Nine_Key, 0x94, 8);
+  addKey("no_0", Zero_Key, 0xCC, 8);
+  addKey("tv_vcr", Input_Key, 0xC8, 8); // "monitor"
+  addKey("av", Unmapped_Key, 0x80, 8);
+  addKey("ff_30sec", Advance_Key, 0x69, 8); // "skip"
+  addKey("die", Unmapped_Key, 0x5F, 8);
+  addKey("start", Unmapped_Key, 0x19, 8);
+  addKey("lock", Unmapped_Key, 0x0F, 8);
+  addKey("showview", Program_Key, 0x83, 8); // program
+  addKey("SOUND1", Unmapped_Key, 0xEB, 8);
+  addKey("SOUND2", Unmapped_Key, 0x27, 8);
+  addKey("SOUND3", Unmapped_Key, 0x3B, 8);
+  addKey("INDEX1", Unmapped_Key, 0xC9, 8);
+  addKey("INDEX2", Unmapped_Key, 0x29, 8);
+  addKey("DISPLAY", Info_Key, 0x1C, 8);
+  addKey("MUTE", Mute_Key, 0xE8, 8);
+  addKey("SPEED", VHSSpeed_Key, 0x8C, 8); // "I/II"
+  addKey("TIMER", Unmapped_Key, 0xAC, 8);
+  addKey("MIC+", Unmapped_Key, 0x8B, 8);
+  addKey("MIC-", Unmapped_Key, 0x4B, 8);
+  addKey("enter", Enter_Key, 0x7C, 8); // "store"
+  addKey("line", Unmapped_Key, 0x76, 8);
+  addKey("check", Unmapped_Key, 0xBC, 8); // "prog_check"
+  addKey("start+", Unmapped_Key, 0x13, 8);
+  addKey("start-", Unmapped_Key, 0x93, 8);
+  addKey("stop+", Unmapped_Key, 0x53, 8);
+  addKey("stop-", Unmapped_Key, 0xD3, 8);
+  addKey("date+", Unmapped_Key, 0x63, 8);
+  addKey("date-", Unmapped_Key, 0xE3, 8);
+  addKey("review", Replay_Key, 0xC3, 8);
+  addKey("IN/OUT", Unmapped_Key, 0x7B, 8);
+  addKey("3dphonic", Unmapped_Key, 0xA9, 8);
+  addKey("Red", Red_Key, 0x89, 8);
+  addKey("Green", Green_Key, 0xDC, 8);
+  addKey("Yellow", Yellow_Key, 0xE9, 8);
+  addKey("Blue", Blue_Key, 0x8C, 8);
+  addKey("ch_set", Unmapped_Key, 0x66, 8);
+  addKey("clock", Unmapped_Key, 0x5C, 8);
+  addKey("mode", Unmapped_Key, 0x61, 8);
+  addKey("scene-finder", Unmapped_Key, 0xE9, 8);
+  addKey("input_1", Unmapped_Key, 0x88, 8);
+}
+
+
+JVCVCR1a::JVCVCR1a(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCVCR1(guiObject, index)
+{
+  setKeysetName("VCR Keyset 1a");
+
+  addKey("red", Red_Key, 0xE0, 8);
+  addKey("green", Green_Key, 0xA8, 8);
+  addKey("yellow", Yellow_Key, 0x28, 8);
+  addKey("blue", Blue_Key, 0x60, 8);
+  addKey("menu", Menu_Key, 0xC8, 8);
+  addKey("last", Unmapped_Key, 0xA8, 8); // what is this?
+  addKey("suchl", Unmapped_Key, 0x69, 8); // ditto
+}
+
+
+// The 0xCA keyset appears to just be the 0xC2 keyset with a different preface,
+// to allow two VCRs in the same room to be controlled independently.
+// Note the hack below won't work with the other VCR keysets!!!
+JVCVCR1b::JVCVCR1b(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCVCR1(guiObject, index)
+{
+  setKeysetName("VCR (alt) keyset 1b");
+
+  NECProtocol *np = dynamic_cast<NECProtocol *>(threadableProtocol);
+  np->setPreData(0xCA, 8);
+}
+
+
+JVCVCR1c::JVCVCR1c(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCVCR1(guiObject, index)
+{
+  setKeysetName("VCR keyset 1c");
+
+  addKey("tv", Input_Key, 0x08, 8);
+}
+
+
+// VCR keyset #2 is apparently identical to #1, but this one uses a header
+// pulse.  Dunno if this is a mistake, or if JVC messes with the fundamental
+// elements of their protocols this much...
+JVCVCR2::JVCVCR2(
+  QObject *guiObject,
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "VCR Keyset 2",
+      JVC_Make,
+      index)
+{
+  NECProtocol *np = new NECProtocol(
+    guiObject,
+    index,
+    600, 500,
+    600, 1600,
+    46000, true);
+
+  threadableProtocol = np;
+
+  np->setHeaderPair(9000, 4500);
+  np->setTrailerPulse(600);
+  np->setFullHeadlessRepeat(true);
+
+  np->setPreData(0xC2, 8);
+
+  addKey("power", Power_Key, 0xD0, 8);
+  addKey("play", Play_Key, 0x30, 8);
+  addKey("forward", FastForward_Key, 0x60, 8);
+  addKey("backward", Rewind_Key, 0xE0, 8);
+  addKey("stop", Stop_Key, 0xC0, 8);
+  addKey("pause", Pause_Key, 0xB0, 8);
+  addKey("menu", Menu_Key, 0xEC, 8); // "PROG"
+  addKey("ok", Select_Key, 0x3C, 8);
+  addKey("CANCEL", Exit_Key, 0x6C, 8); // "zero4x", "reset"
+  addKey("CANCEL", Clear_Key, 0x6C, 8); // "zero4x", "reset"
+  addKey("RECORD", Record_Key, 0x33, 8); // "itr"
+  addKey("recpause", Unmapped_Key, 0xB3, 8);
+  addKey("pr_up", ChannelUp_Key, 0x98, 8);
+  addKey("pr_dn", ChannelDown_Key, 0x18, 8);
+  addKey("pr_up", Up_Key, 0x98, 8);
+  addKey("pr_dn", Down_Key, 0x18, 8);
+  addKey("right", Right_Key, 0x28, 8); // "JOG+"
+  addKey("left", Left_Key, 0xA8, 8); // "JOG-"
+  addKey("eject", Eject_Key, 0x20, 8);
+  addKey("no_1", One_Key, 0x84, 8);
+  addKey("no_2", Two_Key, 0x44, 8);
+  addKey("no_3", Three_Key, 0xC4, 8);
+  addKey("no_4", Four_Key, 0x24, 8);
+  addKey("no_5", Five_Key, 0xA4, 8);
+  addKey("no_6", Six_Key, 0x64, 8);
+  addKey("no_7", Seven_Key, 0xE4, 8);
+  addKey("no_8", Eight_Key, 0x14, 8);
+  addKey("no_9", Nine_Key, 0x94, 8);
+  addKey("no_0", Zero_Key, 0xCC, 8);
+  addKey("tv_vcr", Input_Key, 0xC8, 8); // "monitor"
+  addKey("av", Unmapped_Key, 0x80, 8);
+  addKey("ff_30sec", Advance_Key, 0x69, 8); // "skip"
+  addKey("die", Unmapped_Key, 0x5F, 8);
+  addKey("start", Unmapped_Key, 0x19, 8);
+  addKey("lock", Unmapped_Key, 0x0F, 8);
+  addKey("showview", Program_Key, 0x83, 8); // program
+  addKey("SOUND1", Unmapped_Key, 0xEB, 8);
+  addKey("SOUND2", Unmapped_Key, 0x27, 8);
+  addKey("SOUND3", Unmapped_Key, 0x3B, 8);
+  addKey("INDEX1", Unmapped_Key, 0xC9, 8);
+  addKey("INDEX2", Unmapped_Key, 0x29, 8);
+  addKey("DISPLAY", Info_Key, 0x1C, 8);
+  addKey("MUTE", Mute_Key, 0xE8, 8);
+  addKey("SPEED", VHSSpeed_Key, 0x8C, 8); // "I/II"
+  addKey("TIMER", Unmapped_Key, 0xAC, 8);
+  addKey("MIC+", Unmapped_Key, 0x8B, 8);
+  addKey("MIC-", Unmapped_Key, 0x4B, 8);
+  addKey("enter", Enter_Key, 0x7C, 8);
+  addKey("line", Unmapped_Key, 0x76, 8);
+  addKey("check", Unmapped_Key, 0xBC, 8); // "prog_check"
+  addKey("start+", Unmapped_Key, 0x13, 8);
+  addKey("start-", Unmapped_Key, 0x93, 8);
+  addKey("stop+", Unmapped_Key, 0x53, 8);
+  addKey("stop-", Unmapped_Key, 0xD3, 8);
+  addKey("date+", Unmapped_Key, 0x63, 8);
+  addKey("date-", Unmapped_Key, 0xE3, 8);
+  addKey("review", Replay_Key, 0xC3, 8);
+  addKey("IN/OUT", Unmapped_Key, 0x7B, 8);
+  addKey("3dphonic", Unmapped_Key, 0xA9, 8);
+  addKey("Red", Red_Key, 0x89, 8);
+  addKey("Green", Green_Key, 0xDC, 8);
+  addKey("Yellow", Yellow_Key, 0xE9, 8);
+  addKey("Blue", Blue_Key, 0x8C, 8);
+  addKey("ch_set", Unmapped_Key, 0x66, 8);
+  addKey("clock", Unmapped_Key, 0x5C, 8);
+  addKey("mode", Unmapped_Key, 0x61, 8);
+  addKey("scene-finder", Unmapped_Key, 0xE9, 8);
+  addKey("input_1", Unmapped_Key, 0x88, 8);
+}
+
+
+JVCVCR2a::JVCVCR2a(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCVCR2(guiObject, index)
+{
+  setKeysetName("VCR Keyset 2a");
+
+  addKey("red", Red_Key, 0xE0, 8);
+  addKey("green", Green_Key, 0xA8, 8);
+  addKey("yellow", Yellow_Key, 0x28, 8);
+  addKey("blue", Blue_Key, 0x60, 8);
+  addKey("menu", Menu_Key, 0xC8, 8);
+  addKey("last", Unmapped_Key, 0xA8, 8); // what is this?
+  addKey("suchl", Unmapped_Key, 0x69, 8); // ditto
+}
+
+
+JVCVCR2b::JVCVCR2b(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCVCR2(guiObject, index)
+{
+  setKeysetName("VCR (alt) keyset 2b");
+
+  NECProtocol *np = dynamic_cast<NECProtocol *>(threadableProtocol);
+  np->setPreData(0xCA, 8);
+}
+
+
+JVCVCR2c::JVCVCR2c(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCVCR2(guiObject, index)
+{
+  setKeysetName("VCR Keyset 2c");
+
+  addKey("tv", Input_Key, 0x08, 8);
+}
+
+
+JVCTV1::JVCTV1(
+  QObject *guiObject,
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "TV Keyset 1",
+      JVC_Make,
+      index)
+{
+  NECProtocol *np = new NECProtocol(
+    guiObject,
+    index,
+    600, 500,
+    600, 1600,
+    45000, true);
+
+  threadableProtocol = np;
+
+  np->setTrailerPulse(600);
+
+  np->setPreData(0xC0, 8);
+
+  addKey("Power", Power_Key, 0xE8, 8);
+  addKey("Vol+", VolumeUp_Key, 0x78, 8);
+  addKey("Vol-", VolumeDown_Key, 0xF8, 8);
+  addKey("Prog+", ChannelUp_Key, 0x98, 8);
+  addKey("Prog-", ChannelDown_Key, 0x18, 8);
+  addKey("TV/VCR", Input_Key, 0xC8, 8); // "input"
+  addKey("0", Zero_Key, 0x04, 8);
+  addKey("1", One_Key, 0x84, 8);
+  addKey("2", Two_Key, 0x44, 8);
+  addKey("3", Three_Key, 0xC4, 8);
+  addKey("4", Four_Key, 0x24, 8);
+  addKey("5", Five_Key, 0xA4, 8);
+  addKey("6", Six_Key, 0x64, 8);
+  addKey("7", Seven_Key, 0xE4, 8);
+  addKey("8", Eight_Key, 0x14, 8);
+  addKey("9", Nine_Key, 0x94, 8);
+  addKey("X", Clear_Key, 0x0E, 8);
+  addKey("AUDIO", Mute_Key, 0x38, 8); // "mute"
+  addKey("Timer", Sleep_Key, 0x8E, 8);
+//  addKey("SP/LP", VHSSpeed_Key, 0xB9, 8); // "/_//"
+  addKey("-/--", DoubleDigit_Key, 0xB9, 8);
+//  addKey("Red", Red_Key, 0x89, 8);
+//  addKey("Green", Green_Key, 0xDC, 8);
+//  addKey("Yellow", Yellow_Key, 0xE9, 8);
+//  addKey("Blue", Blue_Key, 0x8C, 8);
+  addKey("info", Info_Key, 0x20, 8); // "display"
+  addKey("standard", PictureMode_Key, 0x9E, 8); // "picture_mode"
+  addKey("menu", Menu_Key, 0x5E, 8);
+  addKey("sound", Unmapped_Key, 0x42, 8); // "<>"
+  addKey("video_status", Unmapped_Key, 0xB0, 8);
+  addKey("theater_pro", Unmapped_Key, 0xAB, 8);
+  addKey("aspect", AspectRatio_Key, 0xC9, 8);
+  addKey("100+", PlusOneHundred_Key, 0xEE, 8);
+  addKey("return", Unmapped_Key, 0xA0, 8);
+  addKey("cc", Captions_Key, 0x70, 8);
+  addKey("exit", Exit_Key, 0x67, 8);
+  addKey("colour", Unmapped_Key, 0x49, 8); // "P/S"
+  addKey("sound", SoundMode_Key, 0x2D, 8);
+  addKey("up", Up_Key, 0x3E, 8);
+  addKey("down", Down_Key, 0xDE, 8);
+  addKey("left", Left_Key, 0xDA, 8);
+  addKey("right", Right_Key, 0x5A, 8);
+  addKey("BROADCAST", Unmapped_Key, 0xD0, 8); // "ant/cable"
+  addKey("RECALL", PrevChannel_Key, 0x3C, 8);
+  addKey("RESET", Reset_Key, 0x60, 8);
+  addKey("FUNCTION", Unmapped_Key, 0xDC, 8);
+  addKey("LEVELDOWN", Unmapped_Key, 0xD8, 8);
+  addKey("LEVELUP", Unmapped_Key, 0x58, 8);
+  addKey("main/sap", Language_Key, 0x00, 8); // "I/II"
+  addKey("CH_PRESET", Unmapped_Key, 0x99, 8);
+  addKey("MAX_CH", Unmapped_Key, 0xB9, 8);
+  addKey("C1/C2", Unmapped_Key, 0x5B, 8);
+  addKey("input_2", Unmapped_Key, 0x48, 8);
+  addKey("input_3", Unmapped_Key, 0x28, 8);
+  addKey("input_s", Unmapped_Key, 0xF0, 8);
+  addKey("tone", Unmapped_Key, 0x09, 8);
+  addKey("VNR", Unmapped_Key, 0xA2, 8);
+  addKey("br_down", Unmapped_Key, 0x8C, 8);
+  addKey("br_up", Unmapped_Key, 0x0C, 8);
+  addKey("con_down", Unmapped_Key, 0xEC, 8);
+  addKey("con_up", Unmapped_Key, 0x6C, 8);
+  addKey("col_down", Unmapped_Key, 0xCC, 8);
+  addKey("col_up", Unmapped_Key, 0x4C, 8);
+}
+
+
+JVCTV1a::JVCTV1a(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCTV1(guiObject, index)
+{
+  setKeysetName("TV Keyset 1a");
+
+  addKey("+10", DoubleDigit_Key, 0x8E, 8);
+}
+
+
+JVCTV1b::JVCTV1b(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCTV1(guiObject, index)
+{
+  setKeysetName("TV Keyset 1b");
+
+  addKey("sleep_timer", Sleep_Key, 0xC0, 8);
+}
+
+
+JVCTV1c::JVCTV1c(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCTV1(guiObject, index)
+{
+  setKeysetName("TV Keyset 1c");
+
+  addKey("REW", Rewind_Key, 0x4D, 8);
+  addKey("PLAY", Play_Key, 0x91, 8);
+  addKey("FF", FastForward_Key, 0x6B, 8);
+  addKey("REC", Record_Key, 0x20, 8);
+  addKey("STOP", Stop_Key, 0x00, 8);
+  addKey("PAUSE", Pause_Key, 0xD0, 8);
+}
+
+
+// TVs where "volume" and "channel" keys are used to navigate menus:
+JVCTV1d::JVCTV1d(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCTV1(guiObject, index)
+{
+  setKeysetName("TV Keyset 1d");
+
+  addKey("up", Up_Key, 0x98, 8);
+  addKey("down", Down_Key, 0x18, 8);
+  addKey("left", Left_Key, 0xF8, 8);
+  addKey("right", Right_Key, 0x78, 8);
+}
+
+
+// Same deal here, two different header specifications on top of the same
+// underlying keyset.
+JVCTV2::JVCTV2(
+  QObject *guiObject,
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "TV Keyset 2",
+      JVC_Make,
+      index)
+{
+  NECProtocol *np = new NECProtocol(
+    guiObject,
+    index,
+    600, 500,
+    600, 1600,
+    46000, true);
+
+  threadableProtocol = np;
+
+  np->setHeaderPair(9000, 4500);
+  np->setTrailerPulse(600);
+  np->setFullHeadlessRepeat(true);
+
+  np->setPreData(0xC0, 8);
+
+  addKey("Power", Power_Key, 0xE8, 8);
+  addKey("Vol+", VolumeUp_Key, 0x78, 8);
+  addKey("Vol-", VolumeDown_Key, 0xF8, 8);
+  addKey("Prog+", ChannelUp_Key, 0x98, 8);
+  addKey("Prog-", ChannelDown_Key, 0x18, 8);
+  addKey("TV/VCR", Input_Key, 0xC8, 8);
+  addKey("0", Zero_Key, 0x04, 8);
+  addKey("1", One_Key, 0x84, 8);
+  addKey("2", Two_Key, 0x44, 8);
+  addKey("3", Three_Key, 0xC4, 8);
+  addKey("4", Four_Key, 0x24, 8);
+  addKey("5", Five_Key, 0xA4, 8);
+  addKey("6", Six_Key, 0x64, 8);
+  addKey("7", Seven_Key, 0xE4, 8);
+  addKey("8", Eight_Key, 0x14, 8);
+  addKey("9", Nine_Key, 0x94, 8);
+  addKey("X", Clear_Key, 0x0E, 8);
+  addKey("AUDIO", Mute_Key, 0x38, 8); // "mute"
+  addKey("Timer", Sleep_Key, 0x8E, 8);
+//  addKey("SP/LP", VHSSpeed_Key, 0xB9, 8);
+  addKey("-/--", DoubleDigit_Key, 0xB9, 8);
+  addKey("info", Info_Key, 0x20, 8);
+  addKey("standard", PictureMode_Key, 0x9E, 8); // "picture_mode"
+  addKey("menu", Menu_Key, 0x5E, 8);
+  addKey("sound", Unmapped_Key, 0x42, 8);
+  addKey("video_status", Unmapped_Key, 0xB0, 8);
+  addKey("theater_pro", Unmapped_Key, 0xAB, 8);
+  addKey("aspect", AspectRatio_Key, 0xC9, 8);
+  addKey("100+", PlusOneHundred_Key, 0xEE, 8);
+  addKey("return", Unmapped_Key, 0xA0, 8);
+  addKey("cc", Captions_Key, 0x70, 8);
+  addKey("exit", Exit_Key, 0x67, 8);
+  addKey("colour", Unmapped_Key, 0x49, 8);
+  addKey("sound", SoundMode_Key, 0x2D, 8);
+  addKey("up", Up_Key, 0x3E, 8);
+  addKey("down", Down_Key, 0xDE, 8);
+  addKey("left", Left_Key, 0xDA, 8);
+  addKey("right", Right_Key, 0x5A, 8);
+  addKey("BROADCAST", Unmapped_Key, 0xD0, 8);
+  addKey("RECALL", PrevChannel_Key, 0x3C, 8);
+  addKey("RESET", Reset_Key, 0x60, 8);
+  addKey("FUNCTION", Unmapped_Key, 0xDC, 8);
+  addKey("LEVELDOWN", Unmapped_Key, 0xD8, 8);
+  addKey("LEVELUP", Unmapped_Key, 0x58, 8);
+  addKey("main/sap", Language_Key, 0x00, 8);
+  addKey("CH_PRESET", Unmapped_Key, 0x99, 8);
+  addKey("MAX_CH", Unmapped_Key, 0xB9, 8);
+  addKey("C1/C2", Unmapped_Key, 0x5B, 8);
+  addKey("input_2", Unmapped_Key, 0x48, 8);
+  addKey("input_3", Unmapped_Key, 0x28, 8);
+  addKey("input_s", Unmapped_Key, 0xF0, 8);
+  addKey("tone", Unmapped_Key, 0x09, 8);
+  addKey("VNR", Unmapped_Key, 0xA2, 8);
+  addKey("br_down", Unmapped_Key, 0x8C, 8);
+  addKey("br_up", Unmapped_Key, 0x0C, 8);
+  addKey("con_down", Unmapped_Key, 0xEC, 8);
+  addKey("con_up", Unmapped_Key, 0x6C, 8);
+  addKey("col_down", Unmapped_Key, 0xCC, 8);
+  addKey("col_up", Unmapped_Key, 0x4C, 8);
+}
+
+
+JVCTV2a::JVCTV2a(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCTV2(guiObject, index)
+{
+  setKeysetName("TV Keyset 2a");
+
+  addKey("+10", DoubleDigit_Key, 0x8E, 8);
+}
+
+
+JVCTV2b::JVCTV2b(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCTV2(guiObject, index)
+{
+  setKeysetName("TV Keyset 2b");
+
+  addKey("sleep_timer", Sleep_Key, 0xC0, 8);
+}
+
+
+JVCTV2c::JVCTV2c(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCTV2(guiObject, index)
+{
+  setKeysetName("TV Keyset 2c");
+
+  addKey("REW", Rewind_Key, 0x4D, 8);
+  addKey("PLAY", Play_Key, 0x91, 8);
+  addKey("FF", FastForward_Key, 0x6B, 8);
+  addKey("REC", Record_Key, 0x20, 8);
+  addKey("STOP", Stop_Key, 0x00, 8);
+  addKey("PAUSE", Pause_Key, 0xD0, 8);
+}
+
+
+JVCTV2d::JVCTV2d(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCTV2(guiObject, index)
+{
+  setKeysetName("TV Keyset 2d");
+
+  addKey("up", Up_Key, 0x98, 8);
+  addKey("down", Down_Key, 0x18, 8);
+  addKey("left", Left_Key, 0xF8, 8);
+  addKey("right", Right_Key, 0x78, 8);
+}
+
+
+JVCDAT1::JVCDAT1(
+  QObject *guiObject,
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "DAT Keyset 1",
+      JVC_Make,
+      index)
+{
+  NECProtocol *np = new NECProtocol(
+    guiObject,
+    index,
+    600, 500,
+    600, 1600,
+    46000, true);
+
+  threadableProtocol = np;
+
+  np->setHeaderPair(9000, 4500);
+  np->setTrailerPulse(600);
+
+  np->setFullHeadlessRepeat(true);
+
+  np->setPreData(0xC9, 8);
+
+  addKey("1", One_Key, 0x84, 8);
+  addKey("2", Two_Key, 0x44, 8);
+  addKey("3", Three_Key, 0xC4, 8);
+  addKey("4", Four_Key, 0x24, 8);
+  addKey("5", Five_Key, 0xA4, 8);
+  addKey("6", Six_Key, 0x64, 8);
+  addKey("7", Seven_Key, 0xE4, 8);
+  addKey("8", Eight_Key, 0x14, 8);
+  addKey("9", Nine_Key, 0x94, 8);
+  addKey("0", Zero_Key, 0x04, 8);
+  addKey("MEMORY", Unmapped_Key, 0x48, 8);
+  addKey("REPEAT", Unmapped_Key, 0xD8, 8);
+  addKey("DISPLAY", Info_Key, 0x28, 8);
+  addKey("CANCEL/RESET", Reset_Key, 0xB4, 8);
+  addKey("CALL", Unmapped_Key, 0xA8, 8);
+  addKey("RESERVE", Unmapped_Key, 0x54, 8);
+  addKey("INTRO", Unmapped_Key, 0x88, 8);
+  addKey("REC_MUTE", Unmapped_Key, 0x38, 8);
+  addKey("REC", Record_Key, 0x40, 8);
+  addKey("PAUSE", Pause_Key, 0xB0, 8);
+  addKey("|<-SKIP", Previous_Key, 0x18, 8);
+  addKey("SKIP->|", Next_Key, 0x98, 8);
+  addKey("<<-SEARCH", Unmapped_Key, 0xE8, 8);
+  addKey("SEARCH->>", Unmapped_Key, 0x68, 8);
+  addKey("REW", Rewind_Key, 0xE0, 8);
+  addKey("FF", FastForward_Key, 0x60, 8);
+  addKey("STOP", Stop_Key, 0xC0, 8);
+  addKey("PLAY", Play_Key, 0x30, 8);
+}
+
+
+JVCCarDeck1::JVCCarDeck1(
+  QObject *guiObject,
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "Car Deck Keyset 1",
+      JVC_Make,
+      index)
+{
+  NECProtocol *np = new NECProtocol(
+    guiObject,
+    index,
+    600, 500,
+    600, 1600,
+    46000, true);
+
+  threadableProtocol = np;
+
+  np->setHeaderPair(9000, 4500);
+  np->setTrailerPulse(600);
+
+  np->setFullHeadlessRepeat(true);
+
+  np->setPreData(0xF1, 8);
+
+  addKey("Power", Power_Key, 0x71, 8); // "Att"
+  addKey("Sound", Mute_Key, 0xB1, 8); // "SCM"
+  addKey("Source", Input_Key, 0x11, 8);  // "FUNC", "SRC"
+  addKey("DISC+", Up_Key, 0x29, 8);
+  addKey("DISC-", Down_Key, 0xA9, 8);
+  addKey("Vol+", VolumeUp_Key, 0x21, 8);
+  addKey("Vol-", VolumeDown_Key, 0xA1, 8);
+  addKey("Track+", Next_Key, 0x49, 8);
+  addKey("Track-", Previous_Key, 0xC9, 8);
+  addKey("FF", FastForward_Key, 0x49, 8);
+  addKey("Rew", Rewind_Key, 0xC9, 8);
+}
+
+
+JVCPortableAudio1::JVCPortableAudio1(
+  QObject *guiObject,
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "Portable Audio Keyset 1",
+      JVC_Make,
+      index)
+{
+  NECProtocol *np = new NECProtocol(
+    guiObject,
+    index,
+    600, 500,
+    600, 1600,
+    46000, true);
+
+  threadableProtocol = np;
+
+  np->setHeaderPair(9000, 4500);
+  np->setTrailerPulse(600);
+
+  np->setFullHeadlessRepeat(true);
+
+  addKey("POWER", Power_Key, 0xC5E8, 16);
+  addKey("1", One_Key, 0xCD86, 16);
+  addKey("2", Two_Key, 0xCD46, 16);
+  addKey("3", Three_Key, 0xCDC6, 16);
+  addKey("4", Four_Key, 0xCD26, 16);
+  addKey("5", Five_Key, 0xCDA6, 16);
+  addKey("6", Six_Key, 0xCD66, 16);
+  addKey("7", Seven_Key, 0xCDE6, 16);
+  addKey("8", Eight_Key, 0xCD16, 16);
+  addKey("9", Nine_Key, 0xCD96, 16);
+  addKey("10", Zero_Key, 0xCD76, 16); // Ok, yeah, this one is a hack...
+  addKey("+10", DoubleDigit_Key, 0xCDF6, 16);
+  addKey("REPEAT", Unmapped_Key, 0xCDDA, 16);
+  addKey("RANDOM", Unmapped_Key, 0xCD4E, 16);
+  addKey("INTRO", Unmapped_Key, 0xCD12, 16);
+  addKey("MEMORY/CALL", Unmapped_Key, 0xCD56, 16);
+  addKey("REW", Rewind_Key, 0xCD1A, 16);
+  addKey("FF", FastForward_Key, 0xCD9A, 16); // "CD.Next"
+  addKey("STOP", Stop_Key, 0xCDC2, 16); // "CD.Stop"
+  addKey("PLAY", Play_Key, 0xCD32, 16); // "CD.Play"
+  addKey("VOL-", VolumeDown_Key, 0xC5F8, 16);
+  addKey("VOL+", VolumeUp_Key, 0xC578, 16);
+  addKey("SLEEP", Sleep_Key, 0xC5C0, 16);
+  addKey("DIMMER", Unmapped_Key, 0xCD4A, 16);
+  addKey("FM-MODE", Unmapped_Key, 0xC55A, 16);
+  addKey("MD-AUX", Unmapped_Key, 0xC57C, 16); // "TAPE-AUX"
+  addKey("AHB-PRO", Unmapped_Key, 0xC5AE, 16);
+  addKey("AUTO-PRESET", Unmapped_Key, 0xC5EE, 16);
+  addKey("CD-EJECT", Eject_Key, 0xCD22, 16);
+  addKey("PROGRAM", Program_Key, 0xCD56, 16);
+  addKey("RANDOM", Unmapped_Key, 0xCD4E, 16);
+  addKey("REPEAT", Unmapped_Key, 0xCDDA, 16);
+  addKey("BASS", Unmapped_Key, 0xF578, 16);
+  addKey("TREBLE", Unmapped_Key, 0xF574, 16);
+  addKey("CANCEL", Clear_Key, 0xCDB6, 16);
+  addKey("UP", Up_Key, 0xF500, 16);
+  addKey("DOWN", Down_Key, 0xF580, 16);
+  addKey("LEFT", Left_Key, 0xF5C0, 16);
+  addKey("RIGHT", Right_Key, 0xF540, 16);
+  addKey("PTY-EON", Unmapped_Key, 0xF5A1, 16);
+  addKey("DISPLAY-MODE", Info_Key, 0xF5C1, 16);
+  addKey("SET", Select_Key, 0xF589, 16);
+  addKey("TAPE", Unmapped_Key, 0xC5FC, 16);
+  addKey("TUNER-BAND", Unmapped_Key, 0xC5DA, 16);
+  addKey("PREV", Previous_Key, 0xF560, 16);
+  addKey("NEXT", Next_Key, 0xF5A0, 16);
+  addKey("EDIT-TITLE", Unmapped_Key, 0xFD91, 16);
+  addKey("CHARA", Unmapped_Key, 0xFD1D, 16);
+}
+
+
+JVCPortableAudio1a::JVCPortableAudio1a(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCPortableAudio1(guiObject, index)
+{
+  setKeysetName("Portable Audio Keyset 1a");
+
+  addKey("CD-PLAY-PAUSE", Play_Key, 0xC5BC, 16);
+  addKey("MD-PLAY-PAUSE", Unmapped_Key, 0xF50C, 16);
+}
+
+
+// This is not portable audio.  This is all sorts of audio devices.  I need
+// to do some work to clean this up!
+JVCPortableAudio1b::JVCPortableAudio1b(
+  QObject *guiObject,
+  unsigned int index)
+  : JVCPortableAudio1(guiObject, index)
+{
+  setKeysetName("Portable(?) Audio Keyset 1b");
+
+  addKey("0", Zero_Key, 0xCD06, 16); // What about "10" key here?
+  addKey("TUNER", Unmapped_Key, 0xC5D0, 16);
+  addKey("VCR", Unmapped_Key, 0xC224, 16);
+  addKey("CD", Unmapped_Key, 0xC5BC, 16);
+  addKey("PHONO", Unmapped_Key, 0xC53C, 16);
+  addKey("MONITOR/TAPE2", Unmapped_Key, 0xC5E0, 16);
+  addKey("STOP2", Unmapped_Key, 0xC1C2, 16);
+  addKey("STILL/PAUSE", Pause_Key, 0xC1B0, 16);
+  addKey("STOP", Stop_Key, 0xC1B0, 16);
+  addKey("REC+PLAY", Unmapped_Key, 0xC133, 16);
+  addKey("FORWARDS", FastForward_Key, 0xC160, 16); // "Deck.Right"
+  addKey("BACKWARDS", Rewind_Key, 0xC1E0, 16); // "Deck.Left"
+  addKey("PLAY", Play_Key, 0xC130, 16);
+  addKey("FADE_MUTING", Unmapped_Key, 0xC538, 16);
+  addKey("Disc 1", Unmapped_Key, 0xCD9E, 16);
+  addKey("Disc 2", Unmapped_Key, 0xCD5E, 16);
+  addKey("Disc 3", Unmapped_Key, 0xCDDE, 16);
+  addKey("Disc 4", Unmapped_Key, 0xCD3E, 16);
+  addKey("Disc 5", Unmapped_Key, 0xCDBE, 16);
+  addKey("Disc 6", Unmapped_Key, 0xCD7E, 16);
+  addKey("Disc continue", Unmapped_Key, 0xCDEE, 16);
+  addKey("Disc program", Unmapped_Key, 0xCD8E, 16);
+  addKey("Tuner 1", Unmapped_Key, 0xC584, 16);
+  addKey("Tuner 2", Unmapped_Key, 0xC544, 16);
+  addKey("Tuner 3", Unmapped_Key, 0xC5C4, 16);
+  addKey("Tuner 4", Unmapped_Key, 0xC524, 16);
+  addKey("Tuner 5", Unmapped_Key, 0xC5A4, 16);
+  addKey("Tuner 6", Unmapped_Key, 0xC564, 16);
+  addKey("Tuner 7", Unmapped_Key, 0xC5E4, 16);
+  addKey("Tuner 8", Unmapped_Key, 0xC514, 16);
+  addKey("Tuner 9", Unmapped_Key, 0xC594, 16);
+  addKey("Tuner 10", Unmapped_Key, 0xC554, 16);
+  addKey("Tuner +10", Unmapped_Key, 0xC5F4, 16);
+  addKey("Tuner 0", Unmapped_Key, 0xC504, 16);
+  addKey("tape-play", Unmapped_Key, 0xC130, 16);
+  addKey("tape-stop", Unmapped_Key, 0xC1C0, 16); // "Deck.Stop"
+  addKey("tuner-", Unmapped_Key, 0xC518, 16);
+  addKey("tuner+", Unmapped_Key, 0xC598, 16);
+  addKey("cd-play", Unmapped_Key, 0xC5BC, 16);
+  addKey("cd-stop", Unmapped_Key, 0xCDC2, 16);
+  addKey("cd-pause", Unmapped_Key, 0xCDB2, 16);
+  addKey("cd-prev", Unmapped_Key, 0xCD1A, 16);
+  addKey("cd-next", Unmapped_Key, 0xCD9A, 16);
+  addKey("cd-back", Unmapped_Key, 0xCD0E, 16);
+  addKey("cd-forw", Unmapped_Key, 0xCD6E, 16);
+  addKey("Deck.PlayLeft", Unmapped_Key, 0xC170, 16);
+  addKey("Deck.PlayRight", Unmapped_Key, 0xC1F0, 16);
+  addKey("Deck.A", Unmapped_Key, 0xC10B, 16);
+  addKey("Deck.B", Unmapped_Key, 0xC18B, 16);
+  addKey("RecPause", Unmapped_Key, 0xC1B3, 16);
+  addKey("SoundMode", Unmapped_Key, 0xC51C, 16);
+}
+
+
+JVCPortableAudio2::JVCPortableAudio2(
+  QObject *guiObject,
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "Portable Audio Keyset 2",
+      JVC_Make,
+      index)
+{
+  NECProtocol *np = new NECProtocol(
+    guiObject,
+    index,
+    600, 500,
+    600, 1600,
+    46000, true);
+
+  threadableProtocol = np;
+
+  np->setHeaderPair(9000, 4500);
+  np->setTrailerPulse(600);
+
+  np->setFullHeadlessRepeat(true);
+
+  np->setPreData(0xF9, 8);
+
+  addKey("stop", Stop_Key, 0x8E, 8); // "CD_STOP" "stop_clear"
+  addKey("stop", Clear_Key, 0x8E, 8); // "CD_STOP" "stop_clear"
+  addKey("vol+", VolumeUp_Key, 0x80, 8);
+  addKey("vol-", VolumeDown_Key, 0x40, 8);
+  addKey("play", Play_Key, 0x0E, 8); // "CD_PLAY_PAUSE"
+  addKey("play", Pause_Key, 0x0E, 8); // "CD_PLAY_PAUSE"
+  addKey("ff", FastForward_Key, 0xBC, 8); // "SEARCH_UP" "search_forward"
+  addKey("rew", Rewind_Key, 0x7C, 8);  // "SEARCH_DOWN" "search_back"
+  addKey("1", One_Key, 0x84, 8);
+  addKey("2", Two_Key, 0x44, 8);
+  addKey("3", Three_Key, 0xC4, 8);
+  addKey("4", Four_Key, 0x24, 8);
+  addKey("5", Five_Key, 0xA4, 8);
+  addKey("6", Six_Key, 0x64, 8);
+  addKey("7", Seven_Key, 0xE4, 8);
+  addKey("8", Eight_Key, 0x14, 8);
+  addKey("9", Nine_Key, 0x94, 8);
+  addKey("10", Zero_Key, 0x54, 8); // Yeah, I know this is bad
+  addKey("10+", DoubleDigit_Key, 0x74, 8);
+  addKey("enter", Enter_Key, 0x88, 8);
+  addKey("repeat", Unmapped_Key, 0x1E, 8);
+  addKey("random", Unmapped_Key, 0xEE, 8);
+  addKey("intro", Unmapped_Key, 0x6E, 8);
+  addKey("memory", Program_Key, 0x2E, 8); // "MEMORY_CALL", "program"
+  addKey("call", Unmapped_Key, 0xFE, 8);
+  addKey("display", Info_Key, 0x38, 8); // "CLOCK"
+  addKey("sleep", Sleep_Key, 0x4C, 8);
+  addKey("power", Power_Key, 0x00, 8);
+  addKey("band", Unmapped_Key, 0xD0, 8);  // "TUNER_BAND"
+  addKey("PRESET_SCAN", Unmapped_Key, 0x48, 8);
+  addKey("SET", Select_Key, 0xCC, 8); // "clock"
+  addKey("TIMER_ON_OFF", Unmapped_Key, 0x6C, 8); // might be another sleep
+  addKey("TIMER_SET", Unmapped_Key, 0x0C, 8);
+  addKey("ACTIVE_HYPER_BASS", Unmapped_Key, 0x20, 8); // "bass"
+  addKey("FREQUENCY", Unmapped_Key, 0x01, 8);
+  addKey("NEXT_TRACK", Next_Key, 0x4E, 8);
+  addKey("PREV_TRACK", Previous_Key, 0xCE, 8);
+  addKey("auto_preset", Unmapped_Key, 0xC8, 8);
+  addKey("open_close", Eject_Key, 0xDE, 8); // "allcdeject"
+  addKey("auto_preset", Unmapped_Key, 0xC8, 8);
+  addKey("auto_mono", Unmapped_Key, 0xF8, 8);  // "fmstereo", "mode"
+  addKey("tone", Unmapped_Key, 0x61, 8);
+  addKey("revmode", Unmapped_Key, 0xFA, 8);
+  addKey("playcd1", Unmapped_Key, 0x8F, 8);
+  addKey("playcd2", Unmapped_Key, 0x4F, 8);
+  addKey("playcd3", Unmapped_Key, 0xCF, 8);
+  addKey("continue", Unmapped_Key, 0xBE, 8);
+  addKey("ejectcd1", Unmapped_Key, 0x2F, 8);
+  addKey("ejectcd2", Unmapped_Key, 0xAF, 8);
+  addKey("ejectcd2", Unmapped_Key, 0x6F, 8);
+  addKey("tape", Unmapped_Key, 0x42, 8);
+  addKey("aux", Unmapped_Key, 0xB0, 8);
+  addKey("deckab", Unmapped_Key, 0x1A, 8);
+  addKey("sound", Unmapped_Key, 0xF1, 8);
+  addKey("presettuning", Unmapped_Key, 0xA8, 8);
+  addKey("record", Record_Key, 0xD2, 8); // "TAPEREC"
+  addKey("reverseplay", Unmapped_Key, 0xB2, 8); // "TAPELEFT"
+  addKey("stop", Unmapped_Key, 0x82, 8); // "TAPESTOP"
+  addKey("play", Unmapped_Key, 0x32, 8); // "TAPERIGHT"
+  addKey("bass-", Unmapped_Key, 0x11, 8);
+  addKey("bass+", Unmapped_Key, 0xE1, 8);
+  addKey("treble-", Unmapped_Key, 0x51, 8);
+  addKey("treble+", Unmapped_Key, 0x91, 8);
+  addKey("onoff", Unmapped_Key, 0x6C, 8); // same keyset already has "power"?
+  addKey("edit", Unmapped_Key, 0xAE, 8);
+  addKey("synchrorec", Unmapped_Key, 0x6A, 8);
+  addKey("rewind", Unmapped_Key, 0xA2, 8); // "TAPEPREV"
+  addKey("ff", Unmapped_Key, 0x22, 8); // "TAPENEXT"
+  addKey("beat-cut", Unmapped_Key, 0x77, 8);
+  addKey("pty-eon", Unmapped_Key, 0xE8, 8);
+  addKey("left-select", Unmapped_Key, 0x98, 8);
+  addKey("right-select", Unmapped_Key, 0x18, 8);
+  addKey("display-mode", Unmapped_Key, 0x68, 8);
+}
+
+
+JVCDVD1::JVCDVD1(
+  QObject *guiObject,
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "DVD Keyset 1",
+      JVC_Make,
+      index)
+{
+  NECProtocol *np = new NECProtocol(
+    guiObject,
+    index,
+    600, 500,
+    600, 1600,
+    46000, true);
+
+  threadableProtocol = np;
+
+  np->setHeaderPair(9000, 4500);
+  np->setTrailerPulse(600);
+  np->setFullHeadlessRepeat(true);
+
+  addKey("openclose", Eject_Key, 0xF722, 16);
+  addKey("1", One_Key, 0xF786, 16);
+  addKey("2", Two_Key, 0xF746, 16);
+  addKey("3", Three_Key, 0xF7C6, 16);
+  addKey("4", Four_Key, 0xF726, 16);
+  addKey("5", Five_Key, 0xF7A6, 16);
+  addKey("6", Six_Key, 0xF766, 16);
+  addKey("7", Seven_Key, 0xF7E6, 16);
+  addKey("8", Eight_Key, 0xF716, 16);
+  addKey("9", Nine_Key, 0xF796, 16);
+  addKey("10", Unmapped_Key, 0xF776, 16);
+  addKey("0", Zero_Key, 0xF706, 16);
+  addKey("+10", DoubleDigit_Key, 0xF7F6, 16);
+  addKey("return", Exit_Key, 0xF7AB, 16);
+  addKey("title/group", Unmapped_Key, 0xF777, 16);
+  addKey("cancel", Clear_Key, 0xF7B6, 16);
+  addKey("topmenu", DiscTitle_Key, 0xF743, 16);
+  addKey("up", Up_Key, 0xF70B, 16);
+  addKey("menu", Menu_Key, 0xF783, 16);
+  addKey("left", Left_Key, 0xF74B, 16);
+  addKey("enter", Select_Key, 0xF72B, 16);
+  addKey("right", Right_Key, 0xF7CB, 16);
+  addKey("choice", Unmapped_Key, 0xF7FE, 16);
+  addKey("down", Down_Key, 0xF78B, 16);
+  addKey("onscreen", Unmapped_Key, 0xF703, 16);
+  addKey("skip_back", Previous_Key, 0xF78D, 16); // "previous"
+  addKey("skip_forw", Next_Key, 0xF70D, 16); // "next"
+  addKey("stop", Stop_Key, 0xF7C2, 16);
+  addKey("play", Play_Key, 0xF732, 16);
+  addKey("pause", Pause_Key, 0xF7B2, 16);
+  addKey("back", Rewind_Key, 0xF70E, 16); // "SLOW_MINUS"
+  addKey("forw", FastForward_Key, 0xF76E, 16); // "SLOW_PLUS"
+  addKey("repeat", Unmapped_Key, 0xF7DA, 16);
+  addKey("subtitle", Captions_Key, 0xF7B3, 16);
+  addKey("audio", Unmapped_Key, 0xF713, 16);
+  addKey("vfp", Unmapped_Key, 0xF77D, 16); // "theaterposition"
+  addKey("digest", Unmapped_Key, 0xF79D, 16);
+  addKey("angle", Unmapped_Key, 0xF7D3, 16);
+  addKey("zoom-", Unmapped_Key, 0xF7F5, 16);
+  addKey("zoom+", Unmapped_Key, 0xF775, 16);
+  addKey("3dphonix", Unmapped_Key, 0xF7BD, 16);
+  addKey("voldown", VolumeDown_Key, 0xC5F8, 16);
+  addKey("volup", VolumeUp_Key, 0xC578, 16);
+  addKey("power", Power_Key, 0xF702, 16);
+  addKey("playmode", Unmapped_Key, 0xF7C1, 16);
+  addKey("zoom", Unmapped_Key, 0xF73D, 16);
+  addKey("display", Info_Key, 0xF7AD, 16);
+  addKey("SWOOP", Unmapped_Key, 0xF792, 16);
+  addKey("DIMMER", Unmapped_Key, 0xF78A, 16);
+}
diff --git a/keysets/jvc.h b/keysets/jvc.h
new file mode 100644 (file)
index 0000000..6eefad7
--- /dev/null
@@ -0,0 +1,224 @@
+#ifndef JVC_H
+#define JVC_H
+
+#include "pirkeysetmetadata.h"
+
+#include <QObject>
+
+class JVCSat1: public PIRKeysetMetaData
+{
+public:
+  JVCSat1(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCSat2: public PIRKeysetMetaData
+{
+public:
+  JVCSat2(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCVCR1: public PIRKeysetMetaData
+{
+public:
+  JVCVCR1(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCVCR1a: public JVCVCR1
+{
+public:
+  JVCVCR1a(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCVCR1b: public JVCVCR1
+{
+public:
+  JVCVCR1b(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCVCR1c: public JVCVCR1
+{
+public:
+  JVCVCR1c(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCVCR2: public PIRKeysetMetaData
+{
+public:
+  JVCVCR2(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCVCR2a: public JVCVCR2
+{
+public:
+  JVCVCR2a(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCVCR2b: public JVCVCR2
+{
+public:
+  JVCVCR2b(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCVCR2c: public JVCVCR2
+{
+public:
+  JVCVCR2c(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCTV1: public PIRKeysetMetaData
+{
+public:
+  JVCTV1(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCTV1a: public JVCTV1
+{
+public:
+  JVCTV1a(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCTV1b: public JVCTV1
+{
+public:
+  JVCTV1b(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCTV1c: public JVCTV1
+{
+public:
+  JVCTV1c(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCTV1d: public JVCTV1
+{
+public:
+  JVCTV1d(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCTV2: public PIRKeysetMetaData
+{
+public:
+  JVCTV2(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCTV2a: public JVCTV2
+{
+public:
+  JVCTV2a(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCTV2b: public JVCTV2
+{
+public:
+  JVCTV2b(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCTV2c: public JVCTV2
+{
+public:
+  JVCTV2c(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCTV2d: public JVCTV2
+{
+public:
+  JVCTV2d(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCDAT1: public PIRKeysetMetaData
+{
+public:
+  JVCDAT1(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCCarDeck1: public PIRKeysetMetaData
+{
+public:
+  JVCCarDeck1(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCPortableAudio1: public PIRKeysetMetaData
+{
+public:
+  JVCPortableAudio1(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCPortableAudio1a: public JVCPortableAudio1
+{
+public:
+  JVCPortableAudio1a(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCPortableAudio1b: public JVCPortableAudio1
+{
+public:
+  JVCPortableAudio1b(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCPortableAudio2: public PIRKeysetMetaData
+{
+public:
+  JVCPortableAudio2(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+class JVCDVD1: public PIRKeysetMetaData
+{
+public:
+  JVCDVD1(
+    QObject *guiObject,
+    unsigned int index);
+};
+
+#endif // JVC_H
index 364b205..fef8bb4 100644 (file)
@@ -82,7 +82,7 @@ RCATV1a::RCATV1a(
 {
   setKeysetName("TV Keyset 1a");
 
-  addKey("repeat", Unmapped_Key, 0x050FA, 20):
+  addKey("repeat", Unmapped_Key, 0x050FA, 20);
   addKey("pip", PIP_Key, 0x1B0E4, 20);
   addKey("swap", PIPSwap_Key, 0xC303C, 20);
   addKey("aspect", AspectRatio_Key, 0x9006F, 20);
@@ -177,7 +177,7 @@ RCAAux1::RCAAux1(
   addKey("aux-clear", Exit_Key, 0x06BF9, 20);
   addKey("aux-1", One_Key, 0x31BCE, 20);
   addKey("aux-2", Two_Key, 0x32BCD, 20);
-  addKey("aux-3", Three_key, 0x33BCC, 20);
+  addKey("aux-3", Three_Key, 0x33BCC, 20);
   addKey("aux-4", Four_Key, 0x34BCB, 20);
   addKey("aux-5", Five_Key, 0x35BCA, 20);
   addKey("aux-6", Six_Key, 0x36BC9, 20);
@@ -242,7 +242,7 @@ RCAAux2::RCAAux2(
   addKey("aux-ok", Select_Key, 0xF430B, 20);
   addKey("aux-1", One_Key, 0x313CE, 20);
   addKey("aux-2", Two_Key, 0x323CD, 20);
-  addKey("aux-3", Three_key, 0x333CC, 20);
+  addKey("aux-3", Three_Key, 0x333CC, 20);
   addKey("aux-4", Four_Key, 0x343CB, 20);
   addKey("aux-5", Five_Key, 0x353CA, 20);
   addKey("aux-6", Six_Key, 0x363C9, 20);
@@ -549,7 +549,7 @@ RCASat2::RCASat2(
   QObject *guiObject,
   unsigned int index)
   : PIRKeysetMetaData(
-      "Satellite(Dish Network) Keyset 2",
+      "Satellite (Dish Network) Keyset 2",
       RCA_Make,
       index)
 {
@@ -567,7 +567,8 @@ RCASat2::RCASat2(
 
   np->setPostData(0x000, 10);
 
-  np->setMinimumRepetitions(6);
+//  np->setMinimumRepetitions(6);
+  np->setFullHeadlessRepeat(true);
 
   np->setCarrierFrequency(56000);
   np->setDutyCycle(32);
index 2f84102..5957138 100644 (file)
@@ -41,7 +41,7 @@ WestinghouseTV1::WestinghouseTV1(
   addKey("KEY_LEFT", Left_Key, 0x827D, 16);
   addKey("KEY_RIGHT", Right_Key, 0xC23D, 16);
   addKey("KEY_MUTE", Mute_Key, 0x08F7, 16);
-  addKey("KEY_INFO", Info_Key, 0xD827, 16):
+  addKey("KEY_INFO", Info_Key, 0xD827, 16);
   addKey("KEY_VOLUMEUP", VolumeUp_Key, 0x20DF, 16);
   addKey("KEY_VOLUMEDOWN", VolumeDown_Key, 0xA05F, 16);
   addKey("INPUT", Input_Key, 0x00FF, 16);
index d396843..49156ef 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -1,79 +1,6 @@
 #include "mainwindow.h"
-
-/*
-#include <unistd.h> // for fork()
-#include <sys/types.h> // for pid_t
-#include <sys/wait.h> // for waitpid()
-#include "pirexception.h"
-#include <sstream>
-#include <errno.h>
-*/
-
 #include <QtGui/QApplication>
 
-/*
-int loadRX51Module()
-{
-  // First, fork off a child process:
-  pid_t pid = fork();
-
-  if (pid == -1)
-  {
-    // The fork failed!  Tell our user about the error:
-    std::stringstream ss;
-    ss << "Failed to fork a child process.\n";
-    ss << "Error returned was: " << strerror(errno) << "\n";
-    PIRException e(ss.str());
-    e.display();
-    return -1;
-  }
-  else if (pid == 0)
-  {
-    // We're inside the child process, so exec a modprobe:
-    execl("/sbin/modprobe", "/sbin/modprobe", "lirc_rx51", NULL);
-    // The execl call should overwrite the child process.  So, if we still
-    // exist at this point, an error has occurred:
-    std::stringstream ss;
-    ss << "Failed to successfully call execl().\n";
-    ss << "Error returned was: " << strerror(errno) << "\n";
-    PIRException e(ss.str());
-    e.display();
-    return -1;
-  }
-
-  // If we reach this point, we are inside the parent process.  So, we'll wait
-  // for the child process to complete:
-  int *stat_loc = NULL;
-  if (waitpid(pid, stat_loc, 0) == -1)
-  {
-    // The call to modprobe failed.
-    std::stringstream ss;
-    ss << "Call to modprobe failed.\n";
-    ss << "Error returned was: " << strerror(errno) << "\n";
-    PIRException e(ss.str());
-    e.display();
-    return -1;
-  }
-
-  if (stat_loc)
-  {
-    if (WIFEXITED(*stat_loc) == 0)
-    {
-      // modprobe encountered an error of some sort.
-      std::stringstream ss;
-      ss << "'modprobe' was unable to load the lirc_rx51 module.\n";
-      // Need better details about the error here!
-      PIRException e(ss.str());
-      e.display();
-      return -1;
-    }
-  }
-
-  // By this point, we should have successfully ensured the module is loaded.
-  return 0;
-}
-*/
-
 int main(int argc, char *argv[])
 {
   QApplication app(argc, argv);
@@ -82,15 +9,5 @@ int main(int argc, char *argv[])
   mainWindow.setOrientation(MainWindow::ScreenOrientationLockLandscape);
   mainWindow.showExpanded();
 
-/*
-  // Make sure lirc_rx51 module is loaded:
-  if (loadRX51Module() != 0)
-  {
-    // Couldn't load module, quit:
-    app.quit();
-  }
-*/
-
   return app.exec();
 }
-
index e27a342..d0ffd63 100644 (file)
@@ -13,6 +13,8 @@
 
 //#include <iostream>
 
+//#define DEBUGGING
+
 extern PIRMakeMgr makeManager;
 
 
@@ -54,6 +56,36 @@ MainWindow::MainWindow(QWidget *parent)
     this,
     SLOT(keysetSelectionChanged(QListWidgetItem *)),
     Qt::QueuedConnection);
+
+  // Make sure the two selection lists don't show different selections:
+  connect(
+    ui->favoriteKeysetsWidget,
+    SIGNAL(itemActivated(QListWidgetItem *)),
+    mySelectionWindow->nameListWidget,
+    SLOT(clearSelection()),
+    Qt::QueuedConnection);
+
+  connect(
+    mySelectionWindow->nameListWidget,
+    SIGNAL(itemActivated(QListWidgetItem *)),
+    ui->favoriteKeysetsWidget,
+    SLOT(clearSelection()),
+    Qt::QueuedConnection);
+
+#ifndef DEBUGGING
+  // The PIRModprobe object should take care of setting up and shutting down
+  // the lirc_rx51 kernel module, if necessary:
+  if (modprobeObj.loadRX51Module() != 0)
+  {
+    // Couldn't load module, quit:
+    QMessageBox errBox;
+    errBox.setText("Couldn't load lirc_rx51 kernel module!");
+    errBox.setIcon(QMessageBox::Warning);
+    errBox.exec();
+//    throw; // Need a clean way to exit here!!!
+  }
+#endif
 }
 
 
index e652395..181f935 100644 (file)
@@ -8,6 +8,7 @@
 #include "pirdocumentationform.h"
 #include "piraboutform.h"
 #include "pirkeysetmanager.h"
+#include "pirmodprobe.h"
 
 namespace Ui {
     class MainWindow;
@@ -306,6 +307,8 @@ private:
   PIRKeysetManager *myKeysets;
 
   unsigned int currentKeyset;
+
+  PIRModprobe modprobeObj;
 };
 
 
index 15c6b2d..101895f 100644 (file)
@@ -21,7 +21,8 @@ NECProtocol::NECProtocol(
     hasTrailerPulse(false),
     hasHeaderPair(false),
     hasRepeatPair(false),
-    repeatNeedsHeader(false)
+    repeatNeedsHeader(false),
+    fullHeadlessRepeat(false)
 {
 }
 
@@ -56,6 +57,12 @@ void NECProtocol::setRepeatNeedsHeader(
   repeatNeedsHeader = flag;
 }
 
+void NECProtocol::setFullHeadlessRepeat(
+  bool flag)
+{
+  fullHeadlessRepeat = flag;
+}
+
 void NECProtocol::setPreData(
   unsigned long data,
   unsigned int bits)
@@ -102,10 +109,14 @@ void NECProtocol::startSendingCommand(
 
       // If we are currently repeating, and have a special "repeat signal",
       // use that signal.  Otherwise, generate a normal command string.
-      if ((hasRepeatPair) && repeatCount)
+      if (hasRepeatPair && repeatCount)
       {
         commandDuration = generateRepeatCommand(device);
       }
+      else if (fullHeadlessRepeat && repeatCount)
+      {
+        commandDuration = generateHeadlessCommand((*i).second, device);
+      }
       else
       {
         commandDuration = generateStandardCommand((*i).second, device);
@@ -171,6 +182,32 @@ int NECProtocol::generateStandardCommand(
 }
 
 
+int NECProtocol::generateHeadlessCommand(
+  const CommandSequence &bits,
+  PIRDevice &device)
+{
+  int duration = 0;
+
+  // First, the "pre" data:
+  duration += pushBits(preData, device);
+
+  // Next, add the actual command:
+  duration += pushBits(bits, device);
+
+  // Next, add the "post" data:
+  duration += pushBits(postData, device);
+
+  // Finally add the "trail":
+  if (hasTrailerPulse)
+  {
+    device.addSingle(trailerPulse);
+    duration += trailerPulse;
+  }
+
+  return duration;
+}
+
+
 int NECProtocol::generateRepeatCommand(
   PIRDevice &device)
 {
index 8610522..57deae5 100644 (file)
@@ -55,6 +55,9 @@ public:
   void setRepeatNeedsHeader(
     bool flag);
 
+  void setFullHeadlessRepeat(
+    bool flag);
+
 public slots:
   void startSendingCommand(
     unsigned int threadableID,
@@ -88,11 +91,16 @@ private:
   unsigned int repeatSpace;
   bool hasRepeatPair;
   bool repeatNeedsHeader; // Put the header ahead of the repeat pulse
+  bool fullHeadlessRepeat; // Repeat full command but without header
 
   int generateStandardCommand(
     const CommandSequence &bits,
     PIRDevice &device);
 
+  int generateHeadlessCommand(
+    const CommandSequence &bits,
+    PIRDevice &device);
+
   int generateRepeatCommand(
     PIRDevice &device);
 
index 57700d2..6a77ca3 100644 (file)
@@ -2,9 +2,14 @@
 # by adapting the examples below.
 # file1.source = myfile
 # dir1.source = mydir
-DEPLOYMENTFOLDERS = # file1 dir1
+#DEPLOYMENTFOLDERS = # file1 dir1
+sudoers_stuff.source = pierogi.sudoers
+sudoers_stuff.target = ../../etc/sudoers.d
+loadModule.source = loadRX51Module unloadRX51Module
+loadModule.target = bin
+DEPLOYMENTFOLDERS = loadModule
 
-symbian:TARGET.UID3 = 0xE0C0A793
+#symbian:TARGET.UID3 = 0xE0C0A793
 
 # Smart Installer package's UID
 # This UID is from the protected range 
@@ -14,7 +19,7 @@ symbian:TARGET.UID3 = 0xE0C0A793
 #symbian:DEPLOYMENT.installer_header = 0x2002CCCF
 
 # Allow network access on Symbian
-symbian:TARGET.CAPABILITY += NetworkServices
+#symbian:TARGET.CAPABILITY += NetworkServices
 
 # If your application uses the Qt Mobility libraries, uncomment
 # the following lines and add the respective components to the 
@@ -47,7 +52,12 @@ SOURCES += main.cpp mainwindow.cpp \
     keysets/toshiba.cpp \
     keysets/zenith.cpp \
     pirkeysetmetadata.cpp \
-    pirkeysetmanager.cpp
+    pirkeysetmanager.cpp \
+    keysets/rca.cpp \
+    keysets/westinghouse.cpp \
+    keysets/mitsubishi.cpp \
+    pirmodprobe.cpp \
+    keysets/jvc.cpp
 HEADERS += mainwindow.h \
     pirdevice.h \
     pirkeynames.h \
@@ -74,7 +84,12 @@ HEADERS += mainwindow.h \
     keysets/toshiba.h \
     keysets/zenith.h \
     pirkeysetmetadata.h \
-    pirkeysetmanager.h
+    pirkeysetmanager.h \
+    keysets/rca.h \
+    keysets/westinghouse.h \
+    keysets/mitsubishi.h \
+    pirmodprobe.h \
+    keysets/jvc.h
 FORMS += mainwindow.ui \
     pirdocumentationform.ui \
     piraboutform.ui
@@ -121,7 +136,25 @@ OTHER_FILES += \
     icons/undo_icon&48.png \
     icons/yellow_square.png \
     doc/about.html \
-    doc/documentation.html
+    doc/documentation.html \
+    qtc_packaging/debian_fremantle/rules \
+    qtc_packaging/debian_fremantle/README \
+    qtc_packaging/debian_fremantle/copyright \
+    qtc_packaging/debian_fremantle/control \
+    qtc_packaging/debian_fremantle/compat \
+    qtc_packaging/debian_fremantle/changelog \
+    pierogi.sudoers \
+    qtc_packaging/debian_fremantle/postinst \
+    www/index.html \
+    www/FavoritesTab.png \
+    www/KeypadTab.png \
+    www/MainTab.png \
+    www/MediaTab.png \
+    www/MenuTab.png \
+    www/MiscTab.png \
+    www/PierogiIcon.png \
+    www/SelectKeysetWindow.png \
+    www/UtilityTab.png
 
 RESOURCES += \
     PierogiResources.qrc
index e8b3ee6..312dc96 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by Qt Creator 2.4.0, 2012-01-01T18:09:45. -->
+<!-- Written by Qt Creator 2.4.0, 2012-01-09T01:28:37. -->
 <qtcreator>
  <data>
   <variable>ProjectExplorer.Project.ActiveTarget</variable>
        <value type="QString"></value>
       </valuelist>
       <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedTimes">
-       <value type="QDateTime">2012-01-01T15:41:24</value>
+       <value type="QDateTime">2012-01-06T10:31:10</value>
        <value type="QDateTime">2012-01-01T15:35:35</value>
       </valuelist>
      </valuemap>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy files via UTFS mount</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">MaemoMountAndCopyDeployStep</value>
-      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedFiles"/>
-      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedHosts"/>
-      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedRemotePaths"/>
-      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedTimes"/>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedFiles">
+       <value type="QString">/Users/john/Develop/n900/pierogi/pierogi.sudoers</value>
+       <value type="QString">/Users/john/Develop/n900/pierogi/pierogi.sudoers</value>
+       <value type="QString">/Users/john/Develop/n900/pierogi/pierogi.desktop</value>
+       <value type="QString">/Users/john/Develop/n900/pierogi/pierogi.sudoers</value>
+       <value type="QString">/Users/john/Develop/n900/pierogi/unloadRX51Module</value>
+       <value type="QString">/Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi</value>
+       <value type="QString">/Users/john/Develop/n900/pierogi/loadRX51Module</value>
+       <value type="QString">/Users/john/Develop/n900/pierogi/pierogi64.png</value>
+      </valuelist>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedHosts">
+       <value type="QString">192.168.0.15</value>
+       <value type="QString">192.168.0.15</value>
+       <value type="QString">192.168.0.15</value>
+       <value type="QString">192.168.0.15</value>
+       <value type="QString">192.168.0.15</value>
+       <value type="QString">192.168.0.15</value>
+       <value type="QString">192.168.0.15</value>
+       <value type="QString">192.168.0.15</value>
+      </valuelist>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedRemotePaths">
+       <value type="QString">/opt/pierogi/../../etc/sudoers.d/pierogi.sudoers</value>
+       <value type="QString">/opt/pierogi//etc/sudoers.d/pierogi.sudoers</value>
+       <value type="QString">/usr/share/applications/hildon</value>
+       <value type="QString">/opt/pierogi/../../etc/sudoers.d</value>
+       <value type="QString">/opt/pierogi/bin</value>
+       <value type="QString">/opt/pierogi/bin</value>
+       <value type="QString">/opt/pierogi/bin</value>
+       <value type="QString">/usr/share/icons/hicolor/64x64/apps</value>
+      </valuelist>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedTimes">
+       <value type="QDateTime">2012-01-05T11:06:10</value>
+       <value type="QDateTime">2012-01-05T11:04:41</value>
+       <value type="QDateTime">2012-01-05T12:18:12</value>
+       <value type="QDateTime">2012-01-05T14:48:09</value>
+       <value type="QDateTime">2012-01-05T14:54:41</value>
+       <value type="QDateTime">2012-01-05T14:54:41</value>
+       <value type="QDateTime">2012-01-05T14:54:41</value>
+       <value type="QDateTime">2012-01-05T12:05:38</value>
+      </valuelist>
      </valuemap>
      <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Copy Files to Maemo5 Device</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">DeployToFremantleWithoutPackaging</value>
-    <value type="qulonglong" key="Qt4ProjectManager.MaemoRunConfiguration.DeviceId">1</value>
+    <value type="qulonglong" key="Qt4ProjectManager.MaemoRunConfiguration.DeviceId">2</value>
    </valuemap>
    <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">2</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
index 8fed1ec..cf3a282 100644 (file)
Binary files a/pierogi64.png and b/pierogi64.png differ
index 2129699..cd6395f 100644 (file)
@@ -4,14 +4,18 @@
 #include "keysets/ei.h"
 #include "keysets/goldstar.h"
 #include "keysets/hauppauge.h"
+#include "keysets/jvc.h"
 #include "keysets/lg.h"
+#include "keysets/mitsubishi.h"
 #include "keysets/nokia.h"
 #include "keysets/panasonic.h"
+#include "keysets/rca.h"
 #include "keysets/samsung.h"
 #include "keysets/sanyo.h"
 #include "keysets/sharp.h"
 #include "keysets/sony.h"
 #include "keysets/toshiba.h"
+#include "keysets/westinghouse.h"
 #include "keysets/zenith.h"
 //#include "protocol.h"
 #include "pirmakenames.h"
@@ -41,9 +45,11 @@ PIRKeysetManager::PIRKeysetManager(
   QObject *guiObject)
   : counter(0)
 {
-  // Create the keysets.  This needs to be worked on!
+  // Create the keysets.  Ugly!  This needs to be worked on!
   populateKeyset(new AppleWhiteRemote(guiObject, counter++));
+
   populateKeyset(new EiKeyset(guiObject, counter++));
+
   populateKeyset(new GoldStarTV1(guiObject, counter++));
   populateKeyset(new GoldStarTV2(guiObject, counter++));
   populateKeyset(new GoldStarVCR1(guiObject, counter++));
@@ -52,8 +58,38 @@ PIRKeysetManager::PIRKeysetManager(
   populateKeyset(new GoldStarVCR1c(guiObject, counter++));
   populateKeyset(new GoldStarVCR1d(guiObject, counter++));
   populateKeyset(new GoldStarCD1(guiObject, counter++));
+
   populateKeyset(new HauppaugeGeneric(guiObject, counter++));
   populateKeyset(new HauppaugeTV1(guiObject, counter++));
+
+  populateKeyset(new JVCSat1(guiObject, counter++));
+  populateKeyset(new JVCSat2(guiObject, counter++));
+  populateKeyset(new JVCVCR1(guiObject, counter++));
+  populateKeyset(new JVCVCR1a(guiObject, counter++));
+  populateKeyset(new JVCVCR1b(guiObject, counter++));
+  populateKeyset(new JVCVCR1c(guiObject, counter++));
+  populateKeyset(new JVCVCR2(guiObject, counter++));
+  populateKeyset(new JVCVCR2a(guiObject, counter++));
+  populateKeyset(new JVCVCR2b(guiObject, counter++));
+  populateKeyset(new JVCVCR2c(guiObject, counter++));
+  populateKeyset(new JVCTV1(guiObject, counter++));
+  populateKeyset(new JVCTV1a(guiObject, counter++));
+  populateKeyset(new JVCTV1b(guiObject, counter++));
+  populateKeyset(new JVCTV1c(guiObject, counter++));
+  populateKeyset(new JVCTV1d(guiObject, counter++));
+  populateKeyset(new JVCTV2(guiObject, counter++));
+  populateKeyset(new JVCTV2a(guiObject, counter++));
+  populateKeyset(new JVCTV2b(guiObject, counter++));
+  populateKeyset(new JVCTV2c(guiObject, counter++));
+  populateKeyset(new JVCTV2d(guiObject, counter++));
+  populateKeyset(new JVCDAT1(guiObject, counter++));
+  populateKeyset(new JVCCarDeck1(guiObject, counter++));
+  populateKeyset(new JVCPortableAudio1(guiObject, counter++));
+  populateKeyset(new JVCPortableAudio1a(guiObject, counter++));
+  populateKeyset(new JVCPortableAudio1b(guiObject, counter++));
+  populateKeyset(new JVCPortableAudio2(guiObject, counter++));
+  populateKeyset(new JVCDVD1(guiObject, counter++));
+
   populateKeyset(new LGTV1(guiObject, counter++));
   populateKeyset(new LGTV1a(guiObject, counter++));
   populateKeyset(new LGTV1b(guiObject, counter++));
@@ -67,7 +103,14 @@ PIRKeysetManager::PIRKeysetManager(
   populateKeyset(new LGVCR1(guiObject, counter++));
   populateKeyset(new LGVCR1a(guiObject, counter++));
   populateKeyset(new LGVCR1b(guiObject, counter++));
+
+  populateKeyset(new MitsubishiTV1(guiObject, counter++));
+  populateKeyset(new MitsubishiTV1a(guiObject, counter++));
+  populateKeyset(new MitsubishiVCR1(guiObject, counter++));
+  populateKeyset(new MitsubishiVCR1a(guiObject, counter++));
+
   populateKeyset(new NokiaGenericVCR(guiObject, counter++));
+
   populateKeyset(new PanasonicAmp(guiObject, counter++));
   populateKeyset(new PanasonicCarAudio(guiObject, counter++));
   populateKeyset(new PanasonicSat1(guiObject, counter++));
@@ -82,6 +125,20 @@ PIRKeysetManager::PIRKeysetManager(
   populateKeyset(new PanasonicDVD1(guiObject, counter++));
   populateKeyset(new PanasonicDVD1a(guiObject, counter++));
   populateKeyset(new PanasonicAudio(guiObject, counter++));
+
+  populateKeyset(new RCATV1(guiObject, counter++));
+  populateKeyset(new RCATV1a(guiObject, counter++));
+  populateKeyset(new RCATV2(guiObject, counter++));
+  populateKeyset(new RCAAux1(guiObject, counter++));
+  populateKeyset(new RCAAux2(guiObject, counter++));
+  populateKeyset(new RCAAux2a(guiObject, counter++));
+  populateKeyset(new RCAVCR1(guiObject, counter++));
+  populateKeyset(new RCAVCR2(guiObject, counter++));
+  populateKeyset(new RCADVD1(guiObject, counter++));
+  populateKeyset(new RCADVD1a(guiObject, counter++));
+  populateKeyset(new RCASat1(guiObject, counter++));
+  populateKeyset(new RCASat2(guiObject, counter++));
+
   populateKeyset(new SamsungTV1(guiObject, counter++));
   populateKeyset(new SamsungTV1a(guiObject, counter++));
   populateKeyset(new SamsungTV1b(guiObject, counter++));
@@ -102,9 +159,11 @@ PIRKeysetManager::PIRKeysetManager(
   populateKeyset(new SamsungDVD1b(guiObject, counter++));
   populateKeyset(new SamsungDVD2(guiObject, counter++));
   populateKeyset(new SamsungAC1(guiObject, counter++));
+
   populateKeyset(new SanyoTV1(guiObject, counter++));
   populateKeyset(new SanyoTV2(guiObject, counter++));
   populateKeyset(new SanyoVCR1(guiObject, counter++));
+
   populateKeyset(new SharpTV1(guiObject, counter++));
   populateKeyset(new SharpTV1a(guiObject, counter++));
   populateKeyset(new SharpTV1b(guiObject, counter++));
@@ -113,6 +172,7 @@ PIRKeysetManager::PIRKeysetManager(
   populateKeyset(new SharpTV1e(guiObject, counter++));
   populateKeyset(new SharpVCR1(guiObject, counter++));
   populateKeyset(new SharpReceiver1(guiObject, counter++));
+
   populateKeyset(new SonyTV1(guiObject, counter++));
   populateKeyset(new SonyTV1a(guiObject, counter++));
   populateKeyset(new SonyTV1b(guiObject, counter++));
@@ -120,6 +180,7 @@ PIRKeysetManager::PIRKeysetManager(
   populateKeyset(new SonyAmp1(guiObject, counter++));
   populateKeyset(new SonyAmp2(guiObject, counter++));
   populateKeyset(new SonyCD1(guiObject, counter++));
+  populateKeyset(new SonyCD1a(guiObject, counter++));
   populateKeyset(new SonyCD2(guiObject, counter++));
   populateKeyset(new SonyCD3(guiObject, counter++));
   populateKeyset(new SonyDAT1(guiObject, counter++));
@@ -130,6 +191,7 @@ PIRKeysetManager::PIRKeysetManager(
   populateKeyset(new SonyVCR1(guiObject, counter++));
   populateKeyset(new SonyVCR1a(guiObject, counter++));
   populateKeyset(new SonyReceiver1(guiObject, counter++));
+
   populateKeyset(new ToshibaTV1(guiObject, counter++));
   populateKeyset(new ToshibaTV1a(guiObject, counter++));
   populateKeyset(new ToshibaTV1b(guiObject, counter++));
@@ -143,6 +205,10 @@ PIRKeysetManager::PIRKeysetManager(
   populateKeyset(new ToshibaDisc1b(guiObject, counter++));
   populateKeyset(new ToshibaDisc1c(guiObject, counter++));
   populateKeyset(new ToshibaDisc1d(guiObject, counter++));
+
+  populateKeyset(new WestinghouseTV1(guiObject, counter++));
+  populateKeyset(new WestinghouseTV2(guiObject, counter++));
+
   populateKeyset(new ZenithC32V37(guiObject, counter++));
 
   // Start the thread running:
index 8a02b3c..ec94091 100644 (file)
@@ -7,14 +7,19 @@ PIRMakeMgr::PIRMakeMgr()
   makes[Ei_Make] = "Ei";
   makes[GoldStar_Make] = "GoldStar";
   makes[Hauppauge_Make] = "Hauppauge";
+  makes[JVC_Make] = "JVC";
   makes[LG_Make] = "LG";
+  makes[Mitsubishi_Make] = "Mitsubishi";
   makes[Nokia_Make] = "Nokia";
+  makes[Philips_Make] = "Philips";
   makes[Panasonic_Make] = "Panasonic";
+  makes[RCA_Make] = "RCA";
   makes[Samsung_Make] = "Samsung";
   makes[Sanyo_Make] = "Sanyo";
   makes[Sharp_Make] = "Sharp";
   makes[Sony_Make] = "Sony";
   makes[Toshiba_Make] = "Toshiba";
+  makes[Westinghouse_Make] = "Westinghouse";
   makes[Zenith_Make] = "Zenith";
 }
 
index efbe3c1..5fc5c44 100644 (file)
@@ -11,14 +11,19 @@ enum PIRMakeName{
   Ei_Make,
   GoldStar_Make,
   Hauppauge_Make,
+  JVC_Make,
   LG_Make,
+  Mitsubishi_Make,
   Nokia_Make,
   Panasonic_Make,
+  Philips_Make,
+  RCA_Make,
   Samsung_Make,
   Sanyo_Make,
   Sharp_Make,
   Sony_Make,
   Toshiba_Make,
+  Westinghouse_Make,
   Zenith_Make
 };
 
index cc79f75..fc4c2d5 100644 (file)
@@ -8,7 +8,6 @@
 #include <errno.h>
 #include <sys/stat.h>
 
-
 PIRModprobe::PIRModprobe()
   : successfullyLoadedModule(false)
 {
@@ -24,8 +23,7 @@ PIRModprobe::~PIRModprobe()
 }
 
 
-int PIRModprobe::modprobeRX51Module(
-  bool unloadModule)
+int PIRModprobe::loadRX51Module()
 {
   // First, has the module already been loaded?  If /dev/lirc0 exists, it
   // should already be there:
@@ -33,6 +31,7 @@ int PIRModprobe::modprobeRX51Module(
   if (stat("/dev/lirc0", &statBuffer) == 0)
   {
     // "/dev/lirc0" exists, so no need to do anything:
+    successfullyLoadedModule = false;
     return 0;
   }
 
@@ -51,23 +50,13 @@ int PIRModprobe::modprobeRX51Module(
   }
   else if (pid == 0)
   {
-    // We're inside the child process, so exec a modprobe:
-    if (unloadModule)
-    {
-      execl(
-        "/usr/bin/sudo",
-        "/usr/bin/sudo",
-        "/opt/pierogi/bin/unloadRX51Module",
-        NULL);
-    }
-    else
-    {
-      execl(
-        "/usr/bin/sudo",
-        "/usr/bin/sudo",
-        "/opt/pierogi/bin/loadRX51Module",
-        NULL);
-    }
+    // We're inside the child process, so exec the load module script:
+    execl(
+      "/usr/bin/sudo",
+      "/usr/bin/sudo",
+      "/opt/pierogi/bin/loadRX51Module",
+      NULL);
+
     // The execl call should overwrite the child process.  So, if we still
     // exist at this point, an error has occurred:
     std::stringstream ss;
@@ -106,8 +95,77 @@ int PIRModprobe::modprobeRX51Module(
     }
   }
 
-  // By this point, we should have successfully ensured the module is loaded.
+  // By this point, we should have successfully loaded module.
   successfullyLoadedModule = true;
 
   return 0;
 }
+
+
+int PIRModprobe::unloadRX51Module()
+{
+  // start by forking off a child process:
+  pid_t pid = fork();
+
+  if (pid == -1)
+  {
+    // The fork failed!  Tell our user about the error:
+    std::stringstream ss;
+    ss << "Failed to fork a child process.\n";
+    ss << "Error returned was: " << strerror(errno) << "\n";
+    PIRException e(ss.str());
+    e.display();
+    return -1;
+  }
+  else if (pid == 0)
+  {
+    // We're inside the child process, so exec the unload script:
+    execl(
+      "/usr/bin/sudo",
+      "/usr/bin/sudo",
+      "/opt/pierogi/bin/unloadRX51Module",
+      NULL);
+
+    // The execl call should overwrite the child process.  So, if we still
+    // exist at this point, an error has occurred:
+    std::stringstream ss;
+    ss << "Failed to successfully call execl().\n";
+    ss << "Error returned was: " << strerror(errno) << "\n";
+    PIRException e(ss.str());
+    e.display();
+    return -1;
+  }
+
+  // If we reach this point, we are inside the parent process.  So, we'll wait
+  // for the child process to complete:
+  int *stat_loc = NULL;
+  if (waitpid(pid, stat_loc, 0) == -1)
+  {
+    // The call to modprobe failed.
+    std::stringstream ss;
+    ss << "Call to modprobe failed.\n";
+    ss << "Error returned was: " << strerror(errno) << "\n";
+    PIRException e(ss.str());
+    e.display();
+    return -1;
+  }
+
+  if (stat_loc)
+  {
+    if (WIFEXITED(*stat_loc) == 0)
+    {
+      // modprobe encountered an error of some sort.
+      std::stringstream ss;
+      ss << "Unable to unload the lirc_rx51 module.\n";
+      // Need better details about the error here!
+      PIRException e(ss.str());
+      e.display();
+      return -1;
+    }
+  }
+
+  // If we reach this point, module has been unloaded successfully:
+  successfullyLoadedModule = false;
+
+  return 0;
+}
index c87feee..d999d8b 100644 (file)
@@ -10,24 +10,10 @@ public:
 
   int loadRX51Module();
 
-private:
   int unloadRX51Module();
 
-  int modprobeRX51Module(
-    bool unloadModule);
-
+private:
   bool successfullyLoadedModule;
 };
 
-
-inline int PIRModprobe::loadRX51Module()
-{
-  return modprobeRX51Module(false);
-}
-
-inline int PIRModprobe::unloadRX51Module()
-{
-  return modprobeRX51Module(true);
-}
-
 #endif // PIRMODPROBE_H
index 1bc41bd..ac16527 100644 (file)
@@ -26,12 +26,16 @@ public:
     unsigned int index,
     PIRMakeName make);
 
+  // Public just for now, to get a quick hack working.  (Actually, this whole
+  // class should be replaced with a UI form eventually, to match the rest of
+  // the code...)
+  QListWidget *nameListWidget;
+
 private slots:
   void filterListByMake(
     int make);
 
 private:
-  QListWidget *nameListWidget;
   QLabel *makeLabel;
   QComboBox *makeComboBox;
   QGridLayout *layout;
diff --git a/welcome b/welcome
deleted file mode 100644 (file)
index e69de29..0000000
index c8d690c..bf12f87 100644 (file)
@@ -13,7 +13,7 @@ Pierogi
 <img src="PierogiIcon.png">
 </h1>
 
-<h2 align="center">A Universal Infrared Remote Control app for the Nokia N900</h2>
+<h2 align="center">A Universal Infrared Remote Control App for the Nokia N900</h2>
 
 <p>Welcome to the Pierogi website!  This web page and the app itself are
 still under active construction.  Until I have time to construct a proper