From 24fa7b68d212fd25c7ed9c83af12179689c6e046 Mon Sep 17 00:00:00 2001 From: Jeff Zignego Date: Tue, 15 Feb 2022 09:10:24 -0600 Subject: [PATCH 01/10] convert all files to unix line endings --- resources/default.html | 72 ++++---- src/cachingnm.cpp | 24 +-- src/cachingnm.h | 34 ++-- src/fakewebview.cpp | 50 +++--- src/fakewebview.h | 42 ++--- src/main.cpp | 238 +++++++++++++------------- src/qplayer.h | 14 +- src/qt-webkit-kiosk.pro | 360 +++++++++++++++++++-------------------- src/socketpair.cpp | 164 +++++++++--------- src/socketpair.h | 76 ++++----- src/unixsignals.cpp | 362 ++++++++++++++++++++-------------------- src/unixsignals.h | 86 +++++----- src/webview.h | 166 +++++++++--------- 13 files changed, 844 insertions(+), 844 deletions(-) diff --git a/resources/default.html b/resources/default.html index 9f9156a..308c244 100644 --- a/resources/default.html +++ b/resources/default.html @@ -1,36 +1,36 @@ - - -Qt WebKit browser for Kiosk - - - -
-

Hello, World!

-

This is your kiosk browser, written in Qt/C++ & WebKit!

-
-

Check link click sound.

-

Check print via Javascript

-

Try Close window via Javascript (tag a).

-

Try via Javascript (tag button).

-

Try and wait for Qt to interrupt.

-

Fullscreen mode switched by <F11>

-

Toggle Developer Tools by <F12> if enabled

-

To reload page press <F5>

-

To reload page with cache clean up press <CTRL+R>

-

To Quit press <CTRL+Q>

-
- - + + +Qt WebKit browser for Kiosk + + + +
+

Hello, World!

+

This is your kiosk browser, written in Qt/C++ & WebKit!

+
+

Check link click sound.

+

Check print via Javascript

+

Try Close window via Javascript (tag a).

+

Try via Javascript (tag button).

+

Try and wait for Qt to interrupt.

+

Fullscreen mode switched by <F11>

+

Toggle Developer Tools by <F12> if enabled

+

To reload page press <F5>

+

To reload page with cache clean up press <CTRL+R>

+

To Quit press <CTRL+Q>

