00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00068
00069
00070
00071
00072 #include "TEmulation.h"
00073
00074
00075 #include <stdio.h>
00076 #include <stdlib.h>
00077 #include <unistd.h>
00078
00079
00080
00081
00082
00083
00084
00085
00086 #define CNTL(c) ((c)-'@')
00087
00091 TEmulation::TEmulation(TEWidget* gui)
00092 : decoder((QTextDecoder*)NULL)
00093 {
00094 this->gui = gui;
00095
00096 screen[0] = new TEScreen(gui->Lines(),gui->Columns());
00097 screen[1] = new TEScreen(gui->Lines(),gui->Columns());
00098 scr = screen[0];
00099
00100 bulk_nlcnt = 0;
00101 bulk_incnt = 0;
00102 connected = FALSE;
00103
00104 QObject::connect(&bulk_timer, SIGNAL(timeout()), this, SLOT(showBulk()) );
00105 QObject::connect(gui,SIGNAL(changedImageSizeSignal(int,int)),
00106 this,SLOT(onImageSizeChange(int,int)));
00107 QObject::connect(gui,SIGNAL(changedHistoryCursor(int)),
00108 this,SLOT(onHistoryCursorChange(int)));
00109 QObject::connect(gui,SIGNAL(keyPressedSignal(QKeyEvent*)),
00110 this,SLOT(onKeyPress(QKeyEvent*)));
00111 QObject::connect(gui,SIGNAL(beginSelectionSignal(const int,const int)),
00112 this,SLOT(onSelectionBegin(const int,const int)) );
00113 QObject::connect(gui,SIGNAL(extendSelectionSignal(const int,const int)),
00114 this,SLOT(onSelectionExtend(const int,const int)) );
00115 QObject::connect(gui,SIGNAL(endSelectionSignal(const BOOL)),
00116 this,SLOT(setSelection(const BOOL)) );
00117 QObject::connect(gui,SIGNAL(clearSelectionSignal()),
00118 this,SLOT(clearSelection()) );
00119 }
00120
00124 TEmulation::~TEmulation()
00125 {
00126 delete screen[0];
00127 delete screen[1];
00128 bulk_timer.stop();
00129 }
00130
00134 void TEmulation::setScreen(int n)
00135 {
00136 scr = screen[n&1];
00137 }
00138
00139 void TEmulation::setHistory(bool on)
00140 {
00141 screen[0]->setScroll(on);
00142 if (!connected) return;
00143 showBulk();
00144 }
00145
00146 bool TEmulation::history()
00147 {
00148 return screen[0]->hasScroll();
00149 }
00150
00151 void TEmulation::setCodec(int c)
00152 {
00153
00154 codec = c ? QTextCodec::codecForName("utf8")
00155 : QTextCodec::codecForLocale();
00156 if (decoder) delete decoder;
00157 decoder = codec->makeDecoder();
00158 }
00159
00160 void TEmulation::setKeytrans(int no)
00161 {
00162 keytrans = KeyTrans::find(no);
00163 }
00164
00165 void TEmulation::setKeytrans(const char * no)
00166 {
00167 keytrans = KeyTrans::find(no);
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00182 void TEmulation::onRcvChar(int c)
00183
00184
00185 {
00186 c &= 0xff;
00187 switch (c)
00188 {
00189 case '\b' : scr->BackSpace(); break;
00190 case '\t' : scr->Tabulate(); break;
00191 case '\n' : scr->NewLine(); break;
00192 case '\r' : scr->Return(); break;
00193 case 0x07 : gui->Bell(); break;
00194 default : scr->ShowCharacter(c); break;
00195 };
00196 }
00197
00198
00199
00200
00201
00202
00203
00207 void TEmulation::onKeyPress( QKeyEvent* ev )
00208 {
00209 if (!connected) return;
00210 if (scr->getHistCursor() != scr->getHistLines());
00211 scr->setHistCursor(scr->getHistLines());
00212 if (!ev->text().isEmpty())
00213 {
00214
00215
00216
00217 emit sndBlock(ev->text().ascii(),ev->text().length());
00218 }
00219 else if (ev->ascii()>0)
00220 { unsigned char c[1];
00221 c[0] = ev->ascii();
00222 emit sndBlock((char*)c,1);
00223 }
00224 }
00225
00226
00227
00228
00229
00230
00231
00232 void TEmulation::onRcvBlock(const char *s, int len)
00233 {
00234 bulkStart();
00235 bulk_incnt += 1;
00236 for (int i = 0; i < len; i++)
00237 {
00238 QString result = decoder->toUnicode(&s[i],1);
00239 int reslen = result.length();
00240 for (int j = 0; j < reslen; j++)
00241 onRcvChar(result[j].unicode());
00242 if (s[i] == '\n') bulkNewline();
00243 }
00244 bulkEnd();
00245 }
00246
00247
00248
00249 void TEmulation::onSelectionBegin(const int x, const int y) {
00250 if (!connected) return;
00251 scr->setSelBeginXY(x,y);
00252 showBulk();
00253 }
00254
00255 void TEmulation::onSelectionExtend(const int x, const int y) {
00256 if (!connected) return;
00257 scr->setSelExtentXY(x,y);
00258 showBulk();
00259 }
00260
00261 void TEmulation::setSelection(const BOOL preserve_line_breaks) {
00262 if (!connected) return;
00263 QString t = scr->getSelText(preserve_line_breaks);
00264 if (!t.isNull()) gui->setSelection(t);
00265 }
00266
00267 void TEmulation::clearSelection() {
00268 if (!connected) return;
00269 scr->clearSelection();
00270 showBulk();
00271 }
00272 void TEmulation::streamHistory(QTextStream* stream) {
00273 *stream << scr->getHistory();
00274 }
00275
00276
00277 #define BULK_TIMEOUT 20
00278
00283 void TEmulation::bulkNewline()
00284 {
00285 bulk_nlcnt += 1;
00286 bulk_incnt = 0;
00287 }
00288
00292 void TEmulation::showBulk()
00293 {
00294 bulk_nlcnt = 0;
00295 bulk_incnt = 0;
00296 if (connected)
00297 {
00298 ca* image = scr->getCookedImage();
00299 gui->setImage(image,
00300 scr->getLines(),
00301 scr->getColumns());
00302 free(image);
00303
00304 gui->setScroll(scr->getHistCursor(),scr->getHistLines());
00305 }
00306 }
00307
00308 void TEmulation::bulkStart()
00309 {
00310 if (bulk_timer.isActive()) bulk_timer.stop();
00311 }
00312
00313 void TEmulation::bulkEnd()
00314 {
00315 if ( bulk_nlcnt > gui->Lines() || bulk_incnt > 20 )
00316 showBulk();
00317 else
00318 bulk_timer.start(BULK_TIMEOUT,TRUE);
00319 }
00320
00321 void TEmulation::setConnect(bool c)
00322 {
00323 connected = c;
00324 if ( connected)
00325 {
00326 onImageSizeChange(gui->Lines(), gui->Columns());
00327 showBulk();
00328 }
00329 else
00330 {
00331 scr->clearSelection();
00332 }
00333 }
00334
00335
00336
00343 void TEmulation::onImageSizeChange(int lines, int columns)
00344 {
00345 if (!connected) return;
00346 screen[0]->resizeImage(lines,columns);
00347 screen[1]->resizeImage(lines,columns);
00348 showBulk();
00349 emit ImageSizeChanged(lines,columns);
00350 }
00351
00352 void TEmulation::onHistoryCursorChange(int cursor)
00353 {
00354 if (!connected) return;
00355 scr->setHistCursor(cursor);
00356 showBulk();
00357 }
00358
00359 void TEmulation::setColumns(int columns)
00360 {
00361
00362
00363 emit changeColumns(columns);
00364 }