#include <unistd.h> #include <sys/un.h> #include <sys/socket.h> #include <errno.h> #include <tqsocket.h> #include <kdebug.h> #include <klocale.h> #include <kmessagebox.h> #include "lirc.h" Lirc::Lirc(TQObject *tqparent) : TQObject(tqparent), 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 TQSocket; m_socket->setSocket(sock); connect(m_socket, TQT_SIGNAL(readyRead()), TQT_SLOT(slotRead())); update(); } Lirc::~Lirc() { delete m_socket; } const TQStringList Lirc::remotes() const { TQStringList 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()) { TQString 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; } TQStringList 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 (TQStringList::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; } TQString remote = line.mid(5); TQStringList buttons; int count = readLine().toInt(); for (int i = 0; i < count; ++i) { // <code> <name> TQString 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.tqfind(' '); if (pos < 0) return; bool ok; int repeat = line.left(pos).toInt(&ok, 16); if (!ok) return; line.remove(0, pos + 1); pos = line.tqfind(' '); if (pos < 0) return; TQString btn = line.left(pos); line.remove(0, pos + 1); emit commandReceived(line, btn, repeat); } } } void Lirc::update() { m_remotes.clear(); sendCommand("LIST"); } const TQString Lirc::readLine() { if (!m_socket->bytesAvailable()) return TQString(); TQString line = m_socket->readLine(); if (line.isEmpty()) return TQString(); line.remove(line.length() - 1, 1); return line; } void Lirc::sendCommand(const TQString &command) { TQString cmd = command + "\n"; m_socket->writeBlock(cmd.latin1(), cmd.length()); } #include "lirc.moc"