Keyset Memory Management Bugfix
authorJohn Pietrzak <john@pietrzak.org>
Wed, 19 Sep 2012 20:43:25 +0000 (16:43 -0400)
committerJohn Pietrzak <john@pietrzak.org>
Wed, 19 Sep 2012 20:43:25 +0000 (16:43 -0400)
This update fixes a serious bug in the handling of keysets: keyset
protocol data must not be deleted while a command is still in progress.
Also in this update, a first pass at keysets for Changhong, Frontech,
and Sinotec; a new Thomson keyset; and fixes for an ADB (I-Can) keyset.

23 files changed:
keysets/adb.cpp
keysets/changhong.cpp [new file with mode: 0644]
keysets/changhong.h [new file with mode: 0644]
keysets/frontech.cpp [new file with mode: 0644]
keysets/frontech.h [new file with mode: 0644]
keysets/sinotec.cpp [new file with mode: 0644]
keysets/sinotec.h [new file with mode: 0644]
keysets/thomson.cpp
keysets/thomson.h
macros/pirmacro.cpp
macros/pirmacrocommanditem.cpp
pierogi.pro
pierogi.pro.user
pirkeysetmanager.cpp
pirkeysetmanager.h
pirkeysetmetadata.cpp
pirkeysetmetadata.h
pirmakenames.cpp
pirmakenames.h
pirrx51hardware.cpp
protocols/necprotocol.cpp
qtc_packaging/debian_fremantle/changelog
qtc_packaging/debian_fremantle/control

