aboutsummaryrefslogtreecommitdiff
path: root/desktop-utilities
diff options
context:
space:
mode:
authorKen Moore <moorekou@gmail.com>2016-04-11 16:28:13 -0400
committerKen Moore <moorekou@gmail.com>2016-04-11 16:28:13 -0400
commite36db04274e700c154e26e7c459c36329afb2c42 (patch)
treefc8eff3481acd4f7bd0ffabf16fd0231e767af57 /desktop-utilities
parentEnsure that the current audio volume gets saved to the local file on session ... (diff)
downloadlumina-e36db04274e700c154e26e7c459c36329afb2c42.tar.gz
lumina-e36db04274e700c154e26e7c459c36329afb2c42.tar.bz2
lumina-e36db04274e700c154e26e7c459c36329afb2c42.zip
Get more of the terminal working. Now all the special xterm stuff is getting trimmed out.
Diffstat (limited to 'desktop-utilities')
-rw-r--r--desktop-utilities/lumina-terminal/TermWindow.cpp18
-rw-r--r--desktop-utilities/lumina-terminal/TermWindow.h4
-rw-r--r--desktop-utilities/lumina-terminal/TerminalWidget.cpp87
-rw-r--r--desktop-utilities/lumina-terminal/TerminalWidget.h1
-rw-r--r--desktop-utilities/lumina-terminal/TrayIcon.cpp2
-rw-r--r--desktop-utilities/lumina-terminal/TtyProcess.cpp21
6 files changed, 105 insertions, 28 deletions
diff --git a/desktop-utilities/lumina-terminal/TermWindow.cpp b/desktop-utilities/lumina-terminal/TermWindow.cpp
index 4fc7fab5..6dfab80a 100644
--- a/desktop-utilities/lumina-terminal/TermWindow.cpp
+++ b/desktop-utilities/lumina-terminal/TermWindow.cpp
@@ -17,8 +17,9 @@
// ===============
// PUBLIC
// ===============
-TermWindow::TermWindow() : QWidget(0, Qt::Window | Qt::BypassWindowManagerHint){//, ui(new Ui::TermWindow){
+TermWindow::TermWindow(QSettings *set) : QWidget(0, Qt::Window | Qt::BypassWindowManagerHint){//, ui(new Ui::TermWindow){
CLOSING = false; //internal flag
+ settings = set;
//Create the Window
this->setLayout(new QVBoxLayout());
this->setCursor(Qt::SplitVCursor);
@@ -49,6 +50,13 @@ TermWindow::TermWindow() : QWidget(0, Qt::Window | Qt::BypassWindowManagerHint){
//Now set the defaults
screennum = 0; //default value
setTopOfScreen(true); //default value
+ if(settings->contains("lastSize")){
+ //qDebug() << "Re-use last size:" << settings->value("lastSize").toSize();
+ this->resize( settings->value("lastSize").toSize() );
+ CalculateGeom();
+ //qDebug() << "After size:" << this->size();
+ }
+
//this->resize(this->width(),300);
//this->setMinimumSize(20, 300);
@@ -96,11 +104,12 @@ void TermWindow::setTopOfScreen(bool ontop){
// PUBLIC SLOTS
// =======================
void TermWindow::ShowWindow(){
+ if(animRunning>=0){ return; } //something running
+ animRunning = 1;
this->hide();
QApplication::processEvents();
CalculateGeom();
//Now setup the animation
- animRunning = 1;
ANIM->setEndValue(this->geometry());
if(onTop){ //use top edge
ANIM->setStartValue( QRect(this->x(), this->y(), this->width(), 0) ); //same location - no height
@@ -108,10 +117,12 @@ void TermWindow::ShowWindow(){
ANIM->setStartValue( QRect(this->x(), this->geometry().bottom(), this->width(), 0) ); //same location - no height
}
this->show();
+ qDebug() << "Start Animation" << ANIM->startValue() << ANIM->endValue();
ANIM->start();
}
void TermWindow::HideWindow(){
+ if(animRunning>=0){ return; } //something running
//Now setup the animation
//Note: Do *not* use the private settings/variables because it may be changing right now - use the current geometry *ONLY*
animRunning = 0;
@@ -128,6 +139,7 @@ void TermWindow::HideWindow(){
}
void TermWindow::CloseWindow(){
+ if(animRunning>=0){ return; } //something running
//Now setup the animation
animRunning = 2;
ANIM->setStartValue(this->geometry());
@@ -153,6 +165,7 @@ void TermWindow::ReShowWindow(){
// PRIVATE
// =======================
void TermWindow::CalculateGeom(){
+ //qDebug() << "Calculating Geom:" << this->size();
QDesktopWidget *desk = QApplication::desktop();
if(desk->screenCount() <= screennum){ screennum = desk->primaryScreen(); } //invalid screen detected
//Now align the window with the proper screen edge
@@ -253,4 +266,5 @@ void TermWindow::mouseMoveEvent(QMouseEvent *ev){
geom.setTop(ev->globalPos().y());
this->setGeometry(geom);
}
+ settings->setValue("lastSize",this->geometry().size());
} \ No newline at end of file
diff --git a/desktop-utilities/lumina-terminal/TermWindow.h b/desktop-utilities/lumina-terminal/TermWindow.h
index ae40928f..135da0ef 100644
--- a/desktop-utilities/lumina-terminal/TermWindow.h
+++ b/desktop-utilities/lumina-terminal/TermWindow.h
@@ -13,11 +13,12 @@
#include <QDir>
#include <QShortcut>
#include <QMouseEvent>
+#include <QSettings>
class TermWindow : public QWidget{
Q_OBJECT
public:
- TermWindow();
+ TermWindow(QSettings *set);
~TermWindow();
void cleanup(); //called right before the window is closed
@@ -34,6 +35,7 @@ public slots:
private:
QTabWidget *tabWidget;
+ QSettings *settings;
QShortcut *hideS, *closeS, *newTabS, *closeTabS;
int screennum;
bool onTop, CLOSING;
diff --git a/desktop-utilities/lumina-terminal/TerminalWidget.cpp b/desktop-utilities/lumina-terminal/TerminalWidget.cpp
index b16dd6ba..9023b222 100644
--- a/desktop-utilities/lumina-terminal/TerminalWidget.cpp
+++ b/desktop-utilities/lumina-terminal/TerminalWidget.cpp
@@ -10,14 +10,24 @@
#include <QDebug>
#include <QApplication>
#include <QScrollBar>
+#include <QTextBlock>
+
+//Special control code ending symbols (aside from letters)
+//QByteArray CC_END_SYMBOLS("@");
TerminalWidget::TerminalWidget(QWidget *parent, QString dir) : QTextEdit(parent){
//Setup the text widget
this->setLineWrapMode(QTextEdit::WidgetWidth);
+ this->setAcceptRichText(false);
+ //this->setOverwriteMode(true);
//this->setStyleSheet("");
DEFFMT = this->textCursor().charFormat(); //save the default structure for later
CFMT = this->textCursor().charFormat(); //current format
-
+ QFontDatabase FDB;
+ QStringList fonts = FDB.families(QFontDatabase::Latin);
+ for(int i=0; i<fonts.length(); i++){
+ if(FDB.isFixedPitch(fonts[i])){ this->setFont(QFont(fonts[i])); qDebug() << "Using Font:" << fonts[i]; break; }
+ }
//Create/open the TTY port
PROC = new TTYProcess(this);
qDebug() << "Open new TTY";
@@ -43,34 +53,56 @@ void TerminalWidget::aboutToClose(){
// ==================
// PRIVATE
// ==================
+void TerminalWidget::InsertText(QString txt){
+ //qDebug() << "Insert Text:" << txt << "Cursor Pos:" << this->textCursor().position() << "Column:" << this->textCursor().columnNumber();
+ QTextCursor cur(this->textCursor());
+ cur.setCharFormat(CFMT);
+ cur.insertText( txt, CFMT);
+ this->textCursor().swap(cur);
+}
+
void TerminalWidget::applyData(QByteArray data){
//Iterate through the data and apply it when possible
+ QByteArray chars;
+ qDebug() << "Data:" << data;
for(int i=0; i<data.size(); i++){
if( data.at(i)=='\b' ){
+ //Flush current text buffer to widget
+ if(!chars.isEmpty()){
+ chars.chop(1);
+ //InsertText(chars); chars.clear();
+ }else{
+ this->textCursor().deletePreviousChar();
+ }
//Simple cursor backward 1 (NOT backspace in this context!!)
- this->moveCursor(QTextCursor::Left, QTextCursor::MoveAnchor);
+ //this->moveCursor(QTextCursor::Left, QTextCursor::MoveAnchor);
}else if( data.at(i)=='\x1B' ){
+ //Flush current text buffer to widget
+ if(!chars.isEmpty()){ InsertText(chars); chars.clear(); }
//ANSI Control Code start
//Look for the end of the code
int end = -1;
for(int j=1; j<(data.size()-i) && end<0; j++){
- if(QChar(data.at(i+j)).isLetter()){ end = j; }
+ if(QChar(data.at(i+j)).isLetter() || data.at(i+j)=='@' ){ end = j; }
}
if(end<0){ return; } //skip everything else - no end to code found
applyANSI(data.mid(i+1, end));
+ //qDebug() << "Code:" << data.mid(i+1, end) << "Next Char:" << data[i+end+2];
i+=end; //move the final loop along - already handled these bytes
- }else if( data.at(i) != '\r' ) {
+ }else if( data.at(i) != '\r' ){
//Special Check: if inserting text within a line, clear the rest of this line first
if(i==0 && this->textCursor().position() < this->document()->characterCount()-1){
applyANSI("[K");
}
+ chars.append(data.at(i));
//Plaintext character - just add it here
//qDebug() << "Insert Text:" << data.at(i) << CFMT.foreground().color() << CFMT.background().color();
- this->textCursor().insertText( QChar(data.at(i)), CFMT );
+ //qDebug() << " " << this->currentCharFormat().foreground().color() << this->currentCharFormat().background().color();
+ //this->textCursor().insertText( QChar(data.at(i)), CFMT );
}
-
} //end loop over data
+ if(!chars.isEmpty()){ InsertText(chars); }
}
void TerminalWidget::applyANSI(QByteArray code){
@@ -112,17 +144,29 @@ void TerminalWidget::applyANSI(QByteArray code){
int mid = code.indexOf(";");
if(mid>0){
int numR, numC; numR = numC = 1;
- if(mid >=3){ numR = code.mid(1,mid-1).toInt(); }
- if(mid < code.size()-1){ numC = code.mid(mid+1,code.size()-mid-1).toInt(); }
- //this->textCursor().setPosition(
- qDebug() << "Set Text Position (absolute):" << "Row:" << numR << "Col:" << numC;
- // TO-DO
+ if(mid >=3){ numR = code.mid(1,mid-1).toInt()/this->fontMetrics().lineSpacing(); }
+ if(mid < code.size()-1){ numC = code.mid(mid+1,code.size()-mid-2).toInt(); }
+ qDebug() << "Set Text Position (absolute):" << "Code:" << code << "Row:" << numR << "Col:" << numC;
+ qDebug() << " - Current Pos:" << this->textCursor().position() << "Line Count:" << this->document()->lineCount();
+ //if(!this->textCursor().movePosition(QTextCursor::Start, QTextCursor::MoveAnchor,1) ){ qDebug() << "Could not go to start"; }
+ QTextCursor cur(this->textCursor());
+ cur.setPosition(0, QTextCursor::MoveAnchor); //go to start of document
+ qDebug() << " - Pos After Start Move:" << cur.position();
+ if( !cur.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, numR) ){ qDebug() << "Could not go to row:" << numR; }
+ qDebug() << " - Pos After Down Move:" << cur.position();
+ if( !cur.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, numC) ){ qDebug() << "Could not go to col:" << numC; }
+ /*this->textCursor().setPosition( this->document()->findBlockByLineNumber(numR).position() );
+ qDebug() << " - Pos After Row Move:" << this->textCursor().position();
+ if( !this->textCursor().movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, numC) ){ qDebug() << "Could not go to col:" << numC; }*/
+ qDebug() << " - Ending Pos:" << cur.position();
+ this->setTextCursor(cur);
}
// DISPLAY CLEAR CODES
}else if(code.endsWith("J")){ //ED - Erase Display
int num = 0;
if(code.size()>2){ num = code.mid(1, code.size()-2).toInt(); } //everything in the middle
+ //qDebug() << "Erase Display:" << num;
if(num==1){
//Clear from cursor to beginning of screen
for(int i=this->textCursor().position(); i>=0; i--){
@@ -130,6 +174,7 @@ void TerminalWidget::applyANSI(QByteArray code){
}
}else if(num==2){
//Clear the whole screen
+ qDebug() << "Clear Screen:" << this->document()->lineCount();
this->clear();
}else{
//Clear from cursor to end of screen
@@ -165,10 +210,10 @@ void TerminalWidget::applyANSI(QByteArray code){
}
//SCROLL MOVEMENT CODES
- }else if(code.endsWith("S")){ // SU - Scrolll Up
-
+ }else if(code.endsWith("S")){ // SU - Scroll Up
+ qDebug() << "Scroll Up:" << code;
}else if(code.endsWith("T")){ // SD - Scroll Down
-
+ qDebug() << "Scroll Down:" << code;
// GRAPHICS RENDERING
}else if(code.endsWith("m")){
@@ -185,13 +230,20 @@ void TerminalWidget::applyANSI(QByteArray code){
end = code.size()-1;
if(end>start){ applyANSIColor(code.mid(start, end-start).toInt());}
else{ applyANSIColor(0); }
+
+
+ // GRAPHICS MODES
+ }else if(code.endsWith("h")){
+
+ }else if(code.endsWith("l")){
+
+ }else{
+ qDebug() << "Unhandled Control Code:" << code;
}
-
-
}
void TerminalWidget::applyANSIColor(int code){
- qDebug() << "Apply Color code:" << code;
+ //qDebug() << "Apply Color code:" << code;
if(code <=0){ CFMT = DEFFMT; } //Reset back to default
else if(code==1){ CFMT.setFontWeight(75); } //BOLD font
else if(code==2){ CFMT.setFontWeight(25); } //Faint font (smaller than normal by a bit)
@@ -229,6 +281,7 @@ QBrush brush = CFMT.background();
color.setAlpha(255); //fully opaque
brush.setColor(color);
CFMT.setForeground( brush );
+ this->setTextColor(color); //just in case the format is not used
}
else if(code>=40 && code<=49){
//Set the font color
diff --git a/desktop-utilities/lumina-terminal/TerminalWidget.h b/desktop-utilities/lumina-terminal/TerminalWidget.h
index 6fe660a7..f0c84013 100644
--- a/desktop-utilities/lumina-terminal/TerminalWidget.h
+++ b/desktop-utilities/lumina-terminal/TerminalWidget.h
@@ -28,6 +28,7 @@ private:
QTextCharFormat DEFFMT, CFMT; //default/current text format
//Incoming Data parsing
+ void InsertText(QString);
void applyData(QByteArray data); //overall data parsing
void applyANSI(QByteArray code); //individual code application
void applyANSIColor(int code); //Add the designated color code to the CFMT structure
diff --git a/desktop-utilities/lumina-terminal/TrayIcon.cpp b/desktop-utilities/lumina-terminal/TrayIcon.cpp
index 14ea24b4..4519e5e5 100644
--- a/desktop-utilities/lumina-terminal/TrayIcon.cpp
+++ b/desktop-utilities/lumina-terminal/TrayIcon.cpp
@@ -17,7 +17,7 @@ TrayIcon::TrayIcon() : QSystemTrayIcon(){
this->setContextMenu(new QMenu());
ScreenMenu = new QMenu();
connect(ScreenMenu, SIGNAL(triggered(QAction*)), this, SLOT(ChangeScreen(QAction*)) );
- TERM = new TermWindow();
+ TERM = new TermWindow(settings);
//Load the current settings
TERM->setTopOfScreen(settings->value("TopOfScreen",true).toBool());
TERM->setCurrentScreen(settings->value("OnScreen",0).toInt());
diff --git a/desktop-utilities/lumina-terminal/TtyProcess.cpp b/desktop-utilities/lumina-terminal/TtyProcess.cpp
index ec0a6309..7a68a7d1 100644
--- a/desktop-utilities/lumina-terminal/TtyProcess.cpp
+++ b/desktop-utilities/lumina-terminal/TtyProcess.cpp
@@ -1,6 +1,7 @@
#include "TtyProcess.h"
#include <QDir>
+#include <QProcessEnvironment>
TTYProcess::TTYProcess(QObject *parent) : QObject(parent){
childProc = 0;
@@ -16,6 +17,13 @@ TTYProcess::~TTYProcess(){
bool TTYProcess::startTTY(QString prog, QStringList args, QString workdir){
if(workdir=="~"){ workdir = QDir::homePath(); }
QDir::setCurrent(workdir);
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ setenv("TERM","lumina-terminal",1);
+ setenv("TERMCAP","",1); //see /etc/termcap as well
+ QStringList filter = env.keys().filter("XTERM");
+ for(int i=0; i<filter.length(); i++){ unsetenv(filter[i].toLocal8Bit().data()); }
+ //if(env.contains("TERM")){ unsetenv("TERM"); }
+ //else if(env.contains
//Turn the program/arguments into C-compatible arrays
char cprog[prog.length()]; strcpy(cprog, prog.toLocal8Bit().data());
char *cargs[args.length()+2];
@@ -77,9 +85,9 @@ QByteArray TTYProcess::readTTY(){
if(sn==0){ return BA; } //not setup yet
char buffer[64];
ssize_t rtot = read(sn->socket(),&buffer,64);
- buffer[rtot]='\0';
+ //buffer[rtot]='\0';
BA = QByteArray(buffer, rtot);
- qDebug() << " - Got Data:" << BA;
+ //qDebug() << " - Got Data:" << BA;
if(!fragBA.isEmpty()){
//Have a leftover fragment, include this too
BA = BA.prepend(fragBA);
@@ -93,7 +101,6 @@ QByteArray TTYProcess::readTTY(){
return readTTY();
}else{
//qDebug() << "Read Data:" << BA;
- qDebug() << ".."; //Crashes when the debug line is removed - not sure why....
return BA;
}
}
@@ -134,7 +141,7 @@ QByteArray TTYProcess::CleanANSI(QByteArray raw, bool &incomplete){
}
// GENERIC ANSI CODES ((Make sure the output is not cut off in the middle of a code)
- index = raw.indexOf("\x1B[");
+ index = raw.indexOf("\x1B");
while(index>=0){
//CURSOR MOVEMENT
int end = 0;
@@ -145,7 +152,7 @@ QByteArray TTYProcess::CleanANSI(QByteArray raw, bool &incomplete){
end = i; //found the end of the control code
}
}
- index = raw.indexOf("\x1B[",index+1); //now find the next one
+ index = raw.indexOf("\x1B",index+1); //now find the next one
}
// SYSTEM BELL
@@ -165,7 +172,7 @@ pid_t TTYProcess::LaunchProcess(int& fd, char *prog, char **child_args){
//Returns: -1 for errors, positive value (file descriptor) for the master side of the TTY to watch
//First open/setup a new pseudo-terminal file/device on the system (master side)
- fd = posix_openpt(O_RDWR); //open read/write
+ fd = posix_openpt(O_RDWR | O_NOCTTY); //open read/write
if(fd<0){ return -1; } //could not create pseudo-terminal
int rc = grantpt(fd); //set permissions
if(rc!=0){ return -1; }
@@ -175,7 +182,7 @@ pid_t TTYProcess::LaunchProcess(int& fd, char *prog, char **child_args){
pid_t PID = fork();
if(PID==0){
//SLAVE/child
- int fds = ::open(ptsname(fd), O_RDWR); //open slave side read/write
+ int fds = ::open(ptsname(fd), O_RDWR | O_NOCTTY); //open slave side read/write
::close(fd); //close the master side from the slave thread
//Adjust the slave side mode to RAW
bgstack15