Index: /code/branches/netp4/src/orxonox/gamestates/GSDedicated.cc
===================================================================
--- /code/branches/netp4/src/orxonox/gamestates/GSDedicated.cc	(revision 3125)
+++ /code/branches/netp4/src/orxonox/gamestates/GSDedicated.cc	(revision 3126)
@@ -63,16 +63,37 @@
         , inputIterator_(0)
         , cleanLine_(true)
-    {
-        this->inputThread_ = new boost::thread(boost::bind(&GSDedicated::inputThread, this));
+        , cursorX_(0)
+        , cursorY_(0)
+    {
         this->commandLine_ = new unsigned char[MAX_COMMAND_LENGTH];
 //         memset( this->commandLine_, 0, MAX_COMMAND_LENGTH );
+    }
+
+    GSDedicated::~GSDedicated()
+    {
+    }
+
+    void GSDedicated::activate()
+    {
+        GameMode::setHasServer(true);
+        
+        this->inputThread_ = new boost::thread(boost::bind(&GSDedicated::inputThread, this));
+        
 #ifndef ORXONOX_PLATFORM_WINDOWS
         this->originalTerminalSettings_ = new termios;
         this->setTerminalMode();
 #endif
-    }
-
-    GSDedicated::~GSDedicated()
-    {
+
+        this->server_ = new Server(CommandLine::getValue("port"));
+        COUT(0) << "Loading scene in server mode" << std::endl;
+
+        server_->open();
+    }
+
+    void GSDedicated::deactivate()
+    {
+        this->server_->close();
+        delete this->server_;
+        
         closeThread_ = true;
 #ifndef ORXONOX_PLATFORM_WINDOWS
@@ -83,20 +104,4 @@
 #endif
         //inputThread_->join();
-    }
-
-    void GSDedicated::activate()
-    {
-        GameMode::setHasServer(true);
-
-        this->server_ = new Server(CommandLine::getValue("port"));
-        COUT(0) << "Loading scene in server mode" << std::endl;
-
-        server_->open();
-    }
-
-    void GSDedicated::deactivate()
-    {
-        this->server_->close();
-        delete this->server_;
 
         GameMode::setHasServer(false);
@@ -124,45 +129,78 @@
     {
         unsigned char c;
+        unsigned int  escapeChar=0;
         while(!closeThread_)
         {
             c = getchar();
             {
-                boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+//                 boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
                 if ( inputIterator_>=MAX_COMMAND_LENGTH-1 && c!='\n' )
                     continue;
-                switch (c)
+                if( escapeChar > 0 )
                 {
-                    case '\n':
-                        this->cleanLine_ = true;
+                    if( c == '[' )
+                    {
+                        escapeChar = 2;
+                        continue;
+                    }
+                    else if ( escapeChar == 2 )
+                    {
+                        switch (c)
                         {
-                            boost::recursive_mutex::scoped_lock(this->inputQueueMutex_);
-                            boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-                            this->commandQueue_.push( std::string((const char*)this->commandLine_,inputIterator_) );
+                            case 'A': //keyup
+                                
+                                break;
+                            case 'B': //keydown
+                                
+                                break;
+                            case 'C': //keyright
+                                if(cursorX_<inputIterator_)
+                                    ++cursorX_;
+                                break;
+                            case 'D': //keyleft
+                                if(cursorX_>0)
+                                    --cursorX_;
+                                break;
+                            default: //not supported...
+                                break;
                         }
-                        memset( this->commandLine_, 0, inputIterator_ );
-                        inputIterator_ = 0;
-                        std::cout << endl;
-                        break;
-                    case 127: // backspace
-                    case '\b':
+                        escapeChar = 0;
+                    }
+                }
+                else // not in escape sequence mode
+                {
+                    switch (c)
                     {
-                        boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-                        if(inputIterator_>0)
-                            --inputIterator_;
-                        break;
-                    }
-                    case '\t':
-                    {
-                        boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-                        COUT(0) << endl << CommandExecutor::hint( std::string((const char*)this->commandLine_,inputIterator_) ) << endl;
-                        strncpy((char*)this->commandLine_, CommandExecutor::complete( std::string((const char*)this->commandLine_,inputIterator_) ).c_str(), MAX_COMMAND_LENGTH);
-                        inputIterator_ = strlen((const char*)this->commandLine_);
-                        break;
-                    }
-                    default:
-                    {
-                        boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-                        this->commandLine_[this->inputIterator_++] = c;
-                        break;
+                        case '\n':
+                            this->cleanLine_ = true;
+                            {
+                                boost::recursive_mutex::scoped_lock(this->inputQueueMutex_);
+                                boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+                                this->commandQueue_.push( std::string((const char*)this->commandLine_,inputIterator_) );
+                            }
+                            memset( this->commandLine_, 0, inputIterator_ );
+                            inputIterator_ = 0;
+                            this->cursorX_ = 0;
+                            this->cursorY_ = 0;
+                            std::cout << endl;
+                            break;
+                        case 127: // backspace
+                        case '\b':
+                            deleteCharacter( this->cursorX_ );
+                            break;
+                        case '\t':
+                        {
+//                             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+                            std::cout << endl << CommandExecutor::hint( std::string((const char*)this->commandLine_,inputIterator_) ) << endl;
+                            strncpy((char*)this->commandLine_, CommandExecutor::complete( std::string((const char*)this->commandLine_,inputIterator_) ).c_str(), MAX_COMMAND_LENGTH);
+                            inputIterator_ = strlen((const char*)this->commandLine_);
+                            break;
+                        }
+                        case '\033': // 1. escape character
+                            escapeChar = 1;
+                            break;
+                        default:
+                            insertCharacter( this->cursorX_, c );
+                            break;
                     }
                 }
@@ -174,12 +212,17 @@
     {
 #ifndef ORXONOX_PLATFORM_WINDOWS
-//         std::cout << "\033[s\033[0G";
+        // set cursor to the begining of the line and erase the line
         std::cout << "\033[0G\033[K";
-        boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-        std::cout << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, " << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms avg ticktime # " << std::string((const char*)this->commandLine_,inputIterator_);
-        //if ( this->cleanLine_ )
-        //    this->cleanLine_ = false;
-        //else
-        //    std::cout <<"\033[u";
+//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+        // print status line
+        std::cout << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, " << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms avg ticktime # ";
+        //save cursor position
+        std::cout << "\033[s";
+        //print commandLine buffer
+        std::cout << std::string((const char*)this->commandLine_, inputIterator_);
+        //restore cursor position and move it cursorX_ to the right
+        std::cout << "\033[u";
+        if( this->cursorX_ > 0 )
+            std::cout << "\033[" << this->cursorX_ << "C";
         std::cout.flush();
 #endif
@@ -227,3 +270,31 @@
 #endif
     }
+    
+    void GSDedicated::insertCharacter( unsigned int position, char c )
+    {
+//         std::cout << endl << (unsigned int)c << endl;
+        // check that we do not exceed MAX_COMMAND_LENGTH
+        if( inputIterator_+1 < MAX_COMMAND_LENGTH )
+        {
+            // if cursor not at end of line then move the rest of the line
+            if( position != this->inputIterator_ )
+                    memmove( this->commandLine_+position+1, this->commandLine_+position, this->inputIterator_-position);
+//             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+            this->commandLine_[position] = c;
+            ++this->cursorX_;
+            ++this->inputIterator_;
+        }
+    }
+    void GSDedicated::deleteCharacter( unsigned int position )
+    {
+//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+        if ( this->inputIterator_>0 && position>0 )
+        {
+            if ( position != this->inputIterator_ )
+                memmove( this->commandLine_+position-1, this->commandLine_+position, this->inputIterator_-position);
+            --this->cursorX_;
+            --this->inputIterator_;
+        }
+    }
+    
 }
Index: /code/branches/netp4/src/orxonox/gamestates/GSDedicated.h
===================================================================
--- /code/branches/netp4/src/orxonox/gamestates/GSDedicated.h	(revision 3125)
+++ /code/branches/netp4/src/orxonox/gamestates/GSDedicated.h	(revision 3126)
@@ -61,4 +61,7 @@
         static void resetTerminalMode();
         
+        void insertCharacter( unsigned int position, char c );
+        void deleteCharacter( unsigned int position );
+        
         Server*                 server_;
         float                   timeSinceLastUpdate_;
@@ -73,4 +76,7 @@
         std::queue<std::string> commandQueue_;
         static termios*         originalTerminalSettings_;
+        
+        unsigned int            cursorX_;
+        unsigned int            cursorY_;
     };
 }
