diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | e2de64d6f1beb9e492daf5b886e19933c1fa41dd (patch) | |
tree | 9047cf9e6b5c43878d5bf82660adae77ceee097a /noatun/modules/infrared | |
download | tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.tar.gz tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'noatun/modules/infrared')
-rw-r--r-- | noatun/modules/infrared/Makefile.am | 16 | ||||
-rw-r--r-- | noatun/modules/infrared/README | 3 | ||||
-rw-r--r-- | noatun/modules/infrared/infrared.cpp | 120 | ||||
-rw-r--r-- | noatun/modules/infrared/infrared.h | 30 | ||||
-rw-r--r-- | noatun/modules/infrared/infrared.plugin | 120 | ||||
-rw-r--r-- | noatun/modules/infrared/irprefs.cpp | 311 | ||||
-rw-r--r-- | noatun/modules/infrared/irprefs.h | 62 | ||||
-rw-r--r-- | noatun/modules/infrared/lirc.cpp | 173 | ||||
-rw-r--r-- | noatun/modules/infrared/lirc.h | 75 |
9 files changed, 910 insertions, 0 deletions
diff --git a/noatun/modules/infrared/Makefile.am b/noatun/modules/infrared/Makefile.am new file mode 100644 index 00000000..bf8a7212 --- /dev/null +++ b/noatun/modules/infrared/Makefile.am @@ -0,0 +1,16 @@ + +INCLUDES= -I$(top_srcdir)/noatun/library $(all_includes) +kde_module_LTLIBRARIES = noatun_infrared.la + +noatun_infrared_la_SOURCES = infrared.cpp lirc.cpp irprefs.cpp +noinst_HEADERS = infrared.h lirc.h irprefs.h + +noatun_infrared_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +noatun_infrared_la_LIBADD = $(LIB_KFILE) $(top_builddir)/noatun/library/libnoatun.la \ + -lqtmcop -lkmedia2_idl -lsoundserver_idl + +noatun_infrared_la_METASOURCES = AUTO + + +noatun_modules_infrared_DATA = infrared.plugin +noatun_modules_infrareddir = $(kde_datadir)/noatun diff --git a/noatun/modules/infrared/README b/noatun/modules/infrared/README new file mode 100644 index 00000000..b3fda334 --- /dev/null +++ b/noatun/modules/infrared/README @@ -0,0 +1,3 @@ +This plugin enables Noatun to be controlled with an IR remote control. +You'll need lirc (http://fsinfo.cs.uni-sb.de/~columbus/lirc/) and +an IR receiver supported by lirc. diff --git a/noatun/modules/infrared/infrared.cpp b/noatun/modules/infrared/infrared.cpp new file mode 100644 index 00000000..60ea145c --- /dev/null +++ b/noatun/modules/infrared/infrared.cpp @@ -0,0 +1,120 @@ + +#include <stdio.h> + +#include <unistd.h> +#include <noatun/player.h> +#include <noatun/app.h> + +#include <klocale.h> +#include <qtimer.h> + +#include "infrared.h" +#include "lirc.h" +#include "irprefs.h" + +extern "C" +{ + KDE_EXPORT Plugin *create_plugin() + { + return new InfraRed(); + } +} + + +InfraRed::InfraRed() + : QObject(), + Plugin() +{ + NOATUNPLUGINC(InfraRed); + m_lirc = new Lirc(this); + connect(m_lirc, + SIGNAL(commandReceived(const QString &, const QString &, int)), + SLOT(slotCommand(const QString &, const QString &, int))); + + IRPrefs::s_lirc = m_lirc; + volume=0; + QTimer::singleShot(0, this, SLOT(start())); +} + +InfraRed::~InfraRed() +{ +} + +void InfraRed::start() +{ + new IRPrefs(this); +} + +void InfraRed::slotCommand(const QString &remote, const QString &button, int repeat) +{ + switch (IRPrefs::actionFor(remote, button, repeat)) + { + case IRPrefs::None: + break; + + case IRPrefs::Play: + napp->player()->play(); + break; + + case IRPrefs::Stop: + napp->player()->stop(); + break; + + case IRPrefs::Pause: + napp->player()->playpause(); + break; + + case IRPrefs::Mute: + if (napp->player()->volume()) + { + volume=napp->player()->volume(); + napp->player()->setVolume(0); + } + else + { + napp->player()->setVolume(volume); + } + break; + + case IRPrefs::Previous: + napp->player()->back(); + break; + + case IRPrefs::Next: + napp->player()->forward(); + break; + + case IRPrefs::VolumeDown: + napp->player()->setVolume(napp->player()->volume() - 4); + break; + + case IRPrefs::VolumeUp: + napp->player()->setVolume(napp->player()->volume() + 4); + break; + + case IRPrefs::SeekBackward: // - 3 seconds + napp->player()->skipTo( QMAX(0, napp->player()->getTime() - 3000) ); + break; + + case IRPrefs::SeekForward: // + 3 seconds + napp->player()->skipTo( QMIN(napp->player()->getLength(), + napp->player()->getTime() + 3000) ); + break; + case IRPrefs::ShowPlaylist: + napp->player()->toggleListView(); + break; + case IRPrefs::NextSection: + // This and the next case theoretically shouldn't bypass player() + // but I'm making this change as inobtrusive as possible. That + // means restricting the change to infrared and not messing around + // in libnoatun -- Neil + napp->playlist()->nextSection(); + break; + case IRPrefs::PreviousSection: + napp->playlist()->previousSection(); + break; + } +} + +#include "infrared.moc" + diff --git a/noatun/modules/infrared/infrared.h b/noatun/modules/infrared/infrared.h new file mode 100644 index 00000000..37e97735 --- /dev/null +++ b/noatun/modules/infrared/infrared.h @@ -0,0 +1,30 @@ + +#ifndef _INFRARED_H_ +#define _INFRARED_H_ + +#include <noatun/player.h> +#include <noatun/plugin.h> + +class NoatunPreferences; +class Lirc; + +class InfraRed : public QObject, public Plugin +{ +Q_OBJECT +NOATUNPLUGIND +public: + InfraRed(); + ~InfraRed(); + +private slots: + void slotCommand(const QString &, const QString &, int); + + void start(); + +private: + Lirc *m_lirc; + int volume; +}; + +#endif + diff --git a/noatun/modules/infrared/infrared.plugin b/noatun/modules/infrared/infrared.plugin new file mode 100644 index 00000000..dab20149 --- /dev/null +++ b/noatun/modules/infrared/infrared.plugin @@ -0,0 +1,120 @@ +Filename=noatun_infrared.la +Author=Malte Starostik +Email=malte@kde.org +Type=other +License=Artistic +Name=Infrared Control +Name[af]=Infrared Kontrole +Name[ar]=تحكم بالأشعة تحت الحمراء +Name[az]=İnfra Qırmızı İdarə +Name[bn]=ইনফ্রা-রেড নিয়ন্ত্রণ +Name[bs]=Infrared kontrola +Name[ca]=Control per infraroigs +Name[cs]=Dálkové ovládání +Name[cy]=Rheolaeth Isgoch +Name[da]=Infrarød kontrol +Name[de]=Infrarot-Fernbedienung +Name[el]=Έλεγχος μέσω υπέρυθρων +Name[eo]=INfraruĝstirilo +Name[es]=Control por infrarrojos +Name[et]=Infrapunaliidese kaudu juhtimine +Name[eu]=Kontrol infragorria +Name[fa]= کنترل مادون قرمز +Name[fi]=Infrapunahallinta +Name[fr]=Contrôleur infrarouge +Name[ga]=Rialú Infridhearg +Name[gl]=Control por Infravermellos +Name[he]=שליטה בעזרת אינפרא־אדום +Name[hi]=इन्फ्रारेड नियंत्रण +Name[hr]=Infra-crvena kontrola +Name[hu]=Távirányító +Name[id]=Kontrol infra merah +Name[is]=Innrauð stýring +Name[it]=Controllo a infrarossi +Name[ja]=赤外線コントロール +Name[kk]=ИҚ тұтқасымен басқару +Name[km]=ឧបករណ៍ Infrared +Name[ko]=적외선 제어 +Name[lt]=Infraraudonųjų spindulių valdymas +Name[lv]=Infrasarkanā Vadība +Name[mk]=Инфрацрвена контрола +Name[mt]=Kontroll Infrared +Name[nb]=Infrarød kontroll +Name[nds]=Infraroot-Feernbedenen +Name[ne]=इन्फ्रारेड नियन्त्रण +Name[nl]=Infraroodbediening +Name[nn]=Infraraud kontroll +Name[pa]=ਇੰਫਰਾਰੈੱਡ ਕੰਟਰੋਲ +Name[pl]=Sterowanie przez podczerwień +Name[pt]=Controlo de Infra-Vermelhos +Name[pt_BR]=Controle de Infravermelho +Name[ro]=Control în infraroşu +Name[ru]=ИК пульт +Name[se]=Infrarukses stivrran +Name[sk]=Diaľkové ovládanie +Name[sl]=Infrardeči nadzor +Name[sr]=Инфрацрвена контрола +Name[sr@Latn]=Infracrvena kontrola +Name[sv]=Infraröd fjärrkontroll +Name[ta]=செங்கீழ்க்கதிர்க் கட்டுப்பாடு +Name[tg]=Идоракунии Инфрасурх +Name[th]=ตัวควบคุมแบบอินฟราเรด +Name[tr]=Kızılötesi Kontrol +Name[uk]=Керуванням інфрачервоним зв'язком +Name[ven]=Vhulanguli ha Infrared +Name[xh]=Ulawulo olwakhelwe ngezantsi +Name[zh_CN]=红外线控制 +Name[zh_HK]=紅外線控制 +Name[zh_TW]=紅外線控制 +Name[zu]=Ulawulo Olunokubomvu +Comment=Control Noatun with your IR remote +Comment[bg]=Управление на Noatun с помощта на инфрачервено, дистанционно управление +Comment[bn]=আপনার ইনফ্রা-রেড রিমোট ব্যবহার করে নোটান নিয়ন্ত্রণ করুন +Comment[bs]=Kontrolišite Noatun vašim infracrvenim daljinskim upravljačem +Comment[ca]=Controla Noatun amb el comandament a distància +Comment[cs]=Ovládejte Noatun svým dálkovým ovladačem +Comment[cy]=Rheoli Noatun efo'ch Rheolydd Isgoch +Comment[da]=Kontrollér Noatun med din fjernbetjening +Comment[de]=Kontrollieren Sie Noatun mit Ihrer Infrarot-Fernbedienung +Comment[el]=Έλεγχος του Noatun με το IR τηλεκοντρόλ σας +Comment[eo]=Stiru Noatun per via infraruĝstirilo +Comment[es]=Controle Noatun con su mando a distancia +Comment[et]=Noatun juhtimine IR puldi abil +Comment[eu]=Kontrolatu Noatun urruneko infragorriekin +Comment[fa]=کنترل Noatun با IR دور شما +Comment[fi]=Hallitse Noatunia infrapunakauko-ohjaimella +Comment[fr]=Contrôlez Noatun avec votre télécommande infrarouge +Comment[ga]=Rialaigh Noatun le do cianrialtán infridhearg +Comment[gl]=Controlar Noatun co seu IR remoto +Comment[he]=שליטה ב-Noatun באמצעות שלט אינפרא־אדום +Comment[hu]=A Noatun kezelése távirányítóval +Comment[is]=Stjórnaðu Nóatún með fjarstýringunni þinni +Comment[it]=Controlla Noatun con il tuo telecomando +Comment[ja]=赤外線リモコンで Noatun をコントロール +Comment[kk]=Noatun-ды ИҚ тұтқасымен басқару +Comment[km]=បញ្ជា Noatun ដោយប្រើ IR របស់អ្នកពីចម្ងាយ +Comment[ko]=적외선 리모콘으로 Noatun 조정하기 +Comment[lt]=Valdykite Noatun pasitelkdami nuotolinį pultą +Comment[mk]=Го контролира Noatun со вашиот инфрацрвен далечински управувач +Comment[nb]=Styr Noatun med en infrerød fjernkontroll +Comment[nds]=Noatun mit Dien Infraroot-Feernbedenen stüern +Comment[ne]=तपाईँको IR टाढाकोसँग नियन्त्रण नोवटुन +Comment[nl]=Bedien Noatun met uw infrarood afstandbediening +Comment[nn]=Styr Noatun med ein infraraud fjernkontroll +Comment[pl]=Sterowanie Noatun za pomocą pilota podczerwieni +Comment[pt]=Controle o Noatun com um comando à distância +Comment[pt_BR]=Controlar o Noatun com seu controle-remoto infravermelho +Comment[ro]=Controlează Noatun cu telecomanda în infraroşu +Comment[ru]=Управление Noatun с помощью инфракрасного пульта +Comment[sk]=Ovládajte Noatun vaším diaľkovým ovládačom +Comment[sl]=Nadzorujte Noatun z vašim infrardečim daljinskim upravljalcem +Comment[sr]=Контролишите Noatun вашим ИЦ даљинским управљачем +Comment[sr@Latn]=Kontrolišite Noatun vašim IC daljinskim upravljačem +Comment[sv]=Styr Noatun med en infraröd fjärrkontroll +Comment[ta]=உங்கள் IR கருவியால் Noatun இனைக் கட்டுப்படுத்தவும் +Comment[th]=ควบคุม Noatun ด้วยตัวรีโมทอินฟราเรดของคุณ +Comment[tr]=Kızılötesi Uzaktan Kumanda ile Noatun'u Kontrol Edin +Comment[uk]=Керує Noatun з віддаленого інфрачервоного пульта керування +Comment[zh_CN]=使用红外线遥控 Noatun +Comment[zh_HK]=使用紅外線遙控控制 Noatun +Comment[zh_TW]=使用 Noatun 透過紅外線遙控 diff --git a/noatun/modules/infrared/irprefs.cpp b/noatun/modules/infrared/irprefs.cpp new file mode 100644 index 00000000..409fa94e --- /dev/null +++ b/noatun/modules/infrared/irprefs.cpp @@ -0,0 +1,311 @@ + +#include <qlayout.h> +#include <qlabel.h> +#include <qcheckbox.h> +#include <noatun/app.h> + +#include <kdialog.h> +#include <klocale.h> +#include <kconfig.h> +#include <klistview.h> +#include <kcombobox.h> +#include <knuminput.h> + +#include "irprefs.h" +#include "lirc.h" + +class CommandItem : public QListViewItem +{ +public: + CommandItem(QListViewItem *remote, const QString &name, + IRPrefs::Action action, int interval) + : QListViewItem(remote, name, IRPrefs::actionName(action), + interval ? QString().setNum(interval) : QString::null), + m_name(remote->text(0) + "::" + name), + m_action(action), + m_interval(interval) + { + } + + const QString &name() const { return m_name; } + IRPrefs::Action action() const { return m_action; } + int interval() const { return m_interval; } + void setAction(IRPrefs::Action action) + { + setText(1, IRPrefs::actionName(action)); + m_action = action; + } + void setInterval(int interval) + { + setText(2, interval ? QString().setNum(interval) : QString::null); + m_interval = interval; + } + +private: + QString m_name; + IRPrefs::Action m_action; + int m_interval; +}; + +Lirc *IRPrefs::s_lirc = 0; +bool IRPrefs::s_configRead = false; +QMap<QString, IRPrefs::Command> IRPrefs::s_commands; + +IRPrefs::IRPrefs(QObject *parent) + : CModule(i18n("Infrared Control"), i18n("Configure Infrared Commands"), "remote", parent) +{ + QGridLayout *layout = new QGridLayout(this, 3, 5, KDialog::marginHint(), KDialog::spacingHint()); + layout->setColStretch(1, 1); + + QLabel *label = new QLabel(i18n("Remote control &commands:"), this); + layout->addMultiCellWidget(label, 0, 0, 0, 4); + + label->setBuddy(m_commands = new KListView(this)); + layout->addMultiCellWidget(m_commands, 1, 1, 0, 4); + + label = new QLabel(i18n("&Action:"), this); + layout->addWidget(label, 2, 0); + + label->setBuddy(m_action = new KComboBox(this)); + m_action->setEnabled(false); + layout->addWidget(m_action, 2, 1); + + m_repeat = new QCheckBox(i18n("&Repeat"), this); + m_repeat->setEnabled(false); + layout->addWidget(m_repeat, 2, 2); + + label = new QLabel(i18n("&Interval:"), this); + layout->addWidget(label, 2, 3); + + label->setBuddy(m_interval = new KIntSpinBox(this)); + m_interval->setMinValue(1); + m_interval->setMaxValue(0xff); + m_interval->setValue(10); + m_interval->setEnabled(false); + layout->addWidget(m_interval, 2, 4); + + connect(s_lirc, SIGNAL(remotesRead()), SLOT(reopen())); + connect(m_commands, + SIGNAL(selectionChanged(QListViewItem *)), + SLOT(slotCommandSelected(QListViewItem *))); + connect(m_action, + SIGNAL(activated(int)), + SLOT(slotActionActivated(int))); + connect(m_repeat, + SIGNAL(toggled(bool)), + SLOT(slotRepeatToggled(bool))); + connect(m_interval, + SIGNAL(valueChanged(int)), + SLOT(slotIntervalChanged(int))); + + reopen(); +} + +void IRPrefs::save() +{ + KConfig *c = kapp->config(); + KConfigGroupSaver groupSaver(c, "Infrared"); + c->writeEntry("CommandCount", s_commands.count()); + int i = 1; + for (QMap<QString, Command>::ConstIterator it = s_commands.begin(); it != s_commands.end(); ++it) + { + c->writePathEntry(QString("Command_%1").arg(i), it.key()); + c->writeEntry(QString("Action_%1").arg(i), (int)((*it).action)); + c->writeEntry(QString("Interval_%1").arg(i), (*it).interval); + ++i; + } +} + +void IRPrefs::reopen() +{ + readConfig(); + + QStringList remotes = s_lirc->remotes(); + m_commands->clear(); + while (m_commands->columns()) m_commands->removeColumn(0); + if (!remotes.count()) + { + m_commands->addColumn(i18n("Sorry")); + m_commands->setSorting(-1); + if (s_lirc->isConnected()) + { + new QListViewItem(m_commands, i18n("You do not have any remote control configured.")); + new QListViewItem(m_commands, i18n("Please make sure lirc is setup correctly.")); + } + else + { + new QListViewItem(m_commands, i18n("Connection could not be established.")); + new QListViewItem(m_commands, i18n("Please make sure lirc is setup correctly and lircd is running.")); + } + m_commands->setEnabled(false); + return; + } + m_commands->setEnabled(true); + m_commands->addColumn(i18n("Button")); + m_commands->addColumn(i18n("Action")); + m_commands->addColumn(i18n("Interval")); + m_commands->setSorting(0); + for (QStringList::ConstIterator it = remotes.begin(); it != remotes.end(); ++it) + { + QListViewItem *remote = new QListViewItem(m_commands, *it); + const QStringList &buttons = s_lirc->buttons(*it); + for (QStringList::ConstIterator btn = buttons.begin(); btn != buttons.end(); ++btn) + { + QString key = *it + "::" + *btn; + if (s_commands.contains(key)) + new CommandItem(remote, *btn, s_commands[key].action, s_commands[key].interval); + else + new CommandItem(remote, *btn, None, 0); + } + remote->setOpen(true); + } + + m_action->clear(); + for (int i = 0; ; ++i) + { + QString action = actionName((Action)i); + if (action.isNull()) + break; + if (action.isEmpty()) + m_action->insertItem(i18n("None")); + else + m_action->insertItem(action); + } + + +} + +void IRPrefs::slotCommandSelected(QListViewItem *item) +{ + CommandItem *cmd = dynamic_cast<CommandItem *>(item); + if (cmd) + { + m_action->setCurrentItem((int)(cmd->action())); + m_repeat->setChecked(cmd->interval()); + if (cmd->interval()) + m_interval->setValue(cmd->interval()); + else + { + m_interval->setValue(10); + cmd->setInterval(0); // HACKHACKHACK + } + m_action->setEnabled(true); + m_repeat->setEnabled(cmd->action() != None); + m_interval->setEnabled(cmd->interval()); + } + else + { + m_action->setEnabled(false); + m_repeat->setEnabled(false); + m_interval->setEnabled(false); + } +} + +void IRPrefs::slotActionActivated(int action) +{ + CommandItem *cmd = dynamic_cast<CommandItem *>(m_commands->currentItem()); + if (!cmd) + return; // Shouldn't happen + cmd->setAction((Action)action); + if (cmd->action() == None) + { + cmd->setInterval(0); + m_repeat->setChecked(false); + m_repeat->setEnabled(false); + m_interval->setEnabled(false); + } + else + { + m_repeat->setEnabled(true); + m_interval->setEnabled(cmd->interval()); + } + s_commands[cmd->name()].action = cmd->action(); + s_commands[cmd->name()].interval = 0; +} + +void IRPrefs::slotRepeatToggled(bool value) +{ + CommandItem *cmd = dynamic_cast<CommandItem *>(m_commands->currentItem()); + if (!cmd) + return; // Shouldn't happen + cmd->setInterval(value ? 10 : 0); + s_commands[cmd->name()].interval = cmd->interval(); + m_interval->setEnabled(value); +} + +void IRPrefs::slotIntervalChanged(int value) +{ + CommandItem *cmd = dynamic_cast<CommandItem *>(m_commands->currentItem()); + if (!cmd) + return; // Shouldn't happen + cmd->setInterval(value); + s_commands[cmd->name()].interval = cmd->interval(); +} + +const QString IRPrefs::actionName(Action action) +{ + switch (action) + { + case None: + return QString(""); + case Play: + return i18n("Play"); + case Stop: + return i18n("Stop"); + case Previous: + return i18n("Back"); + case Next: + return i18n("Next"); + case VolumeDown: + return i18n("Volume Down"); + case VolumeUp: + return i18n("Volume Up"); + case Mute: + return i18n("Mute"); + case Pause: + return i18n("Pause"); + case SeekBackward: + return i18n("Seek Backward"); + case SeekForward: + return i18n("Seek Forward"); + case ShowPlaylist: + return i18n("Show Playlist"); + case NextSection: + return i18n("Next Section"); + case PreviousSection: + return i18n("Previous Section"); + } + return QString::null; +} + +void IRPrefs::readConfig() +{ + if (s_configRead) + return; + KConfig *c = kapp->config(); + KConfigGroupSaver groupSaver(c, "Infrared"); + int count = c->readNumEntry("CommandCount"); + for (int i = 1; i <= count; ++i) + { + Command cmd; + cmd.action = (Action)(c->readNumEntry(QString("Action_%1").arg(i))); + cmd.interval = c->readNumEntry(QString("Interval_%1").arg(i)); + s_commands.insert(c->readPathEntry(QString("Command_%1").arg(i)), cmd); + } + s_configRead = true; +} + +IRPrefs::Action IRPrefs::actionFor(const QString &remote, const QString &button, int repeat) +{ + readConfig(); + Command cmd = s_commands[remote + "::" + button]; + if ((cmd.interval == 0 && repeat == 0) + || (cmd.interval != 0 && repeat % cmd.interval == 0)) + return cmd.action; + else + return None; +} + +#include "irprefs.moc" + + diff --git a/noatun/modules/infrared/irprefs.h b/noatun/modules/infrared/irprefs.h new file mode 100644 index 00000000..7f813ac8 --- /dev/null +++ b/noatun/modules/infrared/irprefs.h @@ -0,0 +1,62 @@ + +#ifndef _IRPREFS_H_ +#define _IRPREFS_H_ + +#include <qmap.h> +#include <noatun/pref.h> + +class QCheckBox; +class QListViewItem; +class KListView; +class KComboBox; +class KIntSpinBox; +class Lirc; + +class IRPrefs : public CModule +{ +Q_OBJECT +public: + enum Action + { + None, Play, Stop, Pause, Mute, + Previous, Next, VolumeDown, VolumeUp, + SeekBackward, SeekForward, ShowPlaylist, + NextSection, PreviousSection + }; + + IRPrefs(QObject *parent); + + virtual void save(); + + static const QString actionName(Action); + static Action actionFor(const QString &, const QString &, int); + +public slots: + static Lirc *s_lirc; + +private slots: + virtual void reopen(); + void slotCommandSelected(QListViewItem *); + void slotActionActivated(int); + void slotRepeatToggled(bool); + void slotIntervalChanged(int); + +private: + static void readConfig(); + + KListView *m_commands; + KComboBox *m_action; + QCheckBox *m_repeat; + KIntSpinBox *m_interval; + + struct Command + { + Action action; + int interval; + }; + static bool s_configRead; + static QMap<QString, Command> s_commands; +}; + +#endif + diff --git a/noatun/modules/infrared/lirc.cpp b/noatun/modules/infrared/lirc.cpp new file mode 100644 index 00000000..857c07e2 --- /dev/null +++ b/noatun/modules/infrared/lirc.cpp @@ -0,0 +1,173 @@ + +#include <unistd.h> +#include <sys/un.h> +#include <sys/socket.h> +#include <errno.h> + +#include <qsocket.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kmessagebox.h> + +#include "lirc.h" + +Lirc::Lirc(QObject *parent) + : QObject(parent), + m_socket(0) +{ + int sock = ::socket(PF_UNIX, SOCK_STREAM, 0); + if (sock == -1) + { + KMessageBox::sorry(0, i18n("Could not create a socket to receive infrared signals. The error is:\n") + strerror(errno)); + return; + } + sockaddr_un addr; + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, "/dev/lircd"); + if (::connect(sock, (struct sockaddr *)(&addr), sizeof(addr)) == -1) + { + KMessageBox::sorry(0, i18n("Could not establish a connection to receive infrared signals. The error is:\n") + strerror(errno)); + ::close(sock); + return; + } + + m_socket = new QSocket; + m_socket->setSocket(sock); + connect(m_socket, SIGNAL(readyRead()), SLOT(slotRead())); + update(); +} + +Lirc::~Lirc() +{ + delete m_socket; +} + +const QStringList Lirc::remotes() const +{ + QStringList result; + for (Remotes::ConstIterator it = m_remotes.begin(); it != m_remotes.end(); ++it) + result.append(it.key()); + result.sort(); + return result; +} + +void Lirc::slotRead() +{ + while (m_socket->bytesAvailable()) + { + QString line = readLine(); + if (line == "BEGIN") + { + // BEGIN + // <command> + // [SUCCESS|ERROR] + // [DATA + // n + // n lines of data] + // END + line = readLine(); + if (line == "SIGHUP") + { + // Configuration changed + do line = readLine(); + while (!line.isEmpty() && line != "END"); + update(); + return; + } + else if (line == "LIST") + { + // remote control list + if (readLine() != "SUCCESS" || readLine() != "DATA") + { + do line = readLine(); + while (!line.isEmpty() && line != "END"); + return; + } + QStringList remotes; + int count = readLine().toInt(); + for (int i = 0; i < count; ++i) + remotes.append(readLine()); + do line = readLine(); + while (!line.isEmpty() && line != "END"); + if (line.isEmpty()) + return; // abort on corrupt data + for (QStringList::ConstIterator it = remotes.begin(); it != remotes.end(); ++it) + sendCommand("LIST " + *it); + return; + } + else if (line.left(4) == "LIST") + { + // button list + if (readLine() != "SUCCESS" || readLine() != "DATA") + { + do line = readLine(); + while (!line.isEmpty() && line != "END"); + return; + } + QString remote = line.mid(5); + QStringList buttons; + int count = readLine().toInt(); + for (int i = 0; i < count; ++i) + { + // <code> <name> + QString btn = readLine(); + buttons.append(btn.mid(17)); + } + m_remotes.insert(remote, buttons); + } + do line = readLine(); + while (!line.isEmpty() && line != "END"); + emit remotesRead(); + } + else + { + // <code> <repeat> <button name> <remote control name> + line.remove(0, 17); // strip code + int pos = line.find(' '); + if (pos < 0) + return; + bool ok; + int repeat = line.left(pos).toInt(&ok, 16); + if (!ok) + return; + line.remove(0, pos + 1); + + pos = line.find(' '); + if (pos < 0) + return; + QString btn = line.left(pos); + line.remove(0, pos + 1); + + emit commandReceived(line, btn, repeat); + } + } +} + +void Lirc::update() +{ + m_remotes.clear(); + sendCommand("LIST"); +} + +const QString Lirc::readLine() +{ + if (!m_socket->bytesAvailable()) + return QString::null; + + QString line = m_socket->readLine(); + if (line.isEmpty()) + return QString::null; + + line.remove(line.length() - 1, 1); + return line; +} + +void Lirc::sendCommand(const QString &command) +{ + QString cmd = command + "\n"; + m_socket->writeBlock(cmd.latin1(), cmd.length()); +} + +#include "lirc.moc" + diff --git a/noatun/modules/infrared/lirc.h b/noatun/modules/infrared/lirc.h new file mode 100644 index 00000000..e5380c5c --- /dev/null +++ b/noatun/modules/infrared/lirc.h @@ -0,0 +1,75 @@ + +#ifndef _LIRC_H_ +#define _LIRC_H_ + +#include <qobject.h> +#include <qstringlist.h> +#include <qmap.h> + +class QSocket; + +typedef QMap<QString, QStringList> Remotes; + +class Lirc : public QObject +{ +Q_OBJECT +public: + /** + * Constructor + */ + Lirc(QObject *parent); + /** + * Destructor + */ + virtual ~Lirc(); + + /** + * Returns true if the connection to lircd is operational + */ + bool isConnected() const { return m_socket; } + /** + * The names of the remote configured controls + */ + const QStringList remotes() const; + /** + * The names of the buttons for the specified + * remote control + */ + const QStringList buttons(const QString &remote) const + { + return m_remotes[remote]; + } + +signals: + /** + * Emitted when the list of controls / buttons was cmpletely read + */ + void remotesRead(); + /** + * Emitted when a IR command was received + * + * The arguments are the name of the remote control used, + * the name of the button pressed and the repeat counter. + * + * The signal is emitted repeatedly as long as the button + * on the remote control remains pressed. + * The repeat counter starts with 0 and increases + * every time this signal is emitted. + */ + void commandReceived(const QString &, const QString &, int); + +private slots: + void slotRead(); + +private: + void update(); + const QString readLine(); + void sendCommand(const QString &); + +private: + QSocket *m_socket; + Remotes m_remotes; +}; + +#endif + |