+
+ + diff --git a/src/cachingnm.cpp b/src/cachingnm.cpp index 2dc4949..a4130be 100644 --- a/src/cachingnm.cpp +++ b/src/cachingnm.cpp @@ -1,12 +1,12 @@ -#include - -CachingNetworkManager::CachingNetworkManager(QObject *parent) : QNetworkAccessManager(parent) -{ -} - -QNetworkReply *CachingNetworkManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData) -{ - QNetworkRequest request(req); - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - return QNetworkAccessManager::createRequest(op, request, outgoingData); -} +#include + +CachingNetworkManager::CachingNetworkManager(QObject *parent) : QNetworkAccessManager(parent) +{ +} + +QNetworkReply *CachingNetworkManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData) +{ + QNetworkRequest request(req); + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + return QNetworkAccessManager::createRequest(op, request, outgoingData); +} diff --git a/src/cachingnm.h b/src/cachingnm.h index 6413ebe..2d6dbe3 100644 --- a/src/cachingnm.h +++ b/src/cachingnm.h @@ -1,17 +1,17 @@ -#ifndef CACHINGNM_H -#define CACHINGNM_H - -#include - -class CachingNetworkManager : public QNetworkAccessManager -{ - Q_OBJECT - -public: - explicit CachingNetworkManager(QObject* parent = 0); - - QNetworkReply *createRequest( Operation op, const QNetworkRequest & req, QIODevice * outgoingData); -}; - - -#endif // CACHINGNM_H +#ifndef CACHINGNM_H +#define CACHINGNM_H + +#include + +class CachingNetworkManager : public QNetworkAccessManager +{ + Q_OBJECT + +public: + explicit CachingNetworkManager(QObject* parent = 0); + + QNetworkReply *createRequest( Operation op, const QNetworkRequest & req, QIODevice * outgoingData); +}; + + +#endif // CACHINGNM_H diff --git a/src/fakewebview.cpp b/src/fakewebview.cpp index c509dd2..f555913 100644 --- a/src/fakewebview.cpp +++ b/src/fakewebview.cpp @@ -1,29 +1,29 @@ -#include - -FakeWebView::FakeWebView(QWidget *parent) : QWebView(parent) -{ +#include + +FakeWebView::FakeWebView(QWidget *parent) : QWebView(parent) +{ this->settings()->setAttribute(QWebSettings::JavascriptEnabled, false); this->settings()->setAttribute(QWebSettings::WebGLEnabled, false); this->settings()->setAttribute(QWebSettings::JavaEnabled, false); this->settings()->setAttribute(QWebSettings::PluginsEnabled, false); -} - -void FakeWebView::setUrl(const QUrl &url) -{ - emit ( urlChanged( url ) ); -} - - -void FakeWebView::load(const QUrl &url) -{ - emit ( urlChanged( url ) ); -} - -void FakeWebView::load(const QNetworkRequest &request, - QNetworkAccessManager::Operation operation, - const QByteArray &body) -{ - Q_UNUSED(operation); - Q_UNUSED(body); - emit ( urlChanged( request.url() ) ); -} +} + +void FakeWebView::setUrl(const QUrl &url) +{ + emit ( urlChanged( url ) ); +} + + +void FakeWebView::load(const QUrl &url) +{ + emit ( urlChanged( url ) ); +} + +void FakeWebView::load(const QNetworkRequest &request, + QNetworkAccessManager::Operation operation, + const QByteArray &body) +{ + Q_UNUSED(operation); + Q_UNUSED(body); + emit ( urlChanged( request.url() ) ); +} diff --git a/src/fakewebview.h b/src/fakewebview.h index 0b8489f..4ed9de6 100644 --- a/src/fakewebview.h +++ b/src/fakewebview.h @@ -1,25 +1,25 @@ -#ifndef FAKEWEBVIEW_H -#define FAKEWEBVIEW_H - -#include +#ifndef FAKEWEBVIEW_H +#define FAKEWEBVIEW_H + +#include #ifdef QT5 -#include +#include #else -#include +#include #endif - -class FakeWebView : public QWebView -{ - Q_OBJECT - -public: - explicit FakeWebView(QWidget* parent = 0); - - void load(const QUrl& url); - void load(const QNetworkRequest& request, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, const QByteArray &body = QByteArray()); - void setUrl(const QUrl &url); - -}; - -#endif // FAKEWEBVIEW_H + +class FakeWebView : public QWebView +{ + Q_OBJECT + +public: + explicit FakeWebView(QWidget* parent = 0); + + void load(const QUrl& url); + void load(const QNetworkRequest& request, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, const QByteArray &body = QByteArray()); + void setUrl(const QUrl &url); + +}; + +#endif // FAKEWEBVIEW_H diff --git a/src/main.cpp b/src/main.cpp index bde6abf..e899b0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,119 +1,119 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Sergey Dryabzhinsky -** All rights reserved. -** Contact: Sergey Dryabzhinsky (sergey.dryabzhinsky@gmail.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "mainwindow.h" -#include "anyoption.h" - -bool setupOptions(AnyOption *cmdopts) -{ - cmdopts->addUsage("This is a simple web-browser working in fullscreen kiosk-mode."); - cmdopts->addUsage(""); - cmdopts->addUsage("Usage: "); - cmdopts->addUsage(""); - cmdopts->addUsage(" -h --help Print usage and exit"); - cmdopts->addUsage(" -v --version Print version and exit"); - cmdopts->addUsage(" -c --config options.ini Configuration INI-file"); - cmdopts->addUsage(" -u --uri http://www.example.com/ Open this URI, home page"); - cmdopts->addUsage(" -C --clear-cache Clear cached request data"); - cmdopts->addUsage(""); - cmdopts->addUsage("Build with:"); - cmdopts->addUsage(" Qt: " QT_VERSION_STR); - cmdopts->addUsage(" WebKit: library v" QTWEBKIT_VERSION_STR); - cmdopts->addUsage(""); - cmdopts->addUsage("Runing with:"); - - QString qtv = QString(" Qt: ") + QString(qVersion()); - QByteArray qtvb = qtv.toLocal8Bit(); - const char * qtvch = qtvb.constData(); - cmdopts->addUsage(qtvch); - - QString qtwv = QString(" WebKit: engine v") + qWebKitVersion(); - QByteArray qtwvb = qtwv.toLocal8Bit(); - const char * qtwvch = qtwvb.constData(); - cmdopts->addUsage(qtwvch); - cmdopts->addUsage(""); - - qDebug() << "Build with: Qt = " QT_VERSION_STR << "; WebKit = " QTWEBKIT_VERSION_STR; - qDebug() << "Runing with: Qt =" << qVersion() << "; WebKit =" << qWebKitVersion(); - - cmdopts->setFlag("help", 'h'); - cmdopts->setFlag("version", 'v'); - cmdopts->setFlag("clear-cache", 'C'); - - cmdopts->setOption("config", 'c'); - cmdopts->setOption("uri", 'u'); - - cmdopts->setVersion(VERSION); - -#ifdef QT5 - cmdopts->processCommandArgs( QCoreApplication::arguments().length(), QCoreApplication::arguments() ); -#else - cmdopts->processCommandArgs( QCoreApplication::argc(), QCoreApplication::argv() ); -#endif - - if (cmdopts->getFlag('h') || cmdopts->getFlag("help")) { - qDebug(">> Help option in command prompt..."); - cmdopts->printUsage(); - return false; - } - - if (cmdopts->getFlag('v') || cmdopts->getFlag("version")) { - qDebug(">> Version option in command prompt..."); - cmdopts->printVersion(); - return false; - } - - return true; -} - -int main(int argc, char * argv[]) -{ - QApplication app(argc, argv); - - AnyOption *cmdopts = new AnyOption(); - if (!setupOptions(cmdopts)) { - return 0; - } - - MainWindow *browser = new MainWindow(); - browser->init(cmdopts); - - // executes browser.cleanupSlot() when the Qt framework emits aboutToQuit() signal. - QObject::connect(qApp, SIGNAL(aboutToQuit()), - browser, SLOT(cleanupSlot())); - - int ret = app.exec(); - qDebug() << "Application return: " << ret; -} +/**************************************************************************** +** +** Copyright (C) 2011 Sergey Dryabzhinsky +** All rights reserved. +** Contact: Sergey Dryabzhinsky (sergey.dryabzhinsky@gmail.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "mainwindow.h" +#include "anyoption.h" + +bool setupOptions(AnyOption *cmdopts) +{ + cmdopts->addUsage("This is a simple web-browser working in fullscreen kiosk-mode."); + cmdopts->addUsage(""); + cmdopts->addUsage("Usage: "); + cmdopts->addUsage(""); + cmdopts->addUsage(" -h --help Print usage and exit"); + cmdopts->addUsage(" -v --version Print version and exit"); + cmdopts->addUsage(" -c --config options.ini Configuration INI-file"); + cmdopts->addUsage(" -u --uri http://www.example.com/ Open this URI, home page"); + cmdopts->addUsage(" -C --clear-cache Clear cached request data"); + cmdopts->addUsage(""); + cmdopts->addUsage("Build with:"); + cmdopts->addUsage(" Qt: " QT_VERSION_STR); + cmdopts->addUsage(" WebKit: library v" QTWEBKIT_VERSION_STR); + cmdopts->addUsage(""); + cmdopts->addUsage("Runing with:"); + + QString qtv = QString(" Qt: ") + QString(qVersion()); + QByteArray qtvb = qtv.toLocal8Bit(); + const char * qtvch = qtvb.constData(); + cmdopts->addUsage(qtvch); + + QString qtwv = QString(" WebKit: engine v") + qWebKitVersion(); + QByteArray qtwvb = qtwv.toLocal8Bit(); + const char * qtwvch = qtwvb.constData(); + cmdopts->addUsage(qtwvch); + cmdopts->addUsage(""); + + qDebug() << "Build with: Qt = " QT_VERSION_STR << "; WebKit = " QTWEBKIT_VERSION_STR; + qDebug() << "Runing with: Qt =" << qVersion() << "; WebKit =" << qWebKitVersion(); + + cmdopts->setFlag("help", 'h'); + cmdopts->setFlag("version", 'v'); + cmdopts->setFlag("clear-cache", 'C'); + + cmdopts->setOption("config", 'c'); + cmdopts->setOption("uri", 'u'); + + cmdopts->setVersion(VERSION); + +#ifdef QT5 + cmdopts->processCommandArgs( QCoreApplication::arguments().length(), QCoreApplication::arguments() ); +#else + cmdopts->processCommandArgs( QCoreApplication::argc(), QCoreApplication::argv() ); +#endif + + if (cmdopts->getFlag('h') || cmdopts->getFlag("help")) { + qDebug(">> Help option in command prompt..."); + cmdopts->printUsage(); + return false; + } + + if (cmdopts->getFlag('v') || cmdopts->getFlag("version")) { + qDebug(">> Version option in command prompt..."); + cmdopts->printVersion(); + return false; + } + + return true; +} + +int main(int argc, char * argv[]) +{ + QApplication app(argc, argv); + + AnyOption *cmdopts = new AnyOption(); + if (!setupOptions(cmdopts)) { + return 0; + } + + MainWindow *browser = new MainWindow(); + browser->init(cmdopts); + + // executes browser.cleanupSlot() when the Qt framework emits aboutToQuit() signal. + QObject::connect(qApp, SIGNAL(aboutToQuit()), + browser, SLOT(cleanupSlot())); + + int ret = app.exec(); + qDebug() << "Application return: " << ret; +} diff --git a/src/qplayer.h b/src/qplayer.h index b95593a..6f0e4ac 100644 --- a/src/qplayer.h +++ b/src/qplayer.h @@ -1,16 +1,16 @@ -#ifndef QPLAYER_H -#define QPLAYER_H - +#ifndef QPLAYER_H +#define QPLAYER_H + #ifdef PLAYER_MULTIMEDIA #include "player/multimedia.h" #endif - + #ifdef PLAYER_PHONON #include "player/phonon.h" #endif - + #ifdef PLAYER_NULL #include "player/null.h" #endif - -#endif // QPLAYER_H + +#endif // QPLAYER_H diff --git a/src/qt-webkit-kiosk.pro b/src/qt-webkit-kiosk.pro index 71f8667..c70181b 100644 --- a/src/qt-webkit-kiosk.pro +++ b/src/qt-webkit-kiosk.pro @@ -1,180 +1,180 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2010-07-22T01:54:24 -# -#------------------------------------------------- - -QT = core gui network webkit - -contains(QT_VERSION, ^5\\.[0-9]+\\..*) { - QT += widgets webkitwidgets printsupport - DEFINES += QT5 -} - -CONFIG += console link_pkgconfig -TARGET = qt-webkit-kiosk -TEMPLATE = app -VERSION = 1.99.11-dev - -CONFIG(debug, debug|release) { -# here comes debug specific statements - message(Debug build) -} else { -# here comes release specific statements - CONFIG -= debug - DEFINES += QT_NO_DEBUG_OUTPUT -} - -DEFINES += VERSION=\\\"$${VERSION}\\\" - -PLAYER = NONE - -!win32 { - isEmpty( PREFIX ) { - PREFIX = /usr/local - } - - ICON = $${PREFIX}/share/icons/$${TARGET}.png - DEFINES += RESOURCES=\\\"$${PREFIX}/share/$${TARGET}/\\\" - DEFINES += ICON=\\\"$${ICON}\\\" - - PKG_TEST=QtTest - -contains(QT_VERSION, ^5\\.[0-9]+\\..*) { - - PKG_TEST=Qt5Test - - packagesExist(Qt5Multimedia) { - message('Multimedia framework found. Using Multimedia-player.') - DEFINES += PLAYER_MULTIMEDIA - QT += multimedia - PLAYER = MULTIMEDIA - SOURCES += player/multimedia.cpp - HEADERS += player/multimedia.h - } - - contains(PLAYER, NONE) { - # Ubuntu / Debian version? - packagesExist(phonon4qt5) { - message('Phonon framework found. Using Phonon-player.') - DEFINES += PLAYER_PHONON - QT += phonon4qt5 - PLAYER = PHONON - SOURCES += player/phonon.cpp - HEADERS += player/phonon.h - } - } -} - - contains(PLAYER, NONE) { - - packagesExist(phonon) { - message('Phonon framework found. Using Phonon-player.') - DEFINES += PLAYER_PHONON - QT += phonon - PLAYER = PHONON - SOURCES += player/phonon.cpp - HEADERS += player/phonon.h - } - - } - - packagesExist($${PKG_TEST}) { - message('Test framework found.') - DEFINES += USE_TESTLIB - QT += testlib - } else { - warning('No QtTest framework found! Will not do hacks with window...') - } -} -win32 { - ICON = ./$${TARGET}.png - DEFINES += RESOURCES=\\\"./\\\" - DEFINES += ICON=\\\"$${ICON}\\\" - -# Windows don't have pkg-config -# So we check generic paths... - -contains(QT_VERSION, ^5\\.[0-9]+\\..*) { - exists($$[QT_INSTALL_PREFIX]\\bin\\Qt*Multimedia*) { - message('Multimedia framework found. Using Multimedia-player.') - DEFINES += PLAYER_MULTIMEDIA - QT += multimedia - PLAYER = MULTIMEDIA - SOURCES += player/multimedia.cpp - HEADERS += player/multimedia.h - } -} - contains(PLAYER, NONE) { - exists($$[QT_INSTALL_PREFIX]\\bin\\phonon*) { - message('Phonon framework found. Using Phonon-player.') - DEFINES += PLAYER_PHONON - QT += phonon - PLAYER = PHONON - SOURCES += player/phonon.cpp - HEADERS += player/phonon.h - } - } - exists($$[QT_INSTALL_PREFIX]\\bin\\Qt*Test*) { - message('Test framework found.') - DEFINES += USE_TESTLIB - QT += testlib - } else { - warning('No QtTest framework found! Will not do hacks with window...') - } -} - -message(Qt player: $${PLAYER}) - -contains(PLAYER, NONE) { - warning('No multimedia framework found! Using NULL-player.') - DEFINES += PLAYER_NULL - SOURCES += player/null.cpp - HEADERS += player/null.h -} - -message(Qt version: $$[QT_VERSION]) -message(Qt is installed in $$[QT_INSTALL_PREFIX]) -message(Settings:) -message(- QT : $${QT}) -message(- PREFIX : $${PREFIX}) -message(- TARGET : $${TARGET}) -message(- VERSION: $${VERSION}) - -SOURCES += main.cpp\ - mainwindow.cpp \ - qwk_webpage.cpp \ - webview.cpp \ - anyoption.cpp \ - fakewebview.cpp \ - cachingnm.cpp \ - unixsignals.cpp \ - socketpair.cpp \ - persistentcookiejar.cpp \ - qwk_settings.cpp - -HEADERS += mainwindow.h \ - qwk_webpage.h \ - webview.h \ - anyoption.h \ - config.h \ - qplayer.h \ - fakewebview.h \ - cachingnm.h \ - unixsignals.h \ - socketpair.h \ - persistentcookiejar.h \ - qwk_settings.h - -# DEBUG -#message(- SOURCES: $${SOURCES}) -#message(- HEADERS: $${HEADERS}) - -# INSTALL - -target.path = $${PREFIX}/bin - -icon.files = ../resources/$${TARGET}.png -icon.path = $${PREFIX}/share/icons - -INSTALLS += target icon +#------------------------------------------------- +# +# Project created by QtCreator 2010-07-22T01:54:24 +# +#------------------------------------------------- + +QT = core gui network webkit + +contains(QT_VERSION, ^5\\.[0-9]+\\..*) { + QT += widgets webkitwidgets printsupport + DEFINES += QT5 +} + +CONFIG += console link_pkgconfig +TARGET = qt-webkit-kiosk +TEMPLATE = app +VERSION = 1.99.11-dev + +CONFIG(debug, debug|release) { +# here comes debug specific statements + message(Debug build) +} else { +# here comes release specific statements + CONFIG -= debug + DEFINES += QT_NO_DEBUG_OUTPUT +} + +DEFINES += VERSION=\\\"$${VERSION}\\\" + +PLAYER = NONE + +!win32 { + isEmpty( PREFIX ) { + PREFIX = /usr/local + } + + ICON = $${PREFIX}/share/icons/$${TARGET}.png + DEFINES += RESOURCES=\\\"$${PREFIX}/share/$${TARGET}/\\\" + DEFINES += ICON=\\\"$${ICON}\\\" + + PKG_TEST=QtTest + +contains(QT_VERSION, ^5\\.[0-9]+\\..*) { + + PKG_TEST=Qt5Test + + packagesExist(Qt5Multimedia) { + message('Multimedia framework found. Using Multimedia-player.') + DEFINES += PLAYER_MULTIMEDIA + QT += multimedia + PLAYER = MULTIMEDIA + SOURCES += player/multimedia.cpp + HEADERS += player/multimedia.h + } + + contains(PLAYER, NONE) { + # Ubuntu / Debian version? + packagesExist(phonon4qt5) { + message('Phonon framework found. Using Phonon-player.') + DEFINES += PLAYER_PHONON + QT += phonon4qt5 + PLAYER = PHONON + SOURCES += player/phonon.cpp + HEADERS += player/phonon.h + } + } +} + + contains(PLAYER, NONE) { + + packagesExist(phonon) { + message('Phonon framework found. Using Phonon-player.') + DEFINES += PLAYER_PHONON + QT += phonon + PLAYER = PHONON + SOURCES += player/phonon.cpp + HEADERS += player/phonon.h + } + + } + + packagesExist($${PKG_TEST}) { + message('Test framework found.') + DEFINES += USE_TESTLIB + QT += testlib + } else { + warning('No QtTest framework found! Will not do hacks with window...') + } +} +win32 { + ICON = ./$${TARGET}.png + DEFINES += RESOURCES=\\\"./\\\" + DEFINES += ICON=\\\"$${ICON}\\\" + +# Windows don't have pkg-config +# So we check generic paths... + +contains(QT_VERSION, ^5\\.[0-9]+\\..*) { + exists($$[QT_INSTALL_PREFIX]\\bin\\Qt*Multimedia*) { + message('Multimedia framework found. Using Multimedia-player.') + DEFINES += PLAYER_MULTIMEDIA + QT += multimedia + PLAYER = MULTIMEDIA + SOURCES += player/multimedia.cpp + HEADERS += player/multimedia.h + } +} + contains(PLAYER, NONE) { + exists($$[QT_INSTALL_PREFIX]\\bin\\phonon*) { + message('Phonon framework found. Using Phonon-player.') + DEFINES += PLAYER_PHONON + QT += phonon + PLAYER = PHONON + SOURCES += player/phonon.cpp + HEADERS += player/phonon.h + } + } + exists($$[QT_INSTALL_PREFIX]\\bin\\Qt*Test*) { + message('Test framework found.') + DEFINES += USE_TESTLIB + QT += testlib + } else { + warning('No QtTest framework found! Will not do hacks with window...') + } +} + +message(Qt player: $${PLAYER}) + +contains(PLAYER, NONE) { + warning('No multimedia framework found! Using NULL-player.') + DEFINES += PLAYER_NULL + SOURCES += player/null.cpp + HEADERS += player/null.h +} + +message(Qt version: $$[QT_VERSION]) +message(Qt is installed in $$[QT_INSTALL_PREFIX]) +message(Settings:) +message(- QT : $${QT}) +message(- PREFIX : $${PREFIX}) +message(- TARGET : $${TARGET}) +message(- VERSION: $${VERSION}) + +SOURCES += main.cpp\ + mainwindow.cpp \ + qwk_webpage.cpp \ + webview.cpp \ + anyoption.cpp \ + fakewebview.cpp \ + cachingnm.cpp \ + unixsignals.cpp \ + socketpair.cpp \ + persistentcookiejar.cpp \ + qwk_settings.cpp + +HEADERS += mainwindow.h \ + qwk_webpage.h \ + webview.h \ + anyoption.h \ + config.h \ + qplayer.h \ + fakewebview.h \ + cachingnm.h \ + unixsignals.h \ + socketpair.h \ + persistentcookiejar.h \ + qwk_settings.h + +# DEBUG +#message(- SOURCES: $${SOURCES}) +#message(- HEADERS: $${HEADERS}) + +# INSTALL + +target.path = $${PREFIX}/bin + +icon.files = ../resources/$${TARGET}.png +icon.path = $${PREFIX}/share/icons + +INSTALLS += target icon diff --git a/src/socketpair.cpp b/src/socketpair.cpp index 6244a72..967adb3 100644 --- a/src/socketpair.cpp +++ b/src/socketpair.cpp @@ -1,82 +1,82 @@ -#include "socketpair.h" -#include -#include - -SocketPair::SocketPair(QObject *parent) - : QObject(parent) -{ - dataCheck = new QTimer(); - dataCheck->setInterval(100); -} - -bool SocketPair::create() -{ - connect(dataCheck, SIGNAL(timeout()), this, SLOT(readServerData())); - connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection())); - - int tries = 5; - while (tries) { - if (!server.isListening()) { - if (server.listen(QHostAddress::LocalHost)) { - break; - } - } else { - break; - } - tries--; - } - if (!server.isListening()) { - qDebug() << "Can't start tcpServer:" << server.errorString(); - return false; - } - - clientConnection.setSocketOption( QAbstractSocket::LowDelayOption, 1 ); - clientConnection.setSocketOption( QAbstractSocket::KeepAliveOption, 1 ); - - clientConnection.connectToHost(QHostAddress::LocalHost, server.serverPort(), QIODevice::WriteOnly); - return true; -} - -void SocketPair::newConnection() -{ - serverConnection = server.nextPendingConnection(); - - serverConnection->setSocketOption( QAbstractSocket::LowDelayOption, 1 ); - serverConnection->setSocketOption( QAbstractSocket::KeepAliveOption, 1 ); - serverConnection->setReadBufferSize( 1 ); - - dataCheck->start(); - -// connect(serverConnection, SIGNAL(readyRead()), this, SLOT(readServerData())); - server.close(); -} - -void SocketPair::readServerData() -{ - QByteArray data = serverConnection->readAll(); - if (data.length()) { - emit sigData(data); - } -} - -void SocketPair::close() -{ - dataCheck->stop(); - clientConnection.close(); - if (serverConnection) { - serverConnection->close(); - delete serverConnection; - serverConnection = 0; - } - server.close(); -} - -QTcpSocket* SocketPair::input() -{ - return &clientConnection; -} - -QTcpSocket* SocketPair::output() -{ - return serverConnection; -} +#include "socketpair.h" +#include +#include + +SocketPair::SocketPair(QObject *parent) + : QObject(parent) +{ + dataCheck = new QTimer(); + dataCheck->setInterval(100); +} + +bool SocketPair::create() +{ + connect(dataCheck, SIGNAL(timeout()), this, SLOT(readServerData())); + connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection())); + + int tries = 5; + while (tries) { + if (!server.isListening()) { + if (server.listen(QHostAddress::LocalHost)) { + break; + } + } else { + break; + } + tries--; + } + if (!server.isListening()) { + qDebug() << "Can't start tcpServer:" << server.errorString(); + return false; + } + + clientConnection.setSocketOption( QAbstractSocket::LowDelayOption, 1 ); + clientConnection.setSocketOption( QAbstractSocket::KeepAliveOption, 1 ); + + clientConnection.connectToHost(QHostAddress::LocalHost, server.serverPort(), QIODevice::WriteOnly); + return true; +} + +void SocketPair::newConnection() +{ + serverConnection = server.nextPendingConnection(); + + serverConnection->setSocketOption( QAbstractSocket::LowDelayOption, 1 ); + serverConnection->setSocketOption( QAbstractSocket::KeepAliveOption, 1 ); + serverConnection->setReadBufferSize( 1 ); + + dataCheck->start(); + +// connect(serverConnection, SIGNAL(readyRead()), this, SLOT(readServerData())); + server.close(); +} + +void SocketPair::readServerData() +{ + QByteArray data = serverConnection->readAll(); + if (data.length()) { + emit sigData(data); + } +} + +void SocketPair::close() +{ + dataCheck->stop(); + clientConnection.close(); + if (serverConnection) { + serverConnection->close(); + delete serverConnection; + serverConnection = 0; + } + server.close(); +} + +QTcpSocket* SocketPair::input() +{ + return &clientConnection; +} + +QTcpSocket* SocketPair::output() +{ + return serverConnection; +} diff --git a/src/socketpair.h b/src/socketpair.h index 0fedc66..0b4719a 100644 --- a/src/socketpair.h +++ b/src/socketpair.h @@ -1,38 +1,38 @@ -#ifndef SOCKETPAIR_H -#define SOCKETPAIR_H - -/** - * Unix socketpair function emulation - */ - -#include -#include -#include -#include - -class SocketPair: public QObject -{ - Q_OBJECT -public: - SocketPair(QObject *parent = 0); - - bool create(); - void close(); - QTcpSocket* input(); - QTcpSocket* output(); - -Q_SIGNALS: - void sigData(QByteArray); - -public slots: - void newConnection(); - void readServerData(); - -private: - QTimer *dataCheck; - QTcpSocket *serverConnection; - QTcpSocket clientConnection; - QTcpServer server; -}; - -#endif // SOCKETPAIR_H +#ifndef SOCKETPAIR_H +#define SOCKETPAIR_H + +/** + * Unix socketpair function emulation + */ + +#include +#include +#include +#include + +class SocketPair: public QObject +{ + Q_OBJECT +public: + SocketPair(QObject *parent = 0); + + bool create(); + void close(); + QTcpSocket* input(); + QTcpSocket* output(); + +Q_SIGNALS: + void sigData(QByteArray); + +public slots: + void newConnection(); + void readServerData(); + +private: + QTimer *dataCheck; + QTcpSocket *serverConnection; + QTcpSocket clientConnection; + QTcpServer server; +}; + +#endif // SOCKETPAIR_H diff --git a/src/unixsignals.cpp b/src/unixsignals.cpp index 18d7dac..2f38c73 100644 --- a/src/unixsignals.cpp +++ b/src/unixsignals.cpp @@ -1,181 +1,181 @@ -#include -#include -#include -#include "unixsignals.h" - -SocketPair UnixSignals::sockPair; - -/** - * It should be created only ones - * - * @brief UnixSignals::UnixSignals - * @param parent - */ -UnixSignals::UnixSignals( QObject *parent ) - : QObject(parent) -{ - if (!UnixSignals::sockPair.create()) - qFatal("Unable to create signal socket pair"); - - connect(&UnixSignals::sockPair, SIGNAL(sigData(QByteArray)), this, SLOT(handleSig(QByteArray))); -} - -void UnixSignals::start() -{ -#ifdef SIGBREAK - // Available on Windows - if (receivers(SIGNAL(sigBREAK())) > 0) { - if (signal(SIGBREAK, UnixSignals::signalHandler) == SIG_ERR) { - qFatal("Unable to set signal handler on BREAK"); - } - } else { - qDebug("No listeners for signal BREAK"); - } -#else - qWarning("No signal BREAK defined"); -#endif - -#ifdef SIGTERM - if (receivers(SIGNAL(sigTERM())) > 0) { - if (signal(SIGTERM, UnixSignals::signalHandler) == SIG_ERR) { - qFatal("Unable to set signal handler on TERM"); - } - } else { - qDebug("No listeners for signal TERM"); - } -#else - qWarning("No signal TERM defined"); -#endif - -#ifdef SIGINT - if (receivers(SIGNAL(sigINT())) > 0) { - if (signal(SIGINT, UnixSignals::signalHandler) == SIG_ERR) { - qFatal("Unable to set signal handler on INT"); - } - } else { - qDebug("No listeners for signal INT"); - } -#else - qWarning("No signal INT defined"); -#endif - -#ifdef SIGHUP - // Unavailable on Windows - if (receivers(SIGNAL(sigHUP())) > 0) { - if (signal(SIGHUP, UnixSignals::signalHandler) == SIG_ERR) { - qFatal("Unable to set signal handler on HUP"); - } - } else { - qDebug("No listeners for signal HUP"); - } -#else - qWarning("No signal HUP defined"); -#endif - -#ifdef SIGUSR1 - // Unavailable on Windows - if (receivers(SIGNAL(sigUSR1())) > 0) { - if (signal(SIGUSR1, UnixSignals::signalHandler) == SIG_ERR) { - qFatal("Unable to set signal handler on USR1"); - } - } else { - qDebug("No listeners for signal USR1"); - } -#else - qWarning("No signal USR1 defined"); -#endif - -#ifdef SIGUSR2 - // Unavailable on Windows - if (receivers(SIGNAL(sigUSR2())) > 0) { - if (signal(SIGUSR2, UnixSignals::signalHandler) == SIG_ERR) { - qFatal("Unable to set signal handler on USR2"); - } - } else { - qDebug("No listeners for signal USR1"); - } -#else - qWarning("No signal USR2 defined"); -#endif -} - -void UnixSignals::stop() -{ - UnixSignals::sockPair.close(); -} - -void UnixSignals::signalHandler(int number) -{ - char tmp = number; - qDebug() << "UnixSignals::signalHandler -- pass signal" << number; - UnixSignals::sockPair.input()->write(&tmp, sizeof(tmp)); -} - -void UnixSignals::handleSig(QByteArray data) -{ - qDebug() << "Got data:" << data.toHex(); - int number = 0, lastNumber = 0; - if (data.length()) { - qDebug() << " signals in data:" << data.length(); - - // Socket can be filled with several signals - // If they come too fast... - while (data.length()) { - number = data[0]; - data.remove(0, 1); - - // Skeep repeated signals - if (number != lastNumber) { - handleSignal(number); - lastNumber = number; - } - } - - } -} - -void UnixSignals::handleSignal(int number) -{ - qDebug() << "Got signal:" << number; - switch (number) { -#ifdef SIGBREAK - case SIGBREAK: - qDebug() << "Got SIGBREAK! emit event!"; - emit sigBREAK(); - break; -#endif -#ifdef SIGHUP - case SIGHUP: - qDebug() << "Got SIGHUP! emit event!"; - emit sigHUP(); - break; -#endif -#ifdef SIGINT - case SIGINT: - qDebug() << "Got SIGINT! emit event!"; - emit sigINT(); - break; -#endif -#ifdef SIGTERM - case SIGTERM: - qDebug() << "Got SIGTERM! emit event!"; - emit sigTERM(); - break; -#endif -#ifdef SIGUSR1 - case SIGUSR1: - qDebug() << "Got SIGUSR1! emit event!"; - emit sigUSR1(); - break; -#endif -#ifdef SIGUSR2 - case SIGUSR2: - qDebug() << "Got SIGUSR2! emit event!"; - emit sigUSR2(); - break; -#endif - default: - qDebug() << "Got something? Dunno what to do..."; - } - -} +#include +#include +#include +#include "unixsignals.h" + +SocketPair UnixSignals::sockPair; + +/** + * It should be created only ones + * + * @brief UnixSignals::UnixSignals + * @param parent + */ +UnixSignals::UnixSignals( QObject *parent ) + : QObject(parent) +{ + if (!UnixSignals::sockPair.create()) + qFatal("Unable to create signal socket pair"); + + connect(&UnixSignals::sockPair, SIGNAL(sigData(QByteArray)), this, SLOT(handleSig(QByteArray))); +} + +void UnixSignals::start() +{ +#ifdef SIGBREAK + // Available on Windows + if (receivers(SIGNAL(sigBREAK())) > 0) { + if (signal(SIGBREAK, UnixSignals::signalHandler) == SIG_ERR) { + qFatal("Unable to set signal handler on BREAK"); + } + } else { + qDebug("No listeners for signal BREAK"); + } +#else + qWarning("No signal BREAK defined"); +#endif + +#ifdef SIGTERM + if (receivers(SIGNAL(sigTERM())) > 0) { + if (signal(SIGTERM, UnixSignals::signalHandler) == SIG_ERR) { + qFatal("Unable to set signal handler on TERM"); + } + } else { + qDebug("No listeners for signal TERM"); + } +#else + qWarning("No signal TERM defined"); +#endif + +#ifdef SIGINT + if (receivers(SIGNAL(sigINT())) > 0) { + if (signal(SIGINT, UnixSignals::signalHandler) == SIG_ERR) { + qFatal("Unable to set signal handler on INT"); + } + } else { + qDebug("No listeners for signal INT"); + } +#else + qWarning("No signal INT defined"); +#endif + +#ifdef SIGHUP + // Unavailable on Windows + if (receivers(SIGNAL(sigHUP())) > 0) { + if (signal(SIGHUP, UnixSignals::signalHandler) == SIG_ERR) { + qFatal("Unable to set signal handler on HUP"); + } + } else { + qDebug("No listeners for signal HUP"); + } +#else + qWarning("No signal HUP defined"); +#endif + +#ifdef SIGUSR1 + // Unavailable on Windows + if (receivers(SIGNAL(sigUSR1())) > 0) { + if (signal(SIGUSR1, UnixSignals::signalHandler) == SIG_ERR) { + qFatal("Unable to set signal handler on USR1"); + } + } else { + qDebug("No listeners for signal USR1"); + } +#else + qWarning("No signal USR1 defined"); +#endif + +#ifdef SIGUSR2 + // Unavailable on Windows + if (receivers(SIGNAL(sigUSR2())) > 0) { + if (signal(SIGUSR2, UnixSignals::signalHandler) == SIG_ERR) { + qFatal("Unable to set signal handler on USR2"); + } + } else { + qDebug("No listeners for signal USR1"); + } +#else + qWarning("No signal USR2 defined"); +#endif +} + +void UnixSignals::stop() +{ + UnixSignals::sockPair.close(); +} + +void UnixSignals::signalHandler(int number) +{ + char tmp = number; + qDebug() << "UnixSignals::signalHandler -- pass signal" << number; + UnixSignals::sockPair.input()->write(&tmp, sizeof(tmp)); +} + +void UnixSignals::handleSig(QByteArray data) +{ + qDebug() << "Got data:" << data.toHex(); + int number = 0, lastNumber = 0; + if (data.length()) { + qDebug() << " signals in data:" << data.length(); + + // Socket can be filled with several signals + // If they come too fast... + while (data.length()) { + number = data[0]; + data.remove(0, 1); + + // Skeep repeated signals + if (number != lastNumber) { + handleSignal(number); + lastNumber = number; + } + } + + } +} + +void UnixSignals::handleSignal(int number) +{ + qDebug() << "Got signal:" << number; + switch (number) { +#ifdef SIGBREAK + case SIGBREAK: + qDebug() << "Got SIGBREAK! emit event!"; + emit sigBREAK(); + break; +#endif +#ifdef SIGHUP + case SIGHUP: + qDebug() << "Got SIGHUP! emit event!"; + emit sigHUP(); + break; +#endif +#ifdef SIGINT + case SIGINT: + qDebug() << "Got SIGINT! emit event!"; + emit sigINT(); + break; +#endif +#ifdef SIGTERM + case SIGTERM: + qDebug() << "Got SIGTERM! emit event!"; + emit sigTERM(); + break; +#endif +#ifdef SIGUSR1 + case SIGUSR1: + qDebug() << "Got SIGUSR1! emit event!"; + emit sigUSR1(); + break; +#endif +#ifdef SIGUSR2 + case SIGUSR2: + qDebug() << "Got SIGUSR2! emit event!"; + emit sigUSR2(); + break; +#endif + default: + qDebug() << "Got something? Dunno what to do..."; + } + +} diff --git a/src/unixsignals.h b/src/unixsignals.h index fb66590..0e773a2 100644 --- a/src/unixsignals.h +++ b/src/unixsignals.h @@ -1,43 +1,43 @@ -#ifndef UNIXSIGNALS_H -#define UNIXSIGNALS_H - -/** - * Realy ugly QSocketNotifier behaviour... - * I can't send signal number through socket - * So I create socket pair for every signal I listen to... - * Damn... - */ - -#include -#include -#include "socketpair.h" - -class UnixSignals : public QObject -{ - Q_OBJECT -public: - UnixSignals( QObject *parent = 0 ); - - void start(); - void stop(); - - static void signalHandler(int number); - - static SocketPair sockPair; - -Q_SIGNALS: - void sigBREAK(); - void sigTERM(); - void sigHUP(); - void sigINT(); - void sigUSR1(); - void sigUSR2(); - -private slots: - void handleSig(QByteArray); - -private: - void handleSignal(int); -}; - -#endif // UNIXSIGNALS_H +#ifndef UNIXSIGNALS_H +#define UNIXSIGNALS_H + +/** + * Realy ugly QSocketNotifier behaviour... + * I can't send signal number through socket + * So I create socket pair for every signal I listen to... + * Damn... + */ + +#include +#include +#include "socketpair.h" + +class UnixSignals : public QObject +{ + Q_OBJECT +public: + UnixSignals( QObject *parent = 0 ); + + void start(); + void stop(); + + static void signalHandler(int number); + + static SocketPair sockPair; + +Q_SIGNALS: + void sigBREAK(); + void sigTERM(); + void sigHUP(); + void sigINT(); + void sigUSR1(); + void sigUSR2(); + +private slots: + void handleSig(QByteArray); + +private: + void handleSignal(int); +}; + +#endif // UNIXSIGNALS_H diff --git a/src/webview.h b/src/webview.h index 6e4e897..7798a63 100644 --- a/src/webview.h +++ b/src/webview.h @@ -1,83 +1,83 @@ -#ifndef WEBVIEW_H -#define WEBVIEW_H - -#include - -#ifdef QT5 -#include -#include -#endif - -#include -#include "qplayer.h" -#include "qwk_webpage.h" -#include "fakewebview.h" -#include "qwk_settings.h" - -class WebView : public QWebView -{ - Q_OBJECT - -public: - explicit WebView(QWidget* parent = 0); - - void setSettings(QwkSettings *settings); - QwkSettings* getSettings(); - - void loadCustomPage(QString uri); - void loadHomepage(); - void initSignals(); - - void setPage(QwkWebPage* page); - void resetLoadTimer(); - void stopLoadTimer(); - - QWebView *createWindow(QWebPage::WebWindowType type); - - void playSound(QString soundSetting); - - // http://slow-tone.blogspot.com/2011/04/qt-hide-scrollbars-qwebview.html?showComment=1318404188431#c5258624438625837585 - void scrollUp(); - void scrollDown(); - void scrollPageUp(); - void scrollPageDown(); - void scrollHome(); - void scrollEnd(); - -public slots: - void handlePrintRequested(QWebFrame *); - void handleFakeviewUrlChanged(const QUrl &); - void handleFakeviewLoadFinished(bool); - -protected: - void mousePressEvent(QMouseEvent *event); - QPlayer *getPlayer(); - QWebView *getFakeLoader(); - QTimer *getLoadTimer(); - -signals: - - void qwkNetworkError(QNetworkReply::NetworkError error, QString message); - void qwkNetworkReplyUrl(QUrl url); - -private: - QPlayer *player; - QwkSettings *qwkSettings; - FakeWebView *loader; - QPrinter *printer; - QTimer *loadTimer; - -private slots: - #ifndef QT_NO_SSL - void handleSslErrors(QNetworkReply* reply, const QList &errors); - #endif - void handleWindowCloseRequested(); - - void handleNetworkReply(QNetworkReply *reply); - void handleAuthReply(QNetworkReply *aReply, QAuthenticator *aAuth); - void handleProxyAuthReply(const QNetworkProxy &proxy, QAuthenticator *aAuth); - - void handleLoadTimerTimeout(); -}; - -#endif // WEBVIEW_H +#ifndef WEBVIEW_H +#define WEBVIEW_H + +#include + +#ifdef QT5 +#include +#include +#endif + +#include +#include "qplayer.h" +#include "qwk_webpage.h" +#include "fakewebview.h" +#include "qwk_settings.h" + +class WebView : public QWebView +{ + Q_OBJECT + +public: + explicit WebView(QWidget* parent = 0); + + void setSettings(QwkSettings *settings); + QwkSettings* getSettings(); + + void loadCustomPage(QString uri); + void loadHomepage(); + void initSignals(); + + void setPage(QwkWebPage* page); + void resetLoadTimer(); + void stopLoadTimer(); + + QWebView *createWindow(QWebPage::WebWindowType type); + + void playSound(QString soundSetting); + + // http://slow-tone.blogspot.com/2011/04/qt-hide-scrollbars-qwebview.html?showComment=1318404188431#c5258624438625837585 + void scrollUp(); + void scrollDown(); + void scrollPageUp(); + void scrollPageDown(); + void scrollHome(); + void scrollEnd(); + +public slots: + void handlePrintRequested(QWebFrame *); + void handleFakeviewUrlChanged(const QUrl &); + void handleFakeviewLoadFinished(bool); + +protected: + void mousePressEvent(QMouseEvent *event); + QPlayer *getPlayer(); + QWebView *getFakeLoader(); + QTimer *getLoadTimer(); + +signals: + + void qwkNetworkError(QNetworkReply::NetworkError error, QString message); + void qwkNetworkReplyUrl(QUrl url); + +private: + QPlayer *player; + QwkSettings *qwkSettings; + FakeWebView *loader; + QPrinter *printer; + QTimer *loadTimer; + +private slots: + #ifndef QT_NO_SSL + void handleSslErrors(QNetworkReply* reply, const QList &errors); + #endif + void handleWindowCloseRequested(); + + void handleNetworkReply(QNetworkReply *reply); + void handleAuthReply(QNetworkReply *aReply, QAuthenticator *aAuth); + void handleProxyAuthReply(const QNetworkProxy &proxy, QAuthenticator *aAuth); + + void handleLoadTimerTimeout(); +}; + +#endif // WEBVIEW_H From cc4be4528c2368174bcd83e7b164d4c4b1c6751c Mon Sep 17 00:00:00 2001 From: Jeff Zignego Date: Tue, 15 Feb 2022 09:13:10 -0600 Subject: [PATCH 02/10] src/socketpair.cpp: Fix inconsistent indentation --- src/socketpair.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/socketpair.cpp b/src/socketpair.cpp index 967adb3..932ac7e 100644 --- a/src/socketpair.cpp +++ b/src/socketpair.cpp @@ -30,8 +30,8 @@ bool SocketPair::create() return false; } - clientConnection.setSocketOption( QAbstractSocket::LowDelayOption, 1 ); - clientConnection.setSocketOption( QAbstractSocket::KeepAliveOption, 1 ); + clientConnection.setSocketOption( QAbstractSocket::LowDelayOption, 1 ); + clientConnection.setSocketOption( QAbstractSocket::KeepAliveOption, 1 ); clientConnection.connectToHost(QHostAddress::LocalHost, server.serverPort(), QIODevice::WriteOnly); return true; @@ -41,9 +41,9 @@ void SocketPair::newConnection() { serverConnection = server.nextPendingConnection(); - serverConnection->setSocketOption( QAbstractSocket::LowDelayOption, 1 ); - serverConnection->setSocketOption( QAbstractSocket::KeepAliveOption, 1 ); - serverConnection->setReadBufferSize( 1 ); + serverConnection->setSocketOption( QAbstractSocket::LowDelayOption, 1 ); + serverConnection->setSocketOption( QAbstractSocket::KeepAliveOption, 1 ); + serverConnection->setReadBufferSize( 1 ); dataCheck->start(); From 133e7994028e2c28e61ae52c5a1ca2c98ea14848 Mon Sep 17 00:00:00 2001 From: Jeff Zignego Date: Tue, 15 Feb 2022 09:17:29 -0600 Subject: [PATCH 03/10] src/anyoption.cpp: Add missing { } after if --- src/anyoption.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/anyoption.cpp b/src/anyoption.cpp index ede1917..a2bf859 100644 --- a/src/anyoption.cpp +++ b/src/anyoption.cpp @@ -1003,10 +1003,11 @@ AnyOption::consumeFile( char *buffer ) bool newline = true; for( unsigned int i = 0 ; i < strlen( buffer ) ; i++ ){ if( *cursor == endofline ) { /* end of line */ - if( pline != NULL ) /* valid line */ + if( pline != NULL ) { /* valid line */ processLine( pline, linelength ); pline = NULL; newline = true; + } }else if( newline ){ /* start of line */ newline = false; if( (*cursor != comment ) ){ /* not a comment */ From 105bd4ab1885aa2506684ee2286135410953c641 Mon Sep 17 00:00:00 2001 From: Jeff Zignego Date: Thu, 24 Feb 2022 10:55:48 -0600 Subject: [PATCH 04/10] Don't add signal handlers until socket connection If we add the OS signal handlers (via `handler->start()`) before the client connection to the `QTcpServer` has been completed, we will deadlock by writing to a socket that doesn't exist yet. So instead, we emit a Qt Signal once the client has been connected to the server in socketpair.cpp. unixsignals.cpp then connects that signal to its `start()` function as a slot. Then no matter what, the signal handler will not be installed until we are able to write to the socket. If we receive an OS signal before that, the default OS signal handler for the signal will be used instead. For example, if we receive SIGTERM before that, then the process will exit. --- src/mainwindow.cpp | 1 - src/socketpair.cpp | 1 + src/socketpair.h | 1 + src/unixsignals.cpp | 1 + src/unixsignals.h | 2 +- 5 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ac9cd4d..98d7245 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -103,7 +103,6 @@ void MainWindow::init(AnyOption *opts) connect(handler, SIGNAL(sigUSR1()), SLOT(unixSignalUsr1())); connect(handler, SIGNAL(sigUSR2()), SLOT(unixSignalUsr2())); } - handler->start(); setMinimumWidth(320); setMinimumHeight(200); diff --git a/src/socketpair.cpp b/src/socketpair.cpp index 932ac7e..f5d82d8 100644 --- a/src/socketpair.cpp +++ b/src/socketpair.cpp @@ -49,6 +49,7 @@ void SocketPair::newConnection() // connect(serverConnection, SIGNAL(readyRead()), this, SLOT(readServerData())); server.close(); + emit clientConnected(); } void SocketPair::readServerData() diff --git a/src/socketpair.h b/src/socketpair.h index 0b4719a..5d1e331 100644 --- a/src/socketpair.h +++ b/src/socketpair.h @@ -22,6 +22,7 @@ class SocketPair: public QObject QTcpSocket* output(); Q_SIGNALS: + void clientConnected(); void sigData(QByteArray); public slots: diff --git a/src/unixsignals.cpp b/src/unixsignals.cpp index 2f38c73..cb211da 100644 --- a/src/unixsignals.cpp +++ b/src/unixsignals.cpp @@ -17,6 +17,7 @@ UnixSignals::UnixSignals( QObject *parent ) if (!UnixSignals::sockPair.create()) qFatal("Unable to create signal socket pair"); + connect(&UnixSignals::sockPair, SIGNAL(clientConnected()), this, SLOT(start())); connect(&UnixSignals::sockPair, SIGNAL(sigData(QByteArray)), this, SLOT(handleSig(QByteArray))); } diff --git a/src/unixsignals.h b/src/unixsignals.h index 0e773a2..576d311 100644 --- a/src/unixsignals.h +++ b/src/unixsignals.h @@ -18,7 +18,6 @@ class UnixSignals : public QObject public: UnixSignals( QObject *parent = 0 ); - void start(); void stop(); static void signalHandler(int number); @@ -34,6 +33,7 @@ class UnixSignals : public QObject void sigUSR2(); private slots: + void start(); void handleSig(QByteArray); private: From dfd076282caf7556c927b1a413d94f8dbcc6ca18 Mon Sep 17 00:00:00 2001 From: Jeff Zignego Date: Thu, 24 Feb 2022 11:03:08 -0600 Subject: [PATCH 05/10] socketpair.cpp: use Qt::QueuedConnection for newConnection We can't handle signals (like SIGTERM) until after the event loop has started since we call `QApplication::exit(0);` when we receive SIGTERM or SIGINT, and that function won't do anything if we haven't started the event loop yet. See https://doc.qt.io/qt-5/qcoreapplication.html#exit A Qt signal and slot, connected by Qt::QueuedConnection however, means that the signal won't be delivered to the slot until the next iteration of the event loop. Which means that if the event loop hasn't started yet, it won't be delivered until the event loop starts. --- src/socketpair.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/socketpair.cpp b/src/socketpair.cpp index f5d82d8..9361313 100644 --- a/src/socketpair.cpp +++ b/src/socketpair.cpp @@ -12,7 +12,7 @@ SocketPair::SocketPair(QObject *parent) bool SocketPair::create() { connect(dataCheck, SIGNAL(timeout()), this, SLOT(readServerData())); - connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection())); + connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection()), Qt::QueuedConnection); int tries = 5; while (tries) { From 0c2ea47dbf6d869161ef3849aa1c7eb5402bd239 Mon Sep 17 00:00:00 2001 From: Jeff Zignego Date: Thu, 24 Feb 2022 11:44:57 -0600 Subject: [PATCH 06/10] src/socketpair.*: log all connection errors QTcpSocket and QTcpServer emit an Qt signal on error, so we create slots to receive those signals, and print the error that ocurred to stderr through qCritical. qCritical gives the admin flexibility in choosing whether or not to make those errors fatal or not through setting or not the environment variable `QT_FATAL_CRITICALS`. See https://doc.qt.io/qt-5/qtglobal.html#qCritical --- src/socketpair.cpp | 33 ++++++++++++++++++++++++++++++++- src/socketpair.h | 6 ++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/socketpair.cpp b/src/socketpair.cpp index 9361313..e95054e 100644 --- a/src/socketpair.cpp +++ b/src/socketpair.cpp @@ -1,6 +1,7 @@ #include "socketpair.h" -#include #include +#include +#include SocketPair::SocketPair(QObject *parent) : QObject(parent) @@ -14,6 +15,9 @@ bool SocketPair::create() connect(dataCheck, SIGNAL(timeout()), this, SLOT(readServerData())); connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection()), Qt::QueuedConnection); + connect(&server, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(logServerError(QAbstractSocket::SocketError))); + connect(&clientConnection, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(logClientConnectionError(QAbstractSocket::SocketError))); + int tries = 5; while (tries) { if (!server.isListening()) { @@ -40,6 +44,12 @@ bool SocketPair::create() void SocketPair::newConnection() { serverConnection = server.nextPendingConnection(); + if(serverConnection != nullptr) { + connect(serverConnection, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(logServerConnectionError(QAbstractSocket::SocketError))); + } else { + qFatal("%s:%d:%s, server.nextPendingConnection() was NULL.", __FILE__, + __LINE__, __func__); + } serverConnection->setSocketOption( QAbstractSocket::LowDelayOption, 1 ); serverConnection->setSocketOption( QAbstractSocket::KeepAliveOption, 1 ); @@ -81,3 +91,24 @@ QTcpSocket* SocketPair::output() { return serverConnection; } + +void SocketPair::logServerError(QAbstractSocket::SocketError socketError) { + qCritical("%s:%d:%s, server.serverError() is: '%d', and server.errorString() " + "is: '%s', and socketError is: '%d'", __FILE__, __LINE__, __func__, + server.serverError(), qUtf8Printable(server.errorString()), + socketError); +} + +void SocketPair::logServerConnectionError(QAbstractSocket::SocketError socketError) { + qCritical("%s:%d:%s, serverConnection->error() is: '%d', and " + "serverConnection->errorString() is: '%s', and socketError is: '%d'", + __FILE__, __LINE__, __func__, serverConnection->error(), + qUtf8Printable(serverConnection->errorString()), socketError); +} + +void SocketPair::logClientConnectionError(QAbstractSocket::SocketError socketError) { + qCritical("%s:%d:%s, clientConnection.error() is: '%d', and " + "clientConnection.errorString() is: '%s', and socketError is: '%d'", + __FILE__, __LINE__, __func__, clientConnection.error(), + qUtf8Printable(clientConnection.errorString()), socketError); +} diff --git a/src/socketpair.h b/src/socketpair.h index 5d1e331..ef58a5a 100644 --- a/src/socketpair.h +++ b/src/socketpair.h @@ -34,6 +34,12 @@ public slots: QTcpSocket *serverConnection; QTcpSocket clientConnection; QTcpServer server; + +private slots: + void logServerError(QAbstractSocket::SocketError); + void logServerConnectionError(QAbstractSocket::SocketError); + void logClientConnectionError(QAbstractSocket::SocketError); + }; #endif // SOCKETPAIR_H From dfae33fb5698a6368bc79db40872043b8779586f Mon Sep 17 00:00:00 2001 From: Jeff Zignego Date: Thu, 24 Feb 2022 12:16:08 -0600 Subject: [PATCH 07/10] src/unixsignals.cpp: fix signal handler Fix two issues in the signal handler function: * Use `volatile std::sig_atomic_t` for the variable that will be written to the socket. See https://en.cppreference.com/w/cpp/utility/program/sig_atomic_t and https://en.cppreference.com/w/cpp/utility/program/signal * Don't try to print anything to the log or the console in the signal handler. We were calling `qDebug()` which seems convenient for debugging the signal handler, however, `qDebug()` calls `gettimeofday()`, which is not signal safe. The list of signal safe functions is here: https://pubs.opengroup.org/onlinepubs/000095399/functions/xsh_chap02_04.html#tag_02_04_01 which notably does _not_ include `gettimeofday()`. Unfortunately there is virtually no way to log something safely from inside a signal handler itself. We can log stuff once we've passed it along via Qt Signals and Slots, but not inside the OS signal handler itself. Also see https://stackoverflow.com/questions/53155166/is-gettimeofday-async-signal-safe-and-can-it-cause-deadlock-if-used-in-signal and https://man7.org/linux/man-pages/man7/signal-safety.7.html --- src/unixsignals.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/unixsignals.cpp b/src/unixsignals.cpp index cb211da..13bed56 100644 --- a/src/unixsignals.cpp +++ b/src/unixsignals.cpp @@ -1,6 +1,6 @@ -#include #include #include +#include #include "unixsignals.h" SocketPair UnixSignals::sockPair; @@ -107,9 +107,8 @@ void UnixSignals::stop() void UnixSignals::signalHandler(int number) { - char tmp = number; - qDebug() << "UnixSignals::signalHandler -- pass signal" << number; - UnixSignals::sockPair.input()->write(&tmp, sizeof(tmp)); + volatile std::sig_atomic_t tmp = number; + UnixSignals::sockPair.input()->write((char* )&tmp, sizeof(tmp)); } void UnixSignals::handleSig(QByteArray data) From bdf68135020174387c6afc2af739b0e896aa7cf4 Mon Sep 17 00:00:00 2001 From: Jeff Zignego Date: Mon, 28 Feb 2022 15:33:56 -0600 Subject: [PATCH 08/10] src/mainwindow.cpp: don't draw on screen until ready The OS signal handler can't be installed until after the Qt event loop starts since it eventually calls `QApplication::exit(0);`, and that will cleanup anything we draw on the screen. Thus we don't want to connect any slots that touch the what's in focus or draw on the screen until the OS signal handler is ready. `mainwindow->init()` is called in `src/main.cpp` before `app.exec()`, thus we don't want to connect any slots that draw on screen in `mainwindow->init()`. Instead, `mainwindow->init()` will connect the `setupWindow()` slot, to the the `signalHandlerInstalled` Qt signal emitted by `this->handler`. At that point the OS signal handler has been installed and it is safe to draw on the screen. --- src/mainwindow.cpp | 50 +++++++++++++++++++++++++++++---------------- src/mainwindow.h | 5 +++-- src/unixsignals.cpp | 2 ++ src/unixsignals.h | 1 + 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 98d7245..2e5788b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -116,7 +116,7 @@ void MainWindow::init(AnyOption *opts) setMinimumHeight(minimalHeight); } - hiddenCurdor = new QCursor(Qt::BlankCursor); + hiddenCursor = new QCursor(Qt::BlankCursor); qDebug() << "Application icon: " << qwkSettings->getQString("application/icon"); setWindowIcon(QIcon( @@ -302,6 +302,29 @@ void MainWindow::init(AnyOption *opts) qwkSettings->getBool("security/local_content_can_access_remote_urls") ); + QNetworkConfigurationManager manager; + QNetworkConfiguration cfg = manager.defaultConfiguration(); + + n_session = new QNetworkSession(cfg); + connect(n_session, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(networkStateChanged(QNetworkSession::State))); + n_session->open(); + + connect(this->handler, SIGNAL(signalHandlerInstalled()), this, SLOT(setupWindow())); +} + +/* The OS signal handler can't be installed until after the Qt event loop + * starts since it eventually calls `QApplication::exit(0);`, and that will + * cleanup anything we draw on the screen. Thus we don't want to connect any + * slots that touch the what's in focus or draw on the screen until the OS + * signal handler is ready. `this->init()` is called in `src/main.cpp` before + * `app.exec()`, thus we don't do any of this in `this->init()`. Instead, + * `this->init()` will connect this slot, `this->setupWindow()`, to the the + * `signalHandlerInstalled` Qt signal emitted by `this->handler`. At that point + * the OS signal handler has been installed and it is safe to draw on the + * screen. + */ +void MainWindow::setupWindow() +{ connect(view->page()->mainFrame(), SIGNAL(titleChanged(QString)), SLOT(adjustTitle(QString))); connect(view->page()->mainFrame(), SIGNAL(loadStarted()), SLOT(startLoading())); connect(view->page()->mainFrame(), SIGNAL(urlChanged(const QUrl &)), SLOT(urlChanged(const QUrl &))); @@ -311,34 +334,21 @@ void MainWindow::init(AnyOption *opts) connect(view, SIGNAL(qwkNetworkError(QNetworkReply::NetworkError,QString)), SLOT(handleQwkNetworkError(QNetworkReply::NetworkError,QString))); connect(view, SIGNAL(qwkNetworkReplyUrl(QUrl)), SLOT(handleQwkNetworkReplyUrl(QUrl))); - QNetworkConfigurationManager manager; - QNetworkConfiguration cfg = manager.defaultConfiguration(); - - n_session = new QNetworkSession(cfg); - connect(n_session, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(networkStateChanged(QNetworkSession::State))); - n_session->open(); - QDesktopWidget *desktop = QApplication::desktop(); connect(desktop, SIGNAL(resized(int)), SLOT(desktopResized(int))); - // Window show, start events loop - show(); - - view->setFocusPolicy(Qt::StrongFocus); - if (qwkSettings->getBool("view/hide_mouse_cursor")) { QApplication::setOverrideCursor(Qt::BlankCursor); - view->setCursor(*hiddenCurdor); - QApplication::processEvents(); //process events to force cursor update before press + view->setCursor(*hiddenCursor); } - int delay_resize = 1; + int delay_resize = 0; if (qwkSettings->getBool("view/startup_resize_delayed")) { delay_resize = qwkSettings->getUInt("view/startup_resize_delay"); } delayedResize->singleShot(delay_resize, this, SLOT(delayedWindowResize())); - int delay_load = 1; + int delay_load = 0; if (qwkSettings->getBool("browser/startup_load_delayed")) { delay_load = qwkSettings->getUInt("browser/startup_load_delay"); } @@ -361,9 +371,11 @@ void MainWindow::delayedWindowResize() showMaximized(); } else if (qwkSettings->getBool("view/fixed-size")) { centerFixedSizeWindow(); + } else { + show(); } - QApplication::processEvents(); //process events to force update + QApplication::processEvents(); //process events to force update } void MainWindow::resizeEvent(QResizeEvent* event) @@ -629,6 +641,8 @@ void MainWindow::desktopResized(int p) showMaximized(); } else if (qwkSettings->getBool("view/fixed-size")) { centerFixedSizeWindow(); + } else { + show(); } } diff --git a/src/mainwindow.h b/src/mainwindow.h index 01ccbb8..7ceb554 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -87,6 +87,8 @@ protected slots: void desktopResized(int p); + void setupWindow(); + void delayedWindowResize(); void delayedPageLoad(); void delayedPageReload(); @@ -106,7 +108,6 @@ protected slots: void unixSignalUsr2(); protected: - void centerFixedSizeWindow(); void attachJavascripts(); void attachStyles(); @@ -127,7 +128,7 @@ protected slots: QNetworkDiskCache *diskCache; QWebInspector *inspector; - QCursor *hiddenCurdor; + QCursor *hiddenCursor; QKeyEvent *eventExit; AnyOption *cmdopts; diff --git a/src/unixsignals.cpp b/src/unixsignals.cpp index 13bed56..63d2688 100644 --- a/src/unixsignals.cpp +++ b/src/unixsignals.cpp @@ -98,6 +98,8 @@ void UnixSignals::start() #else qWarning("No signal USR2 defined"); #endif + + emit signalHandlerInstalled(); } void UnixSignals::stop() diff --git a/src/unixsignals.h b/src/unixsignals.h index 576d311..3b20ba7 100644 --- a/src/unixsignals.h +++ b/src/unixsignals.h @@ -25,6 +25,7 @@ class UnixSignals : public QObject static SocketPair sockPair; Q_SIGNALS: + void signalHandlerInstalled(); void sigBREAK(); void sigTERM(); void sigHUP(); From 62041944b26f2ff9ed5ee9dc7aa3c3afeecee971 Mon Sep 17 00:00:00 2001 From: Jeff Zignego Date: Mon, 28 Feb 2022 15:41:19 -0600 Subject: [PATCH 09/10] src/mainwindow.cpp: don't keep delayedResize timer We don't need to keep the delayedResize timer around for later. We will potentially use the delayedLoad timer again, but not the delayedResize timer after it has been used the first time. --- src/mainwindow.cpp | 3 +-- src/mainwindow.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2e5788b..1558d51 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -75,7 +75,6 @@ MainWindow::MainWindow() : QMainWindow() network_interface = new QNetworkInterface(); - delayedResize = new QTimer(); delayedLoad = new QTimer(); #ifdef USE_TESTLIB @@ -346,7 +345,7 @@ void MainWindow::setupWindow() if (qwkSettings->getBool("view/startup_resize_delayed")) { delay_resize = qwkSettings->getUInt("view/startup_resize_delay"); } - delayedResize->singleShot(delay_resize, this, SLOT(delayedWindowResize())); + QTimer::singleShot(delay_resize, this, SLOT(delayedWindowResize())); int delay_load = 0; if (qwkSettings->getBool("browser/startup_load_delayed")) { diff --git a/src/mainwindow.h b/src/mainwindow.h index 7ceb554..df28e74 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -146,7 +146,6 @@ protected slots: QNetworkSession *n_session; QNetworkInterface *network_interface; - QTimer *delayedResize; QTimer *delayedLoad; }; From 8c06c876bad8c22f7773dd4bf078abf98dbcf316 Mon Sep 17 00:00:00 2001 From: Jeff Zignego Date: Tue, 8 Mar 2022 12:52:19 -0600 Subject: [PATCH 10/10] src/socketpair.cpp: remove dataCheck timer Now that the race conditions in starting the signal handling are resolved, we can get rid of the dataCheck timer, and just use the readyRead signal from the serverConnection socket. --- src/socketpair.cpp | 8 +------- src/socketpair.h | 1 - 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/socketpair.cpp b/src/socketpair.cpp index e95054e..dfd624c 100644 --- a/src/socketpair.cpp +++ b/src/socketpair.cpp @@ -6,13 +6,10 @@ SocketPair::SocketPair(QObject *parent) : QObject(parent) { - dataCheck = new QTimer(); - dataCheck->setInterval(100); } bool SocketPair::create() { - connect(dataCheck, SIGNAL(timeout()), this, SLOT(readServerData())); connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection()), Qt::QueuedConnection); connect(&server, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(logServerError(QAbstractSocket::SocketError))); @@ -55,9 +52,7 @@ void SocketPair::newConnection() serverConnection->setSocketOption( QAbstractSocket::KeepAliveOption, 1 ); serverConnection->setReadBufferSize( 1 ); - dataCheck->start(); - -// connect(serverConnection, SIGNAL(readyRead()), this, SLOT(readServerData())); + connect(serverConnection, SIGNAL(readyRead()), this, SLOT(readServerData())); server.close(); emit clientConnected(); } @@ -72,7 +67,6 @@ void SocketPair::readServerData() void SocketPair::close() { - dataCheck->stop(); clientConnection.close(); if (serverConnection) { serverConnection->close(); diff --git a/src/socketpair.h b/src/socketpair.h index ef58a5a..3484f0e 100644 --- a/src/socketpair.h +++ b/src/socketpair.h @@ -30,7 +30,6 @@ public slots: void readServerData(); private: - QTimer *dataCheck; QTcpSocket *serverConnection; QTcpSocket clientConnection; QTcpServer server;