summaryrefslogtreecommitdiff
path: root/core/apps/embeddedkonsole/TEScreen.cpp
Unidiff
Diffstat (limited to 'core/apps/embeddedkonsole/TEScreen.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/TEScreen.cpp415
1 files changed, 248 insertions, 167 deletions
diff --git a/core/apps/embeddedkonsole/TEScreen.cpp b/core/apps/embeddedkonsole/TEScreen.cpp
index a3d115d..50807d3 100644
--- a/core/apps/embeddedkonsole/TEScreen.cpp
+++ b/core/apps/embeddedkonsole/TEScreen.cpp
@@ -9,12 +9,13 @@
9/* This file is part of Konsole - an X terminal for KDE */ 9/* This file is part of Konsole - an X terminal for KDE */
10/* */ 10/* */
11/* -------------------------------------------------------------------------- */ 11/* -------------------------------------------------------------------------- */
12 /* */ 12/* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Konsole to Qt/Embedded */
14 /* */ 14/* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */ 16/* */
17/* -------------------------------------------------------------------------- */ 17/* -------------------------------------------------------------------------- */
18// enhancements added by L.J. Potter <ljp@llornkcor.com>
18 19
19/*! \file 20/*! \file
20*/ 21*/
@@ -50,6 +51,7 @@
50#include <string.h> 51#include <string.h>
51#include <ctype.h> 52#include <ctype.h>
52 53
54#include <qpe/config.h>
53#include "TEScreen.h" 55#include "TEScreen.h"
54 56
55#define HERE printf("%s(%d): here\n",__FILE__,__LINE__) 57#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
@@ -58,7 +60,7 @@
58//FIXME: see if we can get this from terminfo. 60//FIXME: see if we can get this from terminfo.
59#define BS_CLEARS FALSE 61#define BS_CLEARS FALSE
60 62
61#define loc(X,Y) ((Y)*columns+(X)) 63#define loc(X,Y) ((Y) * columns + (X))
62 64
63/*! creates a `TEScreen' of `lines' lines and `columns' columns. 65/*! creates a `TEScreen' of `lines' lines and `columns' columns.
64*/ 66*/
@@ -67,11 +69,13 @@ TEScreen::TEScreen(int lines, int columns)
67{ 69{
68 this->lines = lines; 70 this->lines = lines;
69 this->columns = columns; 71 this->columns = columns;
70 72// qDebug("Columns %d", columns);
73
71 image = (ca*) malloc(lines*columns*sizeof(ca)); 74 image = (ca*) malloc(lines*columns*sizeof(ca));
72 tabstops = NULL; initTabStops(); 75 tabstops = NULL; initTabStops();
73 76
74 histCursor = 0; 77 histCursor = 0;
78 horzCursor = 0;
75 79
76 clearSelection(); 80 clearSelection();
77 reset(); 81 reset();
@@ -383,53 +387,49 @@ void TEScreen::restoreCursor()
383 387
384void TEScreen::resizeImage(int new_lines, int new_columns) 388void TEScreen::resizeImage(int new_lines, int new_columns)
385{ 389{
386 390 if (cuY > new_lines-1) {
387 if (cuY > new_lines-1) 391// attempt to preserve focus and lines
388 { // attempt to preserve focus and lines 392 bmargin = lines-1; //FIXME: margin lost
389 bmargin = lines-1; //FIXME: margin lost 393 for (int i = 0; i < cuY-(new_lines-1); i++) {
390 for (int i = 0; i < cuY-(new_lines-1); i++) 394 addHistLine(); scrollUp(horzCursor,1);
391 { 395 }
392 addHistLine(); scrollUp(0,1);
393 } 396 }
394 }
395 397
396 // make new image 398 // make new image
397 ca* newimg = (ca*)malloc(new_lines*new_columns*sizeof(ca)); 399 ca* newimg = (ca*)malloc( new_lines * new_columns * sizeof( ca));
398 400
399 clearSelection(); 401 clearSelection();
400
401 // clear new image
402 for (int y = 0; y < new_lines; y++)
403 for (int x = 0; x < new_columns; x++)
404 {
405 newimg[y*new_columns+x].c = ' ';
406 newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR;
407 newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR;
408 newimg[y*new_columns+x].r = DEFAULT_RENDITION;
409 }
410 int cpy_lines = QMIN(new_lines, lines);
411 int cpy_columns = QMIN(new_columns,columns);
412 // copy to new image
413 for (int y = 0; y < cpy_lines; y++)
414 for (int x = 0; x < cpy_columns; x++)
415 {
416 newimg[y*new_columns+x].c = image[loc(x,y)].c;
417 newimg[y*new_columns+x].f = image[loc(x,y)].f;
418 newimg[y*new_columns+x].b = image[loc(x,y)].b;
419 newimg[y*new_columns+x].r = image[loc(x,y)].r;
420 }
421 free(image);
422 image = newimg;
423 lines = new_lines;
424 columns = new_columns;
425 cuX = QMIN(cuX,columns-1);
426 cuY = QMIN(cuY,lines-1);
427 402
428 // FIXME: try to keep values, evtl. 403 // clear new image
429 tmargin=0; 404 for (int y = 0; y < new_lines; y++)
430 bmargin=lines-1; 405 for (int x = 0; x < new_columns; x++) {
431 initTabStops(); 406 newimg[y*new_columns+x].c = ' ';
432 clearSelection(); 407 newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR;
408 newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR;
409 newimg[y*new_columns+x].r = DEFAULT_RENDITION;
410 }
411 int cpy_lines = QMIN(new_lines, lines);
412 int cpy_columns = QMIN(new_columns,columns);
413 // copy to new image
414 for (int y = 0; y < cpy_lines; y++)
415 for (int x = 0; x < cpy_columns; x++) {
416 newimg[y*new_columns+x].c = image[loc(x,y)].c;
417 newimg[y*new_columns+x].f = image[loc(x,y)].f;
418 newimg[y*new_columns+x].b = image[loc(x,y)].b;
419 newimg[y*new_columns+x].r = image[loc(x,y)].r;
420 }
421 free(image);
422 image = newimg;
423 lines = new_lines;
424 columns = new_columns;
425 cuX = QMIN(cuX,columns-1);
426 cuY = QMIN(cuY,lines-1);
427
428 // FIXME: try to keep values, evtl.
429 tmargin=0;
430 bmargin=lines-1;
431 initTabStops();
432 clearSelection();
433} 433}
434 434
435/* 435/*
@@ -505,7 +505,8 @@ void TEScreen::effectiveRendition()
505*/ 505*/
506 506
507ca* TEScreen::getCookedImage() 507ca* TEScreen::getCookedImage()
508{ int x,y; 508{
509 int x,y;
509 ca* merged = (ca*)malloc(lines*columns*sizeof(ca)); 510 ca* merged = (ca*)malloc(lines*columns*sizeof(ca));
510 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION); 511 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
511 512
@@ -548,6 +549,65 @@ ca* TEScreen::getCookedImage()
548 if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible 549 if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible
549 reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]); 550 reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]);
550 return merged; 551 return merged;
552
553 /*
554 int x, y, z;
555
556 ca* merged = (ca*)malloc( lines * columns * sizeof( ca));
557
558 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
559
560// qDebug("hist lines %d, historyCursor %d, minus %d ,lines %d, columns %d",
561// hist.getLines(), histCursor, hist.getLines() - histCursor , lines, columns);
562 for (y = 0; (y < lines) && (y < ( hist.getLines() - histCursor )); y++) {
563
564 int len = QMIN( columns, hist.getLineLen( y + histCursor) );
565 int yp = y * columns;
566 int yq = ( y + histCursor) * columns;
567// qDebug("horzCursor %d, columns %d, len %d", horzCursor, columns, len);
568// qDebug("lineno %d, colno %d, count %d\n", y + histCursor, (horzCursor / 2), len );
569 qDebug("Y %d", y);
570 hist.getCells( y + histCursor, (horzCursor / 2), len, merged + yp);
571
572 for (x = len; x < columns; x++)
573 merged[yp + x] = dft;
574 for (x = 0; x < columns; x++) {
575 int p = x + yp; int q = x + yq;
576 if ( ( q >= sel_TL ) && ( q <= sel_BR ) )
577 reverseRendition(&merged[p]); // for selection
578 }
579 }
580
581 if (lines >= hist.getLines() - histCursor) {
582 for (y = ( hist.getLines() - histCursor); y < lines ; y++) {
583 int z = horzCursor;
584 int yp = y * columns;
585 int yq = ( y + histCursor) * columns;
586 int yr = ( y - hist.getLines() + histCursor) * columns;
587// qDebug("y %d, yp %d, yq %d, columns %d, z cursor %d", y, yp, yq, columns, z);
588 for (x = 0; x < columns; x++) {
589 int p = x + yp; int q = x + yq; int r = (x + (horzCursor/2) ) + yr;
590 merged[p] = image[r];
591 if ( q >= sel_TL && q <= sel_BR )
592 reverseRendition( &merged[p]); // for selection
593 }
594 }
595 }
596
597
598// evtl. inverse display
599 if (getMode(MODE_Screen))
600 { int i, n = lines * columns;
601 for (i = 0; i < n; i++)
602 reverseRendition( &merged[i]); // for reverse display
603 }
604 if (getMode(MODE_Cursor) && ( cuY + ( hist.getLines() - histCursor) < lines)) // cursor visible
605
606 reverseRendition( &merged[ loc( cuX, cuY + ( hist.getLines() - histCursor))] );
607
608 return merged;
609 */
610
551} 611}
552 612
553 613
@@ -556,7 +616,12 @@ ca* TEScreen::getCookedImage()
556 616
557void TEScreen::reset() 617void TEScreen::reset()
558{ 618{
619 Config cfg("Konsole");
620 cfg.setGroup("ScrollBar");
621 if( !cfg.readBoolEntry("HorzScroll",0) )
559 setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin 622 setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin
623
624
560 resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1] 625 resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1]
561 resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke 626 resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke
562 setMode(MODE_Cursor); // cursor visible 627 setMode(MODE_Cursor); // cursor visible
@@ -658,12 +723,13 @@ void TEScreen::ShowCharacter(unsigned short c)
658 723
659 if (cuX >= columns) 724 if (cuX >= columns)
660 { 725 {
661 if (getMode(MODE_Wrap)) NextLine(); else cuX = columns-1; 726 if (getMode(MODE_Wrap)) NextLine(); else cuX = columns - 1;
727 // comment out for no wrap
662 } 728 }
663 729
664 if (getMode(MODE_Insert)) insertChars(1); 730 if (getMode(MODE_Insert)) insertChars(1);
665 731
666 int i = loc(cuX,cuY); 732 int i = loc( cuX, cuY);
667 733
668 checkSelection(i, i); // check if selection is still valid. 734 checkSelection(i, i); // check if selection is still valid.
669 735
@@ -685,10 +751,11 @@ void TEScreen::ShowCharacter(unsigned short c)
685 751
686void TEScreen::scrollUp(int from, int n) 752void TEScreen::scrollUp(int from, int n)
687{ 753{
688 if (n <= 0 || from + n > bmargin) return; 754 if (n <= 0 || from + n > bmargin) return;
689 //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds. 755 //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
690 moveImage(loc(0,from),loc(0,from+n),loc(columns-1,bmargin)); 756
691 clearImage(loc(0,bmargin-n+1),loc(columns-1,bmargin),' '); 757 moveImage( loc( 0, from), loc( 0, from + n), loc( columns - 1, bmargin));
758 clearImage( loc( 0, bmargin - n + 1), loc( columns - 1, bmargin), ' ');
692} 759}
693 760
694/*! scroll down `n' lines within current region. 761/*! scroll down `n' lines within current region.
@@ -698,14 +765,18 @@ void TEScreen::scrollUp(int from, int n)
698 765
699void TEScreen::scrollDown(int from, int n) 766void TEScreen::scrollDown(int from, int n)
700{ 767{
768
701//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds. 769//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
702 if (n <= 0) return; 770 if (n <= 0) return;
703 if (from > bmargin) return; 771 if (from > bmargin) return;
704 if (from + n > bmargin) n = bmargin - from; 772 if (from + n > bmargin) n = bmargin - from;
705 moveImage(loc(0,from+n),loc(0,from),loc(columns-1,bmargin-n)); 773
774 moveImage( loc(0,from+n), loc(0,from), loc(columns-1,bmargin-n));
706 clearImage(loc(0,from),loc(columns-1,from+n-1),' '); 775 clearImage(loc(0,from),loc(columns-1,from+n-1),' ');
707} 776}
708 777
778
779
709/*! position the cursor to a specific line and column. */ 780/*! position the cursor to a specific line and column. */
710void TEScreen::setCursorYX(int y, int x) 781void TEScreen::setCursorYX(int y, int x)
711{ 782{
@@ -871,7 +942,7 @@ void TEScreen::clearToBeginOfLine()
871 942
872void TEScreen::clearEntireLine() 943void TEScreen::clearEntireLine()
873{ 944{
874 clearImage(loc(0,cuY),loc(columns-1,cuY),' '); 945 clearImage( loc( 0, cuY),loc( columns - 1, cuY),' ');
875} 946}
876 947
877// Rendition ------------------------------------------------------------------ 948// Rendition ------------------------------------------------------------------
@@ -988,17 +1059,17 @@ QString TEScreen::getSelText(const BOOL preserve_line_breaks)
988 if (sel_begin == -1) 1059 if (sel_begin == -1)
989 return QString::null; // Selection got clear while selecting. 1060 return QString::null; // Selection got clear while selecting.
990 1061
991 int *m; // buffer to fill. 1062 int *m; // buffer to fill.
992 int s, d; // source index, dest. index. 1063 int s, d; // source index, dest. index.
993 int hist_BR = loc(0, hist.getLines()); 1064 int hist_BR = loc(0, hist.getLines());
994 int hY = sel_TL / columns; 1065 int hY = sel_TL / columns;
995 int hX = sel_TL % columns; 1066 int hX = sel_TL % columns;
996 int eol; // end of line 1067 int eol; // end of line
997 1068
998 s = sel_TL; // tracks copy in source. 1069 s = sel_TL; // tracks copy in source.
999 1070
1000 // allocate buffer for maximum 1071 // allocate buffer for maximum
1001 // possible size... 1072 // possible size...
1002 d = (sel_BR - sel_TL) / columns + 1; 1073 d = (sel_BR - sel_TL) / columns + 1;
1003 m = new int[d * (columns + 1) + 2]; 1074 m = new int[d * (columns + 1) + 2];
1004 d = 0; 1075 d = 0;
@@ -1006,103 +1077,103 @@ QString TEScreen::getSelText(const BOOL preserve_line_breaks)
1006 while (s <= sel_BR) 1077 while (s <= sel_BR)
1007 { 1078 {
1008 if (s < hist_BR) 1079 if (s < hist_BR)
1009 { // get lines from hist.history 1080 { // get lines from hist.history
1010 // buffer. 1081 // buffer.
1011 eol = hist.getLineLen(hY); 1082 eol = hist.getLineLen(hY);
1012 1083
1013 if ((hY == (sel_BR / columns)) && 1084 if ((hY == (sel_BR / columns)) &&
1014 (eol >= (sel_BR % columns))) 1085 (eol >= (sel_BR % columns)))
1015 { 1086 {
1016 eol = sel_BR % columns + 1; 1087 eol = sel_BR % columns + 1;
1017 } 1088 }
1018 1089
1019 while (hX < eol) 1090 while (hX < eol)
1020 { 1091 {
1021 m[d++] = hist.getCell(hY, hX++).c; 1092 m[d++] = hist.getCell(hY, hX++).c;
1022 s++; 1093 s++;
1023 } 1094 }
1024 1095
1025 if (s <= sel_BR) 1096 if (s <= sel_BR)
1026 { 1097 {
1027 // The line break handling 1098 // The line break handling
1028 // It's different from the screen 1099 // It's different from the screen
1029 // image case! 1100 // image case!
1030 if (eol % columns == 0) 1101 if (eol % columns == 0)
1031 { 1102 {
1032 // That's either a completely filled 1103 // That's either a completely filled
1033 // line or an empty line 1104 // line or an empty line
1034 if (eol == 0) 1105 if (eol == 0)
1035 { 1106 {
1036 m[d++] = '\n'; 1107 m[d++] = '\n';
1037 } 1108 }
1038 else 1109 else
1039 { 1110 {
1040 // We have a full line. 1111 // We have a full line.
1041 // FIXME: How can we handle newlines 1112 // FIXME: How can we handle newlines
1042 // at this position?! 1113 // at this position?!
1043 } 1114 }
1044 } 1115 }
1045 else if ((eol + 1) % columns == 0) 1116 else if ((eol + 1) % columns == 0)
1046 { 1117 {
1047 // FIXME: We don't know if this was a 1118 // FIXME: We don't know if this was a
1048 // space at the last position or a 1119 // space at the last position or a
1049 // short line!! 1120 // short line!!
1050 m[d++] = ' '; 1121 m[d++] = ' ';
1051 } 1122 }
1052 else 1123 else
1053 { 1124 {
1054 // We have a short line here. Put a 1125 // We have a short line here. Put a
1055 // newline or a space into the 1126 // newline or a space into the
1056 // buffer. 1127 // buffer.
1057 m[d++] = preserve_line_breaks ? '\n' : ' '; 1128 m[d++] = preserve_line_breaks ? '\n' : ' ';
1058 } 1129 }
1059 } 1130 }
1060 1131
1061 hY++; 1132 hY++;
1062 hX = 0; 1133 hX = 0;
1063 s = hY * columns; 1134 s = hY * columns;
1064 } 1135 }
1065 else 1136 else
1066 { // or from screen image. 1137 { // or from screen image.
1067 eol = (s / columns + 1) * columns - 1; 1138 eol = (s / columns + 1) * columns - 1;
1068 1139
1069 if (eol < sel_BR) 1140 if (eol < sel_BR)
1070 { 1141 {
1071 while ((eol > s) && 1142 while ((eol > s) &&
1072 isspace(image[eol - hist_BR].c)) 1143 isspace(image[eol - hist_BR].c))
1073 { 1144 {
1074 eol--; 1145 eol--;
1075 } 1146 }
1076 } 1147 }
1077 else 1148 else
1078 { 1149 {
1079 eol = sel_BR; 1150 eol = sel_BR;
1080 } 1151 }
1081 1152
1082 while (s <= eol) 1153 while (s <= eol)
1083 { 1154 {
1084 m[d++] = image[s++ - hist_BR].c; 1155 m[d++] = image[s++ - hist_BR].c;
1085 } 1156 }
1086 1157
1087 if (eol < sel_BR) 1158 if (eol < sel_BR)
1088 { 1159 {
1089 // eol processing see below ... 1160 // eol processing see below ...
1090 if ((eol + 1) % columns == 0) 1161 if ((eol + 1) % columns == 0)
1091 { 1162 {
1092 if (image[eol - hist_BR].c == ' ') 1163 if (image[eol - hist_BR].c == ' ')
1093 { 1164 {
1094 m[d++] = ' '; 1165 m[d++] = ' ';
1095 } 1166 }
1096 } 1167 }
1097 else 1168 else
1098 { 1169 {
1099 m[d++] = ((preserve_line_breaks || 1170 m[d++] = ((preserve_line_breaks ||
1100 ((eol % columns) == 0)) ? 1171 ((eol % columns) == 0)) ?
1101 '\n' : ' '); 1172 '\n' : ' ');
1102 } 1173 }
1103 } 1174 }
1104 1175
1105 s = (eol / columns + 1) * columns; 1176 s = (eol / columns + 1) * columns;
1106 } 1177 }
1107 } 1178 }
1108 1179
@@ -1129,8 +1200,8 @@ cases:
1129 are preserved. 1200 are preserved.
1130 1201
1131FIXME: 1202FIXME:
1132 * this suppresses \n for command output that is 1203 * this suppresses \n for command output that is
1133 sized to the exact column width of the screen. 1204 sized to the exact column width of the screen.
1134 1205
11352) eol%columns == 0 --> blank line. 12062) eol%columns == 0 --> blank line.
1136 insert a \n unconditionally. 1207 insert a \n unconditionally.
@@ -1138,7 +1209,7 @@ FIXME:
1138 or because it's an ASCII paragraph delimiter, so even when 1209 or because it's an ASCII paragraph delimiter, so even when
1139 not preserving line_breaks, you want to preserve paragraph breaks. 1210 not preserving line_breaks, you want to preserve paragraph breaks.
1140 1211
1141 3) else --> partially filled line 12123) else --> partially filled line
1142 insert a \n in preserve line break mode, else a space 1213 insert a \n in preserve line break mode, else a space
1143 The space prevents concatenation of the last word of one 1214 The space prevents concatenation of the last word of one
1144 line with the first of the next. 1215 line with the first of the next.
@@ -1152,18 +1223,18 @@ void TEScreen::addHistLine()
1152 // add to hist buffer 1223 // add to hist buffer
1153 // we have to take care about scrolling, too... 1224 // we have to take care about scrolling, too...
1154 1225
1155 if (hasScroll()) 1226 if (hasScroll()){
1156 { ca dft; 1227 ca dft;
1157 1228
1158 int end = columns-1; 1229 int end = columns - 1;
1159 while (end >= 0 && image[end] == dft) 1230 while (end >= 0 && image[end] == dft)
1160 end -= 1; 1231 end -= 1;
1161 1232
1162 hist.addCells(image,end+1); 1233 hist.addCells( image, end + 1);
1163 hist.addLine(); 1234 hist.addLine();
1164 1235
1165 // adjust history cursor 1236 // adjust history cursor
1166 histCursor += (hist.getLines()-1 == histCursor); 1237 histCursor += ( hist.getLines() - 1 == histCursor);
1167 } 1238 }
1168 1239
1169 if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround 1240 if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround
@@ -1174,11 +1245,21 @@ void TEScreen::setHistCursor(int cursor)
1174 histCursor = cursor; //FIXME:rangecheck 1245 histCursor = cursor; //FIXME:rangecheck
1175} 1246}
1176 1247
1248void TEScreen::setHorzCursor(int cursor)
1249{
1250 horzCursor = cursor;
1251}
1252
1177int TEScreen::getHistCursor() 1253int TEScreen::getHistCursor()
1178{ 1254{
1179 return histCursor; 1255 return histCursor;
1180} 1256}
1181 1257
1258int TEScreen::getHorzCursor()
1259{
1260 return horzCursor;
1261}
1262
1182int TEScreen::getHistLines() 1263int TEScreen::getHistLines()
1183{ 1264{
1184 return hist.getLines(); 1265 return hist.getLines();