00001 #include "LCDClient.h"
00002 #include "LCDConnection.h"
00003 #include "LCDLock.h"
00004 #include "LCDException.h"
00005 #include <string>
00006 #include <sstream>
00007 #include <iostream>
00008
00009 using namespace std;
00010
00011 LCDClient::LCDClient(const string &server, int port) : LCDElement("", "")
00012 {
00013 ::pthread_mutex_init(&_sendMutex, 0);
00014 ::pthread_cond_init(&_gotAnswer, 0);
00015 _answer = "";
00016 _currentScreen = "";
00017
00018 _serverConnection.connect(server, port);
00019 _serverConnection << "hello";
00020 _serverConnection >> _connectionString;
00021
00022 string token;
00023 istringstream response(_connectionString);
00024
00025 while (response >> token)
00026 {
00027 if (token == "LCDproc")
00028 {
00029 response >> _serverVersion;
00030 }
00031 else if (token == "protocol")
00032 {
00033 response >> _protocolVersion;
00034 }
00035 else if (token == "wid")
00036 {
00037 response >> _width;
00038 }
00039 else if (token == "hgt")
00040 {
00041 response >> _height;
00042 }
00043 else if (token == "cellwid")
00044 {
00045 response >> _charWidth;
00046 }
00047 else if (token == "cellhgt")
00048 {
00049 response >> _charHeight;
00050 }
00051 }
00052
00053 ::pthread_create(&_mainThread, 0, mainRepliesLoop, (void *)this);
00054 }
00055
00056 LCDClient::~LCDClient()
00057 {
00058 if (::pthread_cancel(_mainThread) == 0)
00059 {
00060 ::pthread_join(_mainThread, 0);
00061 }
00062 ::pthread_mutex_destroy(&_sendMutex);
00063 }
00064
00065 void LCDClient::sendCommand(const std::string &cmd, const std::string ¶meters)
00066 {
00067 if (cmd.size() > 0)
00068 {
00069 LCDLock l(&_sendMutex);
00070
00071 string command = cmd + " " + parameters;
00072 bool end = false;
00073
00074 _serverConnection << command;
00075
00076 while (_answer == "")
00077 {
00078 ::pthread_cond_wait(&_gotAnswer, &_sendMutex);
00079 }
00080
00081 if (_answer.substr(0, 4) == "huh?")
00082 {
00083 throw LCDException(_answer.substr(5));
00084 }
00085 _answer = "";
00086 }
00087 }
00088
00089 void LCDClient::setClientOption(string optName, string value)
00090 {
00091 sendCommand("client_set", string("-") + optName + " " + value);
00092 }
00093
00094 void LCDClient::setName(string name)
00095 {
00096 setClientOption("name", name);
00097 }
00098
00099
00100
00101
00102
00103
00104 void LCDClient::setBackLight(string backlight)
00105 {
00106 sendCommand("backlight", backlight);
00107 }
00108
00109 void LCDClient::assignKey(KeyEvent key, LCDCallback *callback)
00110 {
00111 _callbacks[key] = callback;
00112 sendCommand("client_add_key", toString(key));
00113 }
00114
00115 void LCDClient::mainLoop()
00116 {
00117 ::pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
00118 string reply;
00119 while(true)
00120 {
00121 _serverConnection >> reply;
00122
00123 if ( (reply.substr(0, 4) == "huh?") || (reply == "success") )
00124 {
00125 LCDLock l(&_sendMutex);
00126 _answer = reply;
00127 ::pthread_cond_signal(&_gotAnswer);
00128 }
00129 else
00130 {
00131 if (reply.substr(0, 3) == "key")
00132 {
00133 KeyEvent key = reply[4];
00134 CallbackMap::iterator it;
00135
00136 it = _callbacks.find(key);
00137
00138 if (it != _callbacks.end())
00139 {
00140 KeyEventInfo *kevI;
00141
00142 kevI = new KeyEventInfo;
00143 kevI->kev = key;
00144 kevI->callback = _callbacks[key];
00145
00146 ::pthread_t tid;
00147 ::pthread_create(&tid, 0, handleKeyEvent, kevI);
00148 }
00149
00150 }
00151 else if (reply.substr(0, 6) == "listen")
00152 {
00153 _currentScreen = reply.substr(7);
00154 }
00155 else if (reply.substr(0, 6) == "ignore")
00156 {
00157 if (_currentScreen == reply.substr(7))
00158 {
00159 _currentScreen = "";
00160 }
00161 }
00162 }
00163 }
00164 }
00165
00166 void *mainRepliesLoop(void *param)
00167 {
00168 LCDClient *client = (LCDClient *)param;
00169 client->mainLoop();
00170 }
00171
00172 void *handleKeyEvent(void *param)
00173 {
00174 KeyEventInfo *kevI = (KeyEventInfo *)param;
00175
00176 (*(kevI->callback))(kevI->kev);
00177
00178 delete kevI;
00179 }