index 65fb8e1..d3cb689 100644 (file)
@@ -270,27 +270,30 @@ void ADBSTB5::populateProtocol(
   addKey("8", Eight_Key, 0x08, 8);
   addKey("9", Nine_Key, 0x09, 8);
   addKey("Menu", Menu_Key, 0x0A, 8);
-  addKey("Guide", Guide_Key, 0x0B, 8);
+//  addKey("Guide", Guide_Key, 0x0B, 8);
   addKey("Power", Power_Key, 0x0C, 8);
   addKey("Format 16:9", AspectRatio_Key, 0x0D, 8);
   addKey("Info/Display", Info_Key, 0x0D, 8);
-  addKey("Stop", Stop_Key, 0x0D, 8);
+//  addKey("Stop", Stop_Key, 0x0D, 8);
   addKey("CH+", ChannelUp_Key, 0x0E, 8);
   addKey("CH-", ChannelDown_Key, 0xF, 8);
   addKey("Volume +", VolumeUp_Key, 0x10, 8);
   addKey("Volume -", VolumeDown_Key, 0x11, 8);
   addKey("Arrow_Right", Right_Key, 0x12, 8);
-  addKey("FFWD", FastForward_Key, 0x13, 8);
+//  addKey("FFWD", FastForward_Key, 0x13, 8);
+  addKey("Guide", Guide_Key, 0x13, 8);
   addKey("EXIT", Exit_Key, 0x14, 8);
   addKey("Arrow_Left", Left_Key, 0x15, 8);
   addKey("OK/Select", Select_Key, 0x16, 8);
   addKey("Subtitle", Captions_Key, 0x18, 8);
+  addKey("TV/RAD", TunerInput_Key, 0x19, 8);
   addKey("Mute", Mute_Key, 0x1A, 8);
   addKey("Input/Source", Input_Key, 0x1B, 8);
   addKey("Arrow_Down", Down_Key, 0x1C, 8);
   addKey("Arrow_Up", Up_Key, 0x1D, 8);
-  addKey("Play", Play_Key, 0x1E, 8);
-  addKey("Audio", Audio_Key, 0x1F, 8);
+//  addKey("Play", Play_Key, 0x1E, 8);
+//  addKey("Audio", Audio_Key, 0x1F, 8);
+  addKey("Back", PrevChannel_Key, 0x1F, 8);
   addKey("Red", Red_Key, 0x20, 8);
   addKey("Green", Green_Key, 0x21, 8);
   addKey("Yellow", Yellow_Key, 0x22, 8);
diff --git a/keysets/changhong.cpp b/keysets/changhong.cpp
new file mode 100644 (file)
index 0000000..2d0a914
--- /dev/null
@@ -0,0 +1,257 @@
+#include "changhong.h"
+#include "protocols/necprotocol.h"
+#include "protocols/protonprotocol.h"
+
+ChanghongTV1::ChanghongTV1(
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "TV Keyset 1",
+      Changhong_Make,
+      index)
+{
+}
+
+
+void ChanghongTV1::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // Keyset already populated.
+    return;
+  }
+
+  threadableProtocol = new NECProtocol(guiObject, index, false, true);
+
+  setPreData(0x40, 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);
+  addKey("4", Four_Key, 0x04, 8);
+  addKey("5", Five_Key, 0x05, 8);
+  addKey("6", Six_Key, 0x06, 8);
+  addKey("7", Seven_Key, 0x07, 8);
+  addKey("8", Eight_Key, 0x08, 8);
+  addKey("9", Nine_Key, 0x09, 8);
+  addKey("100+", PlusOneHundred_Key, 0x0A, 8);
+  addKey("DASH", Dash_Key, 0x0A, 8);
+  addKey("TV/Video", Input_Key, 0x0B, 8);
+  addKey("ENTER", Enter_Key, 0x0C, 8);
+  addKey("Menu", Menu_Key, 0x0E, 8);
+//  addKey("Select", Select_Key, 0x0E, 8); // ?
+  addKey("Mute", Mute_Key, 0x10, 8);
+  addKey("Power", Power_Key, 0x12, 8);
+  addKey("CC", Captions_Key, 0x13, 8);
+  addKey("Sleep", Sleep_Key, 0x15, 8);
+  addKey("Guide", Guide_Key, 0x16, 8);
+  addKey("Select", Select_Key, 0x18, 8);
+  addKey("Arrow_Right", Right_Key, 0x19, 8);
+  addKey("Volume +", VolumeUp_Key, 0x1A, 8);
+  addKey("CH+", ChannelUp_Key, 0x1B, 8);
+  addKey("Info/Display", Info_Key, 0x1C, 8);
+  addKey("Arrow_Left", Left_Key, 0x1D, 8);
+  addKey("Volume -", VolumeDown_Key, 0x1E, 8);
+  addKey("CH-", ChannelDown_Key, 0x1F, 8);
+  addKey("PIP Ch+", PIPChannelUp_Key, 0x4A, 8);
+  addKey("PIP Ch-", PIPChannelDown_Key, 0x4B, 8);
+  addKey("Freeze", PIPPause_Key, 0x4C, 8);
+  addKey("PIP Move", PIPMove_Key, 0x4E, 8);
+  addKey("PIP Source", PIPSource_Key, 0x4F, 8);
+  addKey("PIP On/Off", PIP_Key, 0x51, 8);
+  addKey("PIP Swap", PIPSwap_Key, 0x53, 8);
+  addKey("Format 16:9", AspectRatio_Key, 0x54, 8);
+  addKey("EXIT", Exit_Key, 0x58, 8);
+  addKey("Arrow_Up", Up_Key, 0x82, 8);
+  addKey("Arrow_Down", Down_Key, 0x83, 8);
+}
+
+
+ChanghongTV1a::ChanghongTV1a(
+  unsigned int index)
+  : ChanghongTV1(index)
+{
+  setKeysetName("TV Keyset 1a");
+}
+
+
+void ChanghongTV1a::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // Keyset already populated.
+    return;
+  }
+
+  ChanghongTV1::populateProtocol(guiObject);
+
+  addKey("OK/Select", Select_Key, 0x0A, 8);
+  addKey("100+", PlusOneHundred_Key, 0x0B, 8);
+  addKey("DASH", Dash_Key, 0x0B, 8);
+  addKey("Sleep", Sleep_Key, 0x0D, 8);
+  addKey("Mode", Mode_Key, 0x11, 8);
+  addKey("Input/Source", Input_Key, 0x14, 8);
+  addKey("Info/Display", Info_Key, 0x16, 8);
+  addKey("CC", Captions_Key, 0x17, 8);
+  addKey("Arrow_Up", Up_Key, 0x19, 8);
+  addKey("Arrow_Down", Down_Key, 0x1D, 8);
+  addKey("Last/Prev Ch", PrevChannel_Key, 0x40, 8);
+  addKey("Arrow_Left", Left_Key, 0x46, 8);
+  addKey("Arrow_Right", Right_Key, 0x47, 8);
+  addKey("Menu", Menu_Key, 0x5B, 8);
+}
+
+
+ChanghongTV1b::ChanghongTV1b(
+  unsigned int index)
+  : ChanghongTV1(index)
+{
+  setKeysetName("TV Keyset 1b");
+}
+
+
+void ChanghongTV1b::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // Keyset already populated.
+    return;
+  }
+
+  ChanghongTV1::populateProtocol(guiObject);
+
+  addKey("100+", PlusOneHundred_Key, 0x0B, 8);
+  addKey("DASH", Dash_Key, 0x0B, 8);
+  addKey("Sleep", Sleep_Key, 0x0D, 8);
+  addKey("EXIT", Exit_Key, 0x11, 8);
+  addKey("Mode", Mode_Key, 0x11, 8);
+  addKey("Input/Source", Input_Key, 0x14, 8);
+  addKey("Info/Display", Info_Key, 0x16, 8);
+  addKey("Guide", Guide_Key, 0x18, 8);
+  addKey("Arrow_Right", Right_Key, 0x1A, 8);
+  addKey("Arrow_Up", Up_Key, 0x1B, 8);
+  addKey("Arrow_Left", Left_Key, 0x1E, 8);
+  addKey("Arrow_Down", Down_Key, 0x1F, 8);
+  addKey("Last/Prev Ch", PrevChannel_Key, 0x40, 8);
+  addKey("Menu", Menu_Key, 0x56, 8);
+  addKey("OK/Select", Select_Key, 0x5B, 8);
+}
+
+
+ChanghongTV2::ChanghongTV2(
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "TV Keyset 2",
+      Changhong_Make,
+      index)
+{
+}
+
+
+void ChanghongTV2::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // Keyset already populated.
+    return;
+  }
+
+  threadableProtocol = new NECProtocol(guiObject, index, false, true);
+
+  setPreData(0x40, 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);
+  addKey("4", Four_Key, 0x04, 8);
+  addKey("5", Five_Key, 0x05, 8);
+  addKey("6", Six_Key, 0x06, 8);
+  addKey("7", Seven_Key, 0x07, 8);
+  addKey("8", Eight_Key, 0x08, 8);
+  addKey("9", Nine_Key, 0x09, 8);
+  addKey("TV/Video", Input_Key, 0x0A, 8);
+  addKey("Arrow_Right", Right_Key, 0x0E, 8);
+  addKey("Menu", Menu_Key, 0x0F, 8);
+  addKey("Mute", Mute_Key, 0x10, 8);
+  addKey("CH-", ChannelDown_Key, 0x12, 8);
+  addKey("Info/Display", Info_Key, 0x13, 8);
+  addKey("Red", Red_Key, 0x13, 8);
+  addKey("Radio", TunerInput_Key, 0x14, 8);
+  addKey("-/--", DoubleDigit_Key, 0x15, 8);
+  addKey("Arrow_Up", Up_Key, 0x16, 8);
+  addKey("Last/Prev Ch", PrevChannel_Key, 0x17, 8);
+  addKey("Arrow_Down", Down_Key, 0x19, 8);
+  addKey("Volume +", VolumeUp_Key, 0x1A, 8);
+  addKey("Volume -", VolumeDown_Key, 0x1E, 8);
+  addKey("CH+", ChannelUp_Key, 0x1F, 8);
+  addKey("Audio", Audio_Key, 0x4C, 8);
+  addKey("Blue", PIPMove_Key, 0x4E, 8);
+  addKey("Format 16:9", AspectRatio_Key, 0x54, 8);
+  addKey("Green", Green_Key, 0x57, 8);
+  addKey("Yellow", Yellow_Key, 0x58, 8);
+  addKey("Guide", Guide_Key, 0x5A, 8);
+  addKey("Select", Select_Key, 0x80, 8);
+  addKey("Arrow_Left", Left_Key, 0x82, 8);
+  addKey("Power", Power_Key, 0x83, 8);
+  addKey("100+", PlusOneHundred_Key, 0x90, 8);
+}
+
+
+ChanghongTV3::ChanghongTV3(
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "TV Keyset 3",
+      Changhong_Make,
+      index)
+{
+}
+
+
+void ChanghongTV3::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // Keyset already populated.
+    return;
+  }
+
+  threadableProtocol = new ProtonProtocol(guiObject, index);
+
+  setPreData(0x04, 8);
+
+  addKey("CH+", ChannelUp_Key, 0x01, 8);
+  addKey("CH-", ChannelDown_Key, 0x02, 8);
+  addKey("Volume +", VolumeUp_Key, 0x03, 8);
+  addKey("Volume -", VolumeDown_Key, 0x04, 8);
+  addKey("Brightness +", BrightnessUp_Key, 0x05, 8);
+  addKey("Brightness -", BrightnessDown_Key, 0x06, 8);
+  addKey("Color -", ColorDown_Key, 0x07, 8);
+  addKey("Color +", ColorUp_Key, 0x08, 8);
+  addKey("Mute", Mute_Key, 0x09, 8);
+  addKey("Last/Prev Ch", PrevChannel_Key, 0x0A, 8);
+  addKey("Sleep", Sleep_Key, 0x0C, 8);
+  addKey("TV/Video", Input_Key, 0x0D, 8);
+  addKey("Power", Power_Key, 0x0E, 8);
+  addKey("Info/Display", Info_Key, 0x0F, 8);
+  addKey("1", One_Key, 0x10, 8);
+  addKey("2", Two_Key, 0x11, 8);
+  addKey("3", Three_Key, 0x12, 8);
+  addKey("4", Four_Key, 0x13, 8);
+  addKey("5", Five_Key, 0x14, 8);
+  addKey("6", Six_Key, 0x15, 8);
+  addKey("7", Seven_Key, 0x16, 8);
+  addKey("8", Eight_Key, 0x17, 8);
+  addKey("9", Nine_Key, 0x18, 8);
+  addKey("0", Zero_Key, 0x19, 8);
+  addKey("-/--", DoubleDigit_Key, 0x1A, 8);
+  addKey("Menu", Menu_Key, 0x58, 8);
+  addKey("Select", Select_Key, 0x58, 8);
+  addKey("Arrow_Right", Right_Key, 0x59, 8);
+  addKey("Arrow_Left", Left_Key, 0x5A, 8);
+}
diff --git a/keysets/changhong.h b/keysets/changhong.h
new file mode 100644 (file)
index 0000000..ee6ca09
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef CHANGHONG_H
+#define CHANGHONG_H
+
+#include "pirkeysetmetadata.h"
+
+class QObject;
+
+class ChanghongTV1: public PIRKeysetMetaData
+{
+public:
+  ChanghongTV1(
+    unsigned int index);
+
+  virtual void populateProtocol(
+    QObject *guiObject);
+};
+
+class ChanghongTV1a: public ChanghongTV1
+{
+public:
+  ChanghongTV1a(
+    unsigned int index);
+
+  virtual void populateProtocol(
+    QObject *guiObject);
+};
+
+class ChanghongTV1b: public ChanghongTV1
+{
+public:
+  ChanghongTV1b(
+    unsigned int index);
+
+  virtual void populateProtocol(
+    QObject *guiObject);
+};
+
+class ChanghongTV2: public PIRKeysetMetaData
+{
+public:
+  ChanghongTV2(
+    unsigned int index);
+
+  virtual void populateProtocol(
+    QObject *guiObject);
+};
+
+class ChanghongTV3: public PIRKeysetMetaData
+{
+public:
+  ChanghongTV3(
+    unsigned int index);
+
+  virtual void populateProtocol(
+    QObject *guiObject);
+};
+
+#endif // CHANGHONG_H
diff --git a/keysets/frontech.cpp b/keysets/frontech.cpp
new file mode 100644 (file)
index 0000000..a3051ae
--- /dev/null
@@ -0,0 +1,107 @@
+#include "frontech.h"
+#include "protocols/protonprotocol.h"
+#include "protocols/samsungprotocol.h"
+
+FrontechTV1::FrontechTV1(
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "TV Keyset 1",
+      Frontech_Make,
+      index)
+{
+}
+
+
+void FrontechTV1::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // Keyset already popuated.
+    return;
+  }
+
+  threadableProtocol = new ProtonProtocol(guiObject, index);
+
+  setPreData(0x02, 8);
+
+  addKey("CH+", ChannelUp_Key, 0x01, 8);
+  addKey("CH-", ChannelDown_Key, 0x02, 8);
+  addKey("Volume +", VolumeUp_Key, 0x03, 8);
+  addKey("Volume -", VolumeDown_Key, 0x04, 8);
+  addKey("Brightness +", BrightnessUp_Key, 0x05, 8);
+  addKey("Brightness -", BrightnessDown_Key, 0x06, 8);
+  addKey("Color -", ColorDown_Key, 0x07, 8);
+  addKey("Color +", ColorUp_Key, 0x08, 8);
+  addKey("Mute", Mute_Key, 0x09, 8);
+  addKey("Last/Prev Ch", PrevChannel_Key, 0x0A, 8);
+  addKey("Sleep", Sleep_Key, 0x0C, 8);
+  addKey("TV/Video", Input_Key, 0x0D, 8);
+  addKey("Power", Power_Key, 0x0E, 8);
+  addKey("Info/Display", Info_Key, 0x0F, 8);
+  addKey("1", One_Key, 0x10, 8);
+  addKey("2", Two_Key, 0x11, 8);
+  addKey("3", Three_Key, 0x12, 8);
+  addKey("4", Four_Key, 0x13, 8);
+  addKey("5", Five_Key, 0x14, 8);
+  addKey("6", Six_Key, 0x15, 8);
+  addKey("7", Seven_Key, 0x16, 8);
+  addKey("8", Eight_Key, 0x17, 8);
+  addKey("9", Nine_Key, 0x18, 8);
+  addKey("0", Zero_Key, 0x19, 8);
+  addKey("-/--", DoubleDigit_Key, 0x1A, 8);
+  addKey("Menu", Menu_Key, 0x58, 8);
+  addKey("Select", Select_Key, 0x58, 8);
+  addKey("Arrow_Right", Right_Key, 0x59, 8);
+  addKey("Arrow_Left", Left_Key, 0x5A, 8);
+}
+
+
+FrontechTV2::FrontechTV2(
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "TV Keyset 2",
+      Frontech_Make,
+      index)
+{
+}
+
+
+void FrontechTV2::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // Keyset already populated.
+    return;
+  }
+
+  threadableProtocol = new SamsungProtocol(guiObject, index);
+
+  setPreData(0x0E0E, 16);
+
+  addKey("1", One_Key, 0x00, 8);
+  addKey("2", Two_Key, 0x01, 8);
+  addKey("3", Three_Key, 0x02, 8);
+  addKey("4", Four_Key, 0x03, 8);
+  addKey("5", Five_Key, 0x04, 8);
+  addKey("6", Six_Key, 0x05, 8);
+  addKey("7", Seven_Key, 0x06, 8);
+  addKey("8", Eight_Key, 0x07, 8);
+  addKey("9", Nine_Key, 0x08, 8);
+  addKey("0", Zero_Key, 0x09, 8);
+  addKey("CH+", ChannelUp_Key, 0x10, 8);
+  addKey("CH-", ChannelDown_Key, 0x11, 8);
+  addKey("Volume +", VolumeUp_Key, 0x12, 8);
+  addKey("Volume -", VolumeDown_Key, 0x13, 8);
+  addKey("Power", Power_Key, 0x14, 8);
+  addKey("Mute", Mute_Key, 0x15, 8);
+  addKey("TV/Video", Input_Key, 0x16, 8);
+  addKey("Sleep", Sleep_Key, 0x18, 8);
+  addKey("Info/Display", Info_Key, 0x19, 8);
+  addKey("Last/Prev Ch", PrevChannel_Key, 0x1A, 8);
+  addKey("Arrow_Right", Right_Key, 0x1C, 8);
+  addKey("Arrow_Left", Left_Key, 0x1D, 8);
+  addKey("Menu", Menu_Key, 0x1E, 8);
+  addKey("EXIT", Exit_Key, 0x1E, 8);
+}
diff --git a/keysets/frontech.h b/keysets/frontech.h
new file mode 100644 (file)
index 0000000..a0dc1e7
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef FRONTECH_H
+#define FRONTECH_H
+
+#include "pirkeysetmetadata.h"
+
+class QObject;
+
+class FrontechTV1: public PIRKeysetMetaData
+{
+public:
+  FrontechTV1(
+    unsigned int index);
+
+  virtual void populateProtocol(
+    QObject *guiObject);
+};
+
+class FrontechTV2: public PIRKeysetMetaData
+{
+public:
+  FrontechTV2(
+    unsigned int index);
+
+  virtual void populateProtocol(
+    QObject *guiObject);
+};
+
+#endif // FRONTECH_H
diff --git a/keysets/sinotec.cpp b/keysets/sinotec.cpp
new file mode 100644 (file)
index 0000000..a01e429
--- /dev/null
@@ -0,0 +1,113 @@
+#include "sinotec.h"
+#include "protocols/samsungprotocol.h"
+#include "protocols/aiwaprotocol.h"
+
+SinotecTV1::SinotecTV1(
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "TV Keyset 1",
+      Sinotec_Make,
+      index)
+{
+}
+
+
+void SinotecTV1::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // Keyset already populated.
+    return;
+  }
+
+  threadableProtocol = new SamsungProtocol(guiObject, index);
+
+  setPreData(0x0E0E, 16);
+
+  addKey("1", One_Key, 0x00, 8);
+  addKey("2", Two_Key, 0x01, 8);
+  addKey("3", Three_Key, 0x02, 8);
+  addKey("4", Four_Key, 0x03, 8);
+  addKey("5", Five_Key, 0x04, 8);
+  addKey("6", Six_Key, 0x05, 8);
+  addKey("7", Seven_Key, 0x06, 8);
+  addKey("8", Eight_Key, 0x07, 8);
+  addKey("9", Nine_Key, 0x08, 8);
+  addKey("0", Zero_Key, 0x09, 8);
+  addKey("-/--", DoubleDigit_Key, 0x0A, 8);
+  addKey("Power", Power_Key, 0x0B, 8);
+  addKey("Green", Green_Key, 0x0C, 8);
+  addKey("TV/Video", Input_Key, 0x0F, 8);
+  addKey("CH-", ChannelDown_Key, 0x10, 8);
+  addKey("CH+", ChannelUp_Key, 0x11, 8);
+  addKey("Volume -", VolumeDown_Key, 0x12, 8);
+  addKey("Volume +", VolumeUp_Key, 0x13, 8);
+  addKey("Mute", Mute_Key, 0x14, 8);
+  addKey("Sleep", Sleep_Key, 0x15, 8);
+  addKey("Info/Display", Info_Key, 0x16, 8);
+  addKey("Blue", Blue_Key, 0x16, 8);
+  addKey("Arrow_Down", Down_Key, 0x18, 8);
+  addKey("Arrow_Up", Up_Key, 0x19, 8);
+  addKey("Arrow_Left", Left_Key, 0x1A, 8);
+  addKey("Arrow_Right", Right_Key, 0x1B, 8);
+  addKey("Red", Red_Key, 0x1C, 8);
+  addKey("Menu", Menu_Key, 0x1C, 8);
+  addKey("Yellow", Yellow_Key, 0x1D, 8);
+}
+
+
+SinotecTV2::SinotecTV2(
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "TV Keyset 2",
+      Sinotec_Make,
+      index)
+{
+}
+
+
+void SinotecTV2::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // Keyset already populated.
+    return;
+  }
+
+  threadableProtocol = new AiwaProtocol(guiObject, index);
+
+  setPreData(0x011A, 13);
+
+  addKey("Info/Display", Info_Key, 0x02, 8);
+  addKey("Last/Prev Ch", PrevChannel_Key, 0x03, 8);
+  addKey("Volume +", VolumeUp_Key, 0x04, 8);
+  addKey("Arrow_Right", Right_Key, 0x04, 8);
+//  addKey("Brightness -", BrightnessDown_Key, 0x06, 8);
+//  addKey("Brightness +", BrightnessUp_Key, 0x07, 8);
+  addKey("Menu", Menu_Key, 0x08, 8);
+  addKey("CH-", ChannelDown_Key, 0x09, 8);
+  addKey("Arrow_Down", Down_Key, 0x09, 8);
+  addKey("Power", Power_Key, 0x0A, 8);
+  addKey("Sleep", Sleep_Key, 0x0B, 8);
+  addKey("Input/Source", Input_Key, 0x0C, 8);
+  addKey("Mute", Mute_Key, 0x0D, 8);
+  addKey("100+", PlusOneHundred_Key, 0x0E, 8);
+  addKey("-/--", DoubleDigit_Key, 0x0E, 8);
+  addKey("0", Zero_Key, 0x10, 8);
+  addKey("1", One_Key, 0x11, 8);
+  addKey("2", Two_Key, 0x12, 8);
+  addKey("3", Three_Key, 0x13, 8);
+  addKey("4", Four_Key, 0x14, 8);
+  addKey("5", Five_Key, 0x15, 8);
+  addKey("6", Six_Key, 0x16, 8);
+  addKey("7", Seven_Key, 0x17, 8);
+  addKey("8", Eight_Key, 0x18, 8);
+  addKey("9", Nine_Key, 0x19, 8);
+  addKey("CH+", ChannelUp_Key, 0x1B, 8);
+  addKey("Arrow_Up", Up_Key, 0x1B, 8);
+  addKey("Volume -", VolumeDown_Key, 0x1D, 8);
+  addKey("Arrow_Left", Left_Key, 0x1D, 8);
+  addKey("OK/Select", Select_Key, 0x40, 8);
+}
diff --git a/keysets/sinotec.h b/keysets/sinotec.h
new file mode 100644 (file)
index 0000000..674a29f
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef SINOTEC_H
+#define SINOTEC_H
+
+#include "pirkeysetmetadata.h"
+
+class QObject;
+
+class SinotecTV1: public PIRKeysetMetaData
+{
+public:
+  SinotecTV1(
+    unsigned int index);
+
+  virtual void populateProtocol(
+    QObject *guiObject);
+};
+
+class SinotecTV2: public PIRKeysetMetaData
+{
+public:
+  SinotecTV2(
+    unsigned int index);
+
+  virtual void populateProtocol(
+    QObject *guiObject);
+};
+
+#endif // SINOTEC_H
index 6ce906b..cbebaba 100644 (file)
@@ -2,6 +2,7 @@
 #include "protocols/xmpprotocol.h"
 #include "protocols/thomsonprotocol.h"
 #include "protocols/necprotocol.h"
