/*
- Presence VNC
- Copyright (C) 2010 Christian Pulvermacher
+ Presence VNC
+ Copyright (C) 2010 Christian Pulvermacher
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
#include "connectdialog.h"
#include "rfb/rfbclient.h"
const QString LISTEN_FOR_INCOMING_CONNECTIONS_STRING = QObject::tr("Listen for incoming connections");
ConnectDialog::ConnectDialog(QWidget *parent):
- QDialog(parent)
+ QDialog(parent)
{
- setWindowTitle(tr("Connect to VNC Server"));
- QSettings settings;
-
- //read history
- settings.beginGroup("hosts");
- QStringList hostnames = settings.childGroups();
- QMap<int, QString> hosts_map; //use position as key
- foreach(QString hostname, hostnames) {
- if(!settings.contains(hostname + "/position")) {
- continue; //can happen when host was given as a command line argument, don't show those
- }
-
- int position = settings.value(hostname + "/position").toInt();
- hosts_map.insert(position, hostname);
- }
- hostnames_sorted = hosts_map.values(); //sorted by ascending position
- settings.endGroup();
-
- QHBoxLayout *layout = new QHBoxLayout(this);
- QGridLayout *grid_layout = new QGridLayout();
- layout->addLayout(grid_layout);
-
- //set up combobox
- hosts.addItems(hostnames_sorted);
- hosts.insertSeparator(hosts.count());
- hosts.addItem(QIcon("/usr/share/icons/hicolor/48x48/hildon/general_received.png"), LISTEN_FOR_INCOMING_CONNECTIONS_STRING);
- hosts.setEditable(true);
+ setWindowTitle(tr("Connect to VNC Server"));
+ QSettings settings;
+
+ //read history
+ settings.beginGroup("hosts");
+ QStringList hostnames = settings.childGroups();
+ QMap<int, QString> hosts_map; //use position as key
+ foreach(QString hostname, hostnames) {
+ if(!settings.contains(hostname + "/position")) {
+ continue; //can happen when host was given as a command line argument, don't show those
+ }
+
+ int position = settings.value(hostname + "/position").toInt();
+ hosts_map.insert(position, hostname);
+ }
+ hostnames_sorted = hosts_map.values(); //sorted by ascending position
+ settings.endGroup();
+
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ QGridLayout *grid_layout = new QGridLayout();
+ layout->addLayout(grid_layout);
+
+ //set up combobox
+ hosts.addItems(hostnames_sorted);
+ hosts.insertSeparator(hosts.count());
+ hosts.addItem(QIcon("/usr/share/icons/hicolor/48x48/hildon/general_received.png"), LISTEN_FOR_INCOMING_CONNECTIONS_STRING);
+ hosts.setEditable(true);
#ifdef Q_WS_MAEMO_5
- hosts.lineEdit()->setInputMethodHints(Qt::ImhNoAutoUppercase); //somehow this doesn't work that well here
+ hosts.lineEdit()->setInputMethodHints(Qt::ImhNoAutoUppercase); //somehow this doesn't work that well here
#endif
- connect(&hosts, SIGNAL(editTextChanged(QString)),
- this, SLOT(hostnameUpdated(QString)));
- grid_layout->addWidget(&hosts, 0, 0, 1, 2);
-
- grid_layout->addWidget(new QLabel(tr("Quality")), 1, 0);
- //combobox numbering starts from 0, so currentIndex() == quality-1
- quality_combobox.addItem(tr("High (LAN)")); //1
- quality_combobox.addItem(tr("Medium (DSL)")); //2
- quality_combobox.addItem(tr("Low (ISDN)")); //3
- grid_layout->addWidget(&quality_combobox, 1, 1);
-
- viewonly.setText(tr("View only"));
- grid_layout->addWidget(&viewonly, 2, 0, 1, 2);
-
- done.setMaximumWidth(110);
- connect(&done, SIGNAL(clicked()),
- this, SLOT(accept()));
- layout->addWidget(&done);
-
- //get settings for last host
- hostnameUpdated(hosts.lineEdit()->text());
-
- connect(this, SIGNAL(finished(int)),
- this, SLOT(deleteLater()));
+ connect(&hosts, SIGNAL(editTextChanged(QString)),
+ this, SLOT(hostnameUpdated(QString)));
+ grid_layout->addWidget(&hosts, 0, 0, 1, 2);
+
+ grid_layout->addWidget(new QLabel(tr("Quality")), 1, 0);
+ //combobox numbering starts from 0, so currentIndex() == quality-1
+ quality_combobox.addItem(tr("High (LAN)")); //1
+ quality_combobox.addItem(tr("Medium (DSL)")); //2
+ quality_combobox.addItem(tr("Low (ISDN)")); //3
+ grid_layout->addWidget(&quality_combobox, 1, 1);
+
+ viewonly.setText(tr("View only"));
+ grid_layout->addWidget(&viewonly, 2, 0, 1, 2);
+
+ done.setMaximumWidth(110);
+ connect(&done, SIGNAL(clicked()),
+ this, SLOT(accept()));
+ layout->addWidget(&done);
+
+ //get settings for last host
+ hostnameUpdated(hosts.lineEdit()->text());
+
+ connect(this, SIGNAL(finished(int)),
+ this, SLOT(deleteLater()));
}
void ConnectDialog::hostnameUpdated(QString newtext)
{
- const int cursorpos = hosts.lineEdit()->cursorPosition();
-
- const bool normal_entry = hosts.itemIcon(hosts.currentIndex()).isNull();
- done.setText(normal_entry ? tr("Connect") : tr("Listen"));
-
- //unselect 'listen ...' entry if edited
- if(!normal_entry) {
- if(newtext != LISTEN_FOR_INCOMING_CONNECTIONS_STRING) {
- hosts.setCurrentIndex(-1);
- } else {
- return;
- }
- }
-
- //clean up hostname (we don't want / or \ in saved hostnames)
- newtext.remove(QChar('/'));
- newtext.remove(QChar('\\'));
- hosts.lineEdit()->setText(newtext);
- hosts.lineEdit()->setCursorPosition(cursorpos);
-
- //saved quality setting available?
- QSettings settings;
- int quality = settings.value(QString("hosts/%1/quality").arg(hosts.lineEdit()->text()), 2).toInt();
- if(quality < 1 or quality > 3)
- quality = 2;
- quality_combobox.setCurrentIndex(quality-1);
-
- //saved viewonly setting?
- viewonly.setChecked(settings.value(QString("hosts/%1/viewonly").arg(hosts.lineEdit()->text()), false).toBool());
+ const int cursorpos = hosts.lineEdit()->cursorPosition();
+
+ const bool normal_entry = hosts.itemIcon(hosts.currentIndex()).isNull();
+ done.setText(normal_entry ? tr("Connect") : tr("Listen"));
+
+ //unselect 'listen ...' entry if edited
+ if(!normal_entry) {
+ if(newtext != LISTEN_FOR_INCOMING_CONNECTIONS_STRING) {
+ hosts.setCurrentIndex(-1);
+ } else {
+ return;
+ }
+ }
+
+ //clean up hostname (we don't want / or \ in saved hostnames)
+ newtext.remove(QChar('/'));
+ newtext.remove(QChar('\\'));
+ hosts.lineEdit()->setText(newtext);
+ hosts.lineEdit()->setCursorPosition(cursorpos);
+
+ //saved quality setting available?
+ QSettings settings;
+ int quality = settings.value(QString("hosts/%1/quality").arg(hosts.lineEdit()->text()), 2).toInt();
+ if(quality < 1 or quality > 3)
+ quality = 2;
+ quality_combobox.setCurrentIndex(quality-1);
+
+ //saved viewonly setting?
+ viewonly.setChecked(settings.value(QString("hosts/%1/viewonly").arg(hosts.lineEdit()->text()), false).toBool());
}
void ConnectDialog::accept()
{
- QDialog::accept();
-
- QString selected_host = hosts.currentText();
- if(selected_host.isEmpty()) {
- return;
- }
-
- int quality = quality_combobox.currentIndex() + 1;
-
- QSettings settings;
- if(!hosts.itemIcon(hosts.currentIndex()).isNull()) {
- //listen mode selected
- int listen_port = settings.value("listen_port", LISTEN_PORT_OFFSET).toInt();
-
- //ask user if listen_port is correct
- bool ok;
- listen_port = QInputDialog::getInt(this,
- tr("Listen for Incoming Connections"),
- tr("Listen on Port:"),
- listen_port, 1, 65535, //value, min, max
- 1, &ok);
-
- if(ok) {
- settings.setValue("listen_port", listen_port);
- emit connectToHost("", quality, listen_port, viewonly.isChecked());
- }
- return;
- }
-
- settings.beginGroup("hosts");
- const bool new_item = !hostnames_sorted.contains(selected_host);
- const bool used_old_host = !new_item and hosts.currentIndex() > 0;
- //if both are false, we don't need to mess with positions
-
- if(new_item or used_old_host) {
- //put selected_host at the top
- settings.setValue(QString("%1/position").arg(selected_host), 0);
-
- //don't create duplicates
- if(used_old_host)
- hostnames_sorted.removeAll(selected_host);
-
- //now rebuild list for positions >= 1
- for(int i = 0; i < hostnames_sorted.size(); i++)
- settings.setValue(QString("%1/position").arg(hostnames_sorted.at(i)), i+1);
- }
-
- settings.setValue(QString("%1/quality").arg(selected_host), quality);
- settings.setValue(QString("%1/viewonly").arg(selected_host), viewonly.isChecked());
-
- settings.endGroup();
- settings.sync();
-
- //listen_port = 0 is ignored
- emit connectToHost(QString("vnc://%1").arg(selected_host), quality, 0, viewonly.isChecked());
+ QDialog::accept();
+
+ QString selected_host = hosts.currentText();
+ if(selected_host.isEmpty()) {
+ return;
+ }
+
+ int quality = quality_combobox.currentIndex() + 1;
+
+ QSettings settings;
+ if(!hosts.itemIcon(hosts.currentIndex()).isNull()) {
+ //listen mode selected
+ int listen_port = settings.value("listen_port", LISTEN_PORT_OFFSET).toInt();
+
+ //ask user if listen_port is correct
+ bool ok;
+ listen_port = QInputDialog::getInt(this,
+ tr("Listen for Incoming Connections"),
+ tr("Listen on Port:"),
+ listen_port, 1, 65535, //value, min, max
+ 1, &ok);
+
+ if(ok) {
+ settings.setValue("listen_port", listen_port);
+ emit connectToHost("", quality, listen_port, viewonly.isChecked());
+ }
+ return;
+ }
+
+ settings.beginGroup("hosts");
+ const bool new_item = !hostnames_sorted.contains(selected_host);
+ const bool used_old_host = !new_item and hosts.currentIndex() > 0;
+ //if both are false, we don't need to mess with positions
+
+ if(new_item or used_old_host) {
+ //put selected_host at the top
+ settings.setValue(QString("%1/position").arg(selected_host), 0);
+
+ //don't create duplicates
+ if(used_old_host)
+ hostnames_sorted.removeAll(selected_host);
+
+ //now rebuild list for positions >= 1
+ for(int i = 0; i < hostnames_sorted.size(); i++)
+ settings.setValue(QString("%1/position").arg(hostnames_sorted.at(i)), i+1);
+ }
+
+ settings.setValue(QString("%1/quality").arg(selected_host), quality);
+ settings.setValue(QString("%1/viewonly").arg(selected_host), viewonly.isChecked());
+
+ settings.endGroup();
+ settings.sync();
+
+ //listen_port = 0 is ignored
+ emit connectToHost(QString("vnc://%1").arg(selected_host), quality, 0, viewonly.isChecked());
}
inline bool eventFilter(QObject *obj, QEvent *ev);
private:
- QTimer timer;
+ QTimer timer;
};
FullScreenExitButton::FullScreenExitButton(QWidget *parent)
raise();
// fall through
case QEvent::Resize:
- if (isVisible()) {
- move(parent->width() - width(), parent->height() - height());
- timer.start();
- }
+ if (isVisible()) {
+ move(parent->width() - width(), parent->height() - height());
+ timer.start();
+ }
break;
default:
break;
/*
- Presence VNC
- Copyright (C) 2010 Christian Pulvermacher
+ Presence VNC
+ Copyright (C) 2010 Christian Pulvermacher
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
#include "keymenu.h"
KeyMenu::KeyMenu(QWidget *parent):
- QDialog(parent)
+ QDialog(parent)
{
- setWindowTitle(tr("Additional Keys"));
- QTabWidget *tabwidget = new QTabWidget(this);
-
- //modifiers
- ActionTab *mod_tab = new ActionTab(this);
- QAction *win = new QAction(tr("Win"), this);
- win->setShortcut(Qt::META);
- win->setCheckable(true);
- mod_tab->addAction(win);
- QAction *alt = new QAction(tr("Alt"), this);
- alt->setShortcut(Qt::ALT);
- alt->setCheckable(true);
- mod_tab->addAction(alt);
- tabwidget->addTab(mod_tab, tr("Modifiers"));
-
- //movement/text editing keys
- ActionTab *other_tab = new ActionTab(this);
- other_tab->addAction(tr("Insert"), Qt::Key_Insert);
- other_tab->addAction(tr("Delete"), Qt::Key_Delete);
- other_tab->addAction(tr("Backspace"), Qt::Key_Backspace);
- other_tab->addAction(tr("Home"), Qt::Key_Home);
- other_tab->addAction(tr("End"), Qt::Key_End);
- tabwidget->addTab(other_tab, tr("Editing"));
-
- //F1-F12
- ActionTab *fx_tab = new ActionTab(this);
- for(int i = 1; i<=12; i++)
- fx_tab->addAction(tr("F%1").arg(i), QString("F%1").arg(i));
- tabwidget->addTab(fx_tab, tr("F1-F12"));
-
- //Misc
- ActionTab *misc_tab = new ActionTab(this);
- misc_tab->addAction(tr("Pause"), QString("Pause"));
- misc_tab->addAction(tr("Print"), QString("print"));
- misc_tab->addAction(tr("Menu"), QString("Menu"));
- misc_tab->addAction(tr("Ctrl+Alt+Del"), QString("Ctrl+Alt+Delete"));
- misc_tab->addAction(tr("Ctrl+Alt+Backspace"), QString("Ctrl+Alt+Backspace"));
- tabwidget->addTab(misc_tab, tr("Misc"));
-
- QVBoxLayout *layout = new QVBoxLayout();
- layout->addWidget(tabwidget);
- setLayout(layout);
+ setWindowTitle(tr("Additional Keys"));
+ QTabWidget *tabwidget = new QTabWidget(this);
+
+ //modifiers
+ ActionTab *mod_tab = new ActionTab(this);
+ QAction *win = new QAction(tr("Win"), this);
+ win->setShortcut(Qt::META);
+ win->setCheckable(true);
+ mod_tab->addAction(win);
+ QAction *alt = new QAction(tr("Alt"), this);
+ alt->setShortcut(Qt::ALT);
+ alt->setCheckable(true);
+ mod_tab->addAction(alt);
+ tabwidget->addTab(mod_tab, tr("Modifiers"));
+
+ //movement/text editing keys
+ ActionTab *other_tab = new ActionTab(this);
+ other_tab->addAction(tr("Insert"), Qt::Key_Insert);
+ other_tab->addAction(tr("Delete"), Qt::Key_Delete);
+ other_tab->addAction(tr("Backspace"), Qt::Key_Backspace);
+ other_tab->addAction(tr("Home"), Qt::Key_Home);
+ other_tab->addAction(tr("End"), Qt::Key_End);
+ tabwidget->addTab(other_tab, tr("Editing"));
+
+ //F1-F12
+ ActionTab *fx_tab = new ActionTab(this);
+ for(int i = 1; i<=12; i++)
+ fx_tab->addAction(tr("F%1").arg(i), QString("F%1").arg(i));
+ tabwidget->addTab(fx_tab, tr("F1-F12"));
+
+ //Misc
+ ActionTab *misc_tab = new ActionTab(this);
+ misc_tab->addAction(tr("Pause"), QString("Pause"));
+ misc_tab->addAction(tr("Print"), QString("print"));
+ misc_tab->addAction(tr("Menu"), QString("Menu"));
+ misc_tab->addAction(tr("Ctrl+Alt+Del"), QString("Ctrl+Alt+Delete"));
+ misc_tab->addAction(tr("Ctrl+Alt+Backspace"), QString("Ctrl+Alt+Backspace"));
+ tabwidget->addTab(misc_tab, tr("Misc"));
+
+ QVBoxLayout *layout = new QVBoxLayout();
+ layout->addWidget(tabwidget);
+ setLayout(layout);
}
void KeyMenu::accept()
{
- QAction* selected_action = qobject_cast<QAction* >(sender());
- if(!selected_action) {
- keysequence = QKeySequence();
- } else {
- keysequence = selected_action->shortcut();
- }
-
- QDialog::accept();
+ QAction* selected_action = qobject_cast<QAction* >(sender());
+ if(!selected_action) {
+ keysequence = QKeySequence();
+ } else {
+ keysequence = selected_action->shortcut();
+ }
+
+ QDialog::accept();
}
ActionTab::ActionTab(KeyMenu *parent):
- QScrollArea(parent),
- keymenu(parent)
+ QScrollArea(parent),
+ keymenu(parent)
{
- setWidgetResizable(true);
- setWidget(&widget);
- widget.setLayout(&layout);
+ setWidgetResizable(true);
+ setWidget(&widget);
+ widget.setLayout(&layout);
}
void ActionTab::addAction(QString text, QKeySequence keysequence)
{
- QAction *action = new QAction(text, this);
- action->setShortcut(keysequence);
+ QAction *action = new QAction(text, this);
+ action->setShortcut(keysequence);
- addAction(action);
+ addAction(action);
}
void ActionTab::addAction(QAction *action)
{
- connect(action, SIGNAL(triggered()),
- keymenu, SLOT(accept()));
+ connect(action, SIGNAL(triggered()),
+ keymenu, SLOT(accept()));
- QToolButton *button = new QToolButton();
- button->setDefaultAction(action);
- layout.addWidget(button);
+ QToolButton *button = new QToolButton();
+ button->setDefaultAction(action);
+ layout.addWidget(button);
}
/*
- Presence VNC
- Copyright (C) 2010 Christian Pulvermacher
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ Presence VNC
+ Copyright (C) 2010 Christian Pulvermacher
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
#include "mainwindow.h"
#include "rfb/rfbclient.h"
const QString APPNAME("Presence VNC");
void printHelp() {
- std::cout << "Usage: " << qPrintable(QCoreApplication::arguments().at(0)) << " [options] [URL [quality]]\n"
+ std::cout << "Usage: " << qPrintable(QCoreApplication::arguments().at(0)) << " [options] [URL [quality]]\n"
- << "\nOptions:\n"
- << " --help\t\t\t Print this text and exit.\n"
- << " --listen [port]\t Listen for incoming connections on given port, or 5500 if omitted. Cannot be used with an URL.\n"
- << " --viewonly\t\t Don't send mouse/keyboard input to remote desktop. This is only useful if you also supply a URL, or --listen.\n"
+ << "\nOptions:\n"
+ << " --help\t\t\t Print this text and exit.\n"
+ << " --listen [port]\t Listen for incoming connections on given port, or 5500 if omitted. Cannot be used with an URL.\n"
+ << " --viewonly\t\t Don't send mouse/keyboard input to remote desktop. This is only useful if you also supply a URL, or --listen.\n"
- << "\nURLs:\n"
- << " vnc://:password@server:display\n\n"
- << " Password and display can be omitted, e.g. vnc://server is a valid URL.\n"
- << " Optionally, you can define the quality as a second argument (1-3, where 1 is the best). Default is 2.\n";
+ << "\nURLs:\n"
+ << " vnc://:password@server:display\n\n"
+ << " Password and display can be omitted, e.g. vnc://server is a valid URL.\n"
+ << " Optionally, you can define the quality as a second argument (1-3, where 1 is the best). Default is 2.\n";
}
int main(int argc, char *argv[])
{
- QCoreApplication::setOrganizationName(APPNAME);
- QCoreApplication::setApplicationName(APPNAME);
-
- QApplication app(argc, argv);
-
- QString url;
- int quality = 2;
- int listen_port = 0; //only used if >0
- bool view_only = false;
-
- QStringList arguments = QCoreApplication::arguments();
- for(int i = 1; i < arguments.count(); i++) {
- if(arguments.at(i) == "--help") {
- printHelp();
-
- return 0;
- } else if(arguments.at(i) == "--listen") {
- if(arguments.count() <= i+1 or arguments.at(i+1).startsWith("--")) {
- //no argument found, use default
- listen_port = LISTEN_PORT_OFFSET;
- } else {
- //next argument should be a port number
- listen_port = arguments.at(i+1).toInt();
- if(listen_port < 1 or listen_port > 65535) {
- std::cerr << "\"" << qPrintable(arguments.at(i+1)) << "\" is not a valid port number!\n\n";
- return 1;
- }
-
- //everything ok
- i++;
- }
- } else if(arguments.at(i) == "--viewonly") {
- view_only = true;
- } else { //not a valid command line option, should be the url
- url = arguments.at(i);
-
- //check url
- if(!url.startsWith("vnc://")) {
- std::cerr << "\"" << qPrintable(url) << "\" is not a valid command line option!\n\n";
- printHelp();
-
- return 1;
- }
-
- if(arguments.count() > i+1) { //TODO: having a --quality option would make more sense.
- int arg = arguments.at(i+1).toInt();
- if(1 <= arg and arg <= 3) { //check if arg is valid, might also be another option
- quality = arg;
- i++;
- }
- }
- }
- }
-
- if(!url.isNull() and listen_port > 0) {
- std::cerr << "--listen cannot be used with an URL!\n";
- return 1;
- }
-
- MainWindow main(url, quality, listen_port, view_only);
- main.show();
- return app.exec();
+ QCoreApplication::setOrganizationName(APPNAME);
+ QCoreApplication::setApplicationName(APPNAME);
+
+ QApplication app(argc, argv);
+
+ QString url;
+ int quality = 2;
+ int listen_port = 0; //only used if >0
+ bool view_only = false;
+
+ QStringList arguments = QCoreApplication::arguments();
+ for(int i = 1; i < arguments.count(); i++) {
+ if(arguments.at(i) == "--help") {
+ printHelp();
+
+ return 0;
+ } else if(arguments.at(i) == "--listen") {
+ if(arguments.count() <= i+1 or arguments.at(i+1).startsWith("--")) {
+ //no argument found, use default
+ listen_port = LISTEN_PORT_OFFSET;
+ } else {
+ //next argument should be a port number
+ listen_port = arguments.at(i+1).toInt();
+ if(listen_port < 1 or listen_port > 65535) {
+ std::cerr << "\"" << qPrintable(arguments.at(i+1)) << "\" is not a valid port number!\n\n";
+ return 1;
+ }
+
+ //everything ok
+ i++;
+ }
+ } else if(arguments.at(i) == "--viewonly") {
+ view_only = true;
+ } else { //not a valid command line option, should be the url
+ url = arguments.at(i);
+
+ //check url
+ if(!url.startsWith("vnc://")) {
+ std::cerr << "\"" << qPrintable(url) << "\" is not a valid command line option!\n\n";
+ printHelp();
+
+ return 1;
+ }
+
+ if(arguments.count() > i+1) { //TODO: having a --quality option would make more sense.
+ int arg = arguments.at(i+1).toInt();
+ if(1 <= arg and arg <= 3) { //check if arg is valid, might also be another option
+ quality = arg;
+ i++;
+ }
+ }
+ }
+ }
+
+ if(!url.isNull() and listen_port > 0) {
+ std::cerr << "--listen cannot be used with an URL!\n";
+ return 1;
+ }
+
+ MainWindow main(url, quality, listen_port, view_only);
+ main.show();
+ return app.exec();
}
/*
- Presence VNC
- Copyright (C) 2010 Christian Pulvermacher
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ Presence VNC
+ Copyright (C) 2010 Christian Pulvermacher
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
#include "connectdialog.h"
#include "fullscreenexitbutton.h"
#include "keymenu.h"
MainWindow::MainWindow(QString url, int quality, int listen_port, bool view_only):
- QMainWindow(0),
- vnc_view(0),
- scroll_area(new ScrollArea(0)),
- input_toolbuttons(new QActionGroup(this)),
- key_menu(0)
+ QMainWindow(0),
+ vnc_view(0),
+ scroll_area(new ScrollArea(0)),
+ input_toolbuttons(new QActionGroup(this)),
+ key_menu(0)
{
- setWindowTitle("Presence VNC");
+ setWindowTitle("Presence VNC");
#ifdef Q_WS_MAEMO_5
- setContextMenuPolicy(Qt::NoContextMenu);
- setAttribute(Qt::WA_Maemo5StackedWindow);
+ setContextMenuPolicy(Qt::NoContextMenu);
+ setAttribute(Qt::WA_Maemo5StackedWindow);
#endif
- migrateConfiguration();
+ migrateConfiguration();
- //set up toolbar
- toolbar = new QToolBar(0);
- input_toolbuttons->addAction(toolbar->addAction(QChar(0x2026), this, SLOT(showKeyMenu()))); //"..." button
- input_toolbuttons->addAction(toolbar->addAction(tr("Tab"), this, SLOT(sendTab())));
- input_toolbuttons->addAction(toolbar->addAction(tr("Esc"), this, SLOT(sendEsc())));
- input_toolbuttons->addAction(toolbar->addAction(tr("PgUp"), this, SLOT(sendPgUp())));
- input_toolbuttons->addAction(toolbar->addAction(tr("PgDn"), this, SLOT(sendPgDn())));
+ //set up toolbar
+ toolbar = new QToolBar(0);
+ input_toolbuttons->addAction(toolbar->addAction(QChar(0x2026), this, SLOT(showKeyMenu()))); //"..." button
+ input_toolbuttons->addAction(toolbar->addAction(tr("Tab"), this, SLOT(sendTab())));
+ input_toolbuttons->addAction(toolbar->addAction(tr("Esc"), this, SLOT(sendEsc())));
+ input_toolbuttons->addAction(toolbar->addAction(tr("PgUp"), this, SLOT(sendPgUp())));
+ input_toolbuttons->addAction(toolbar->addAction(tr("PgDn"), this, SLOT(sendPgDn())));
#ifdef Q_WS_MAEMO_5
- input_toolbuttons->addAction(toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/chat_enter.png"), "", this, SLOT(sendReturn())));
- input_toolbuttons->addAction(toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/control_keyboard.png"), "", this, SLOT(showInputPanel())));
+ input_toolbuttons->addAction(toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/chat_enter.png"), "", this, SLOT(sendReturn())));
+ input_toolbuttons->addAction(toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/control_keyboard.png"), "", this, SLOT(showInputPanel())));
#endif
- QSettings settings;
- zoom_slider = new QSlider(Qt::Horizontal, 0);
- zoom_slider->setRange(0, 100);
- connect(zoom_slider, SIGNAL(valueChanged(int)),
- this, SLOT(setZoomLevel(int)));
- connect(zoom_slider, SIGNAL(sliderReleased()),
- this, SLOT(zoomSliderReleased()));
- zoom_slider->setValue(settings.value("zoomlevel", 95).toInt());
- toolbar->addWidget(zoom_slider);
-
- toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/general_fullsize.png"), "", this, SLOT(toggleFullscreen()));
- addToolBar(toolbar);
- toolbar->setVisible(settings.value("show_toolbar", true).toBool());
- toolbar->setEnabled(false);
-
- //set up menu
- QAction *connect_action = new QAction(tr("Connect"), this);
- disconnect_action = new QAction(tr("Disconnect"), this);
- show_toolbar = new QAction(tr("Show toolbar"), this);
- show_toolbar->setCheckable(true);
- show_toolbar->setChecked(settings.value("show_toolbar", true).toBool());
- QAction *pref_action = new QAction(tr("Preferences"), this);
- QAction *about_action = new QAction(tr("About"), this);
+ QSettings settings;
+ zoom_slider = new QSlider(Qt::Horizontal, 0);
+ zoom_slider->setRange(0, 100);
+ connect(zoom_slider, SIGNAL(valueChanged(int)),
+ this, SLOT(setZoomLevel(int)));
+ connect(zoom_slider, SIGNAL(sliderReleased()),
+ this, SLOT(zoomSliderReleased()));
+ zoom_slider->setValue(settings.value("zoomlevel", 95).toInt());
+ toolbar->addWidget(zoom_slider);
+
+ toolbar->addAction(QIcon("/usr/share/icons/hicolor/48x48/hildon/general_fullsize.png"), "", this, SLOT(toggleFullscreen()));
+ addToolBar(toolbar);
+ toolbar->setVisible(settings.value("show_toolbar", true).toBool());
+ toolbar->setEnabled(false);
+
+ //set up menu
+ QAction *connect_action = new QAction(tr("Connect"), this);
+ disconnect_action = new QAction(tr("Disconnect"), this);
+ show_toolbar = new QAction(tr("Show toolbar"), this);
+ show_toolbar->setCheckable(true);
+ show_toolbar->setChecked(settings.value("show_toolbar", true).toBool());
+ QAction *pref_action = new QAction(tr("Preferences"), this);
+ QAction *about_action = new QAction(tr("About"), this);
#ifdef Q_WS_MAEMO_5
- menuBar()->addAction(connect_action);
- menuBar()->addAction(disconnect_action);
- menuBar()->addAction(show_toolbar);
- menuBar()->addAction(pref_action);
- menuBar()->addAction(about_action);
+ menuBar()->addAction(connect_action);
+ menuBar()->addAction(disconnect_action);
+ menuBar()->addAction(show_toolbar);
+ menuBar()->addAction(pref_action);
+ menuBar()->addAction(about_action);
#else
- QMenu* session_menu = menuBar()->addMenu(tr("&Session"));
- session_menu->addAction(connect_action);
- session_menu->addAction(disconnect_action);
- session_menu->addSeparator();
- session_menu->addAction(pref_action);
- session_menu->addSeparator();
- session_menu->addAction(tr("&Quit"), this, SLOT(close()));
-
- QMenu* view_menu = menuBar()->addMenu(tr("&View"));
- view_menu->addAction(show_toolbar);
-
- QMenu* help_menu = menuBar()->addMenu(tr("&Help"));
- help_menu->addAction(about_action);
+ QMenu* session_menu = menuBar()->addMenu(tr("&Session"));
+ session_menu->addAction(connect_action);
+ session_menu->addAction(disconnect_action);
+ session_menu->addSeparator();
+ session_menu->addAction(pref_action);
+ session_menu->addSeparator();
+ session_menu->addAction(tr("&Quit"), this, SLOT(close()));
+
+ QMenu* view_menu = menuBar()->addMenu(tr("&View"));
+ view_menu->addAction(show_toolbar);
+
+ QMenu* help_menu = menuBar()->addMenu(tr("&Help"));
+ help_menu->addAction(about_action);
#endif
- connect(about_action, SIGNAL(triggered()),
- this, SLOT(about()));
- connect(pref_action, SIGNAL(triggered()),
- this, SLOT(showPreferences()));
- connect(connect_action, SIGNAL(triggered()),
- this, SLOT(showConnectDialog()));
- connect(disconnect_action, SIGNAL(triggered()),
- this, SLOT(disconnectFromHost()));
- connect(show_toolbar, SIGNAL(toggled(bool)),
- toolbar, SLOT(setVisible(bool)));
- connect(show_toolbar, SIGNAL(toggled(bool)),
- this, SLOT(updateScreenSpaceDelayed()));
+ connect(about_action, SIGNAL(triggered()),
+ this, SLOT(about()));
+ connect(pref_action, SIGNAL(triggered()),
+ this, SLOT(showPreferences()));
+ connect(connect_action, SIGNAL(triggered()),
+ this, SLOT(showConnectDialog()));
+ connect(disconnect_action, SIGNAL(triggered()),
+ this, SLOT(disconnectFromHost()));
+ connect(show_toolbar, SIGNAL(toggled(bool)),
+ toolbar, SLOT(setVisible(bool)));
+ connect(show_toolbar, SIGNAL(toggled(bool)),
+ this, SLOT(updateScreenSpaceDelayed()));
#ifdef Q_WS_MAEMO_5
QDBusConnection::systemBus().connect("", MCE_SIGNAL_PATH, MCE_SIGNAL_IF, MCE_DISPLAY_SIG,
- this, SLOT(displayStateChanged(QString)));
+ this, SLOT(displayStateChanged(QString)));
#endif
- setCentralWidget(scroll_area);
+ setCentralWidget(scroll_area);
- FullScreenExitButton* fullscreen_exit_button = new FullScreenExitButton(this);
- connect(fullscreen_exit_button, SIGNAL(clicked()),
- this, SLOT(toggleFullscreen()));
+ FullScreenExitButton* fullscreen_exit_button = new FullScreenExitButton(this);
+ connect(fullscreen_exit_button, SIGNAL(clicked()),
+ this, SLOT(toggleFullscreen()));
- grabZoomKeys(true);
- reloadSettings();
+ grabZoomKeys(true);
+ reloadSettings();
- if(url.isEmpty() and listen_port == 0) {
- disconnect_action->setEnabled(false);
- showConnectDialog();
- } else {
- connectToHost(url, quality, listen_port, view_only);
- }
+ if(url.isEmpty() and listen_port == 0) {
+ disconnect_action->setEnabled(false);
+ showConnectDialog();
+ } else {
+ connectToHost(url, quality, listen_port, view_only);
+ }
}
void MainWindow::grabZoomKeys(bool grab)
{
#ifdef Q_WS_MAEMO_5
- unsigned long val = (grab)?1:0;
- Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False);
- if(!atom) {
- qWarning("Couldn't get zoom key atom");
- return;
- }
- XChangeProperty(QX11Info::display(), winId(), atom, XA_INTEGER,
- 32, PropModeReplace, reinterpret_cast<unsigned char *>(&val), 1);
+ unsigned long val = (grab)?1:0;
+ Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False);
+ if(!atom) {
+ qWarning("Couldn't get zoom key atom");
+ return;
+ }
+ XChangeProperty(QX11Info::display(), winId(), atom, XA_INTEGER,
+ 32, PropModeReplace, reinterpret_cast<unsigned char *>(&val), 1);
#endif
}
void MainWindow::closeEvent(QCloseEvent*) {
- grabZoomKeys(false);
+ grabZoomKeys(false);
- QSettings settings;
- settings.setValue("show_toolbar", show_toolbar->isChecked());
- settings.setValue("zoomlevel", zoom_slider->value());
- settings.sync();
+ QSettings settings;
+ settings.setValue("show_toolbar", show_toolbar->isChecked());
+ settings.setValue("zoomlevel", zoom_slider->value());
+ settings.sync();
- hide();
+ hide();
- disconnectFromHost();
+ disconnectFromHost();
}
void MainWindow::about() {
- QMessageBox::about(this, tr("About Presence VNC"),
- tr("<center><h1>Presence VNC 0.8</h1>\
-<p>A touchscreen friendly VNC client</p>\
-<p><a href=\"http://presencevnc.garage.maemo.org/\">http://presencevnc.garage.maemo.org/</a></p></center>\
-<small><p>©2010 Christian Pulvermacher <pulvermacher@gmx.de><br />\
-Based on KRDC, © 2007-2008 Urs Wolfer<br />\
-and LibVNCServer, © 2001-2003 Johannes E. Schindelin</p>\
-<p>This program is free software; License: <a href=\"http://www.gnu.org/licenses/gpl-2.0.html\">GNU GPL 2</a> or later.</p></small>"));
+ QMessageBox::about(this, tr("About Presence VNC"),
+ tr("<center><h1>Presence VNC 0.8</h1>\
+ <p>A touchscreen friendly VNC client</p>\
+ <p><a href=\"http://presencevnc.garage.maemo.org/\">http://presencevnc.garage.maemo.org/</a></p></center>\
+ <small><p>©2010 Christian Pulvermacher <pulvermacher@gmx.de><br />\
+ Based on KRDC, © 2007-2008 Urs Wolfer<br />\
+ and LibVNCServer, © 2001-2003 Johannes E. Schindelin</p>\
+ <p>This program is free software; License: <a href=\"http://www.gnu.org/licenses/gpl-2.0.html\">GNU GPL 2</a> or later.</p></small>"));
}
void MainWindow::showConnectDialog()
{
- ConnectDialog *connect_dialog = new ConnectDialog(this);
- connect(connect_dialog, SIGNAL(connectToHost(QString, int, int, bool)),
- this, SLOT(connectToHost(QString, int, int, bool)));
- connect_dialog->exec();
- //ConnectDialog cleans up after itself
+ ConnectDialog *connect_dialog = new ConnectDialog(this);
+ connect(connect_dialog, SIGNAL(connectToHost(QString, int, int, bool)),
+ this, SLOT(connectToHost(QString, int, int, bool)));
+ connect_dialog->exec();
+ //ConnectDialog cleans up after itself
}
void MainWindow::connectToHost(QString url, int quality, int listen_port, bool view_only)
{
- disconnectFromHost();
+ disconnectFromHost();
- vnc_view = new VncView(this, url, RemoteView::Quality(quality), listen_port);
- vnc_view->setViewOnly(view_only);
+ vnc_view = new VncView(this, url, RemoteView::Quality(quality), listen_port);
+ vnc_view->setViewOnly(view_only);
- connect(vnc_view, SIGNAL(statusChanged(RemoteView::RemoteStatus)),
- this, SLOT(statusChanged(RemoteView::RemoteStatus)));
- scroll_area->setWidget(vnc_view);
- vnc_view->start();
+ connect(vnc_view, SIGNAL(statusChanged(RemoteView::RemoteStatus)),
+ this, SLOT(statusChanged(RemoteView::RemoteStatus)));
+ scroll_area->setWidget(vnc_view);
+ vnc_view->start();
- disconnect_action->setEnabled(true);
+ disconnect_action->setEnabled(true);
- //reset key menu
- delete key_menu;
- key_menu = new KeyMenu(this);
+ //reset key menu
+ delete key_menu;
+ key_menu = new KeyMenu(this);
}
void MainWindow::disconnectFromHost()
{
- if(!vnc_view)
- return;
+ if(!vnc_view)
+ return;
- disconnect_action->setEnabled(false);
- toolbar->setEnabled(false);
- scroll_area->setWidget(0);
+ disconnect_action->setEnabled(false);
+ toolbar->setEnabled(false);
+ scroll_area->setWidget(0);
- delete vnc_view;
- vnc_view = 0;
+ delete vnc_view;
+ vnc_view = 0;
}
void MainWindow::statusChanged(RemoteView::RemoteStatus status)
{
- static RemoteView::RemoteStatus old_status = RemoteView::Disconnected;
+ static RemoteView::RemoteStatus old_status = RemoteView::Disconnected;
- switch(status) {
- case RemoteView::Connecting:
+ switch(status) {
+ case RemoteView::Connecting:
#ifdef Q_WS_MAEMO_5
- setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
+ setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
#endif
- break;
- case RemoteView::Connected:
+ break;
+ case RemoteView::Connected:
#ifdef Q_WS_MAEMO_5
- setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
+ setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
#endif
- toolbar->setEnabled(true);
-
- //disable key input buttons in view only mode
- input_toolbuttons->setEnabled(!vnc_view->viewOnly());
-
- vnc_view->setZoomLevel(zoom_slider->value());
- vnc_view->useFastTransformations(false);
- vnc_view->repaint();
- break;
- case RemoteView::Disconnecting:
- if(old_status == RemoteView::Disconnected) //Disconnecting also occurs while connecting, so check last state
- break;
-
- if(disconnect_action->isEnabled()) //don't show when manually disconnecting
- scroll_area->showMessage(tr("Connection lost"));
-
- //clean up
- scroll_area->setWidget(0);
- vnc_view = 0;
- disconnect_action->setEnabled(false);
- toolbar->setEnabled(false);
-
- //exit fullscreen mode
- if(windowState() & Qt::WindowFullScreen)
- setWindowState(windowState() ^ Qt::WindowFullScreen);
- break;
- case RemoteView::Disconnected:
+ toolbar->setEnabled(true);
+
+ //disable key input buttons in view only mode
+ input_toolbuttons->setEnabled(!vnc_view->viewOnly());
+
+ vnc_view->setZoomLevel(zoom_slider->value());
+ vnc_view->useFastTransformations(false);
+ vnc_view->repaint();
+ break;
+ case RemoteView::Disconnecting:
+ if(old_status == RemoteView::Disconnected) //Disconnecting also occurs while connecting, so check last state
+ break;
+
+ if(disconnect_action->isEnabled()) //don't show when manually disconnecting
+ scroll_area->showMessage(tr("Connection lost"));
+
+ //clean up
+ scroll_area->setWidget(0);
+ vnc_view = 0;
+ disconnect_action->setEnabled(false);
+ toolbar->setEnabled(false);
+
+ //exit fullscreen mode
+ if(windowState() & Qt::WindowFullScreen)
+ setWindowState(windowState() ^ Qt::WindowFullScreen);
+ break;
+ case RemoteView::Disconnected:
#ifdef Q_WS_MAEMO_5
- setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
+ setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
#endif
- if(old_status == RemoteView::Disconnecting) {
- scroll_area->setWidget(0); //remove widget
- }
- break;
- default: //avoid compiler warnings
- break;
- }
-
- old_status = status;
+ if(old_status == RemoteView::Disconnecting) {
+ scroll_area->setWidget(0); //remove widget
+ }
+ break;
+ default: //avoid compiler warnings
+ break;
+ }
+
+ old_status = status;
}
//updates available screen space for current zoom level
//necessary when rotating, showing fullscreen, etc.
void MainWindow::updateScreenSpace()
{
- if(vnc_view) {
- vnc_view->setZoomLevel();
- }
+ if(vnc_view) {
+ vnc_view->setZoomLevel();
+ }
}
void MainWindow::updateScreenSpaceDelayed()
{
- QTimer::singleShot(500, this, SLOT(updateScreenSpace()));
+ QTimer::singleShot(500, this, SLOT(updateScreenSpace()));
}
void MainWindow::toggleFullscreen()
{
- bool in_fullscreen = windowState() & Qt::WindowFullScreen;
+ bool in_fullscreen = windowState() & Qt::WindowFullScreen;
- //hide menu/toolbar in fullscreen (new state is !in_fullscreen)
- toolbar->setVisible(show_toolbar->isChecked() and in_fullscreen);
+ //hide menu/toolbar in fullscreen (new state is !in_fullscreen)
+ toolbar->setVisible(show_toolbar->isChecked() and in_fullscreen);
#ifndef Q_WS_MAEMO_5
- //menu bar is invisible by default on maemo
- menuBar()->setVisible(in_fullscreen);
+ //menu bar is invisible by default on maemo
+ menuBar()->setVisible(in_fullscreen);
#endif
- setWindowState(windowState() ^ Qt::WindowFullScreen);
- updateScreenSpaceDelayed();
+ setWindowState(windowState() ^ Qt::WindowFullScreen);
+ updateScreenSpaceDelayed();
}
void MainWindow::showKeyMenu()
{
- key_menu->exec();
- vnc_view->sendKeySequence(key_menu->getKeySequence());
+ key_menu->exec();
+ vnc_view->sendKeySequence(key_menu->getKeySequence());
}
void MainWindow::showPreferences()
{
- Preferences *p = new Preferences(this);
- p->exec();
- delete p;
+ Preferences *p = new Preferences(this);
+ p->exec();
+ delete p;
- reloadSettings();
+ reloadSettings();
}
void MainWindow::reloadSettings()
{
- QSettings settings;
- zoom_to_cursor = settings.value("zoom_to_cursor", true).toBool();
-
+ QSettings settings;
+ zoom_to_cursor = settings.value("zoom_to_cursor", true).toBool();
+
#ifdef Q_WS_MAEMO_5
- int rotation = settings.value("screen_rotation", 0).toInt();
- setAttribute(Qt::WA_Maemo5AutoOrientation, rotation == 0);
- setAttribute(Qt::WA_Maemo5LandscapeOrientation, rotation == 1);
- setAttribute(Qt::WA_Maemo5PortraitOrientation, rotation == 2);
+ int rotation = settings.value("screen_rotation", 0).toInt();
+ setAttribute(Qt::WA_Maemo5AutoOrientation, rotation == 0);
+ setAttribute(Qt::WA_Maemo5LandscapeOrientation, rotation == 1);
+ setAttribute(Qt::WA_Maemo5PortraitOrientation, rotation == 2);
#endif
- if(vnc_view)
- vnc_view->reloadSettings();
+ if(vnc_view)
+ vnc_view->reloadSettings();
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
- QMainWindow::resizeEvent(event);
+ QMainWindow::resizeEvent(event);
+
+ updateScreenSpace();
+ if(vnc_view)
+ vnc_view->setZoomLevel(zoom_slider->value());
- updateScreenSpace();
- if(vnc_view)
- vnc_view->setZoomLevel(zoom_slider->value());
-
#ifdef Q_WS_MAEMO_5
- //hide zoom slider in portrait mode
- zoom_slider->setVisible(height() < width());
+ //hide zoom slider in portrait mode
+ zoom_slider->setVisible(height() < width());
#endif
}
void MainWindow::showInputPanel()
{
#ifdef Q_WS_MAEMO_5
- //TODO: when hardware keyboard is open, this will only cause the IM to mess up 'real' key events
- vnc_view->setAttribute(Qt::WA_InputMethodEnabled, true);
- vnc_view->setInputMethodHints(Qt::ImhNoAutoUppercase); //without this, IM starts with caps lock
+ //TODO: when hardware keyboard is open, this will only cause the IM to mess up 'real' key events
+ vnc_view->setAttribute(Qt::WA_InputMethodEnabled, true);
+ vnc_view->setInputMethodHints(Qt::ImhNoAutoUppercase); //without this, IM starts with caps lock
- QEvent event(QEvent::RequestSoftwareInputPanel);
- QApplication::sendEvent(vnc_view, &event);
+ QEvent event(QEvent::RequestSoftwareInputPanel);
+ QApplication::sendEvent(vnc_view, &event);
#endif
}
void MainWindow::setZoomLevel(int level)
{
- if(!vnc_view)
- return;
-
- const qreal old_factor = vnc_view->zoomFactor();
- QPoint center = vnc_view->visibleRegion().boundingRect().center();
+ if(!vnc_view)
+ return;
- vnc_view->setZoomLevel(level);
+ const qreal old_factor = vnc_view->zoomFactor();
+ QPoint center = vnc_view->visibleRegion().boundingRect().center();
- const qreal new_factor = vnc_view->zoomFactor();
+ vnc_view->setZoomLevel(level);
- //scroll to center, if zoom level actually changed
- if(old_factor != new_factor) {
- if(zoom_to_cursor)
- center = new_factor * vnc_view->cursorPosition();
- else //zoom to center of visible region
- center = center * (double(new_factor)/old_factor);
+ const qreal new_factor = vnc_view->zoomFactor();
- scroll_area->ensureVisible(center.x(), center.y(),
- vnc_view->visibleRegion().boundingRect().width()/2,
- vnc_view->visibleRegion().boundingRect().height()/2);
+ //scroll to center, if zoom level actually changed
+ if(old_factor != new_factor) {
+ if(zoom_to_cursor)
+ center = new_factor * vnc_view->cursorPosition();
+ else //zoom to center of visible region
+ center = center * (double(new_factor)/old_factor);
- vnc_view->useFastTransformations(zoom_slider->isSliderDown());
- vnc_view->update();
+ scroll_area->ensureVisible(center.x(), center.y(),
+ vnc_view->visibleRegion().boundingRect().width()/2,
+ vnc_view->visibleRegion().boundingRect().height()/2);
- scroll_area->showMessage(tr("Zoom: %1\%").arg(qRound(100*new_factor)));
- }
+ vnc_view->useFastTransformations(zoom_slider->isSliderDown());
+ vnc_view->update();
+
+ scroll_area->showMessage(tr("Zoom: %1\%").arg(qRound(100*new_factor)));
+ }
}
void MainWindow::zoomSliderReleased()
{
- static QTime time;
- if(!time.isNull() and time.elapsed() < 500) //double clicked
- zoom_slider->setValue(95); //100%
-
- time.restart();
-
- //stopped zooming, reenable high quality
- vnc_view->useFastTransformations(false);
+ static QTime time;
+ if(!time.isNull() and time.elapsed() < 500) //double clicked
+ zoom_slider->setValue(95); //100%
+
+ time.restart();
+
+ //stopped zooming, reenable high quality
+ vnc_view->useFastTransformations(false);
}
void MainWindow::displayStateChanged(QString state)
/*
- Presence VNC
- Copyright (C) 2010 Christian Pulvermacher
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ Presence VNC
+ Copyright (C) 2010 Christian Pulvermacher
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
#include <QtGui>
#ifdef Q_WS_MAEMO_5
void migrateConfiguration()
{
- QSettings settings;
- int config_ver = settings.value("config_version", 0).toInt();
- const int current_ver = 3;
- if(config_ver == current_ver) //config file up-to-date
- return;
- if(config_ver > current_ver) {
- std::cout << "Warning: Config file was created by a newer version of Presence VNC. This may break things.\n";
- return;
- }
-
- if(settings.allKeys().isEmpty()) { //no config file
- settings.setValue("config_version", current_ver);
- settings.sync();
- return;
- }
-
- std::cout << "Migrating from configuration ver. " << config_ver << "\n";
-
- if(config_ver == 0) {
- int left_zoom = settings.value("left_zoom", 0).toInt();
- int right_zoom = settings.value("left_zoom", 0).toInt();
- if(left_zoom >= 2)
- settings.setValue("left_zoom", left_zoom+1);
- if(right_zoom >= 2)
- settings.setValue("left_zoom", right_zoom+1);
- config_ver = 1;
- }
- if(config_ver == 1) {
- QString last_hostname = settings.value("last_hostname", "").toString();
- settings.remove("last_hostname");
- if(!last_hostname.isEmpty()) {
- //make sure hostname is sane
- last_hostname.remove(QChar('/'));
- last_hostname.remove(QChar('\\'));
- last_hostname = last_hostname.toLower();
-
- settings.setValue(QString("hosts/%1/position").arg(last_hostname), 0);
- }
-
- config_ver = 2;
- }
- if(config_ver == 2) {
- bool rescale = settings.value("rescale", false).toBool();
- settings.remove("rescale");
-
- int zoomlevel;
- if(rescale)
- zoomlevel = 0;
- else
- zoomlevel = 95;
-
- settings.setValue("zoomlevel", zoomlevel);
-
- config_ver = 3;
- }
- Q_ASSERT(config_ver == current_ver);
- settings.setValue("config_version", config_ver);
- settings.sync();
+ QSettings settings;
+ int config_ver = settings.value("config_version", 0).toInt();
+ const int current_ver = 3;
+ if(config_ver == current_ver) //config file up-to-date
+ return;
+ if(config_ver > current_ver) {
+ std::cout << "Warning: Config file was created by a newer version of Presence VNC. This may break things.\n";
+ return;
+ }
+
+ if(settings.allKeys().isEmpty()) { //no config file
+ settings.setValue("config_version", current_ver);
+ settings.sync();
+ return;
+ }
+
+ std::cout << "Migrating from configuration ver. " << config_ver << "\n";
+
+ if(config_ver == 0) {
+ int left_zoom = settings.value("left_zoom", 0).toInt();
+ int right_zoom = settings.value("left_zoom", 0).toInt();
+ if(left_zoom >= 2)
+ settings.setValue("left_zoom", left_zoom+1);
+ if(right_zoom >= 2)
+ settings.setValue("left_zoom", right_zoom+1);
+ config_ver = 1;
+ }
+ if(config_ver == 1) {
+ QString last_hostname = settings.value("last_hostname", "").toString();
+ settings.remove("last_hostname");
+ if(!last_hostname.isEmpty()) {
+ //make sure hostname is sane
+ last_hostname.remove(QChar('/'));
+ last_hostname.remove(QChar('\\'));
+ last_hostname = last_hostname.toLower();
+
+ settings.setValue(QString("hosts/%1/position").arg(last_hostname), 0);
+ }
+
+ config_ver = 2;
+ }
+ if(config_ver == 2) {
+ bool rescale = settings.value("rescale", false).toBool();
+ settings.remove("rescale");
+
+ int zoomlevel;
+ if(rescale)
+ zoomlevel = 0;
+ else
+ zoomlevel = 95;
+
+ settings.setValue("zoomlevel", zoomlevel);
+
+ config_ver = 3;
+ }
+ Q_ASSERT(config_ver == current_ver);
+ settings.setValue("config_version", config_ver);
+ settings.sync();
}
Preferences::Preferences(QWidget *parent):
- QDialog(parent)
+ QDialog(parent)
{
- setWindowTitle(tr("Preferences"));
+ setWindowTitle(tr("Preferences"));
- QHBoxLayout *layout1 = new QHBoxLayout();
- QVBoxLayout *layout2 = new QVBoxLayout();
+ QHBoxLayout *layout1 = new QHBoxLayout();
+ QVBoxLayout *layout2 = new QVBoxLayout();
#ifdef Q_WS_MAEMO_5
- QMaemo5ValueButton *rotation = new QMaemo5ValueButton(tr("Screen rotation"), this);
- rotation_selector = new QMaemo5ListPickSelector(this);
- QStandardItemModel *model = new QStandardItemModel(0, 1, this);
- model->appendRow(new QStandardItem(tr("Automatic")));
- model->appendRow(new QStandardItem(tr("Landscape")));
- model->appendRow(new QStandardItem(tr("Portrait")));
- rotation_selector->setModel(model);
- rotation_selector->setCurrentIndex(settings.value("screen_rotation", 0).toInt());
- rotation->setPickSelector(rotation_selector);
- rotation->setValueLayout(QMaemo5ValueButton::ValueBesideText);
- layout2->addWidget(rotation);
-
- QMaemo5ValueButton *leftzoom = new QMaemo5ValueButton(tr("Left zoom button"), this);
- leftzoom_selector = new QMaemo5ListPickSelector(this);
- QStandardItemModel *key_model = new QStandardItemModel(0, 1, this);
- key_model->insertRow(0, new QStandardItem(tr("Left click")));
- key_model->insertRow(1, new QStandardItem(tr("Right click")));
- key_model->insertRow(2, new QStandardItem(tr("Middle click")));
- key_model->insertRow(3, new QStandardItem(tr("Wheel up")));
- key_model->insertRow(4, new QStandardItem(tr("Wheel down")));
- key_model->insertRow(5, new QStandardItem(tr("Page up")));
- key_model->insertRow(6, new QStandardItem(tr("Page down")));
- leftzoom_selector->setModel(key_model);
- leftzoom_selector->setCurrentIndex(settings.value("left_zoom", 0).toInt());
- leftzoom->setPickSelector(leftzoom_selector);
- leftzoom->setValueLayout(QMaemo5ValueButton::ValueBesideText);
- layout2->addWidget(leftzoom);
-
- QMaemo5ValueButton *rightzoom = new QMaemo5ValueButton(tr("Right zoom button"), this);
- rightzoom_selector = new QMaemo5ListPickSelector(this);
- rightzoom_selector->setModel(key_model);
- rightzoom_selector->setCurrentIndex(settings.value("right_zoom", 1).toInt());
- rightzoom->setPickSelector(rightzoom_selector);
- rightzoom->setValueLayout(QMaemo5ValueButton::ValueBesideText);
- layout2->addWidget(rightzoom);
-
- //useful if one only wants to click using the zoom buttons exclusively
- disable_tapping = new QCheckBox(tr("Disable tapping"), this);
- disable_tapping->setChecked(settings.value("disable_tapping", false).toBool());
- layout2->addWidget(disable_tapping);
+ QMaemo5ValueButton *rotation = new QMaemo5ValueButton(tr("Screen rotation"), this);
+ rotation_selector = new QMaemo5ListPickSelector(this);
+ QStandardItemModel *model = new QStandardItemModel(0, 1, this);
+ model->appendRow(new QStandardItem(tr("Automatic")));
+ model->appendRow(new QStandardItem(tr("Landscape")));
+ model->appendRow(new QStandardItem(tr("Portrait")));
+ rotation_selector->setModel(model);
+ rotation_selector->setCurrentIndex(settings.value("screen_rotation", 0).toInt());
+ rotation->setPickSelector(rotation_selector);
+ rotation->setValueLayout(QMaemo5ValueButton::ValueBesideText);
+ layout2->addWidget(rotation);
+
+ QMaemo5ValueButton *leftzoom = new QMaemo5ValueButton(tr("Left zoom button"), this);
+ leftzoom_selector = new QMaemo5ListPickSelector(this);
+ QStandardItemModel *key_model = new QStandardItemModel(0, 1, this);
+ key_model->insertRow(0, new QStandardItem(tr("Left click")));
+ key_model->insertRow(1, new QStandardItem(tr("Right click")));
+ key_model->insertRow(2, new QStandardItem(tr("Middle click")));
+ key_model->insertRow(3, new QStandardItem(tr("Wheel up")));
+ key_model->insertRow(4, new QStandardItem(tr("Wheel down")));
+ key_model->insertRow(5, new QStandardItem(tr("Page up")));
+ key_model->insertRow(6, new QStandardItem(tr("Page down")));
+ leftzoom_selector->setModel(key_model);
+ leftzoom_selector->setCurrentIndex(settings.value("left_zoom", 0).toInt());
+ leftzoom->setPickSelector(leftzoom_selector);
+ leftzoom->setValueLayout(QMaemo5ValueButton::ValueBesideText);
+ layout2->addWidget(leftzoom);
+
+ QMaemo5ValueButton *rightzoom = new QMaemo5ValueButton(tr("Right zoom button"), this);
+ rightzoom_selector = new QMaemo5ListPickSelector(this);
+ rightzoom_selector->setModel(key_model);
+ rightzoom_selector->setCurrentIndex(settings.value("right_zoom", 1).toInt());
+ rightzoom->setPickSelector(rightzoom_selector);
+ rightzoom->setValueLayout(QMaemo5ValueButton::ValueBesideText);
+ layout2->addWidget(rightzoom);
+
+ //useful if one only wants to click using the zoom buttons exclusively
+ disable_tapping = new QCheckBox(tr("Disable tapping"), this);
+ disable_tapping->setChecked(settings.value("disable_tapping", false).toBool());
+ layout2->addWidget(disable_tapping);
#endif
- always_show_local_cursor = new QCheckBox(tr("Always show local cursor"), this);
- always_show_local_cursor->setChecked(settings.value("always_show_local_cursor", false).toBool());
- layout2->addWidget(always_show_local_cursor);
+ always_show_local_cursor = new QCheckBox(tr("Always show local cursor"), this);
+ always_show_local_cursor->setChecked(settings.value("always_show_local_cursor", false).toBool());
+ layout2->addWidget(always_show_local_cursor);
- zoom_to_cursor = new QCheckBox(tr("Zoom to cursor"), this);
- zoom_to_cursor->setChecked(settings.value("zoom_to_cursor", true).toBool());
- layout2->addWidget(zoom_to_cursor);
+ zoom_to_cursor = new QCheckBox(tr("Zoom to cursor"), this);
+ zoom_to_cursor->setChecked(settings.value("zoom_to_cursor", true).toBool());
+ layout2->addWidget(zoom_to_cursor);
- QPushButton *ok = new QPushButton(tr("Done"));
- ok->setMaximumWidth(100);
+ QPushButton *ok = new QPushButton(tr("Done"));
+ ok->setMaximumWidth(100);
- layout1->addLayout(layout2);
- layout1->addWidget(ok);
+ layout1->addLayout(layout2);
+ layout1->addWidget(ok);
- setLayout(layout1);
+ setLayout(layout1);
- connect(ok, SIGNAL(clicked()),
- this, SLOT(accept()));
- connect(this, SIGNAL(accepted()),
- this, SLOT(save()));
+ connect(ok, SIGNAL(clicked()),
+ this, SLOT(accept()));
+ connect(this, SIGNAL(accepted()),
+ this, SLOT(save()));
}
void Preferences::save()
{
#ifdef Q_WS_MAEMO_5
- settings.setValue("screen_rotation", rotation_selector->currentIndex());
- settings.setValue("left_zoom", leftzoom_selector->currentIndex());
- settings.setValue("right_zoom", rightzoom_selector->currentIndex());
- settings.setValue("disable_tapping", disable_tapping->isChecked());
+ settings.setValue("screen_rotation", rotation_selector->currentIndex());
+ settings.setValue("left_zoom", leftzoom_selector->currentIndex());
+ settings.setValue("right_zoom", rightzoom_selector->currentIndex());
+ settings.setValue("disable_tapping", disable_tapping->isChecked());
#endif
- settings.setValue("always_show_local_cursor", always_show_local_cursor->isChecked());
- settings.setValue("zoom_to_cursor", zoom_to_cursor->isChecked());
+ settings.setValue("always_show_local_cursor", always_show_local_cursor->isChecked());
+ settings.setValue("zoom_to_cursor", zoom_to_cursor->isChecked());
- settings.sync();
+ settings.sync();
}
cl->format.blueMax = 0xff;
switch (t->quality()) {
- case RemoteView::High:
- cl->appData.useBGR233 = 0;
- cl->appData.encodingsString = "copyrect hextile raw";
- cl->appData.compressLevel = 0;
- cl->appData.qualityLevel = 9;
- break;
- case RemoteView::Medium:
- cl->appData.useBGR233 = 0;
- cl->appData.encodingsString = "tight zrle ultra copyrect hextile zlib corre rre raw";
- cl->appData.compressLevel = 5;
- cl->appData.qualityLevel = 7;
- break;
- case RemoteView::Low:
- case RemoteView::Unknown:
- default:
- cl->appData.useBGR233 = 1;
- cl->appData.encodingsString = "tight zrle ultra copyrect hextile zlib corre rre raw";
- cl->appData.compressLevel = 9;
- cl->appData.qualityLevel = 1;
+ case RemoteView::High:
+ cl->appData.useBGR233 = 0;
+ cl->appData.encodingsString = "copyrect hextile raw";
+ cl->appData.compressLevel = 0;
+ cl->appData.qualityLevel = 9;
+ break;
+ case RemoteView::Medium:
+ cl->appData.useBGR233 = 0;
+ cl->appData.encodingsString = "tight zrle ultra copyrect hextile zlib corre rre raw";
+ cl->appData.compressLevel = 5;
+ cl->appData.qualityLevel = 7;
+ break;
+ case RemoteView::Low:
+ case RemoteView::Unknown:
+ default:
+ cl->appData.useBGR233 = 1;
+ cl->appData.encodingsString = "tight zrle ultra copyrect hextile zlib corre rre raw";
+ cl->appData.compressLevel = 9;
+ cl->appData.qualityLevel = 1;
}
SetFormatAndEncodings(cl);
void VncClientThread::updatefb(rfbClient* cl, int x, int y, int w, int h)
{
- //kDebug(5011) << "updated client: x: " << x << ", y: " << y << ", w: " << w << ", h: " << h;
+ //kDebug(5011) << "updated client: x: " << x << ", y: " << y << ", w: " << w << ", h: " << h;
const int width = cl->width, height = cl->height;
void VncClientThread::setPassword(const QString &password)
{
- if(password.isNull()) //cancelled, don't retry
- m_passwordError = false;
+ if(password.isNull()) //cancelled, don't retry
+ m_passwordError = false;
- m_password = password;
+ m_password = password;
}
void VncClientThread::outputHandler(const char *format, ...)
outputErrorMessageString = "INTERNAL:APPLE_VNC_COMPATIBILTY";
}
-VncClientThread::VncClientThread(QObject *parent)
- : QThread(parent)
- , frameBuffer(0)
+ VncClientThread::VncClientThread(QObject *parent)
+ : QThread(parent)
+ , frameBuffer(0)
{
QMutexLocker locker(&mutex);
m_stopped = false;
const bool quitSuccess = wait(1000);
- if(!quitSuccess)
- kDebug(5011) << "~VncClientThread(): Quit failed";
-
+ if(!quitSuccess)
+ kDebug(5011) << "~VncClientThread(): Quit failed";
+
delete [] frameBuffer;
//cl is free()d when event loop exits.
}
void VncClientThread::stop()
{
- if(m_stopped)
- return;
+ if(m_stopped)
+ return;
- //also abort listening for connections, should be safe without locking
- if(listen_port)
- cl->listenSpecified = false;
+ //also abort listening for connections, should be safe without locking
+ if(listen_port)
+ cl->listenSpecified = false;
- QMutexLocker locker(&mutex);
- m_stopped = true;
+ QMutexLocker locker(&mutex);
+ m_stopped = true;
}
void VncClientThread::run()
int passwd_failures = 0;
while (!m_stopped) { // try to connect as long as the server allows
m_passwordError = false;
- outputErrorMessageString.clear(); //don't deliver error messages of old instances...
+ outputErrorMessageString.clear(); //don't deliver error messages of old instances...
rfbClientLog = outputHandler;
rfbClientErr = outputHandler;
m_port += 5900;
cl->serverPort = m_port;
- cl->listenSpecified = rfbBool(listen_port > 0);
- cl->listenPort = listen_port;
+ cl->listenSpecified = rfbBool(listen_port > 0);
+ cl->listenPort = listen_port;
kDebug(5011) << "--------------------- trying init ---------------------";
- if (rfbInitClient(cl, 0, 0))
- break;
+ if (rfbInitClient(cl, 0, 0))
+ break;
- //init failed...
+ //init failed...
if (m_passwordError) {
- passwd_failures++;
- if(passwd_failures < 3)
- continue; //that's ok, try again
- }
+ passwd_failures++;
+ if(passwd_failures < 3)
+ continue; //that's ok, try again
+ }
- //stop connecting
- m_stopped = true;
+ //stop connecting
+ m_stopped = true;
return; //no cleanup necessary, cl was free()d by rfbInitClient()
}
// Main VNC event loop
while (!m_stopped) {
const int i = WaitForMessage(cl, 500);
- if(m_stopped or i < 0)
- break;
+ if(m_stopped or i < 0)
+ break;
if (i)
if (!HandleRFBServerMessage(cl))
// Cleanup allocated resources
locker.relock();
- rfbClientCleanup(cl);
+ rfbClientCleanup(cl);
m_stopped = true;
}
void stop();
void setHost(const QString &host);
void setPort(int port);
- void setListenPort(int port) { listen_port = port; }
+ void setListenPort(int port) { listen_port = port; }
void setQuality(RemoteView::Quality quality);
void setPassword(const QString &password);
const QString password() const { return m_password; }
: RemoteView(parent),
m_initDone(false),
m_buttonMask(0),
- cursor_x(0),
- cursor_y(0),
+ cursor_x(0),
+ cursor_y(0),
m_quitFlag(false),
m_firstPasswordTry(true),
m_dontSendClipboard(false),
m_horizontalFactor(1.0),
m_verticalFactor(1.0),
m_forceLocalCursor(false),
- quality(quality),
- listen_port(listen_port),
- transformation_mode(Qt::FastTransformation),
- display_off(false)
+ quality(quality),
+ listen_port(listen_port),
+ transformation_mode(Qt::FastTransformation),
+ display_off(false)
{
m_url = url;
m_host = url.host();
m_port = url.port();
- //BlockingQueuedConnection can cause deadlocks when exiting, handled in startQuitting()
+ //BlockingQueuedConnection can cause deadlocks when exiting, handled in startQuitting()
connect(&vncThread, SIGNAL(imageUpdated(int, int, int, int)), this, SLOT(updateImage(int, int, int, int)), Qt::BlockingQueuedConnection);
connect(&vncThread, SIGNAL(gotCut(const QString&)), this, SLOT(setCut(const QString&)), Qt::BlockingQueuedConnection);
connect(&vncThread, SIGNAL(passwordRequest()), this, SLOT(requestPassword()), Qt::BlockingQueuedConnection);
connect(&vncThread, SIGNAL(outputErrorMessage(QString)), this, SLOT(outputErrorMessage(QString)));
- //don't miss early connection failures
- connect(&vncThread, SIGNAL(finished()), this, SLOT(startQuitting()));
+ //don't miss early connection failures
+ connect(&vncThread, SIGNAL(finished()), this, SLOT(startQuitting()));
m_clipboard = QApplication::clipboard();
connect(m_clipboard, SIGNAL(selectionChanged()), this, SLOT(clipboardSelectionChanged()));
event->type() == QEvent::Wheel ||
event->type() == QEvent::MouseMove) {
- event->ignore();
+ event->ignore();
return true;
}
}
void VncView::startQuitting()
{
- if(isQuitting())
- return;
+ if(isQuitting())
+ return;
kDebug(5011) << "about to quit";
vncThread.stop();
const bool quitSuccess = vncThread.wait(700);
- if(!quitSuccess) {
- //happens when vncThread wants to call a slot via BlockingQueuedConnection,
- //needs an event loop in this thread so execution continues after 'emit'
- QEventLoop loop;
- if(!loop.processEvents())
- kDebug(5011) << "BUG: deadlocked, but no events to deliver?";
- vncThread.wait(700);
- }
+ if(!quitSuccess) {
+ //happens when vncThread wants to call a slot via BlockingQueuedConnection,
+ //needs an event loop in this thread so execution continues after 'emit'
+ QEventLoop loop;
+ if(!loop.processEvents())
+ kDebug(5011) << "BUG: deadlocked, but no events to deliver?";
+ vncThread.wait(700);
+ }
setStatus(Disconnected);
}
return;
}
- QSettings settings;
- settings.beginGroup("hosts");
+ QSettings settings;
+ settings.beginGroup("hosts");
- //check for saved password
- QString password = settings.value(QString("%1/password").arg(m_host), "").toString();
- if(m_firstPasswordTry and !password.isEmpty()) {
- kDebug(5011) << "Trying saved password";
- m_firstPasswordTry = false;
- vncThread.setPassword(password);
- return;
- }
- m_firstPasswordTry = false;
-
- //build dialog
- QDialog dialog(this);
- dialog.setWindowTitle(tr("Password required"));
-
- QLineEdit passwordbox;
- passwordbox.setEchoMode(QLineEdit::Password);
- passwordbox.setText(password);
- QCheckBox save_password(tr("Save Password"));
- save_password.setChecked(!password.isEmpty()); //offer to overwrite saved password
- QPushButton ok_button(tr("Done"));
- ok_button.setMaximumWidth(100);
- connect(&ok_button, SIGNAL(clicked()),
- &dialog, SLOT(accept()));
-
- QHBoxLayout layout1;
- QVBoxLayout layout2;
- layout2.addWidget(&passwordbox);
- if(!m_host.isEmpty()) //don't save incoming connections
- layout2.addWidget(&save_password);
- layout1.addLayout(&layout2);
- layout1.addWidget(&ok_button);
- dialog.setLayout(&layout1);
-
- if(dialog.exec()) { //dialog accepted
- password = passwordbox.text();
-
- if(!m_host.isEmpty() and save_password.isChecked()) {
- kDebug(5011) << "Saving password for host '" << m_host << "'";
-
- settings.setValue(QString("%1/password").arg(m_host), password);
- settings.sync();
- }
+ //check for saved password
+ QString password = settings.value(QString("%1/password").arg(m_host), "").toString();
+ if(m_firstPasswordTry and !password.isEmpty()) {
+ kDebug(5011) << "Trying saved password";
+ m_firstPasswordTry = false;
+ vncThread.setPassword(password);
+ return;
+ }
+ m_firstPasswordTry = false;
+
+ //build dialog
+ QDialog dialog(this);
+ dialog.setWindowTitle(tr("Password required"));
+
+ QLineEdit passwordbox;
+ passwordbox.setEchoMode(QLineEdit::Password);
+ passwordbox.setText(password);
+ QCheckBox save_password(tr("Save Password"));
+ save_password.setChecked(!password.isEmpty()); //offer to overwrite saved password
+ QPushButton ok_button(tr("Done"));
+ ok_button.setMaximumWidth(100);
+ connect(&ok_button, SIGNAL(clicked()),
+ &dialog, SLOT(accept()));
+
+ QHBoxLayout layout1;
+ QVBoxLayout layout2;
+ layout2.addWidget(&passwordbox);
+ if(!m_host.isEmpty()) //don't save incoming connections
+ layout2.addWidget(&save_password);
+ layout1.addLayout(&layout2);
+ layout1.addWidget(&ok_button);
+ dialog.setLayout(&layout1);
+
+ if(dialog.exec()) { //dialog accepted
+ password = passwordbox.text();
+
+ if(!m_host.isEmpty() and save_password.isChecked()) {
+ kDebug(5011) << "Saving password for host '" << m_host << "'";
+
+ settings.setValue(QString("%1/password").arg(m_host), password);
+ settings.sync();
+ }
- vncThread.setPassword(password);
- } else {
- vncThread.setPassword(QString()); //null string to exit
- }
+ vncThread.setPassword(password);
+ } else {
+ vncThread.setPassword(QString()); //null string to exit
+ }
}
void VncView::outputErrorMessage(const QString &message)
void VncView::updateImage(int x, int y, int w, int h)
{
- //don't update if window is out of focus / display is off
- if(!QApplication::focusWidget() || display_off) {
- return;
- }
+ //don't update if window is out of focus / display is off
+ if(!QApplication::focusWidget() || display_off) {
+ return;
+ }
//kDebug(5011) << "got update" << width() << height();
setStatus(Connected);
emit connected();
- resize(width(), height());
+ resize(width(), height());
m_initDone = true;
-
}
static QSize old_frame_size = QSize();
if ((y == 0 && x == 0) && (m_frame.size() != old_frame_size)) {
old_frame_size = m_frame.size();
kDebug(5011) << "Updating framebuffer size";
- setZoomLevel();
- useFastTransformations(false);
+ setZoomLevel();
+ useFastTransformations(false);
emit framebufferSizeChanged(m_frame.width(), m_frame.height());
}
//level should be in [0, 100]
void VncView::setZoomLevel(int level)
{
- Q_ASSERT(parentWidget() != 0);
+ Q_ASSERT(parentWidget() != 0);
- if(level == -1) { //handle resize
- resize(m_frame.width()*m_horizontalFactor, m_frame.height()*m_verticalFactor);
- return;
- }
+ if(level == -1) { //handle resize
+ resize(m_frame.width()*m_horizontalFactor, m_frame.height()*m_verticalFactor);
+ return;
+ }
- double magnification;
- if(level == 100) {
- magnification = 2.0;
- } else if(level >= 90) {
- magnification = 1.0;
- } else {
- const double min_horiz_magnification = double(parentWidget()->width())/m_frame.width();
- const double min_vert_magnification = double(parentWidget()->height())/m_frame.height();
- const double fit_screen_magnification = qMin(min_horiz_magnification, min_vert_magnification);
-
- //level=90 => magnification=1.0, level=0 => magnification=fit_screen_magnification
- magnification = (level)/90.0*(1.0 - fit_screen_magnification) + fit_screen_magnification;
- }
+ double magnification;
+ if(level == 100) {
+ magnification = 2.0;
+ } else if(level >= 90) {
+ magnification = 1.0;
+ } else {
+ const double min_horiz_magnification = double(parentWidget()->width())/m_frame.width();
+ const double min_vert_magnification = double(parentWidget()->height())/m_frame.height();
+ const double fit_screen_magnification = qMin(min_horiz_magnification, min_vert_magnification);
- if(magnification < 0 //remote display smaller than local?
- or magnification != magnification) //nan
- magnification = 1.0;
-
- m_verticalFactor = m_horizontalFactor = magnification;
- resize(m_frame.width()*magnification, m_frame.height()*magnification);
+ //level=90 => magnification=1.0, level=0 => magnification=fit_screen_magnification
+ magnification = (level)/90.0*(1.0 - fit_screen_magnification) + fit_screen_magnification;
+ }
+
+ if(magnification < 0 //remote display smaller than local?
+ or magnification != magnification) //nan
+ magnification = 1.0;
+
+ m_verticalFactor = m_horizontalFactor = magnification;
+ resize(m_frame.width()*magnification, m_frame.height()*magnification);
}
void VncView::setCut(const QString &text)
event->accept();
- const QRect update_rect = event->rect();
+ const QRect update_rect = event->rect();
QPainter painter(this);
- if (update_rect != rect()) {
- // kDebug(5011) << "Partial repaint";
- const int sx = qRound(update_rect.x()/m_horizontalFactor);
- const int sy = qRound(update_rect.y()/m_verticalFactor);
- const int sw = qRound(update_rect.width()/m_horizontalFactor);
- const int sh = qRound(update_rect.height()/m_verticalFactor);
-
- painter.drawImage(update_rect,
- m_frame.copy(sx, sy, sw, sh)
- .scaled(update_rect.size(), Qt::IgnoreAspectRatio, transformation_mode));
- } else {
- //kDebug(5011) << "Full repaint" << width() << height() << m_frame.width() << m_frame.height();
+ if (update_rect != rect()) {
+ // kDebug(5011) << "Partial repaint";
+ const int sx = qRound(update_rect.x()/m_horizontalFactor);
+ const int sy = qRound(update_rect.y()/m_verticalFactor);
+ const int sw = qRound(update_rect.width()/m_horizontalFactor);
+ const int sh = qRound(update_rect.height()/m_verticalFactor);
+
+ painter.drawImage(update_rect,
+ m_frame.copy(sx, sy, sw, sh)
+ .scaled(update_rect.size(), Qt::IgnoreAspectRatio, transformation_mode));
+ } else {
+ //kDebug(5011) << "Full repaint" << width() << height() << m_frame.width() << m_frame.height();
- painter.drawImage(rect(),
- m_frame.scaled(size(), Qt::IgnoreAspectRatio, transformation_mode));
+ painter.drawImage(rect(),
+ m_frame.scaled(size(), Qt::IgnoreAspectRatio, transformation_mode));
}
- //draw local cursor ourselves, normal mouse pointer doesn't deal with scrolling
- if((m_dotCursorState == CursorOn) || m_forceLocalCursor) {
+ //draw local cursor ourselves, normal mouse pointer doesn't deal with scrolling
+ if((m_dotCursorState == CursorOn) || m_forceLocalCursor) {
#if QT_VERSION >= 0x040500
- painter.setCompositionMode(QPainter::RasterOp_SourceXorDestination);
+ painter.setCompositionMode(QPainter::RasterOp_SourceXorDestination);
#endif
- //rectangle size includes 1px pen width
- painter.drawRect(cursor_x*m_horizontalFactor - CURSOR_SIZE/2, cursor_y*m_verticalFactor - CURSOR_SIZE/2, CURSOR_SIZE-1, CURSOR_SIZE-1);
- }
+ //rectangle size includes 1px pen width
+ painter.drawRect(cursor_x*m_horizontalFactor - CURSOR_SIZE/2, cursor_y*m_verticalFactor - CURSOR_SIZE/2, CURSOR_SIZE-1, CURSOR_SIZE-1);
+ }
RemoteView::paintEvent(event);
}
bool VncView::event(QEvent *event)
{
- switch (event->type()) {
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- keyEventHandler(static_cast<QKeyEvent*>(event));
- return true;
-
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove:
- mouseEventHandler(static_cast<QMouseEvent*>(event));
- return true;
-
- case QEvent::Wheel:
- wheelEventHandler(static_cast<QWheelEvent*>(event));
- return true;
-
- case QEvent::WindowActivate: //input panel may have been closed, prevent IM from interfering with hardware keyboard
- setAttribute(Qt::WA_InputMethodEnabled, false);
- //fall through
- default:
- return RemoteView::event(event);
- }
+ switch (event->type()) {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ keyEventHandler(static_cast<QKeyEvent*>(event));
+ return true;
+
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ mouseEventHandler(static_cast<QMouseEvent*>(event));
+ return true;
+
+ case QEvent::Wheel:
+ wheelEventHandler(static_cast<QWheelEvent*>(event));
+ return true;
+
+ case QEvent::WindowActivate: //input panel may have been closed, prevent IM from interfering with hardware keyboard
+ setAttribute(Qt::WA_InputMethodEnabled, false);
+ //fall through
+ default:
+ return RemoteView::event(event);
+ }
}
//call with e == 0 to flush held events
void VncView::mouseEventHandler(QMouseEvent *e)
{
- static bool tap_detected = false;
- static bool double_tap_detected = false;
- static bool tap_drag_detected = false;
- static QTime press_time;
- static QTime up_time; //used for double clicks/tap&drag, for time after first tap
-
-
- if(!e) { //flush held taps
- if(tap_detected) {
- m_buttonMask |= rfbButton1Mask;
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- m_buttonMask &= ~rfbButton1Mask;
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- tap_detected = false;
- } else if(double_tap_detected and press_time.elapsed() > TAP_PRESS_TIME) { //got tap + another press -> tap & drag
- m_buttonMask |= rfbButton1Mask;
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- double_tap_detected = false;
- tap_drag_detected = true;
- }
-
- return;
- }
+ static bool tap_detected = false;
+ static bool double_tap_detected = false;
+ static bool tap_drag_detected = false;
+ static QTime press_time;
+ static QTime up_time; //used for double clicks/tap&drag, for time after first tap
+
+
+ if(!e) { //flush held taps
+ if(tap_detected) {
+ m_buttonMask |= rfbButton1Mask;
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ m_buttonMask &= ~rfbButton1Mask;
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ tap_detected = false;
+ } else if(double_tap_detected and press_time.elapsed() > TAP_PRESS_TIME) { //got tap + another press -> tap & drag
+ m_buttonMask |= rfbButton1Mask;
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ double_tap_detected = false;
+ tap_drag_detected = true;
+ }
- if(e->x() < 0 or e->y() < 0) { //QScrollArea tends to send invalid events sometimes...
- e->ignore();
- return;
- }
+ return;
+ }
- cursor_x = qRound(e->x()/m_horizontalFactor);
- cursor_y = qRound(e->y()/m_verticalFactor);
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask); // plain move event
-
- if(!disable_tapping and e->button() == Qt::LeftButton) { //implement touchpad-like input for left button
- if(e->type() == QEvent::MouseButtonPress or e->type() == QEvent::MouseButtonDblClick) {
- press_time.start();
- if(tap_detected and up_time.elapsed() < DOUBLE_TAP_UP_TIME) {
- tap_detected = false;
- double_tap_detected = true;
-
- QTimer::singleShot(TAP_PRESS_TIME, this, SLOT(mouseEventHandler()));
- }
- } else if(e->type() == QEvent::MouseButtonRelease) {
- if(tap_drag_detected) { //end tap & drag
- m_buttonMask &= ~rfbButton1Mask;
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- tap_drag_detected = false;
- } else if(double_tap_detected) { //double click
- double_tap_detected = false;
-
- m_buttonMask |= rfbButton1Mask;
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- m_buttonMask &= ~rfbButton1Mask;
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- m_buttonMask |= rfbButton1Mask;
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- m_buttonMask &= ~rfbButton1Mask;
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- } else if(press_time.elapsed() < TAP_PRESS_TIME) { //tap
- up_time.start();
- tap_detected = true;
- QTimer::singleShot(DOUBLE_TAP_UP_TIME, this, SLOT(mouseEventHandler()));
- }
+ if(e->x() < 0 or e->y() < 0) { //QScrollArea tends to send invalid events sometimes...
+ e->ignore();
+ return;
+ }
- }
- } else { //middle or right button, send directly
- if ((e->type() == QEvent::MouseButtonPress)) {
- if (e->button() & Qt::MidButton)
- m_buttonMask |= rfbButton2Mask;
- if (e->button() & Qt::RightButton)
- m_buttonMask |= rfbButton3Mask;
- } else if (e->type() == QEvent::MouseButtonRelease) {
- if (e->button() & Qt::MidButton)
- m_buttonMask &= ~rfbButton2Mask;
- if (e->button() & Qt::RightButton)
- m_buttonMask &= ~rfbButton3Mask;
- }
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- }
+ cursor_x = qRound(e->x()/m_horizontalFactor);
+ cursor_y = qRound(e->y()/m_verticalFactor);
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask); // plain move event
+
+ if(!disable_tapping and e->button() == Qt::LeftButton) { //implement touchpad-like input for left button
+ if(e->type() == QEvent::MouseButtonPress or e->type() == QEvent::MouseButtonDblClick) {
+ press_time.start();
+ if(tap_detected and up_time.elapsed() < DOUBLE_TAP_UP_TIME) {
+ tap_detected = false;
+ double_tap_detected = true;
+
+ QTimer::singleShot(TAP_PRESS_TIME, this, SLOT(mouseEventHandler()));
+ }
+ } else if(e->type() == QEvent::MouseButtonRelease) {
+ if(tap_drag_detected) { //end tap & drag
+ m_buttonMask &= ~rfbButton1Mask;
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ tap_drag_detected = false;
+ } else if(double_tap_detected) { //double click
+ double_tap_detected = false;
+
+ m_buttonMask |= rfbButton1Mask;
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ m_buttonMask &= ~rfbButton1Mask;
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ m_buttonMask |= rfbButton1Mask;
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ m_buttonMask &= ~rfbButton1Mask;
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ } else if(press_time.elapsed() < TAP_PRESS_TIME) { //tap
+ up_time.start();
+ tap_detected = true;
+ QTimer::singleShot(DOUBLE_TAP_UP_TIME, this, SLOT(mouseEventHandler()));
+ }
- //prevent local cursor artifacts
- static int old_cursor_x = cursor_x;
- static int old_cursor_y = cursor_y;
- if(((m_dotCursorState == CursorOn) || m_forceLocalCursor)
- and (cursor_x != old_cursor_x or cursor_y != old_cursor_y)) {
- //clear last position
- repaint(old_cursor_x*m_horizontalFactor - CURSOR_SIZE/2, old_cursor_y*m_verticalFactor - CURSOR_SIZE/2, CURSOR_SIZE, CURSOR_SIZE);
- //and refresh new one
- repaint(cursor_x*m_horizontalFactor - CURSOR_SIZE/2, cursor_y*m_verticalFactor - CURSOR_SIZE/2, CURSOR_SIZE, CURSOR_SIZE);
-
- old_cursor_x = cursor_x; old_cursor_y = cursor_y;
- }
+ }
+ } else { //middle or right button, send directly
+ if ((e->type() == QEvent::MouseButtonPress)) {
+ if (e->button() & Qt::MidButton)
+ m_buttonMask |= rfbButton2Mask;
+ if (e->button() & Qt::RightButton)
+ m_buttonMask |= rfbButton3Mask;
+ } else if (e->type() == QEvent::MouseButtonRelease) {
+ if (e->button() & Qt::MidButton)
+ m_buttonMask &= ~rfbButton2Mask;
+ if (e->button() & Qt::RightButton)
+ m_buttonMask &= ~rfbButton3Mask;
+ }
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ }
+
+ //prevent local cursor artifacts
+ static int old_cursor_x = cursor_x;
+ static int old_cursor_y = cursor_y;
+ if(((m_dotCursorState == CursorOn) || m_forceLocalCursor)
+ and (cursor_x != old_cursor_x or cursor_y != old_cursor_y)) {
+ //clear last position
+ repaint(old_cursor_x*m_horizontalFactor - CURSOR_SIZE/2, old_cursor_y*m_verticalFactor - CURSOR_SIZE/2, CURSOR_SIZE, CURSOR_SIZE);
+ //and refresh new one
+ repaint(cursor_x*m_horizontalFactor - CURSOR_SIZE/2, cursor_y*m_verticalFactor - CURSOR_SIZE/2, CURSOR_SIZE, CURSOR_SIZE);
+
+ old_cursor_x = cursor_x; old_cursor_y = cursor_y;
+ }
}
void VncView::wheelEventHandler(QWheelEvent *event)
}
- int current_zoom = -1;
- if(e->key() == Qt::Key_F8)
- current_zoom = left_zoom;
- else if(e->key() == Qt::Key_F7)
- current_zoom = right_zoom;
- else if (k) {
- // kDebug(5011) << "got '" << e->text() << "'.";
- vncThread.keyEvent(k, pressed);
- } else {
- kDebug(5011) << "nativeVirtualKey() for '" << e->text() << "' failed.";
- return;
- }
-
- if(current_zoom == -1)
- return;
-
- //handle zoom buttons
- if(current_zoom == 0) { //left click
- if(pressed)
- m_buttonMask |= rfbButton1Mask;
- else
- m_buttonMask &= ~rfbButton1Mask;
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- } else if(current_zoom == 1) { //right click
- if(pressed)
- m_buttonMask |= rfbButton3Mask;
- else
- m_buttonMask &= ~rfbButton3Mask;
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- } else if(current_zoom == 2) { //middle click
- if(pressed)
- m_buttonMask |= rfbButton2Mask;
- else
- m_buttonMask &= ~rfbButton2Mask;
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- } else if(current_zoom == 3 and pressed) { //wheel up
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask | rfbWheelUpMask);
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- } else if(current_zoom == 4 and pressed) { //wheel down
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask | rfbWheelDownMask);
- vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
- } else if(current_zoom == 5) { //page up
- vncThread.keyEvent(0xff55, pressed);
- } else if(current_zoom == 6) { //page down
- vncThread.keyEvent(0xff56, pressed);
- }
+ int current_zoom = -1;
+ if(e->key() == Qt::Key_F8)
+ current_zoom = left_zoom;
+ else if(e->key() == Qt::Key_F7)
+ current_zoom = right_zoom;
+ else if (k) {
+ // kDebug(5011) << "got '" << e->text() << "'.";
+ vncThread.keyEvent(k, pressed);
+ } else {
+ kDebug(5011) << "nativeVirtualKey() for '" << e->text() << "' failed.";
+ return;
+ }
+
+ if(current_zoom == -1)
+ return;
+
+ //handle zoom buttons
+ if(current_zoom == 0) { //left click
+ if(pressed)
+ m_buttonMask |= rfbButton1Mask;
+ else
+ m_buttonMask &= ~rfbButton1Mask;
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ } else if(current_zoom == 1) { //right click
+ if(pressed)
+ m_buttonMask |= rfbButton3Mask;
+ else
+ m_buttonMask &= ~rfbButton3Mask;
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ } else if(current_zoom == 2) { //middle click
+ if(pressed)
+ m_buttonMask |= rfbButton2Mask;
+ else
+ m_buttonMask &= ~rfbButton2Mask;
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ } else if(current_zoom == 3 and pressed) { //wheel up
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask | rfbWheelUpMask);
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ } else if(current_zoom == 4 and pressed) { //wheel down
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask | rfbWheelDownMask);
+ vncThread.mouseEvent(cursor_x, cursor_y, m_buttonMask);
+ } else if(current_zoom == 5) { //page up
+ vncThread.keyEvent(0xff55, pressed);
+ } else if(current_zoom == 6) { //page down
+ vncThread.keyEvent(0xff56, pressed);
+ }
}
void VncView::unpressModifiers()
//fake key events
void VncView::sendKey(Qt::Key key)
{
- //convert Qt::Key into x11 keysym
- int k = 0;
- switch(key) {
- case Qt::Key_Escape:
- k = 0xff1b;
- break;
- case Qt::Key_Tab:
- k = 0xff09;
- break;
- case Qt::Key_PageUp:
- k = 0xff55;
- break;
- case Qt::Key_PageDown:
- k = 0xff56;
- break;
- case Qt::Key_Return:
- k = 0xff0d;
- break;
- case Qt::Key_Insert:
- k = 0xff63;
- break;
- case Qt::Key_Delete:
- k = 0xffff;
- break;
- case Qt::Key_Home:
- k = 0xff50;
- break;
- case Qt::Key_End:
- k = 0xff57;
- break;
- case Qt::Key_Backspace:
- k = 0xff08;
- break;
- case Qt::Key_F1:
- case Qt::Key_F2:
- case Qt::Key_F3:
- case Qt::Key_F4:
- case Qt::Key_F5:
- case Qt::Key_F6:
- case Qt::Key_F7:
- case Qt::Key_F8:
- case Qt::Key_F9:
- case Qt::Key_F10:
- case Qt::Key_F11:
- case Qt::Key_F12:
- k = 0xffbe + int(key - Qt::Key_F1);
- break;
- case Qt::Key_Pause:
- k = 0xff13;
- break;
- case Qt::Key_Print:
- k = 0xff61;
- break;
- case Qt::Key_Menu:
- k = 0xff67;
- break;
- case Qt::Key_Meta:
- case Qt::MetaModifier:
- k = XK_Super_L;
- break;
- case Qt::Key_Alt:
- case Qt::AltModifier:
- k = XK_Alt_L;
- break;
- case Qt::Key_Control:
- case Qt::ControlModifier:
- k = XK_Control_L;
- break;
- default:
- kDebug(5011) << "sendKey(): Unhandled Qt::Key value " << key;
- return;
- }
+ //convert Qt::Key into x11 keysym
+ int k = 0;
+ switch(key) {
+ case Qt::Key_Escape:
+ k = 0xff1b;
+ break;
+ case Qt::Key_Tab:
+ k = 0xff09;
+ break;
+ case Qt::Key_PageUp:
+ k = 0xff55;
+ break;
+ case Qt::Key_PageDown:
+ k = 0xff56;
+ break;
+ case Qt::Key_Return:
+ k = 0xff0d;
+ break;
+ case Qt::Key_Insert:
+ k = 0xff63;
+ break;
+ case Qt::Key_Delete:
+ k = 0xffff;
+ break;
+ case Qt::Key_Home:
+ k = 0xff50;
+ break;
+ case Qt::Key_End:
+ k = 0xff57;
+ break;
+ case Qt::Key_Backspace:
+ k = 0xff08;
+ break;
+ case Qt::Key_F1:
+ case Qt::Key_F2:
+ case Qt::Key_F3:
+ case Qt::Key_F4:
+ case Qt::Key_F5:
+ case Qt::Key_F6:
+ case Qt::Key_F7:
+ case Qt::Key_F8:
+ case Qt::Key_F9:
+ case Qt::Key_F10:
+ case Qt::Key_F11:
+ case Qt::Key_F12:
+ k = 0xffbe + int(key - Qt::Key_F1);
+ break;
+ case Qt::Key_Pause:
+ k = 0xff13;
+ break;
+ case Qt::Key_Print:
+ k = 0xff61;
+ break;
+ case Qt::Key_Menu:
+ k = 0xff67;
+ break;
+ case Qt::Key_Meta:
+ case Qt::MetaModifier:
+ k = XK_Super_L;
+ break;
+ case Qt::Key_Alt:
+ case Qt::AltModifier:
+ k = XK_Alt_L;
+ break;
+ case Qt::Key_Control:
+ case Qt::ControlModifier:
+ k = XK_Control_L;
+ break;
+ default:
+ kDebug(5011) << "sendKey(): Unhandled Qt::Key value " << key;
+ return;
+ }
- if (k == XK_Shift_L || k == XK_Control_L || k == XK_Meta_L || k == XK_Alt_L || k == XK_Super_L) {
- if (m_mods.contains(k)) { //release
- m_mods.remove(k);
- vncThread.keyEvent(k, false);
- } else { //press
- m_mods[k] = true;
- vncThread.keyEvent(k, true);
- }
- } else { //normal key
- vncThread.keyEvent(k, true);
- vncThread.keyEvent(k, false);
- }
+ if (k == XK_Shift_L || k == XK_Control_L || k == XK_Meta_L || k == XK_Alt_L || k == XK_Super_L) {
+ if (m_mods.contains(k)) { //release
+ m_mods.remove(k);
+ vncThread.keyEvent(k, false);
+ } else { //press
+ m_mods[k] = true;
+ vncThread.keyEvent(k, true);
+ }
+ } else { //normal key
+ vncThread.keyEvent(k, true);
+ vncThread.keyEvent(k, false);
+ }
}
void VncView::sendKeySequence(QKeySequence keys)
{
- Q_ASSERT(keys.count() <= 1); //we can only handle a single combination
-
- //to get at individual key presses, we split 'keys' into its components
- QList<int> key_list;
- int pos = 0;
- while(true) {
- QString k = keys.toString().section('+', pos, pos);
- if(k.isEmpty())
- break;
-
- //kDebug(5011) << "found key: " << k;
- if(k == "Alt") {
- key_list.append(Qt::Key_Alt);
- } else if(k == "Ctrl") {
- key_list.append(Qt::Key_Control);
- } else if(k == "Meta") {
- key_list.append(Qt::Key_Meta);
- } else {
- key_list.append(QKeySequence(k)[0]);
- }
-
- pos++;
- }
-
- for(int i = 0; i < key_list.count(); i++)
- sendKey(Qt::Key(key_list.at(i)));
+ Q_ASSERT(keys.count() <= 1); //we can only handle a single combination
+
+ //to get at individual key presses, we split 'keys' into its components
+ QList<int> key_list;
+ int pos = 0;
+ while(true) {
+ QString k = keys.toString().section('+', pos, pos);
+ if(k.isEmpty())
+ break;
+
+ //kDebug(5011) << "found key: " << k;
+ if(k == "Alt") {
+ key_list.append(Qt::Key_Alt);
+ } else if(k == "Ctrl") {
+ key_list.append(Qt::Key_Control);
+ } else if(k == "Meta") {
+ key_list.append(Qt::Key_Meta);
+ } else {
+ key_list.append(QKeySequence(k)[0]);
+ }
- //release modifiers (everything before final key)
- for(int i = key_list.count()-2; i >= 0; i--)
- sendKey(Qt::Key(key_list.at(i)));
+ pos++;
+ }
+
+ for(int i = 0; i < key_list.count(); i++)
+ sendKey(Qt::Key(key_list.at(i)));
+
+ //release modifiers (everything before final key)
+ for(int i = key_list.count()-2; i >= 0; i--)
+ sendKey(Qt::Key(key_list.at(i)));
}
void VncView::reloadSettings()
{
- QSettings settings;
- left_zoom = settings.value("left_zoom", 0).toInt();
- right_zoom = settings.value("right_zoom", 1).toInt();
- disable_tapping = settings.value("disable_tapping", false).toBool();
+ QSettings settings;
+ left_zoom = settings.value("left_zoom", 0).toInt();
+ right_zoom = settings.value("right_zoom", 1).toInt();
+ disable_tapping = settings.value("disable_tapping", false).toBool();
- bool always_show_local_cursor = settings.value("always_show_local_cursor", false).toBool();
- if(always_show_local_cursor)
- showDotCursor(CursorOn);
+ bool always_show_local_cursor = settings.value("always_show_local_cursor", false).toBool();
+ if(always_show_local_cursor)
+ showDotCursor(CursorOn);
- enableScaling(true);
+ enableScaling(true);
}
//convert commitString into keyevents
void VncView::inputMethodEvent(QInputMethodEvent *event)
{
- //TODO handle replacements
- //NOTE for the return key to work Qt needs to enable multiline input, which only works for Q(Plain)TextEdit
+ //TODO handle replacements
+ //NOTE for the return key to work Qt needs to enable multiline input, which only works for Q(Plain)TextEdit
- //kDebug(5011) << event->commitString() << "|" << event->preeditString() << "|" << event->replacementLength() << "|" << event->replacementStart();
- QString letters = event->commitString();
- for(int i = 0; i < letters.length(); i++) {
- char k = letters.at(i).toLatin1();
- if(!k) {
- kDebug(5011) << "unhandled key";
- continue;
- }
- vncThread.keyEvent(k, true);
- vncThread.keyEvent(k, false);
- }
+ //kDebug(5011) << event->commitString() << "|" << event->preeditString() << "|" << event->replacementLength() << "|" << event->replacementStart();
+ QString letters = event->commitString();
+ for(int i = 0; i < letters.length(); i++) {
+ char k = letters.at(i).toLatin1();
+ if(!k) {
+ kDebug(5011) << "unhandled key";
+ continue;
+ }
+ vncThread.keyEvent(k, true);
+ vncThread.keyEvent(k, false);
+ }
}
void VncView::useFastTransformations(bool enabled)
{
- if(enabled or zoomFactor() >= 1.0) {
- transformation_mode = Qt::FastTransformation;
- } else {
- transformation_mode = Qt::SmoothTransformation;
- update();
- }
+ if(enabled or zoomFactor() >= 1.0) {
+ transformation_mode = Qt::FastTransformation;
+ } else {
+ transformation_mode = Qt::SmoothTransformation;
+ update();
+ }
}
class KConfigGroup{};
#include <QClipboard>
-#include <QTextEdit>
extern "C" {
#include <rfb/rfbclient.h>
void showDotCursor(DotCursorState state);
void useFastTransformations(bool enabled);
QPoint cursorPosition() { return QPoint(cursor_x, cursor_y); }
- void setDisplayOff(bool off) { display_off = off; }
+ void setDisplayOff(bool off) { display_off = off; }
public slots:
void setZoomLevel(int level = -1); //'level' doesn't correspond to actual magnification, though mapping is done here
RemoteView::Quality quality;
int listen_port;
Qt::TransformationMode transformation_mode;
- bool display_off;
+ bool display_off;
void keyEventHandler(QKeyEvent *e);
void unpressModifiers();