Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

TEmulation.cpp

Go to the documentation of this file.
00001 /* -------------------------------------------------------------------------- */
00002 /*                                                                            */
00003 /* [TEmulation.cpp]        Terminal Emulation Decoder                         */
00004 /*                                                                            */
00005 /* -------------------------------------------------------------------------- */
00006 /*                                                                            */
00007 /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>            */
00008 /*                                                                            */
00009 /* This file is part of Konsole - an X terminal for KDE                       */
00010 /*                                                                            */
00011 /* -------------------------------------------------------------------------- */
00012 /*                        */
00013 /* Ported Konsole to Qt/Embedded                                              */
00014 /*                        */
00015 /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com>                  */
00016 /*                        */
00017 /* -------------------------------------------------------------------------- */
00018 
00068 /* FIXME
00069    - evtl. the bulk operations could be made more transparent.
00070 */
00071 
00072 #include "TEmulation.h"
00073 #include <stdio.h>
00074 #include <stdlib.h>
00075 #include <unistd.h>
00076 
00077 
00078 /* ------------------------------------------------------------------------- */
00079 /*                                                                           */
00080 /*                               TEmulation                                  */
00081 /*                                                                           */
00082 /* ------------------------------------------------------------------------- */
00083 
00084 #define CNTL(c) ((c)-'@')
00085 
00089 TEmulation::TEmulation(TEWidget* gui)
00090 : decoder((QTextDecoder*)NULL)
00091 {
00092   this->gui = gui;
00093 
00094   screen[0] = new TEScreen(gui->Lines(),gui->Columns());
00095   screen[1] = new TEScreen(gui->Lines(),gui->Columns());
00096   scr = screen[0];
00097 
00098   bulk_nlcnt = 0; // reset bulk newline counter
00099   bulk_incnt = 0; // reset bulk counter
00100   connected  = FALSE;
00101 
00102   QObject::connect(&bulk_timer, SIGNAL(timeout()), this, SLOT(showBulk()) );
00103 
00104   QObject::connect(gui,SIGNAL(changedImageSizeSignal(int,int)),
00105                    this,SLOT(onImageSizeChange(int,int)));
00106 
00107   QObject::connect(gui,SIGNAL(changedHistoryCursor(int)),
00108                    this,SLOT(onHistoryCursorChange(int)));
00109 
00110   QObject::connect(gui,SIGNAL(changedHorzCursor(int)),
00111                    this,SLOT(onHorzCursorChange(int)));
00112 
00113   QObject::connect(gui,SIGNAL(keyPressedSignal(QKeyEvent*)),
00114                    this,SLOT(onKeyPress(QKeyEvent*)));
00115 
00116   QObject::connect(gui,SIGNAL(beginSelectionSignal(const int,const int)),
00117        this,SLOT(onSelectionBegin(const int,const int)) );
00118 
00119   QObject::connect(gui,SIGNAL(extendSelectionSignal(const int,const int)),
00120        this,SLOT(onSelectionExtend(const int,const int)) );
00121 
00122   QObject::connect(gui,SIGNAL(endSelectionSignal(const BOOL)),
00123        this,SLOT(setSelection(const BOOL)) );
00124 
00125   QObject::connect(gui,SIGNAL(clearSelectionSignal()),
00126        this,SLOT(clearSelection()) );
00127 }
00128 
00132 TEmulation::~TEmulation()
00133 {
00134   delete screen[0];
00135   delete screen[1];
00136   bulk_timer.stop();
00137 }
00138 
00142 void TEmulation::setScreen(int n)
00143 {
00144   scr = screen[n&1];
00145 }
00146 
00147 void TEmulation::setHistory(bool on)
00148 {
00149   screen[0]->setScroll(on);
00150   if (!connected) return;
00151   showBulk();
00152 }
00153 
00154 bool TEmulation::history()
00155 {
00156   return screen[0]->hasScroll();
00157 }
00158 
00159 void TEmulation::setCodec(int c)
00160 {
00161   //FIXME: check whether we have to free codec
00162   codec = c ? QTextCodec::codecForName("utf8")
00163             : QTextCodec::codecForLocale();
00164   if (decoder) delete decoder;
00165   decoder = codec->makeDecoder();
00166 }
00167 
00168 void TEmulation::setKeytrans(int no)
00169 {
00170   keytrans = KeyTrans::find(no);
00171 }
00172 
00173 void TEmulation::setKeytrans(const char * no)
00174 {
00175   keytrans = KeyTrans::find(no);
00176 }
00177 
00178 // Interpreting Codes ---------------------------------------------------------
00179 
00180 /*
00181    This section deals with decoding the incoming character stream.
00182    Decoding means here, that the stream is first seperated into `tokens'
00183    which are then mapped to a `meaning' provided as operations by the
00184    `Screen' class.
00185 */
00186 
00190 void TEmulation::onRcvChar(int c)
00191 // process application unicode input to terminal
00192 // this is a trivial scanner
00193 {
00194   c &= 0xff;
00195 
00196   switch (c)
00197   {
00198     case '\b'      : scr->BackSpace();                 break;
00199     case '\t'      : scr->Tabulate();                  break;
00200     case '\n'      : scr->NewLine();                   break;
00201     case '\r'      : scr->Return();                    break;
00202     case 0x07      : gui->Bell();                      break;
00203     default        : scr->ShowCharacter(c);            break;
00204   };
00205 }
00206 
00207 /* ------------------------------------------------------------------------- */
00208 /*                                                                           */
00209 /*                             Keyboard Handling                             */
00210 /*                                                                           */
00211 /* ------------------------------------------------------------------------- */
00212 
00216 void TEmulation::onKeyPress( QKeyEvent* ev )
00217 {
00218   if (!connected) return; // someone else gets the keys
00219   if (scr->getHistCursor() != scr->getHistLines());
00220     scr->setHistCursor(scr->getHistLines());
00221   if (!ev->text().isEmpty())
00222   { // A block of text
00223     // Note that the text is proper unicode.
00224     // We should do a conversion here, but since this
00225     // routine will never be used, we simply emit plain ascii.
00226     emit sndBlock(ev->text().ascii(),ev->text().length());
00227   }
00228   else if (ev->ascii()>0)
00229   { unsigned char c[1];
00230     c[0] = ev->ascii();
00231     emit sndBlock((char*)c,1);
00232   }
00233 }
00234 
00235 // Unblocking, Byte to Unicode translation --------------------------------- --
00236 
00237 /*
00238    We are doing code conversion from locale to unicode first.
00239 */
00240 
00241 void TEmulation::onRcvBlock(const char *s, int len)
00242 {
00243   bulkStart();
00244   bulk_incnt += 1;
00245   for (int i = 0; i < len; i++)
00246   {
00247     QString result = decoder->toUnicode(&s[i],1);
00248     int reslen = result.length();
00249     for (int j = 0; j < reslen; j++)
00250       onRcvChar(result[j].unicode());
00251     if (s[i] == '\n') bulkNewline();
00252   }
00253   bulkEnd();
00254 }
00255 
00256 // Selection --------------------------------------------------------------- --
00257 
00258 void TEmulation::onSelectionBegin(const int x, const int y) {
00259   if (!connected) return;
00260   scr->setSelBeginXY(x,y);
00261   showBulk();
00262 }
00263 
00264 void TEmulation::onSelectionExtend(const int x, const int y) {
00265   if (!connected) return;
00266   scr->setSelExtentXY(x,y);
00267   showBulk();
00268 }
00269 
00270 void TEmulation::setSelection(const BOOL preserve_line_breaks) {
00271   if (!connected) return;
00272   QString t = scr->getSelText(preserve_line_breaks);
00273   if (!t.isNull()) gui->setSelection(t);
00274 }
00275 
00276 void TEmulation::clearSelection() {
00277   if (!connected) return;
00278   scr->clearSelection();
00279   showBulk();
00280 }
00281 
00282 // Refreshing -------------------------------------------------------------- --
00283 
00284 #define BULK_TIMEOUT 20
00285 
00290 void TEmulation::bulkNewline()
00291 {
00292   bulk_nlcnt += 1;
00293   bulk_incnt = 0;  // reset bulk counter since `nl' rule applies
00294 }
00295 
00299 void TEmulation::showBulk()
00300 {
00301   bulk_nlcnt = 0;                       // reset bulk newline counter
00302   bulk_incnt = 0;                       // reset bulk counter
00303   if (connected)
00304   {
00305     ca* image = scr->getCookedImage();    // get the image
00306     gui->setImage(image,
00307                   scr->getLines(),
00308                   scr->getColumns());     // actual refresh
00309     free(image);
00310 
00311       //FIXME: check that we do not trigger other draw event here.
00312     gui->setScroll(scr->getHistCursor(),scr->getHistLines());
00313 
00314   }
00315 }
00316 
00317 void TEmulation::bulkStart()
00318 {
00319   if (bulk_timer.isActive()) bulk_timer.stop();
00320 }
00321 
00322 void TEmulation::bulkEnd()
00323 {
00324   if ( bulk_nlcnt > gui->Lines() || bulk_incnt > 20 )
00325     showBulk();                         // resets bulk_??cnt to 0, too.
00326   else
00327     bulk_timer.start(BULK_TIMEOUT,TRUE);
00328 }
00329 
00330 void TEmulation::setConnect(bool c)
00331 {
00332   connected = c;
00333   if ( connected)
00334   {
00335     onImageSizeChange(gui->Lines(), gui->Columns());
00336     showBulk();
00337   }
00338   else
00339   {
00340     scr->clearSelection();
00341   }
00342 }
00343 
00344 // ---------------------------------------------------------------------------
00345 
00352 void TEmulation::onImageSizeChange(int lines, int columns) {
00353   if (!connected) return;
00354   screen[0]->resizeImage(lines,columns);
00355   screen[1]->resizeImage(lines,columns);
00356   showBulk();
00357   emit ImageSizeChanged(lines,columns);   // propagate event to serial line
00358 }
00359 
00360 void TEmulation::onHistoryCursorChange(int cursor) {
00361   if (!connected) return;
00362   scr->setHistCursor(cursor);
00363   showBulk();
00364 }
00365 
00366 void TEmulation::onHorzCursorChange(int cursor) {
00367   if (!connected) return;
00368  scr->setHorzCursor(cursor);
00369   showBulk();
00370 }
00371 
00372 void TEmulation::setColumns(int columns) {
00373   //FIXME: this goes strange ways.
00374   //       Can we put this straight or explain it at least?
00375   emit changeColumns(columns);
00376 }

Generated on Sat Nov 5 16:15:27 2005 for OPIE by  doxygen 1.4.2