+#include "protocols/rcaprotocol.h"
 
 
 ThomsonConverter1::ThomsonConverter1(
@@ -402,3 +403,57 @@ void ThomsonAudio1::populateProtocol(
   addKey("presDown", ChannelDown_Key, 0x9D, 8);
   addKey("presDown", PrevPreset_Key, 0x9D, 8);
 }
+
+
+ThomsonAudio2::ThomsonAudio2(
+  unsigned int index)
+  : PIRKeysetMetaData(
+      "Audio Keyset 2",
+      Thomson_Make,
+      index)
+{
+}
+
+
+void ThomsonAudio2::populateProtocol(
+  QObject *guiObject)
+{
+  if (threadableProtocol)
+  {
+    // Keyset already populated.
+    return;
+  }
+
+  threadableProtocol = new RCAProtocol(guiObject, index);
+
+  setPreData(0xC, 4);
+
+  addKey("Sleep", Sleep_Key, 0x07, 8);
+  addKey("Menu", Menu_Key, 0x12, 8);
+  addKey("Tune +", ChannelUp_Key, 0x20, 8);
+  addKey("Tune -", ChannelDown_Key, 0x22, 8);
+  addKey("Power", Power_Key, 0x2A, 8);
+  addKey("CH+", Unmapped_Key, 0x2C, 8); // hoping "Tune +" instead
+  addKey("CH-", Unmapped_Key, 0x2D, 8);
+  addKey("Volume -", VolumeDown_Key, 0x2E, 8);
+  addKey("Arrow_Down", Down_Key, 0x2E, 8);
+  addKey("Volume +", VolumeUp_Key, 0x2F, 8);
+  addKey("Arrow_Up", Up_Key, 0x2F, 8);
+  addKey("0", Zero_Key, 0x30, 8);
+  addKey("1", One_Key, 0x31, 8);
+  addKey("2", Two_Key, 0x32, 8);
+  addKey("3", Three_Key, 0x33, 8);
+  addKey("4", Four_Key, 0x34, 8);
+  addKey("5", Five_Key, 0x35, 8);
+  addKey("6", Six_Key, 0x36, 8);
+  addKey("7", Seven_Key, 0x37, 8);
+  addKey("8", Eight_Key, 0x38, 8);
+  addKey("9", Nine_Key, 0x39, 8);
+  addKey("Info/Display", Info_Key, 0x3A, 8);
+  addKey("Mute", Mute_Key, 0x3F, 8);
+  addKey("OK/Select", Select_Key, 0x4F, 8);  // ?
+  addKey("Last/Prev Ch", PrevChannel_Key, 0x56, 8); // ?
+  addKey("Surround", SoundMode_Key, 0x5B, 8);
+  addKey("Arrow_Left", Left_Key, 0x64, 8);
+  addKey("Arrow_Right", Right_Key, 0x65, 8);
+}
index f443263..653696f 100644 (file)
@@ -75,4 +75,14 @@ public:
     QObject *guiObject);
 };
 
