CMS 3D CMS Logo

VisG4UIShell.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
00002 
00003 #include "VisGeant4/VisG4Core/interface/VisG4UIShell.h"
00004 #include <classlib/utils/DebugAids.h>
00005 #include <cstdlib>
00006 #include <unistd.h>
00007 #include <errno.h>
00008 
00009 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00010 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00011 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00012 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00013 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00014 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00015 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00016 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00017 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00018 
00019 VisG4UIShell::VisG4UIShell (const G4String &prompt, G4int maxhist)
00020     : G4UItcsh (prompt, maxhist),
00021       m_reading (false),
00022       m_quit (false)
00023 {
00024     pthread_mutex_init (&m_lock, 0);
00025     VERIFY (pipe (m_oncancel) != -1);
00026 }
00027 
00028 G4String
00029 VisG4UIShell::GetCommandLine (const char *msg)
00030 {
00031     G4String result;
00032     pthread_mutex_lock (&m_lock);
00033     if (! m_quit)
00034     {
00035         m_reading = true;
00036         pthread_mutex_unlock (&m_lock);
00037 
00038         result = MyGetCommandLine (msg);
00039 
00040         pthread_mutex_lock (&m_lock);
00041         m_reading = false;
00042     }
00043 
00044     // FIXME: What if we are in pause?  We'll have to answer continue!
00045     // Can we use G4StateManager to tell which answer we should give?
00046     if (m_quit)
00047         result = "exit";
00048     pthread_mutex_unlock (&m_lock);
00049 
00050     return result;
00051 }
00052 
00053 void
00054 VisG4UIShell::Quit (void)
00055 {
00056     // Set a flag to indicate that next time the command line reads
00057     // something, it should just exit.  If we are currently reading
00058     // something, interrupt and discard whatever the user was typing.
00059     pthread_mutex_lock (&m_lock);
00060     m_quit = true;
00061     if (m_reading)
00062         write (m_oncancel [1], "\n", 1);
00063     pthread_mutex_unlock (&m_lock);
00064 }
00065 
00066 char
00067 VisG4UIShell::ReadChar (void)
00068 {
00069     // Wait till we can read a character but let us be cancelled.
00070     fd_set r;
00071     FD_ZERO (&r);
00072     FD_SET (0, &r);
00073     FD_SET (m_oncancel[0], &r);
00074     while (select (m_oncancel[0]+1, &r, 0, 0, 0) == -1
00075            && (0
00076 #ifdef EAGAIN
00077                || errno == EAGAIN
00078 #endif
00079 #ifdef EINTR
00080                || errno == EINTR
00081 #endif
00082 #ifdef EWOULDBLOCK
00083                || errno == EWOULDBLOCK
00084 #endif
00085                || 0))
00086         ;
00087 
00088     if (FD_ISSET (m_oncancel [0], &r))
00089         // Someone wanted us to quit so get out of the loop.  In case
00090         // last line was continued, return something that will get us
00091         // out of the command line loop.
00092         return '\n';
00093 
00094     // OK to read from standard input.
00095     char cc;
00096     G4cin.get(cc);
00097     return cc;
00098 }
00099 
00103 // Copied from G4UItcsh.cc.  Sigh.
00104 G4String
00105 VisG4UIShell::MyReadLine (void)
00106 {
00107     static const char AsciiCtrA = '\001';
00108     static const char AsciiCtrB = '\002';
00109     static const char AsciiCtrC = '\003';
00110     static const char AsciiCtrD = '\004';
00111     static const char AsciiCtrE = '\005';
00112     static const char AsciiCtrF = '\006';
00113     static const char AsciiCtrK = '\013';
00114     static const char AsciiCtrL = '\014';
00115     static const char AsciiCtrN = '\016';
00116     static const char AsciiCtrP = '\020';
00117     static const char AsciiCtrQ = '\021';
00118     static const char AsciiCtrS = '\023';
00119     static const char AsciiCtrZ = '\032';
00120     static const char AsciiTAB  = '\011';
00121     static const char AsciiBS   = '\010';
00122     static const char AsciiDEL  = '\177';
00123     static const char AsciiESC  = '\033';
00124 
00125     InitializeCommandLine();
00126 
00127     char cc;
00128     do {
00129         // treatment for special character
00130         switch(cc = ReadChar ()){
00131         case AsciiCtrA:       // ... move cursor to the top
00132             MoveCursorTop();
00133             break;
00134         case AsciiCtrB:       // ... backward cursor
00135             BackwardCursor();
00136             break;
00137         case AsciiCtrD:       // ... delete/exit/show matched list
00138             if(commandLine.length()!=0 && IsCursorLast()) ListMatchedCommand();
00139             else if (commandLine.empty()) {
00140                 G4cout << G4endl;
00141                 exit(0);
00142             } else DeleteCharacter();
00143             break;
00144         case AsciiCtrE:       // ... move cursor to the end
00145             MoveCursorEnd();
00146             break;
00147         case AsciiCtrF:       // ... forward cursor
00148             ForwardCursor();
00149             break;
00150         case AsciiCtrK:       // ... clear after the cursor
00151             ClearAfterCursor();
00152             break;
00153         case AsciiCtrL:       // ... clear screen
00154             // ClearScreen();
00155             break;
00156         case AsciiCtrN: // ... next command
00157             NextCommand();
00158             break;
00159         case AsciiCtrP: // ... previous command
00160             PreviousCommand();
00161             break;
00162         case AsciiTAB:         // ... command completion
00163             if( (!commandLine.empty()) && IsCursorLast()) CompleteCommand();
00164             break;
00165         case AsciiDEL:         // ... backspace
00166             BackspaceCharacter();
00167             break;
00168         case AsciiBS:          // ... backspace
00169             BackspaceCharacter();
00170             break;
00171         case AsciiCtrC:       // ... kill prompt
00172             break;
00173         case AsciiCtrQ:       // ... restarts suspeded output
00174             break;
00175         case AsciiCtrS:       // ... suspend output
00176             break;
00177         case AsciiCtrZ:       // ... suspend
00178             break;
00179         default:
00180             break;
00181         }
00182 
00183         // treatment for ESC. character
00184         if( cc == AsciiESC) { // ESC
00185             G4cin.get(cc);
00186             if (cc == '[') {
00187                 G4cin.get(cc);
00188                 switch(cc) {
00189                 case 'A': // [UP]
00190                     cc = 'P' - '@';
00191                     PreviousCommand();  // ... show previous commad
00192                     break;
00193                 case 'B': // [DOWN]
00194                     cc = 'N' - '@';
00195                     NextCommand();  // ... show next commad
00196                     break;
00197                 case 'C': // [RIGHT]
00198                     cc = 'F' - '@';
00199                     ForwardCursor();   // ... forward cursor
00200                     break;
00201                 case 'D': // [LEFT]
00202                     cc = 'B' - '@';
00203                     BackwardCursor();      // ... backward cursor
00204                     break;
00205                 default:  // who knows !?
00206                     cc = 0;
00207                     break;
00208                 }
00209             }
00210         }
00211 
00212         // insert character to command line and display
00213         InsertCharacter(cc);
00214   
00215     } while( cc != '\n');
00216 
00217     return commandLine;
00218 }
00219 
00220 G4String
00221 VisG4UIShell::MyGetCommandLine (const char *msg)
00222 {
00223     SetTermToInputMode();
00224 
00225     MakePrompt(msg); // update
00226     relativeHistoryIndex= 0;
00227 
00228     G4cout << promptString << std::flush;
00229 
00230     G4String newCommand= MyReadLine();  // read line...
00231     // multi-line
00232     while( (newCommand.length() > 0) &&
00233            ( newCommand[newCommand.length()-1] == '_') ) {
00234         newCommand.remove(newCommand.length()-1);
00235         G4cout << G4endl;
00236         promptString= "? ";
00237         G4cout << promptString << std::flush;
00238         G4String newLine= MyReadLine();
00239         newCommand.append(newLine);
00240     }
00241 
00242     // update history...
00243     G4bool isMeaningfull= FALSE; // check NULL command
00244     for (size_t i=0; i<newCommand.length(); i++) {
00245         if(newCommand[i] != ' ') {
00246             isMeaningfull= TRUE;
00247             break;
00248         }
00249     }
00250     if( !newCommand.empty() && isMeaningfull) StoreHistory(newCommand);
00251 
00252     // reset terminal
00253     RestoreTerm();
00254 
00255     G4cout << G4endl;
00256     return newCommand;
00257 }

Generated on Tue Jun 9 17:50:06 2009 for CMSSW by  doxygen 1.5.4