/[svn]/linuxsampler/trunk/src/shell/lscp.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/shell/lscp.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2516 by schoenebeck, Thu Feb 6 21:11:23 2014 UTC revision 2517 by schoenebeck, Fri Feb 7 19:53:09 2014 UTC
# Line 19  Line 19 
19  #include "CCursor.h"  #include "CCursor.h"
20    
21  #include "../common/global.h"  #include "../common/global.h"
22    #include "../common/global_private.h"
23  #include "../common/Condition.h"  #include "../common/Condition.h"
24    
25  #define LSCP_DEFAULT_HOST "localhost"  #define LSCP_DEFAULT_HOST "localhost"
# Line 27  Line 28 
28  using namespace std;  using namespace std;
29  using namespace LinuxSampler;  using namespace LinuxSampler;
30    
31  static LSCPClient g_client;  static LSCPClient* g_client = NULL;
32  static KeyboardReader g_keyboardReader;  static KeyboardReader* g_keyboardReader = NULL;
33  static Condition g_todo;  static Condition g_todo;
34  static String g_goodPortion;  static String g_goodPortion;
35  static String g_badPortion;  static String g_badPortion;
36  static String g_suggestedPortion;  static String g_suggestedPortion;
37    static const String g_prompt = "lscp=# ";
38    
39  static void printUsage() {  static void printUsage() {
40      cout << "lscp - The LinuxSampler Control Protocol (LSCP) Shell." << endl;      cout << "lscp - The LinuxSampler Control Protocol (LSCP) Shell." << endl;
# Line 47  static void printUsage() { Line 49  static void printUsage() {
49      cout << endl;      cout << endl;
50  }  }
51    
52    static void printWelcome() {
53        cout << "Welcome to lscp " << VERSION << ", the LinuxSampler Control Protocol (LSCP) shell." << endl;
54        cout << endl;
55    }
56    
57    static void printPrompt() {
58        cout << g_prompt << flush;
59    }
60    
61    static int promptOffset() {
62        return g_prompt.size();
63    }
64    
65  // Called by the network reading thread, whenever new data arrived from the  // Called by the network reading thread, whenever new data arrived from the
66  // network connection.  // network connection.
67  static void onLSCPClientNewInputAvailable(LSCPClient* client) {  static void onLSCPClientNewInputAvailable(LSCPClient* client) {
# Line 66  static void autoComplete() { Line 81  static void autoComplete() {
81      // now add the suggested, correct characters      // now add the suggested, correct characters
82      s += g_suggestedPortion;      s += g_suggestedPortion;
83      g_suggestedPortion.clear();      g_suggestedPortion.clear();
84      g_client.send(s);      g_client->send(s);
85  }  }
86    
87  int main(int argc, char *argv[]) {  int main(int argc, char *argv[]) {
# Line 103  int main(int argc, char *argv[]) { Line 118  int main(int argc, char *argv[]) {
118    
119      // try to connect to the sampler's LSCP server and start a thread for      // try to connect to the sampler's LSCP server and start a thread for
120      // receiving incoming network data from the sampler's LSCP server      // receiving incoming network data from the sampler's LSCP server
121      g_client.setCallback(onLSCPClientNewInputAvailable);      g_client = new LSCPClient;
122      if (!g_client.connect(host, port)) return -1;      g_client->setCallback(onLSCPClientNewInputAvailable);
123      String sResponse = g_client.sendCommandSync(      if (!g_client->connect(host, port)) return -1;
124        String sResponse = g_client->sendCommandSync(
125          (autoCorrect) ? "SET SHELL AUTO_CORRECT 1" : "SET SHELL AUTO_CORRECT 0"          (autoCorrect) ? "SET SHELL AUTO_CORRECT 1" : "SET SHELL AUTO_CORRECT 0"
126      );      );
127      sResponse = g_client.sendCommandSync("SET SHELL INTERACT 1");      sResponse = g_client->sendCommandSync("SET SHELL INTERACT 1");
128      if (sResponse.substr(0, 2) != "OK") {      if (sResponse.substr(0, 2) != "OK") {
129          cerr << "Error: sampler too old, it does not support shell instructions\n";          cerr << "Error: sampler too old, it does not support shell instructions\n";
130          return -1;          return -1;
131      }      }
132        
133        printWelcome();
134        printPrompt();
135    
136      // start a thread for reading from the local text input keyboard      // start a thread for reading from the local text input keyboard
137      // (keyboard echo will be disabled as well to have a clean control on what      // (keyboard echo will be disabled as well to have a clean control on what
138      // is appearing on the screen)      // is appearing on the screen)
139      g_keyboardReader.setCallback(onNewKeyboardInputAvailable);      g_keyboardReader = new KeyboardReader;
140      g_keyboardReader.startReading();      g_keyboardReader->setCallback(onNewKeyboardInputAvailable);
141        g_keyboardReader->startReading();
142            
143      // main thread's loop      // main thread's loop
144      while (true) {      while (true) {
# Line 129  int main(int argc, char *argv[]) { Line 149  int main(int argc, char *argv[]) {
149          g_todo.Unlock();          g_todo.Unlock();
150    
151          // did network data arrive?          // did network data arrive?
152          while (g_client.messageComplete()) {          while (g_client->messageComplete()) {
153              String line = *g_client.popLine();              String line = *g_client->popLine();
154              //printf("line '%s'\n", line.c_str());              //printf("line '%s'\n", line.c_str());
155              if (line.substr(0,4) == "SHU:") {              if (line.substr(0,4) == "SHU:") {
156                  int code = 0, n = 0;                  int code = 0, n = 0;
# Line 178  int main(int argc, char *argv[]) { Line 198  int main(int argc, char *argv[]) {
198                      //printf("line '%s' good='%s' bad='%s' suggested='%s' cursor=%d\n", line.c_str(), sGood.c_str(), sBad.c_str(), sSuggest.c_str(), cursorColumn);                      //printf("line '%s' good='%s' bad='%s' suggested='%s' cursor=%d\n", line.c_str(), sGood.c_str(), sBad.c_str(), sSuggest.c_str(), cursorColumn);
199    
200                      CCursor cursor = CCursor::now().toColumn(0).clearLine();                      CCursor cursor = CCursor::now().toColumn(0).clearLine();
201                        printPrompt();
202    
203                      CFmt cfmt;                      CFmt cfmt;
204                      if (code == LSCP_SHU_COMPLETE) cfmt.bold().green();                      if (code == LSCP_SHU_COMPLETE) cfmt.bold().green();
# Line 188  int main(int argc, char *argv[]) { Line 209  int main(int argc, char *argv[]) {
209                      cfmt.bold().yellow();                      cfmt.bold().yellow();
210                      cout << sSuggest << flush;                      cout << sSuggest << flush;
211    
212                      cursor.toColumn(cursorColumn);                      cursor.toColumn(cursorColumn + promptOffset());
213                  }                  }
214              } else if (line.substr(0,2) == "OK") { // single-line response expected ...              } else if (line.substr(0,2) == "OK") { // single-line response expected ...
215                  cout << endl << flush;                  cout << endl << flush;
# Line 197  int main(int argc, char *argv[]) { Line 218  int main(int argc, char *argv[]) {
218                  cout << line.substr(0,2) << flush;                  cout << line.substr(0,2) << flush;
219                  cfmt.reset();                  cfmt.reset();
220                  cout << line.substr(2) << endl << flush;                  cout << line.substr(2) << endl << flush;
221                    printPrompt();
222              } else if (line.substr(0,3) == "WRN") { // single-line response expected ...              } else if (line.substr(0,3) == "WRN") { // single-line response expected ...
223                  cout << endl << flush;                  cout << endl << flush;
224                  CFmt cfmt;                  CFmt cfmt;
# Line 204  int main(int argc, char *argv[]) { Line 226  int main(int argc, char *argv[]) {
226                  cout << line.substr(0,3) << flush;                  cout << line.substr(0,3) << flush;
227                  cfmt.reset();                  cfmt.reset();
228                  cout << line.substr(3) << endl << flush;                  cout << line.substr(3) << endl << flush;
229                    printPrompt();
230              } else if (line.substr(0,3) == "ERR") { // single-line response expected ...              } else if (line.substr(0,3) == "ERR") { // single-line response expected ...
231                  cout << endl << flush;                  cout << endl << flush;
232                  CFmt cfmt;                  CFmt cfmt;
# Line 211  int main(int argc, char *argv[]) { Line 234  int main(int argc, char *argv[]) {
234                  cout << line.substr(0,3) << flush;                  cout << line.substr(0,3) << flush;
235                  cfmt.reset();                  cfmt.reset();
236                  cout << line.substr(3) << endl << flush;                  cout << line.substr(3) << endl << flush;
237              } else if (g_client.multiLine()) { // multi-line response expected ...                  printPrompt();
238                } else if (g_client->multiLine()) { // multi-line response expected ...
239                  cout << endl << flush;                  cout << endl << flush;
240                  while (true) {                                    while (true) {                  
241                     cout << line << endl << flush;                     cout << line << endl << flush;
242                     if (line.substr(0, 1) == ".") break;                     if (line.substr(0, 1) == ".") break;
243                     if (!g_client.lineAvailable()) break;                     if (!g_client->lineAvailable()) break;
244                     line = *g_client.popLine();                     line = *g_client->popLine();
245                  }                  }
246                    printPrompt();
247              } else {              } else {
248                  cout << endl << line << endl << flush;                  cout << endl << line << endl << flush;
249                    printPrompt();
250              }              }
251          }          }
252    
253          // did keyboard input arrive?          // did keyboard input arrive?
254          while (g_keyboardReader.charAvailable()) {          while (g_keyboardReader->charAvailable()) {
255              char c = g_keyboardReader.popChar();              char c = g_keyboardReader->popChar();
256    
257              CFmt cfmt;              CFmt cfmt;
258              cfmt.white();              cfmt.white();
259              //std::cout << c << "(" << int(c) << ")" << std::endl << std::flush;              //std::cout << c << "(" << int(c) << ")" << std::endl << std::flush;
260              if (c == KBD_BACKSPACE) {              if (c == KBD_BACKSPACE) {
261                  cout << "\b \b" << flush;                  if (promptOffset() < CCursor::now().column())
262                        cout << "\b \b" << flush;
263                  c = '\b';                  c = '\b';
264              } else if (c == '\t') { // auto completion ...              } else if (c == '\t') { // auto completion ...
265                  autoComplete();                  autoComplete();
# Line 241  int main(int argc, char *argv[]) { Line 268  int main(int argc, char *argv[]) {
268                  cout << c << flush;                  cout << c << flush;
269              }              }
270    
271              g_client.send(c);              g_client->send(c);
272          }          }
273      }      }
274    

Legend:
Removed from v.2516  
changed lines
  Added in v.2517

  ViewVC Help
Powered by ViewVC