+class ThomsonAudio2: public PIRKeysetMetaData
+{
+public:
+  ThomsonAudio2(
+    unsigned int index);
+
+  virtual void populateProtocol(
+    QObject *guiObject);
+};
+
 #endif // THOMSON_H
index b1a9475..10753c2 100644 (file)
@@ -200,18 +200,19 @@ bool PIRMacro::executeMacro()
   // Don't start a new macro if one is already running:
   if (macroRunning) return false;
 
+  // Start running the list of commands:
+  macroRunning = true;
+
   currentCommand = commands.begin();
 
   // If this macro is empty, just return:
   if (currentCommand == commands.end())
   {
     emit macroCompleted();
+    macroRunning = false;
     return true;
   }
 
-  // Start running the list of commands:
-  macroRunning = true;
-
   // Take note of the current keyset id:
   preMacroKeysetID = mainWindow->getCurrentKeyset();
 
index f78deb3..9b5cdb4 100644 (file)
@@ -51,6 +51,7 @@ PIRKeyCommandItem::PIRKeyCommandItem(
 PIRKeyCommandItem::~PIRKeyCommandItem()
 {
   if (advanceTimer) delete advanceTimer;
+  advanceTimer = 0;
 }
 
 
index 2552dc0..3888c19 100644 (file)
@@ -233,7 +233,10 @@ SOURCES += main.cpp mainwindow.cpp \
     keysets/hantarex.cpp \
     keysets/keymat.cpp \
     keysets/konka.cpp \
-    keysets/wiwa.cpp
+    keysets/wiwa.cpp \
+    keysets/changhong.cpp \
+    keysets/frontech.cpp \
+    keysets/sinotec.cpp
 HEADERS += mainwindow.h \
     pirkeynames.h \
     pirmakenames.h \
@@ -441,7 +444,10 @@ HEADERS += mainwindow.h \
     keysets/hantarex.h \
     keysets/keymat.h \
     keysets/konka.h \
-    keysets/wiwa.h
+    keysets/wiwa.h \
+    keysets/changhong.h \
+    keysets/frontech.h \
+    keysets/sinotec.h
 FORMS += mainwindow.ui \
     pirdocumentationform.ui \
     piraboutform.ui \
index 9e84dcc..40a15b6 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by Qt Creator 2.4.1, 2012-09-16T18:50:09. -->
+<!-- Written by Qt Creator 2.4.1, 2012-09-19T16:26:53. -->
 <qtcreator>
  <data>
   <variable>ProjectExplorer.Project.ActiveTarget</variable>
@@ -79,7 +79,7 @@
       <value type="QString" key="ProjectExplorer.ProcessStep.Arguments">dpkg-buildpackage -sa -S -uc -us</value>
       <value type="QString" key="ProjectExplorer.ProcessStep.Command">/Users/john/QtSDK/Maemo/4.6.2/bin/mad</value>
       <value type="bool" key="ProjectExplorer.ProcessStep.Enabled">false</value>
-      <value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">/Users/john/Develop/n900/pierogi-1.1.12</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">/Users/john/Develop/n900/pierogi-1.1.13</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
        <value type="QString">/Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_1_0_armel.deb</value>
        <value type="QString">/Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_1_2_armel.deb</value>
        <value type="QString">/Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_6_7_armel.deb</value>
+       <value type="QString">/Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_1_1_13_armel.deb</value>
        <value type="QString">/Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_1_5_armel.deb</value>
        <value type="QString">/Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_6_0_armel.deb</value>
        <value type="QString">/Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_0_1_armel.deb</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">localhost</value>
        <value type="QString">192.168.0.15</value>
        <value type="QString">192.168.0.15</value>
        <value type="QString"></value>
        <value type="QString"></value>
        <value type="QString"></value>
+       <value type="QString"></value>
       </valuelist>
       <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedTimes">
        <value type="QDateTime">2012-01-19T22:18:07</value>
        <value type="QDateTime">2012-01-17T00:03:13</value>
        <value type="QDateTime">2012-01-17T12:19:28</value>
        <value type="QDateTime">2012-02-19T10:29:22</value>
+       <value type="QDateTime">2012-09-19T13:24:39</value>
        <value type="QDateTime">2012-01-23T09:47:37</value>
        <value type="QDateTime">2012-02-11T18:03:15</value>
        <value type="QDateTime">2012-01-14T13:11:32</value>
index 719cd93..b3ba761 100644 (file)
@@ -22,6 +22,7 @@
 #include "keysets/bush.h"
 #include "keysets/cambridge.h"
 #include "keysets/canon.h"
+#include "keysets/changhong.h"
 #include "keysets/cisco.h"
 #include "keysets/compro.h"
 #include "keysets/creative.h"
@@ -44,6 +45,7 @@
 #include "keysets/epson.h"
 #include "keysets/fortec.h"
 #include "keysets/foxtel.h"
+#include "keysets/frontech.h"
 #include "keysets/gadmei.h"
 #include "keysets/genius.h"
 #include "keysets/goldstar.h"
 #include "keysets/samsung.h"
 #include "keysets/sanyo.h"
 #include "keysets/sharp.h"
+#include "keysets/sinotec.h"
 #include "keysets/sky.h"
 #include "keysets/sony.h"
 #include "keysets/starsat.h"
@@ -213,6 +216,12 @@ PIRKeysetManager::PIRKeysetManager()
   setupKeyset(new CanonCamcorder1(++counter));
   setupKeyset(new CanonPowershot1(++counter));
 
+  setupKeyset(new ChanghongTV1(++counter));
+  setupKeyset(new ChanghongTV1a(++counter));
+  setupKeyset(new ChanghongTV1b(++counter));
+  setupKeyset(new ChanghongTV2(++counter));
+  setupKeyset(new ChanghongTV3(++counter));
+
   setupKeyset(new CiscoSTB1(++counter));
   setupKeyset(new CiscoSTB2(++counter));
   setupKeyset(new CiscoSTB3(++counter));
@@ -323,6 +332,9 @@ PIRKeysetManager::PIRKeysetManager()
   setupKeyset(new FoxtelSTB1(++counter));
   setupKeyset(new FoxtelSTB2(++counter));
 
+  setupKeyset(new FrontechTV1(++counter));
+  setupKeyset(new FrontechTV2(++counter));
+
   setupKeyset(new GadmeiTuner1(++counter));
 
   setupKeyset(new GeniusSpeakers1(++counter));
@@ -681,6 +693,9 @@ PIRKeysetManager::PIRKeysetManager()
   setupKeyset(new SharpReceiver1(++counter));
   setupKeyset(new SharpAC1(++counter));
 
+  setupKeyset(new SinotecTV1(++counter));
+  setupKeyset(new SinotecTV2(++counter));
+
   setupKeyset(new SkyReceiver1(++counter));
   setupKeyset(new SkyReceiver1a(++counter));
 
@@ -745,6 +760,7 @@ PIRKeysetManager::PIRKeysetManager()
   setupKeyset(new ThomsonDVD1(++counter));
   setupKeyset(new ThomsonSat1(++counter));
   setupKeyset(new ThomsonAudio1(++counter));
+  setupKeyset(new ThomsonAudio2(++counter));
 
   setupKeyset(new Tivo1(++counter));
   setupKeyset(new Tivo1a(++counter));
@@ -966,17 +982,17 @@ void PIRKeysetManager::populateKeyset(
 }
 
 
-void PIRKeysetManager::clearKeyset(
+bool PIRKeysetManager::clearKeyset(
   unsigned int keysetID)
 {
   PIRKeysetCollection::iterator i = keysetsInfo.find(keysetID);
 
   if (i == keysetsInfo.end())
   {
-    return; // should throw error or something
+    return true; // best I can do here right now...
   }
 
-  i->second->clearProtocol();
+  return i->second->clearProtocol();
 }
 
 
index 4b6527c..d9272a4 100644 (file)
@@ -65,7 +65,7 @@ public:
     QObject *guiObject,
     unsigned int keysetID);
 
-  void clearKeyset(
+  bool clearKeyset(
     unsigned int keysetID);
 
   void populateFavorites(
index 903425e..e80822c 100644 (file)
@@ -11,6 +11,9 @@ extern PIRMakeMgr makeManager;
 // Static member definition:
 PIRDeviceCollection PIRKeysetMetaData::controlledDevices;
 
+// Thread synchronization stuff:
+extern bool commandInFlight;
+
 PIRKeysetMetaData::PIRKeysetMetaData(
   const char *r,
   PIRMakeName m,
@@ -25,8 +28,7 @@ PIRKeysetMetaData::PIRKeysetMetaData(
 
 PIRKeysetMetaData::~PIRKeysetMetaData()
 {
-  if (threadableProtocol) delete threadableProtocol;
-  threadableProtocol = 0;
+  clearProtocol();
 }
 
 
@@ -302,11 +304,18 @@ void PIRKeysetMetaData::setKeysetName(
 }
 
 
-void PIRKeysetMetaData::clearProtocol()
+bool PIRKeysetMetaData::clearProtocol()
 {
-  if (threadableProtocol)
+  if (!threadableProtocol)
+  {
+    return true;
+  }
+  else if (!commandInFlight)
   {
     delete threadableProtocol;
     threadableProtocol = 0;
+    return true;
   }
+
+  return false;
 }
index 0f9101a..80c4ed1 100644 (file)
@@ -41,7 +41,7 @@ public:
   virtual void populateProtocol(
     QObject *guiObject) = 0;
 
-  void clearProtocol();
+  bool clearProtocol();
 
   void moveToThread(
     QThread *thread);
index 4d3dcb6..5ecdd19 100644 (file)
@@ -20,6 +20,7 @@ PIRMakeMgr::PIRMakeMgr()
   makes[Bush_Make] = "Bush";
   makes[Cambridge_Make] = "Cambridge Audio";
   makes[Canon_Make] = "Canon";
+  makes[Changhong_Make] = "Changhong";
   makes[Cisco_Make] = "Cisco";
   makes[Compro_Make] = "Compro";
   makes[Creative_Make] = "Creative";
@@ -42,6 +43,7 @@ PIRMakeMgr::PIRMakeMgr()
   makes[Epson_Make] = "Epson";
   makes[Fortec_Make] = "Fortec Star";
   makes[Foxtel_Make] = "Foxtel";
+  makes[Frontech_Make] = "Frontech";
   makes[Gadmei_Make] = "Gadmei";
   makes[Genius_Make] = "Genius";
   makes[GoldStar_Make] = "GoldStar";
@@ -99,6 +101,7 @@ PIRMakeMgr::PIRMakeMgr()
   makes[Samsung_Make] = "Samsung";
   makes[Sanyo_Make] = "Sanyo";
   makes[Sharp_Make] = "Sharp";
+  makes[Sinotec_Make] = "Sinotec";
   makes[Sky_Make] = "Sky";
   makes[Sony_Make] = "Sony";
   makes[Starsat_Make] = "Starsat";
index c8c5dc6..7071548 100644 (file)
@@ -21,6 +21,7 @@ enum PIRMakeName{
   Bush_Make,
   Cambridge_Make,
   Canon_Make,
+  Changhong_Make,
   Cisco_Make,
   Compro_Make,
   Creative_Make,
@@ -43,6 +44,7 @@ enum PIRMakeName{
   Epson_Make,
   Fortec_Make,
   Foxtel_Make,
+  Frontech_Make,
   Gadmei_Make,
   Genius_Make,
   GoldStar_Make,
@@ -100,6 +102,7 @@ enum PIRMakeName{
   Samsung_Make,
   Sanyo_Make,
   Sharp_Make,
+  Sinotec_Make,
   Sky_Make,
   Sony_Make,
   Starsat_Make,
index 256b450..bfd9bc0 100644 (file)
@@ -1,6 +1,6 @@
 #include "pirrx51hardware.h"
 
-//#define DEBUGGING
+// #define DEBUGGING
 
 // Needed system includes:
 #include <sys/ioctl.h>
index 6efde39..ccaca00 100644 (file)
@@ -9,6 +9,9 @@
 extern bool commandInFlight;
 extern QMutex commandIFMutex;
 
+// Debugging:
+#include <iostream>
+
 // The official NEC protocol, as I understand it, has the following attributes:
 // A "zero" is encoded with a 560 usec pulse, 560 usec space.
 // A "one" is encoded with a 560 usec pulse, and 3*560 (1680) usec space.
index d05eb87..8b50812 100644 (file)
@@ -1,3 +1,9 @@
+pierogi (1.1.14) unstable; urgency=low
+  * Fixed a bug that allowed keysets to be deleted while a command was still running (causing all sorts of havoc).  This might improve macro behavior.
+  * Made a first pass at keysets for Changhong, Frontech, Sinotec, and Supra, added a new Thomson keyset, and made a few fixes to ADB (I-Can).
+
+ -- John Pietrzak <jpietrzak8@gmail.com>  Wed, 19 Sep 2012 16:13:03 -0400
+
 pierogi (1.1.13) unstable; urgency=low
   * Found a new source of (possibly unreliable) keysets!  Made a first pass at keysets for Crown Mustang, Hantarex, Keymat, Konka, and Wiwa.  Also added more keysets to ADB (I-Can), Sony, and Triax.  Hopefully more to come...
   * Made small fixes to the macros UI, and improved the cleanup of threads when Pierogi exits.  Also made small fixes to a Cisco keyset and to LG timing.
index bda3181..58dc10a 100644 (file)
@@ -11,8 +11,8 @@ Architecture: armel
 Depends: ${shlibs:Depends}, ${misc:Depends}
 Description: Universal Infrared (IR) Remote Control for N900
  Pierogi is a Universal Infrared Remote Control app for the Nokia N900.  It is independent from the LIRC server, and stores all configuration info internally.
-XB-Maemo-Upgrade-Description: More Keysets!
- Found a new source of keyset data (although it might not be reliable).  Made a first pass at keysets for Crown Mustang, Hantarex, Keymat, Konka, and Wiwa.  Also added new keysets to ADB (I-Can), Sony, and Triax.  There are also some minor bug fixes and tweaks to the new macro system.
+XB-Maemo-Upgrade-Description: A bugfix update
+ This update fixes a situation where keysets were being deleted while a command was still running.  Also, a first pass at keysets for Changhong, Frontech, Sinotec, and Supra; a new Thomson keyset; and a few fixes to ADB (I-Can) keysets.
 XSBC-Bugtracker: https://garage.maemo.org/tracker/?func=add&group_id=2286&atid=7641
 XB-Maemo-Display-Name: Pierogi
 XB-Maemo-Icon-26: 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