Changeset View
Changeset View
Standalone View
Standalone View
src/TerminalDisplay.cpp
Show First 20 Lines • Show All 1074 Lines • ▼ Show 20 Line(s) | 1074 | if ((_readOnlyMessageWidget != nullptr) && _readOnlyMessageWidget->isVisible()) { | |||
---|---|---|---|---|---|
1075 | return; | 1075 | return; | ||
1076 | } | 1076 | } | ||
1077 | 1077 | | |||
1078 | // constrain the region to the display | 1078 | // constrain the region to the display | ||
1079 | // the bottom of the region is capped to the number of lines in the display's | 1079 | // the bottom of the region is capped to the number of lines in the display's | ||
1080 | // internal image - 2, so that the height of 'region' is strictly less | 1080 | // internal image - 2, so that the height of 'region' is strictly less | ||
1081 | // than the height of the internal image. | 1081 | // than the height of the internal image. | ||
1082 | QRect region = screenWindowRegion; | 1082 | QRect region = screenWindowRegion; | ||
1083 | region.setBottom(qMin(region.bottom(), this->_lines - 2)); | 1083 | region.setBottom(qMin(region.bottom(), _lines - 2)); | ||
1084 | 1084 | | |||
1085 | // return if there is nothing to do | 1085 | // return if there is nothing to do | ||
1086 | if (!region.isValid() | 1086 | if (!region.isValid() | ||
1087 | || (region.top() + abs(lines)) >= region.bottom() | 1087 | || (region.top() + abs(lines)) >= region.bottom() | ||
1088 | || this->_lines <= region.height()) { | 1088 | || _lines <= region.height()) { | ||
1089 | return; | 1089 | return; | ||
1090 | } | 1090 | } | ||
1091 | 1091 | | |||
1092 | // hide terminal size label to prevent it being scrolled | 1092 | // hide terminal size label to prevent it being scrolled | ||
1093 | if ((_resizeWidget != nullptr) && _resizeWidget->isVisible()) { | 1093 | if ((_resizeWidget != nullptr) && _resizeWidget->isVisible()) { | ||
1094 | _resizeWidget->hide(); | 1094 | _resizeWidget->hide(); | ||
1095 | } | 1095 | } | ||
1096 | 1096 | | |||
Show All 12 Lines | |||||
1109 | QRect scrollRect; | 1109 | QRect scrollRect; | ||
1110 | if (_scrollbarLocation == Enum::ScrollBarLeft) { | 1110 | if (_scrollbarLocation == Enum::ScrollBarLeft) { | ||
1111 | scrollRect.setLeft(scrollBarWidth + SCROLLBAR_CONTENT_GAP); | 1111 | scrollRect.setLeft(scrollBarWidth + SCROLLBAR_CONTENT_GAP); | ||
1112 | scrollRect.setRight(width()); | 1112 | scrollRect.setRight(width()); | ||
1113 | } else { | 1113 | } else { | ||
1114 | scrollRect.setLeft(0); | 1114 | scrollRect.setLeft(0); | ||
1115 | scrollRect.setRight(width() - scrollBarWidth - SCROLLBAR_CONTENT_GAP); | 1115 | scrollRect.setRight(width() - scrollBarWidth - SCROLLBAR_CONTENT_GAP); | ||
1116 | } | 1116 | } | ||
1117 | void* firstCharPos = &_image[ region.top() * this->_columns ]; | 1117 | void* firstCharPos = &_image[ region.top() * _columns ]; | ||
1118 | void* lastCharPos = &_image[(region.top() + abs(lines)) * this->_columns ]; | 1118 | void* lastCharPos = &_image[(region.top() + abs(lines)) * _columns ]; | ||
1119 | 1119 | | |||
1120 | const int top = _contentRect.top() + (region.top() * _fontHeight); | 1120 | const int top = _contentRect.top() + (region.top() * _fontHeight); | ||
1121 | const int linesToMove = region.height() - abs(lines); | 1121 | const int linesToMove = region.height() - abs(lines); | ||
1122 | const int bytesToMove = linesToMove * this->_columns * sizeof(Character); | 1122 | const int bytesToMove = linesToMove * _columns * sizeof(Character); | ||
1123 | 1123 | | |||
1124 | Q_ASSERT(linesToMove > 0); | 1124 | Q_ASSERT(linesToMove > 0); | ||
1125 | Q_ASSERT(bytesToMove > 0); | 1125 | Q_ASSERT(bytesToMove > 0); | ||
1126 | 1126 | | |||
1127 | //scroll internal image | 1127 | //scroll internal image | ||
1128 | if (lines > 0) { | 1128 | if (lines > 0) { | ||
1129 | // check that the memory areas that we are going to move are valid | 1129 | // check that the memory areas that we are going to move are valid | ||
1130 | Q_ASSERT((char*)lastCharPos + bytesToMove < | 1130 | Q_ASSERT((char*)lastCharPos + bytesToMove < | ||
1131 | (char*)(_image + (this->_lines * this->_columns))); | 1131 | (char*)(_image + (_lines * _columns))); | ||
1132 | 1132 | | |||
1133 | Q_ASSERT((lines * this->_columns) < _imageSize); | 1133 | Q_ASSERT((lines * _columns) < _imageSize); | ||
1134 | 1134 | | |||
1135 | //scroll internal image down | 1135 | //scroll internal image down | ||
1136 | memmove(firstCharPos , lastCharPos , bytesToMove); | 1136 | memmove(firstCharPos , lastCharPos , bytesToMove); | ||
1137 | 1137 | | |||
1138 | //set region of display to scroll | 1138 | //set region of display to scroll | ||
1139 | scrollRect.setTop(top); | 1139 | scrollRect.setTop(top); | ||
1140 | } else { | 1140 | } else { | ||
1141 | // check that the memory areas that we are going to move are valid | 1141 | // check that the memory areas that we are going to move are valid | ||
1142 | Q_ASSERT((char*)firstCharPos + bytesToMove < | 1142 | Q_ASSERT((char*)firstCharPos + bytesToMove < | ||
1143 | (char*)(_image + (this->_lines * this->_columns))); | 1143 | (char*)(_image + (_lines * _columns))); | ||
1144 | 1144 | | |||
1145 | //scroll internal image up | 1145 | //scroll internal image up | ||
1146 | memmove(lastCharPos , firstCharPos , bytesToMove); | 1146 | memmove(lastCharPos , firstCharPos , bytesToMove); | ||
1147 | 1147 | | |||
1148 | //set region of the display to scroll | 1148 | //set region of the display to scroll | ||
1149 | scrollRect.setTop(top + abs(lines) * _fontHeight); | 1149 | scrollRect.setTop(top + abs(lines) * _fontHeight); | ||
1150 | } | 1150 | } | ||
1151 | scrollRect.setHeight(linesToMove * _fontHeight); | 1151 | scrollRect.setHeight(linesToMove * _fontHeight); | ||
▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Line(s) | 1223 | { | |||
1242 | } | 1242 | } | ||
1243 | 1243 | | |||
1244 | Character* const newimg = _screenWindow->getImage(); | 1244 | Character* const newimg = _screenWindow->getImage(); | ||
1245 | const int lines = _screenWindow->windowLines(); | 1245 | const int lines = _screenWindow->windowLines(); | ||
1246 | const int columns = _screenWindow->windowColumns(); | 1246 | const int columns = _screenWindow->windowColumns(); | ||
1247 | 1247 | | |||
1248 | setScroll(_screenWindow->currentLine() , _screenWindow->lineCount()); | 1248 | setScroll(_screenWindow->currentLine() , _screenWindow->lineCount()); | ||
1249 | 1249 | | |||
1250 | Q_ASSERT(this->_usedLines <= this->_lines); | 1250 | Q_ASSERT(_usedLines <= _lines); | ||
1251 | Q_ASSERT(this->_usedColumns <= this->_columns); | 1251 | Q_ASSERT(_usedColumns <= _columns); | ||
1252 | 1252 | | |||
1253 | int y, x, len; | 1253 | int y, x, len; | ||
1254 | 1254 | | |||
1255 | const QPoint tL = contentsRect().topLeft(); | 1255 | const QPoint tL = contentsRect().topLeft(); | ||
1256 | const int tLx = tL.x(); | 1256 | const int tLx = tL.x(); | ||
1257 | const int tLy = tL.y(); | 1257 | const int tLy = tL.y(); | ||
1258 | _hasTextBlinker = false; | 1258 | _hasTextBlinker = false; | ||
1259 | 1259 | | |||
1260 | CharacterColor cf; // undefined | 1260 | CharacterColor cf; // undefined | ||
1261 | 1261 | | |||
1262 | const int linesToUpdate = qMin(this->_lines, qMax(0, lines)); | 1262 | const int linesToUpdate = qMin(_lines, qMax(0, lines)); | ||
1263 | const int columnsToUpdate = qMin(this->_columns, qMax(0, columns)); | 1263 | const int columnsToUpdate = qMin(_columns, qMax(0, columns)); | ||
1264 | 1264 | | |||
1265 | auto dirtyMask = new char[columnsToUpdate + 2]; | 1265 | auto dirtyMask = new char[columnsToUpdate + 2]; | ||
1266 | QRegion dirtyRegion; | 1266 | QRegion dirtyRegion; | ||
1267 | 1267 | | |||
1268 | // debugging variable, this records the number of lines that are found to | 1268 | // debugging variable, this records the number of lines that are found to | ||
1269 | // be 'dirty' ( ie. have changed from the old _image to the new _image ) and | 1269 | // be 'dirty' ( ie. have changed from the old _image to the new _image ) and | ||
1270 | // which therefore need to be repainted | 1270 | // which therefore need to be repainted | ||
1271 | int dirtyLineCount = 0; | 1271 | int dirtyLineCount = 0; | ||
1272 | 1272 | | |||
1273 | for (y = 0; y < linesToUpdate; ++y) { | 1273 | for (y = 0; y < linesToUpdate; ++y) { | ||
1274 | const Character* currentLine = &_image[y * this->_columns]; | 1274 | const Character* currentLine = &_image[y * _columns]; | ||
1275 | const Character* const newLine = &newimg[y * columns]; | 1275 | const Character* const newLine = &newimg[y * columns]; | ||
1276 | 1276 | | |||
1277 | bool updateLine = false; | 1277 | bool updateLine = false; | ||
1278 | 1278 | | |||
1279 | // The dirty mask indicates which characters need repainting. We also | 1279 | // The dirty mask indicates which characters need repainting. We also | ||
1280 | // mark surrounding neighbors dirty, in case the character exceeds | 1280 | // mark surrounding neighbors dirty, in case the character exceeds | ||
1281 | // its cell boundaries | 1281 | // its cell boundaries | ||
1282 | memset(dirtyMask, 0, columnsToUpdate + 2); | 1282 | memset(dirtyMask, 0, columnsToUpdate + 2); | ||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Line(s) | |||||
1369 | memcpy((void*)currentLine, (const void*)newLine, columnsToUpdate * sizeof(Character)); | 1369 | memcpy((void*)currentLine, (const void*)newLine, columnsToUpdate * sizeof(Character)); | ||
1370 | } | 1370 | } | ||
1371 | 1371 | | |||
1372 | // if the new _image is smaller than the previous _image, then ensure that the area | 1372 | // if the new _image is smaller than the previous _image, then ensure that the area | ||
1373 | // outside the new _image is cleared | 1373 | // outside the new _image is cleared | ||
1374 | if (linesToUpdate < _usedLines) { | 1374 | if (linesToUpdate < _usedLines) { | ||
1375 | dirtyRegion |= QRect(_contentRect.left() + tLx , | 1375 | dirtyRegion |= QRect(_contentRect.left() + tLx , | ||
1376 | _contentRect.top() + tLy + _fontHeight * linesToUpdate , | 1376 | _contentRect.top() + tLy + _fontHeight * linesToUpdate , | ||
1377 | _fontWidth * this->_columns , | 1377 | _fontWidth * _columns , | ||
1378 | _fontHeight * (_usedLines - linesToUpdate)); | 1378 | _fontHeight * (_usedLines - linesToUpdate)); | ||
1379 | } | 1379 | } | ||
1380 | _usedLines = linesToUpdate; | 1380 | _usedLines = linesToUpdate; | ||
1381 | 1381 | | |||
1382 | if (columnsToUpdate < _usedColumns) { | 1382 | if (columnsToUpdate < _usedColumns) { | ||
1383 | dirtyRegion |= QRect(_contentRect.left() + tLx + columnsToUpdate * _fontWidth , | 1383 | dirtyRegion |= QRect(_contentRect.left() + tLx + columnsToUpdate * _fontWidth , | ||
1384 | _contentRect.top() + tLy , | 1384 | _contentRect.top() + tLy , | ||
1385 | _fontWidth * (_usedColumns - columnsToUpdate) , | 1385 | _fontWidth * (_usedColumns - columnsToUpdate) , | ||
1386 | _fontHeight * this->_lines); | 1386 | _fontHeight * _lines); | ||
1387 | } | 1387 | } | ||
1388 | _usedColumns = columnsToUpdate; | 1388 | _usedColumns = columnsToUpdate; | ||
1389 | 1389 | | |||
1390 | dirtyRegion |= _inputMethodData.previousPreeditRect; | 1390 | dirtyRegion |= _inputMethodData.previousPreeditRect; | ||
1391 | 1391 | | |||
1392 | // update the parts of the display which have changed | 1392 | // update the parts of the display which have changed | ||
1393 | update(dirtyRegion); | 1393 | update(dirtyRegion); | ||
1394 | 1394 | | |||
▲ Show 20 Lines • Show All 2540 Lines • Show Last 20 Lines |