kdelirc
klircclient.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <unistd.h>
00016 #include <fcntl.h>
00017 #include <cstring>
00018 #include <sys/un.h>
00019 #include <sys/socket.h>
00020 #include <errno.h>
00021
00022 #include <QWidget>
00023 #include <qdialog.h>
00024
00025 #include <q3socket.h>
00026 #include <qsocketnotifier.h>
00027 #include <QFile>
00028
00029 #include <kapplication.h>
00030 #include <ksystemtray.h>
00031 #include <kiconloader.h>
00032 #include <kpassivepopup.h>
00033 #include <kmessagebox.h>
00034 #include <kmenu.h>
00035 #include <kdebug.h>
00036 #include <klocale.h>
00037
00038 #include <dcopclient.h>
00039 #include <dcopref.h>
00040
00041 #include "klircclient.h"
00042
00043
00044 KLircClient::KLircClient(QWidget *parent) : QObject(parent), theSocket(0), listIsUpToDate(false)
00045 {
00046 connectToLirc();
00047 }
00048
00049 bool KLircClient::connectToLirc()
00050 {
00051 int sock = ::socket(PF_UNIX, SOCK_STREAM, 0);
00052 if(sock == -1) return false;
00053
00054 sockaddr_un addr;
00055 addr.sun_family = AF_UNIX;
00056 strcpy(addr.sun_path, "/dev/lircd");
00057 if(::connect(sock, (struct sockaddr *)(&addr), sizeof(addr)) == -1)
00058 { ::close(sock);
00059
00060 strcpy(addr.sun_path, "/tmp/.lircd");
00061 if(::connect(sock, (struct sockaddr *)(&addr), sizeof(addr)) == -1)
00062 { ::close(sock);
00063 return false;
00064 }
00065 }
00066
00067 theSocket = new Q3Socket;
00068 theSocket->setSocket(sock);
00069 connect(theSocket, SIGNAL(readyRead()), SLOT(slotRead()));
00070 connect(theSocket, SIGNAL(connectionClosed()), SLOT(slotClosed()));
00071 updateRemotes();
00072 return true;
00073 }
00074
00075 KLircClient::~KLircClient()
00076 {
00077
00078 delete theSocket;
00079 }
00080
00081 void KLircClient::slotClosed()
00082 {
00083 delete theSocket;
00084 theSocket = 0;
00085 emit connectionClosed();
00086 }
00087
00088 const QStringList KLircClient::remotes() const
00089 {
00090 QStringList remotes;
00091 for(QMap<QString, QStringList>::ConstIterator i = theRemotes.begin(); i != theRemotes.end(); ++i)
00092 remotes.append(i.key());
00093 remotes.sort();
00094 return remotes;
00095 }
00096
00097 const QStringList KLircClient::buttons(const QString &theRemote) const
00098 {
00099 return theRemotes[theRemote];
00100 }
00101
00102 void KLircClient::slotRead()
00103 {
00104 while (theSocket->bytesAvailable())
00105 {
00106 QString line = readLine();
00107 if (line == "BEGIN")
00108 {
00109
00110
00111
00112
00113
00114
00115
00116 line = readLine();
00117 if (line == "SIGHUP")
00118 {
00119
00120 do line = readLine();
00121 while (!line.isEmpty() && line != "END");
00122 updateRemotes();
00123 return;
00124 }
00125 else if (line == "LIST")
00126 {
00127
00128 if (readLine() != "SUCCESS" || readLine() != "DATA")
00129 {
00130 do line = readLine();
00131 while (!line.isEmpty() && line != "END");
00132 return;
00133 }
00134 QStringList remotes;
00135 int count = readLine().toInt();
00136 for (int i = 0; i < count; ++i)
00137 remotes.append(readLine());
00138 do line = readLine();
00139 while (!line.isEmpty() && line != "END");
00140 if (line.isEmpty())
00141 return;
00142 for (QStringList::ConstIterator it = remotes.begin(); it != remotes.end(); ++it)
00143 sendCommand("LIST " + *it);
00144 return;
00145 }
00146 else if (line.left(4) == "LIST")
00147 {
00148
00149 if (readLine() != "SUCCESS" || readLine() != "DATA")
00150 {
00151 do line = readLine();
00152 while (!line.isEmpty() && line != "END");
00153 return;
00154 }
00155 QString remote = line.mid(5);
00156 QStringList buttons;
00157 int count = readLine().toInt();
00158 for (int i = 0; i < count; ++i)
00159 {
00160
00161 QString btn = readLine().mid(17);
00162 if(btn.isNull()) break;
00163 if(btn.startsWith("'") && btn.endsWith("'"))
00164 btn = btn.mid(1, btn.length() - 2);
00165 buttons.append(btn);
00166 }
00167 theRemotes.insert(remote, buttons);
00168 }
00169 do line = readLine();
00170 while (!line.isEmpty() && line != "END");
00171 listIsUpToDate = true;
00172 emit remotesRead();
00173 }
00174 else
00175 {
00176
00177 line.remove(0, 17);
00178 int pos = line.indexOf(' ');
00179 if (pos < 0) return;
00180 bool ok;
00181 int repeat = line.left(pos).toInt(&ok, 16);
00182 if (!ok) return;
00183 line.remove(0, pos + 1);
00184
00185 pos = line.indexOf(' ');
00186 if (pos < 0) return;
00187 QString btn = line.left(pos);
00188 if(btn.startsWith("'") && btn.endsWith("'"))
00189 btn = btn.mid(1, btn.length() - 2);
00190 line.remove(0, pos + 1);
00191
00192 emit commandReceived(line, btn, repeat);
00193 }
00194 }
00195 }
00196
00197 void KLircClient::updateRemotes()
00198 {
00199 listIsUpToDate = false;
00200 theRemotes.clear();
00201 sendCommand("LIST");
00202 }
00203
00204 bool KLircClient::isConnected() const
00205 {
00206 if(!theSocket) return false;
00207 return theSocket->state() == Q3Socket::Connected;
00208 }
00209
00210 bool KLircClient::haveFullList() const
00211 {
00212 return listIsUpToDate;
00213 }
00214
00215 const QString KLircClient::readLine()
00216 {
00217 if (!theSocket->canReadLine())
00218 { bool timeout;
00219
00220
00221 theSocket->waitForMore(500, &timeout);
00222 if (timeout)
00223 {
00224 return QString();
00225 }
00226 }
00227 QString line = theSocket->readLine();
00228 line.truncate(line.length() - 1);
00229 return line;
00230 }
00231
00232 void KLircClient::sendCommand(const QString &command)
00233 {
00234 QByteArray cmd = QFile::encodeName( command + "\n" );;
00235 theSocket->write( cmd );
00236 }
00237
00238
00239 #include "klircclient.moc"