00001
00002 #include "emulation_widget.h"
00003
00004
00005 #include <qscrollbar.h>
00006
00007 #define rimX 0 // left/right rim width
00008 #define rimY 0 // top/bottom rim high
00009
00010 static const ColorEntry color_table[TABLE_COLORS] =
00011 {
00012 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ),
00013 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ),
00014 ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ),
00015 ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ),
00016 ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ),
00017
00018 ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ),
00019 ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ),
00020 ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
00021 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ),
00022 ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 )
00023 };
00024
00025 EmulationWidget::EmulationWidget( const Profile& config, QWidget *parent, const char* name ) : WidgetLayer( config, parent, name )
00026 {
00027
00028
00029 QFontMetrics fm( font() );
00030 f_height = fm.height();
00031 f_width = fm.maxWidth();
00032 f_ascent = fm.ascent();
00033
00034
00035
00036 m_scrollbar = new QScrollBar( this );
00037 m_scrollbar->setCursor( arrowCursor );
00038
00039
00040 calcGeometry();
00041
00042
00043 reloadConfig( config );
00044
00045 m_resizing = false;
00046 }
00047
00048 void EmulationWidget::reloadConfig( const Profile& config )
00049 {
00050
00051
00052 }
00053
00054 EmulationWidget::~EmulationWidget()
00055 {
00056
00057 }
00058
00059 static QChar vt100extended(QChar c)
00060 {
00061 switch (c.unicode())
00062 {
00063 case 0x25c6 : return 1;
00064 case 0x2592 : return 2;
00065 case 0x2409 : return 3;
00066 case 0x240c : return 4;
00067 case 0x240d : return 5;
00068 case 0x240a : return 6;
00069 case 0x00b0 : return 7;
00070 case 0x00b1 : return 8;
00071 case 0x2424 : return 9;
00072 case 0x240b : return 10;
00073 case 0x2518 : return 11;
00074 case 0x2510 : return 12;
00075 case 0x250c : return 13;
00076 case 0x2514 : return 14;
00077 case 0x253c : return 15;
00078 case 0xf800 : return 16;
00079 case 0xf801 : return 17;
00080 case 0x2500 : return 18;
00081 case 0xf803 : return 19;
00082 case 0xf804 : return 20;
00083 case 0x251c : return 21;
00084 case 0x2524 : return 22;
00085 case 0x2534 : return 23;
00086 case 0x252c : return 24;
00087 case 0x2502 : return 25;
00088 case 0x2264 : return 26;
00089 case 0x2265 : return 27;
00090 case 0x03c0 : return 28;
00091 case 0x2260 : return 29;
00092 case 0x00a3 : return 30;
00093 case 0x00b7 : return 31;
00094 }
00095 return c;
00096 }
00097
00098
00099 QSize EmulationWidget::calcSize( int cols, int lins ) const
00100 {
00101 int frw = width() - contentsRect().width();
00102
00103 int frh = height() - contentsRect().height();
00104 int scw = (scrollLoc == SCRNONE? 0 : m_scrollbar->width() );
00105 return QSize( f_width * cols + 2 * rimX + frw + scw, f_height * lins + 2 * rimY + frh );
00106 }
00107
00108 void EmulationWidget::setImage( QArray<Character> const newimg, int lines, int columns )
00109 {
00110 const QPixmap* pm = backgroundPixmap();
00111 QPainter paint;
00112
00113
00114 setUpdatesEnabled( false );
00115
00116 paint.begin( this );
00117
00118 QPoint tL = contentsRect().topLeft();
00119 int tLx = tL.x();
00120 int tLy = tL.y();
00121
00122
00123 int cf = -1;
00124 int cb = -1;
00125 int cr = -1;
00126
00127 int lins = QMIN( m_lines, QMAX( 0, lines ) );
00128 int cols = QMIN( m_columns, QMAX( 0, columns ) );
00129 QArray<QChar> disstrU = QArray<QChar>( cols );
00130
00131 for ( int y = 0; y < lins; ++y )
00132 { int len;
00133 const Character* lcl = &m_image[y * m_columns];
00134 const Character* ext = &newimg[y * m_columns];
00135 if ( ! m_resizing )
00136 for ( int x = 0; x < cols; ++x )
00137 {
00138
00139
00140
00141 if ( ext[x] != lcl[x] )
00142 {
00143 cr = ext[x].r;
00144 cb = ext[x].b;
00145 if ( ext[x].f != cf ) cf = ext[x].f;
00146 int lln = cols - x;
00147 disstrU[0] = vt100extended( ext[x+0].c );
00148 for ( len = 1; len < lln; ++len )
00149 {
00150 if ( ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || ext[x+len] == lcl[x+len] )
00151 break;
00152 disstrU[len] = vt100extended( ext[x+len].c );
00153 }
00154 QString unistr( disstrU, len );
00155 drawAttrString( unistr, paint, QRect( m_blX+tLx+f_width*x, m_bY+tLy+f_height*y, f_width*len, f_height ), ext[x], pm != NULL, true );
00156 x += len -1;
00157 }
00158 }
00159
00160 memcpy( (void*) lcl, (const void*) ext, cols*sizeof( Character ) );
00161 }
00162 drawFrame( &paint );
00163 paint.end();
00164 setUpdatesEnabled( true );
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 delete [] disstrU;
00175 }
00176
00177
00178 void EmulationWidget::paintEvent( QPaintEvent* pe )
00179 {
00180 QPainter painter;
00181 const QPixmap* pm = backgroundPixmap();
00182
00183 painter.begin( this );
00184 painter.setBackgroundMode( TransparentMode );
00185
00186 QRect rect = pe->rect().intersect( contentsRect() );
00187 QPoint tL = contentsRect().topLeft();
00188 int tLx = tL.x();
00189 int tLy = tL.y();
00190
00191 int lux = QMIN(m_columns-1, QMAX(0,(rect.left() - tLx - m_blX ) / f_width));
00192 int luy = QMIN(m_lines-1, QMAX(0,(rect.top() - tLy - m_bY ) / f_height));
00193 int rlx = QMIN(m_columns-1, QMAX(0,(rect.right() - tLx - m_blX ) / f_width));
00194 int rly = QMIN(m_lines-1, QMAX(0,(rect.bottom() - tLy - m_bY ) / f_height));
00195
00196 QChar *disstrU = new QChar[m_columns];
00197 for (int y = luy; y <= rly; y++)
00198 for (int x = lux; x <= rlx; x++)
00199 {
00200 int len = 1;
00201 disstrU[0] = vt100extended(m_image[loc(x,y)].c);
00202 int cf = m_image[loc(x,y)].f;
00203 int cb = m_image[loc(x,y)].b;
00204 int cr = m_image[loc(x,y)].r;
00205 while (x+len <= rlx &&
00206 m_image[loc(x+len,y)].f == cf &&
00207 m_image[loc(x+len,y)].b == cb &&
00208 m_image[loc(x+len,y)].r == cr )
00209 {
00210 disstrU[len] = vt100extended(m_image[loc(x+len,y)].c);
00211 len += 1;
00212 }
00213 QString unistr(disstrU,len);
00214
00215 drawAttrString( unistr, painter, QRect( m_blX+tLx+f_width*x,m_bY+tLy+f_height*y,f_width*len,f_height ), m_image[loc(x ,y )], pm != 0l, false );
00216 x +=len -1;
00217 }
00218 delete [] disstrU;
00219 drawFrame( &painter );
00220 painter.end();
00221 }
00222
00223 void EmulationWidget::calcGeometry()
00224 {
00225 m_scrollbar->resize(QApplication::style().scrollBarExtent().width(), contentsRect().height() );
00226
00227 switch( scrollLoc )
00228 {
00229 case SCRNONE :
00230 m_columns = ( contentsRect().width() -2 * rimX ) / f_width;
00231 m_blX = ( contentsRect().width() - ( m_columns*f_width ) ) / 2;
00232 m_brX = m_blX;
00233 m_scrollbar->hide();
00234 break;
00235 case SCRLEFT :
00236 m_columns = ( contentsRect().width() - 2 * rimX - m_scrollbar->width() ) / f_width;
00237 m_brX = ( contentsRect().width() - ( m_columns*f_width ) - m_scrollbar->width() ) / 2;
00238 m_blX = m_brX + m_scrollbar->width();
00239 m_scrollbar->move( contentsRect().topLeft() );
00240 m_scrollbar->show();
00241 break;
00242 case SCRIGHT:
00243 m_columns = ( contentsRect().width() - 2 * rimX - m_scrollbar->width() ) / f_width;
00244 m_blX = ( contentsRect().width() - ( m_columns*f_width ) - m_scrollbar->width() ) / 2;
00245 m_brX = m_blX;
00246 m_scrollbar->move( contentsRect().topRight() - QPoint (m_scrollbar->width()-1,0 ) );
00247 m_scrollbar->show();
00248 break;
00249 }
00250
00251 m_lines = ( contentsRect().height() - 2 * rimY ) / f_height;
00252 m_bY = ( contentsRect().height() - (m_lines * f_height ) ) / 2;
00253 }
00254
00255 void EmulationWidget::drawAttrString( QString& string, QPainter &painter, QRect rect, Character attr, bool usePixmap, bool clear )
00256 {
00257 if ( usePixmap && color_table[attr.b].transparent )
00258 {
00259 painter.setBackgroundMode( TransparentMode );
00260 if ( clear )
00261 erase( rect );
00262 }
00263 else
00264 {
00265 if ( blinking )
00266 painter.fillRect( rect, color_table[attr.b].color );
00267 else
00268 {
00269 painter.setBackgroundMode( OpaqueMode );
00270 painter.setBackgroundColor( color_table[attr.b].color );
00271 }
00272 }
00273 if ( color_table[attr.f].bold )
00274 painter.setPen( QColor( 0x8F, 0x00, 0x00 ) );
00275 else
00276 painter.setPen( color_table[attr.f].color );
00277 painter.drawText( rect.x(), rect.y() + f_ascent, string );
00278
00279 }
00280
00281
00283
00284
00285
00286 void EmulationWidget::scroll( int value )
00287 {
00288 }
00289
00290 void EmulationWidget::setScroll( int cursor, int slines )
00291 {
00292 }
00293
00294
00295