From f3809ec697222bd9ad47c725bb72dd7272fd594b Mon Sep 17 00:00:00 2001 From: John Pietrzak Date: Wed, 19 Sep 2012 16:43:25 -0400 Subject: [PATCH] Keyset Memory Management Bugfix 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. --- keysets/adb.cpp | 13 +- keysets/changhong.cpp | 257 ++++++++++++++++++++++++++++++ keysets/changhong.h | 58 +++++++ keysets/frontech.cpp | 107 +++++++++++++ keysets/frontech.h | 28 ++++ keysets/sinotec.cpp | 113 +++++++++++++ keysets/sinotec.h | 28 ++++ keysets/thomson.cpp | 55 +++++++ keysets/thomson.h | 10 ++ macros/pirmacro.cpp | 7 +- macros/pirmacrocommanditem.cpp | 1 + pierogi.pro | 10 +- pierogi.pro.user | 8 +- pirkeysetmanager.cpp | 22 ++- pirkeysetmanager.h | 2 +- pirkeysetmetadata.cpp | 17 +- pirkeysetmetadata.h | 2 +- pirmakenames.cpp | 3 + pirmakenames.h | 3 + pirrx51hardware.cpp | 2 +- protocols/necprotocol.cpp | 3 + qtc_packaging/debian_fremantle/changelog | 6 + qtc_packaging/debian_fremantle/control | 4 +- 23 files changed, 735 insertions(+), 24 deletions(-) create mode 100644 keysets/changhong.cpp create mode 100644 keysets/changhong.h create mode 100644 keysets/frontech.cpp create mode 100644 keysets/frontech.h create mode 100644 keysets/sinotec.cpp create mode 100644 keysets/sinotec.h diff --git a/keysets/adb.cpp b/keysets/adb.cpp index 65fb8e1..d3cb689 100644 --- a/keysets/adb.cpp +++ b/keysets/adb.cpp @@ -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 index 0000000..2d0a914 --- /dev/null +++ b/keysets/changhong.cpp @@ -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 index 0000000..ee6ca09 --- /dev/null +++ b/keysets/changhong.h @@ -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 index 0000000..a3051ae --- /dev/null +++ b/keysets/frontech.cpp @@ -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 index 0000000..a0dc1e7 --- /dev/null +++ b/keysets/frontech.h @@ -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 index 0000000..a01e429 --- /dev/null +++ b/keysets/sinotec.cpp @@ -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 index 0000000..674a29f --- /dev/null +++ b/keysets/sinotec.h @@ -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 diff --git a/keysets/thomson.cpp b/keysets/thomson.cpp index 6ce906b..cbebaba 100644 --- a/keysets/thomson.cpp +++ b/keysets/thomson.cpp @@ -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); +} diff --git a/keysets/thomson.h b/keysets/thomson.h index f443263..653696f 100644 --- a/keysets/thomson.h +++ b/keysets/thomson.h @@ -75,4 +75,14 @@ public: QObject *guiObject); }; +class ThomsonAudio2: public PIRKeysetMetaData +{ +public: + ThomsonAudio2( + unsigned int index); + + virtual void populateProtocol( + QObject *guiObject); +}; + #endif // THOMSON_H diff --git a/macros/pirmacro.cpp b/macros/pirmacro.cpp index b1a9475..10753c2 100644 --- a/macros/pirmacro.cpp +++ b/macros/pirmacro.cpp @@ -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(); diff --git a/macros/pirmacrocommanditem.cpp b/macros/pirmacrocommanditem.cpp index f78deb3..9b5cdb4 100644 --- a/macros/pirmacrocommanditem.cpp +++ b/macros/pirmacrocommanditem.cpp @@ -51,6 +51,7 @@ PIRKeyCommandItem::PIRKeyCommandItem( PIRKeyCommandItem::~PIRKeyCommandItem() { if (advanceTimer) delete advanceTimer; + advanceTimer = 0; } diff --git a/pierogi.pro b/pierogi.pro index 2552dc0..3888c19 100644 --- a/pierogi.pro +++ b/pierogi.pro @@ -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 \ diff --git a/pierogi.pro.user b/pierogi.pro.user index 9e84dcc..40a15b6 100644 --- a/pierogi.pro.user +++ b/pierogi.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget @@ -79,7 +79,7 @@ dpkg-buildpackage -sa -S -uc -us /Users/john/QtSDK/Maemo/4.6.2/bin/mad false - /Users/john/Develop/n900/pierogi-1.1.12 + /Users/john/Develop/n900/pierogi-1.1.13 Custom Process Step ProjectExplorer.ProcessStep @@ -209,6 +209,7 @@ /Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_1_0_armel.deb /Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_1_2_armel.deb /Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_6_7_armel.deb + /Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_1_1_13_armel.deb /Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_1_5_armel.deb /Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_6_0_armel.deb /Users/john/Develop/n900/pierogi-build-maemo-Qt_for_Fremantle_PR1_3_Devices__Qt_SDK__Release/pierogi_0_0_1_armel.deb @@ -257,6 +258,7 @@ 192.168.0.15 192.168.0.15 192.168.0.15 + 192.168.0.15 localhost 192.168.0.15 192.168.0.15 @@ -306,6 +308,7 @@ + 2012-01-19T22:18:07 @@ -335,6 +338,7 @@ 2012-01-17T00:03:13 2012-01-17T12:19:28 2012-02-19T10:29:22 + 2012-09-19T13:24:39 2012-01-23T09:47:37 2012-02-11T18:03:15 2012-01-14T13:11:32 diff --git a/pirkeysetmanager.cpp b/pirkeysetmanager.cpp index 719cd93..b3ba761 100644 --- a/pirkeysetmanager.cpp +++ b/pirkeysetmanager.cpp @@ -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" @@ -101,6 +103,7 @@ #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(); } diff --git a/pirkeysetmanager.h b/pirkeysetmanager.h index 4b6527c..d9272a4 100644 --- a/pirkeysetmanager.h +++ b/pirkeysetmanager.h @@ -65,7 +65,7 @@ public: QObject *guiObject, unsigned int keysetID); - void clearKeyset( + bool clearKeyset( unsigned int keysetID); void populateFavorites( diff --git a/pirkeysetmetadata.cpp b/pirkeysetmetadata.cpp index 903425e..e80822c 100644 --- a/pirkeysetmetadata.cpp +++ b/pirkeysetmetadata.cpp @@ -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; } diff --git a/pirkeysetmetadata.h b/pirkeysetmetadata.h index 0f9101a..80c4ed1 100644 --- a/pirkeysetmetadata.h +++ b/pirkeysetmetadata.h @@ -41,7 +41,7 @@ public: virtual void populateProtocol( QObject *guiObject) = 0; - void clearProtocol(); + bool clearProtocol(); void moveToThread( QThread *thread); diff --git a/pirmakenames.cpp b/pirmakenames.cpp index 4d3dcb6..5ecdd19 100644 --- a/pirmakenames.cpp +++ b/pirmakenames.cpp @@ -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"; diff --git a/pirmakenames.h b/pirmakenames.h index c8c5dc6..7071548 100644 --- a/pirmakenames.h +++ b/pirmakenames.h @@ -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, diff --git a/pirrx51hardware.cpp b/pirrx51hardware.cpp index 256b450..bfd9bc0 100644 --- a/pirrx51hardware.cpp +++ b/pirrx51hardware.cpp @@ -1,6 +1,6 @@ #include "pirrx51hardware.h" -//#define DEBUGGING +// #define DEBUGGING // Needed system includes: #include diff --git a/protocols/necprotocol.cpp b/protocols/necprotocol.cpp index 6efde39..ccaca00 100644 --- a/protocols/necprotocol.cpp +++ b/protocols/necprotocol.cpp @@ -9,6 +9,9 @@ extern bool commandInFlight; extern QMutex commandIFMutex; +// Debugging: +#include + // 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. diff --git a/qtc_packaging/debian_fremantle/changelog b/qtc_packaging/debian_fremantle/changelog index d05eb87..8b50812 100644 --- a/qtc_packaging/debian_fremantle/changelog +++ b/qtc_packaging/debian_fremantle/changelog @@ -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 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. diff --git a/qtc_packaging/debian_fremantle/control b/qtc_packaging/debian_fremantle/control index bda3181..58dc10a 100644 --- a/qtc_packaging/debian_fremantle/control +++ b/qtc_packaging/debian_fremantle/control @@ -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: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAEChJREFUaIHtmFmsXudVhp/1TXv/+x/OOZ4TO66dZmBo0jZJoxBQW8ookAq0mIhJQhUXcAGIAhICRClDb4q4YBRDGSoBFS2ikQoUSkpNIEkbnJQ0cVL7xLUd2/GZfKZ/2MP3fYuLE6LUDQEFQi/oe7e/X7/2++71an1rvfAlfAn/vyH/2Q+Hbzp89M47rvm1aw/0XvPs5ea+M5/b+OiJB5/88FX/1Vee4kvjagEC6Dt/+ns++Ya7Xn2ndWX2zkvKLV070Xp72Vy6PG4vLa0/8pcffuytlxcvr3wxSL8Q7qpnBXjzW+64M/QC1hiTUq0xWbHWihjf3TBvwqtene46e377/Z9swztWz59/9ovA+3nYqw9uv/uWH/y27/iat3rv1AcnkARjCSHgQ2FdqNT5Hgf27bpxfsF+/yTms2vPXjkJGL4Ilvo8AXfcfes9P/kTx96/sHtEKKwYURCHMULWjsnmhMlkXSbbG5J1m317Rr073nDknutvPPy2wZ6FA9syOzFbm7X/lwI+z0Jf+dob7jlw3UGsA8ioJlJWZpMpXUzEVGPFUpYW6xSqgeQ80bu/5tpbX/u6L7/1mvvnv+nPPvu3dwFw++2eEye6V1rA8xU4esvRr7/nnm9+z959C7hgVEQEMWxvbtE0nYoYYhxL7DJZjRZlya691zCc2y0qqPcq1+6vDp1f3r7UhbnF2RNPzF5p8rDTdQTQX3rvj11609fedo31EEqPNZa6bnjm7Clyakk5UlW7mN+9gKYZw+EuCBUiUA1203Yt0+01zjz1VJptPWtX1mZ84v6zf/nYE59779LppU++UgLcfwi44caD1zinIKJGDKpIU8/omimYoM4NWdg1J8ElEuhg6MkCvhiSESRNsXkmB665zmyWXncfcLJnz/Dtd9127dtOP33hn/75gUvfe+H0hYuvhIB86NChXbv3zZFF1bsgoLRtw3h7HaMd1hZiTY33Geug7BUSvEUNYKCdXcGZlqpX4Qplbu6oNG3UohDZtXu/XH/TdW8ajj7z4MO7ez/36YdOv/9/WwA33Hr4R3zwrQveOwf1dJvJZJvpeBvjoOh59u4/SGlm9IfzlFUBBkQcMW1Sb62QUkI1I5pw0lF1M7FuSt4TNO/bLUeOvOXab/9O/nh5efNP/uLP/+ETT55a/4Wzj589/j8VYHffvHv41Xfd9jOve/31ryoLb0R2rLO5tUE9ndDrlQyGQ8oS5kYjXGERieQYqSeb1OMVJqufQ0wPX1b0ewOMQSwR5y2+LPHOibGlQVqqasjBa689evjQwg+Ywvhzi5c//hyXl3WPuD3Vnptvvvnwm6wT1dRKypGuS7TNlJynDIZHCMHiQ0CskrqWGDtCWWIlo9aRZhsYU2KrEqO1kCdIEXBZwBbSpRbvS6xLErNRDh9kMBqxf9/gZ1dXZ/c/8fBn/w7IL6cC7pZbD//UzTcfwAqSsgCe6eQyuatxRglFxdxcn6IUvDOogoSC6dYq9fYa0/E5+nuvpywDqut4rVBbEqcrpDglY7DVQeqtc7hynrIsxZrIcDhiNP8V+q6f3//Rum44e/4yT51aO3VlffyRSxfXPnFhaXr8yuLi+Cph9rkqPX/mBtXwDS4MELGoJkUzQkJzLdZYykLRXKtmjzWVqCqqSSfrl6g3zyGFR5p1Uu6Is7GYakERI9urK9pfGGFMQCRjjZHcTDWpx2AwJspoWMnmaq29ysuNN15H09qbjhw58M47bnv1Oy+cX35o5XX7F1evbN136dzGw89IscjiYvMFFej1+vPWW1QziGINYq3HSMA6C0SscWIl03Y1sa2xoS9KDd4SwgDHDIlQhHlyO8UP9mFtKSJCzlHjeF1sb4E4HZPjtthehbM9jIVerxREQLJed2iPrCxfYTxpec1rjtw1HL7+rq7b/r7HP/PYhe3NrSc3Xvfap598fO23zjx14fHnBRR9c8aJ3u6LAksGyVr1K2ZTLzk2zLYv4WW3FsVeNGdJsWO6cVrjbBOLx6Qav+dGMAO0m4iJS2SF/p79KuKxdORmXZmMpTCBLlsVrXCi0uUJvTIznWyrNZ69+4Ys7JojpqBnz5xm45mTjEa7uPPuNx/U3B0M3n+DSP1DbTtjPN7kt379Y+9wVTBzYgPOCkYsYpyEUGCNo4s1WQ1qgqAdmhWNDcaI5BQRalKbIRnEeYwvUR3iwhwxduJDD2OtUlUy21iDXGMkSyg8mUTG4L1Q9voym05w3gAWY5CFXbvwwaDJELspwQecB6FSjJc5W3LnVx/6Tbc9bpK3ZqeHu4A1QgiOohzQNTO6aMg5YyTRzTaxCElB2zXoprTJMSufxQ4ivWqOToV28zLEGSxchw/zpA4wDqHEWQdGMOLxxiBEiuBJeYgSERXEGIrSk2KflHbe712BCw6DINmharTfGxb26Jcd3n/LrUff2BsM1BrBGCPWC84HVDOby4tYEjk1BN9nvD1mtr6E1JcxKM6MKEd7MdqQuzHd+kWsNOKDIbYJX1ZkrOh0E3JL2aski0NzRlONrw6h4lGN5JQQa4mxw7o+IhawDIYVvVGF9yVYxVqDYHnwoSd/zSw9szpeX10mx05SPZXY7gyRRa+iGgwRZ6lnV2imNVkV6wqKahcqGWwPHLRtS1fPaLeexYdK0myb6doSqKXeWpVc17hqH+Vor0g5h+QMucMYg3OKDxbnS5SEdeBDADLCToWc9zjrcSFgTRBjnYjJbF0ZXzQbk+ljy0uXaJuGLjbadTW5m2KkozcYUJRzNLOOWT1jur1CTmNcYUhqURmABHKMWGswRmgmK9pNO7pasdZDzJq7Bgl9CLsVP8C5HmJLxBeIEYwkrAEQBIuIJWsGFJFE2SvxwWMthBDUWof3ha6sbF+wo33zG6Ohe8sNNxzYb51I1oQzJUY6sTbjXA/nCt3aXAXjRHNCxehg/ghuVOGKCqsN4jLV/F4xtsD6nlQLB1SowXvUF0iuxViDQVA8zjmRmOjqTdpp0q5rmEzHIhLI2et00hHbGYNRn/n5CucDxlkRUUmJTtW6D/zBR99hTp04tbqxvvUvKXU55w5rrCRtJKZE1oQNJdXcHlnYf0S2t1apmylt24rxXpwfSujNSWxbMVpKbBNhMMJXFUUlEga7xNgSLyKiCdGEihWxVrouEdOOx1VqMdZI10FKiawiOUUJwchofig2BDFGRXJGsyrglpeXWFpamjiAja3miqasMbY4Z4BAzmCzEEIgGejRZ8v3mc4mqPSYjDep+gPEBEyoEOMwrkDjBGOVLGBcH0ODsSWaZiAexJC6KV09QaQgiSfHCbNZjTEOTYY21kDHaH6eajDCmA5RSAa0U0SsLJ4+dx6eG6efODv+vdiN3103lRpj6BU7cVHKineBqtqNVgv43hz1tGZ74zJrm+tMJhP6VWS0+xCikdw1JALGeUQ8YbAfm1tSOyYTyDgMlqyO7Cu6qKytTalniRgFpGI8UzS3XH/jTRRlj5RaMI7YKQZD1pn8y/0nxn/4Ox/5OkDMsWPH7LmHT14eb20S21piF1EiaIvmDiWDZqwUWO8pqxH90QEwPeoOZo0Qm4aMBRuwxYCMIQM5NeTYktqWFBvUWHJWkvSIuU8bC6azSN3srKxtkxCNjOb7FL0SY/PO3vFcCBhTy3Ra88D9j3545cLKIqDugx/8oAJsbW3n/lxhcnSqWBFRjOyM6G23iTGWspgnm4QyYDqep5nALAqz8QahN8SYRCjm0ay0TaLIkRQzSoGthnSdElOk7oTtrRkx1nT1NooiMkAl0R9WVP0SJJLZWZLAkbWj66KefOK0njx16V1Xj6c0KRy65SsGt2O9FMEgOKwxqEQ0TcmpRUXxrqIq57GhJFQLpAybWy1tSrTdFEMQTA9CxXTa0OVO6mbMxvqEre2JbG6OWb54kenkCk3dIa6PcwN6VZ9Xf9nNzC/spax6iAiaFEGp21ZzhKZN8vM/+9v7lxYvPr9bP58LXbw0/eVTp8ffdfsde+ZSFzE0RHEY/HMBaiZ1E1ocKomi1wOjIHuZTVaZ1pHgStQ0alsnLhhy1yHWqGJlY2OJrD2NMYkaCwTEBHqDOfqDAXPzB9C8BdYi6kj1FFUlK2jOiHj5t0c/Pb46j30+F1p5dmXTD/dW17+qelNVBZw1iChIQnAY4zFkcmbngnEZZwXnHAqkriFGS91MpGkauuiom8ysjlI3ibqJxJgl54wNA4regN6wz559BxmO9hBCSco1AKqZHBNZMzGhbYecO/MM7/+je3/48jNrj75QwBfE62/42q9646/88luOi7ZalIWU5Yi2XcMYSygGGGOxxu+0RmcRIzvku5a6qZluTTV2WWI3I2eLYlXEivUB55xa72Q4t4BxnuD6WNfDWEtOLTEZUqxJqaOLSVOGpo78ye/+6cp9Hz/5dUtnlh6/mu/V6bQ8/I8P/tPSs7dx4MC8NI3T3qCUwC5SnGKtJSdDlojkFkkeVHbGAG8JxuPcPKnrSHlI17VoBmMNRTHHTthn8KFCjMX5gpRaYlRyiojvAx6hIMZNFCObVzb52PFT37jyIuQ/z0IvRBiMbr7+6O5bjAv0ilKM8ZolY10pzlkQ0a6dkVJLzh2KoAJijRzd/000aUVUohahRyhLvA8UvaEYK1ix+GIBsVaMFKgAGFUgJZWui+SkTKednD97lg/9+b1//8jxJ3/1xXi+qIVeiB/9ybf+1du/++5vF2vUGS9F6WlmY3LeIW/FIs6BxOes4Ekpqg9DAYMxjqRGxThxboQxPU2pEWsCObfkHBECTbNFTBlNfZ1NNmVrY5Vffe/v/83qOb57cXFx66U4mhc7PHbsmAX49f7r335leRmiSJdcrusxWROqDqQk5kzXNmisyTGSYmKyMaFtZ2CElDKIRwRy7ohxihWDUCL06bpE09SIVMSIrq+dlaef+hQf+fC9PHTf4rc+R/4lP/KLWujkyZMKCMePa39+7vpd8/611XAksR3Tda0iRkI5T8odOWeUnU6lCr7ogRghJ3LOkBXNUbrYkNsZsaulaxti2zKrt5hOxsxmtXaR/MB9f20+fvzEB//tVPODVy6uXngp4v+Bl1T3Qrz1HW9747FvOXB8194FjHOIZHWuJ854yGMwCRSyqFrnRcQgGBQ0pyhJDTkmUofO2khKEclRzp+7yGceu3DmqafH73vgbz/9nhfw+m+ldC9agRfDZx998hyjw2UzWbvJS+yX/VE0OYiqilgla0ZzVlDJKZNzIkUFFbG2z2R7haaZaoxTbWczGY+35MK5JT5072d/+OwzxY+d+PinPvbf5fKyBAA89ciT9w1vuPPe9eXla/b0u1uKXk8wZa7KAeLnadqZpNhqzkLbNYCVtmu0LPYy3lpCsTKrG3n0xBn+9ZGVj33ykbVffOijj7xv+fz5+uWQhy+8B/5L3HHgVU+/+91/fOx9wI+/5103tPncmwfpqd9YWKjKqizVhVIwGXJmOmlZWd5kbePBlaXN8Idd4/56S8OZBz7w95dgp1k8xKdeLvcv4Uv438C/A7Q6fneUaSRcAAAAAElFTkSuQmCC -- 1.7.9.5