00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00074
00075
00076
00077
00078 #include "emulation_layer.h"
00079 #include <stdio.h>
00080 #include <stdlib.h>
00081 #include <unistd.h>
00082
00083
00084
00085
00086
00087
00088
00089
00090 #define CNTL(c) ((c)-'@')
00091
00095 EmulationLayer::EmulationLayer( WidgetLayer* gui )
00096 : decoder((QTextDecoder*)NULL)
00097 {
00098 this->gui = gui;
00099
00100 screen[0] = new Screen(gui->lines(),gui->columns());
00101 screen[1] = new Screen(gui->lines(),gui->columns());
00102 scr = screen[0];
00103
00104 bulk_nlcnt = 0;
00105 bulk_incnt = 0;
00106 connected = FALSE;
00107
00108 QObject::connect(&bulk_timer, SIGNAL( timeout() ), this, SLOT( showBulk() ) );
00109 QObject::connect(gui,SIGNAL( imageSizeChanged(int,int) ),
00110 this,SLOT( onImageSizeChange(int,int) ) );
00111 QObject::connect(gui,SIGNAL( changedHistoryCursor(int) ),
00112 this,SLOT( historyCursorChange(int) ) );
00113 QObject::connect(gui,SIGNAL( keyPressed(QKeyEvent*) ),
00114 this,SLOT( onKeyPress(QKeyEvent*) ) );
00115 QObject::connect(gui,SIGNAL( selectionBegin(const int,const int) ),
00116 this,SLOT( onSelectionBegin(const int,const int) ) );
00117 QObject::connect(gui,SIGNAL( selectionExtended(const int,const int) ),
00118 this,SLOT( onSelectionExtend(const int,const int) ) );
00119 QObject::connect(gui,SIGNAL( selectionEnd(const bool) ),
00120 this,SLOT( setSelection(const bool) ) );
00121 QObject::connect(gui,SIGNAL( selectionCleared() ),
00122 this,SLOT( clearSelection() ) );
00123 }
00124
00128 EmulationLayer::~EmulationLayer()
00129 {
00130 delete screen[0];
00131 delete screen[1];
00132 bulk_timer.stop();
00133 }
00134
00138 void EmulationLayer::setScreen(int n)
00139 {
00140 scr = screen[n&1];
00141 }
00142
00143 void EmulationLayer::setHistory(bool on)
00144 {
00145 screen[0]->setScroll(on);
00146 if (!connected) return;
00147 showBulk();
00148 }
00149
00150 bool EmulationLayer::history()
00151 {
00152 return screen[0]->hasScroll();
00153 }
00154
00155 void EmulationLayer::setCodec(int c)
00156 {
00157
00158 codec = c ? QTextCodec::codecForName("utf8")
00159 : QTextCodec::codecForLocale();
00160 if (decoder) delete decoder;
00161 decoder = codec->makeDecoder();
00162 }
00163
00164 void EmulationLayer::setKeytrans(int no)
00165 {
00166 keytrans = KeyTrans::find(no);
00167 }
00168
00169 void EmulationLayer::setKeytrans(const char * no)
00170 {
00171 keytrans = KeyTrans::find(no);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00186 void EmulationLayer::onRcvChar(int c)
00187
00188
00189 {
00190 c &= 0xff;
00191 switch (c)
00192 {
00193 case '\b' : scr->BackSpace(); break;
00194 case '\t' : scr->Tabulate(); break;
00195 case '\n' : scr->NewLine(); break;
00196 case '\r' : scr->Return(); break;
00197 case 0x07 : gui->bell(); break;
00198 default : scr->ShowCharacter(c); break;
00199 };
00200 }
00201
00202
00203
00204
00205
00206
00207
00211 void EmulationLayer::onKeyPress( QKeyEvent* ev )
00212 {
00213 if (!connected) return;
00214 if (scr->getHistCursor() != scr->getHistLines());
00215 scr->setHistCursor(scr->getHistLines());
00216 if (!ev->text().isEmpty())
00217 {
00218
00219
00220
00221 sendString( ev->text().ascii() );
00222 }
00223 else if (ev->ascii()>0)
00224 {
00225 QByteArray c = QByteArray( 1 );
00226 c.at( 0 ) = ev->ascii();
00227
00228
00229 emit sndBlock( (QByteArray) c );
00230 }
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 void EmulationLayer::onRcvBlock(const QByteArray &s )
00240 {
00241 bulkStart();
00242 bulk_incnt += 1;
00243 for (int i = 0; i < s.size(); i++)
00244 {
00245
00246 QString result = decoder->toUnicode(&s[i],1);
00247 int reslen = result.length();
00248 for (int j = 0; j < reslen; j++)
00249 onRcvChar(result[j].unicode());
00250 if (s[i] == '\n') bulkNewline();
00251 }
00252 bulkEnd();
00253 }
00254
00255
00256
00257 void EmulationLayer::onSelectionBegin(const int x, const int y) {
00258 if (!connected) return;
00259 scr->setSelBeginXY(x,y);
00260 showBulk();
00261 }
00262
00263 void EmulationLayer::onSelectionExtend(const int x, const int y) {
00264 if (!connected) return;
00265 scr->setSelExtentXY(x,y);
00266 showBulk();
00267 }
00268
00269 void EmulationLayer::setSelection(const BOOL preserve_line_breaks) {
00270 if (!connected) return;
00271 QString t = scr->getSelText(preserve_line_breaks);
00272 if (!t.isNull()) gui->setSelection(t);
00273 }
00274
00275 void EmulationLayer::clearSelection() {
00276 if (!connected) return;
00277 scr->clearSelection();
00278 showBulk();
00279 }
00280
00281
00282
00283 #define BULK_TIMEOUT 20
00284
00289 void EmulationLayer::bulkNewline()
00290 {
00291 bulk_nlcnt += 1;
00292 bulk_incnt = 0;
00293 }
00294
00298 void EmulationLayer::showBulk()
00299 {
00300 bulk_nlcnt = 0;
00301 bulk_incnt = 0;
00302 if (connected)
00303 {
00304 QArray<Character> image = scr->getCookedImage();
00305 gui->setImage(image,
00306 scr->getLines(),
00307 scr->getColumns());
00308 delete image;
00309
00310 gui->setScroll(scr->getHistCursor(),scr->getHistLines());
00311 }
00312 }
00313
00314 void EmulationLayer::bulkStart()
00315 {
00316 if (bulk_timer.isActive()) bulk_timer.stop();
00317 }
00318
00319 void EmulationLayer::bulkEnd()
00320 {
00321 if ( bulk_nlcnt > gui->lines() || bulk_incnt > 20 )
00322 showBulk();
00323 else
00324 bulk_timer.start(BULK_TIMEOUT,TRUE);
00325 }
00326
00327 void EmulationLayer::setConnect(bool c)
00328 {
00329 connected = c;
00330 if ( connected)
00331 {
00332 onImageSizeChange(gui->lines(), gui->columns());
00333 showBulk();
00334 }
00335 else
00336 {
00337 scr->clearSelection();
00338 }
00339 }
00340
00341
00342
00349 void EmulationLayer::onImageSizeChange(int lines, int columns)
00350 {
00351 if (!connected) return;
00352 screen[0]->resizeImage(lines,columns);
00353 screen[1]->resizeImage(lines,columns);
00354 showBulk();
00355 emit ImageSizeChanged(lines,columns);
00356 }
00357
00358 void EmulationLayer::onHistoryCursorChange(int cursor)
00359 {
00360 if (!connected) return;
00361 scr->setHistCursor(cursor);
00362 showBulk();
00363 }
00364
00365 void EmulationLayer::setColumns(int columns)
00366 {
00367
00368
00369 emit changeColumns(columns);
00370 }
00371