895 lines
25 KiB
895 lines
25 KiB
/***************************************************************************
|
|
krdc.cpp - main window
|
|
-------------------
|
|
begin : Tue May 13 23:07:42 CET 2002
|
|
copyright : (C) 2002-2003 by Tim Jansen
|
|
(C) 2003 Nadeem Hasan <nhasan@kde.org>
|
|
email : tim@tjansen.de
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* 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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "krdc.h"
|
|
#include "maindialog.h"
|
|
#include "hostpreferences.h"
|
|
|
|
#include <tdeapplication.h>
|
|
#include <tdeconfig.h>
|
|
#include <kdebug.h>
|
|
#include <kcombobox.h>
|
|
#include <kurl.h>
|
|
#include <kiconloader.h>
|
|
#include <tdelocale.h>
|
|
#include <tdetoolbar.h>
|
|
#include <tdetoolbarbutton.h>
|
|
#include <tdepopupmenu.h>
|
|
#include <tdemessagebox.h>
|
|
#include <twin.h>
|
|
#include <tdestartupinfo.h>
|
|
|
|
#include <tqdockarea.h>
|
|
#include <tqlabel.h>
|
|
#include <tqwhatsthis.h>
|
|
#include <tqtooltip.h>
|
|
|
|
#define BUMP_SCROLL_CONSTANT (200)
|
|
|
|
const int VIEW_ONLY_ID = 10;
|
|
const int SHOW_LOCAL_CURSOR_ID = 20;
|
|
|
|
const int FS_AUTOHIDE_ID = 1;
|
|
const int FS_FULLSCREEN_ID = 2;
|
|
const int FS_SCALE_ID = 3;
|
|
const int FS_HOSTLABEL_ID = 4;
|
|
const int FS_ADVANCED_ID = 5;
|
|
const int FS_ICONIFY_ID = 6;
|
|
const int FS_CLOSE_ID = 7;
|
|
|
|
const int KRDC::TOOLBAR_AUTOHIDE_TIMEOUT = 1000;
|
|
const int KRDC::TOOLBAR_FPS_1000 = 10000;
|
|
const int KRDC::TOOLBAR_SPEED_DOWN = 34;
|
|
const int KRDC::TOOLBAR_SPEED_UP = 20;
|
|
|
|
TQScrollView2::TQScrollView2(TQWidget *w, const char *name) :
|
|
TQScrollView(w, name) {
|
|
setMouseTracking(true);
|
|
viewport()->setMouseTracking(true);
|
|
horizontalScrollBar()->setMouseTracking(true);
|
|
verticalScrollBar()->setMouseTracking(true);
|
|
}
|
|
|
|
void TQScrollView2::mouseMoveEvent( TQMouseEvent *e )
|
|
{
|
|
e->ignore();
|
|
}
|
|
|
|
|
|
TQString KRDC::m_lastHost = "";
|
|
|
|
KRDC::KRDC(WindowMode wm, const TQString &host,
|
|
Quality q, const TQString &encodings,
|
|
const TQString &password,
|
|
bool scale,
|
|
bool localCursor,
|
|
TQSize initialWindowSize) :
|
|
TQWidget(0, 0, TQt::WStyle_ContextHelp),
|
|
m_layout(0),
|
|
m_scrollView(0),
|
|
m_view(0),
|
|
m_fsToolbar(0),
|
|
m_toolbar(0),
|
|
m_dockArea(0),
|
|
m_popup(0),
|
|
m_ftAutoHide(false),
|
|
m_showProgress(false),
|
|
m_host(host),
|
|
m_protocol(PROTOCOL_AUTO),
|
|
m_quality(q),
|
|
m_encodings(encodings),
|
|
m_password(password),
|
|
m_isFullscreen(wm),
|
|
m_oldResolution(),
|
|
m_fullscreenMinimized(false),
|
|
m_windowScaling(scale),
|
|
m_localCursor(localCursor),
|
|
m_initialWindowSize(initialWindowSize)
|
|
{
|
|
connect(&m_autoHideTimer, TQT_SIGNAL(timeout()), TQT_SLOT(hideFullscreenToolbarNow()));
|
|
connect(&m_bumpScrollTimer, TQT_SIGNAL(timeout()), TQT_SLOT(bumpScroll()));
|
|
|
|
m_pindown = UserIcon("pindown");
|
|
m_pinup = UserIcon("pinup");
|
|
|
|
m_keyCaptureDialog = new KeyCaptureDialog(0, 0);
|
|
|
|
setMouseTracking(true);
|
|
|
|
TDEStartupInfo::appStarted();
|
|
}
|
|
|
|
bool KRDC::start()
|
|
{
|
|
TQString userName, password;
|
|
TQString serverHost;
|
|
int serverPort = 5900;
|
|
int ret_status;
|
|
|
|
if (!m_host.isNull() &&
|
|
(m_host != "vnc:/") &&
|
|
(m_host != "rdp:/")) {
|
|
if (m_host.startsWith("vnc:/"))
|
|
m_protocol = PROTOCOL_VNC;
|
|
if (m_host.startsWith("rdp:/"))
|
|
m_protocol = PROTOCOL_RDP;
|
|
if (!parseHost(m_host, m_protocol, serverHost, serverPort,
|
|
userName, password)) {
|
|
KMessageBox::error(0,
|
|
i18n("The entered host does not have the required form."),
|
|
i18n("Malformed URL or Host"));
|
|
emit disconnectedError();
|
|
return true;
|
|
}
|
|
} else {
|
|
|
|
MainDialog mainDlg(this, "MainDialog");
|
|
mainDlg.setRemoteHost(m_lastHost);
|
|
|
|
if (mainDlg.exec() == TQDialog::Rejected) {
|
|
return false;
|
|
}
|
|
|
|
TQString m_host = mainDlg.remoteHost();
|
|
m_lastHost = m_host;
|
|
if (m_host.startsWith("vnc:/"))
|
|
m_protocol = PROTOCOL_VNC;
|
|
if (m_host.startsWith("rdp:/"))
|
|
m_protocol = PROTOCOL_RDP;
|
|
if (!parseHost(m_host, m_protocol, serverHost, serverPort,
|
|
userName, password)) {
|
|
KMessageBox::error(0,
|
|
i18n("The entered host does not have the required form."),
|
|
i18n("Malformed URL or Host"));
|
|
emit disconnectedError();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
setCaption(i18n("%1 - Remote Desktop Connection").arg(serverHost));
|
|
|
|
m_scrollView = new TQScrollView2(this, "remote scrollview");
|
|
m_scrollView->setFrameStyle(TQFrame::NoFrame);
|
|
m_scrollView->setSizePolicy(TQSizePolicy(TQSizePolicy::Expanding,
|
|
TQSizePolicy::Expanding));
|
|
|
|
switch(m_protocol)
|
|
{
|
|
case PROTOCOL_AUTO:
|
|
// fall through
|
|
|
|
case PROTOCOL_VNC:
|
|
m_view = new KVncView(this, 0, serverHost, serverPort,
|
|
m_password.isNull() ? password : m_password,
|
|
m_quality,
|
|
m_localCursor ? DOT_CURSOR_ON : DOT_CURSOR_AUTO,
|
|
m_encodings);
|
|
break;
|
|
|
|
case PROTOCOL_RDP:
|
|
m_view = new KRdpView(this, 0, serverHost, serverPort,
|
|
userName, m_password.isNull() ? password : m_password);
|
|
break;
|
|
}
|
|
|
|
m_view->setViewOnly(kapp->config()->readBoolEntry("viewOnly", false));
|
|
|
|
m_scrollView->addChild(m_view);
|
|
TQWhatsThis::add(m_view, i18n("Here you can see the remote desktop. If the other side allows you to control it, you can also move the mouse, click or enter keystrokes. If the content does not fit your screen, click on the toolbar's full screen button or scale button. To end the connection, just close the window."));
|
|
|
|
connect(m_view, TQT_SIGNAL(changeSize(int,int)), TQT_SLOT(setSize(int,int)));
|
|
connect(m_view, TQT_SIGNAL(connected()), TQT_SLOT(show()));
|
|
connect(m_view, TQT_SIGNAL(disconnected()), TQT_SIGNAL(disconnected()));
|
|
// note that the disconnectedError() will be disconnected when kremoteview
|
|
// is completely initialized
|
|
connect(m_view, TQT_SIGNAL(disconnectedError()), TQT_SIGNAL(disconnectedError()));
|
|
connect(m_view, TQT_SIGNAL(statusChanged(RemoteViewStatus)),
|
|
TQT_SLOT(changeProgress(RemoteViewStatus)));
|
|
connect(m_view, TQT_SIGNAL(showingPasswordDialog(bool)),
|
|
TQT_SLOT(showingPasswordDialog(bool)));
|
|
connect(m_keyCaptureDialog, TQT_SIGNAL(keyPressed(XEvent*)),
|
|
m_view, TQT_SLOT(pressKey(XEvent*)));
|
|
|
|
ret_status = m_view->start();
|
|
|
|
return ret_status;
|
|
}
|
|
|
|
void KRDC::changeProgress(RemoteViewStatus s) {
|
|
if (!m_progressDialog) {
|
|
m_progressDialog = new KProgressDialog(0, 0, TQString(),
|
|
"1234567890", false);
|
|
m_progressDialog->showCancelButton(true);
|
|
m_progressDialog->setMinimumDuration(0x7fffffff);//disable effectively
|
|
m_progress = m_progressDialog->progressBar();
|
|
m_progress->setTextEnabled(false);
|
|
m_progress->setTotalSteps(3);
|
|
connect(m_progressDialog, TQT_SIGNAL(cancelClicked()),
|
|
TQT_SIGNAL(disconnectedError()));
|
|
}
|
|
|
|
if (s == REMOTE_VIEW_CONNECTING) {
|
|
m_progress->setValue(0);
|
|
m_progressDialog->setLabel(i18n("Establishing connection..."));
|
|
m_progressDialog->setAllowCancel(false);
|
|
showProgressDialog();
|
|
}
|
|
else if (s == REMOTE_VIEW_AUTHENTICATING) {
|
|
m_progress->setValue(1);
|
|
m_progressDialog->setLabel(i18n("Authenticating..."));
|
|
m_progressDialog->setAllowCancel(true);
|
|
}
|
|
else if (s == REMOTE_VIEW_PREPARING) {
|
|
m_progress->setValue(2);
|
|
m_progressDialog->setLabel(i18n("Preparing desktop..."));
|
|
}
|
|
else if ((s == REMOTE_VIEW_CONNECTED) ||
|
|
(s == REMOTE_VIEW_DISCONNECTED)) {
|
|
m_progress->setValue(3);
|
|
hideProgressDialog();
|
|
if (s == REMOTE_VIEW_CONNECTED) {
|
|
TQObject::disconnect(m_view, TQT_SIGNAL(disconnectedError()),
|
|
this, TQT_SIGNAL(disconnectedError()));
|
|
connect(m_view, TQT_SIGNAL(disconnectedError()),
|
|
TQT_SIGNAL(disconnected()));
|
|
if (m_view->startFullscreen()) {
|
|
// m_view instance is asking to start in fullscreen mode
|
|
enableFullscreen(true);
|
|
}
|
|
}
|
|
else if (m_isFullscreen == WINDOW_MODE_FULLSCREEN)
|
|
switchToNormal(m_view->scaling());
|
|
}
|
|
}
|
|
|
|
void KRDC::showingPasswordDialog(bool b) {
|
|
if (!m_progressDialog)
|
|
return;
|
|
if (b)
|
|
hideProgressDialog();
|
|
else
|
|
showProgressDialog();
|
|
}
|
|
|
|
void KRDC::showProgressDialog() {
|
|
m_showProgress = true;
|
|
TQTimer::singleShot(400, this, TQT_SLOT(showProgressTimeout()));
|
|
}
|
|
|
|
void KRDC::hideProgressDialog() {
|
|
m_showProgress = false;
|
|
m_progressDialog->hide();
|
|
}
|
|
|
|
void KRDC::showProgressTimeout() {
|
|
if (!m_showProgress)
|
|
return;
|
|
|
|
m_progressDialog->setMinimumSize(300, 50);
|
|
m_progressDialog->show();
|
|
}
|
|
|
|
void KRDC::quit() {
|
|
m_view->releaseKeyboard();
|
|
hide();
|
|
vidmodeNormalSwitch(tqt_xdisplay(), m_oldResolution);
|
|
if (m_view)
|
|
m_view->startQuitting();
|
|
emit disconnected();
|
|
}
|
|
|
|
bool KRDC::parseHost(TQString &str, Protocol &prot, TQString &serverHost, int &serverPort,
|
|
TQString &userName, TQString &password) {
|
|
TQString s = str;
|
|
userName = TQString();
|
|
password = TQString();
|
|
|
|
if (prot == PROTOCOL_AUTO) {
|
|
if(s.startsWith("smb:/")>0) { //we know it's more likely to be windows..
|
|
s = "rdp:/" + s.section("smb:/", 1);
|
|
prot = PROTOCOL_RDP;
|
|
} else if(s.contains("://") > 0) {
|
|
s = s.section("://",1);
|
|
} else if(s.contains(":/") > 0) {
|
|
s = s.section(":/", 1);
|
|
}
|
|
}
|
|
if (prot == PROTOCOL_AUTO || prot == PROTOCOL_VNC) {
|
|
if (s.startsWith(":"))
|
|
s = "localhost" + s;
|
|
if (!s.startsWith("vnc:/"))
|
|
s = "vnc://" + s;
|
|
else if (!s.startsWith("vnc://")) // TODO: fix this in KURL!
|
|
s.insert(4, '/');
|
|
}
|
|
if (prot == PROTOCOL_RDP) {
|
|
if (!s.startsWith("rdp:/"))
|
|
s = "rdp://" + s;
|
|
else if (!s.startsWith("rdp://")) // TODO: fix this in KURL!
|
|
s.insert(4, '/');
|
|
}
|
|
|
|
KURL url(s);
|
|
if (!url.isValid())
|
|
return false;
|
|
serverHost = url.host();
|
|
if (serverHost.isEmpty())
|
|
serverHost = "localhost";
|
|
serverPort = url.port();
|
|
if ((prot == PROTOCOL_AUTO || prot == PROTOCOL_VNC) && serverPort < 100)
|
|
serverPort += 5900;
|
|
if (url.hasUser())
|
|
userName = url.user();
|
|
if (url.hasPass())
|
|
password = url.pass();
|
|
|
|
if (url.port()) {
|
|
if (url.hasUser())
|
|
str = TQString("%1@%2:%3").arg(userName).arg(serverHost).arg(url.port());
|
|
else
|
|
str = TQString("%1:%2").arg(serverHost).arg(url.port());
|
|
}
|
|
else {
|
|
if (url.hasUser())
|
|
str = TQString("%1@%2").arg(userName).arg(serverHost);
|
|
else
|
|
str = TQString("%1").arg(serverHost);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
KRDC::~KRDC()
|
|
{
|
|
// kill explicitly to avoid xlib calls by the threads after closing the window!
|
|
if (m_view)
|
|
delete m_view;
|
|
}
|
|
|
|
void KRDC::enableFullscreen(bool on)
|
|
{
|
|
if (on) {
|
|
if (m_isFullscreen != WINDOW_MODE_FULLSCREEN)
|
|
switchToFullscreen(m_view->scaling());
|
|
}
|
|
else {
|
|
if (m_isFullscreen != WINDOW_MODE_NORMAL)
|
|
switchToNormal(m_view->scaling() || m_windowScaling);
|
|
}
|
|
m_view->switchFullscreen(on);
|
|
}
|
|
|
|
TQSize KRDC::sizeHint()
|
|
{
|
|
if ((m_isFullscreen != WINDOW_MODE_FULLSCREEN) && m_toolbar) {
|
|
int dockHint = m_dockArea->sizeHint().height();
|
|
dockHint = dockHint < 1 ? 1 : dockHint; // fix wrong size hint
|
|
return TQSize(m_view->framebufferSize().width(),
|
|
dockHint + m_view->framebufferSize().height());
|
|
}
|
|
else
|
|
return m_view->framebufferSize();
|
|
}
|
|
|
|
TQPopupMenu *KRDC::createPopupMenu(TQWidget *parent) const {
|
|
TDEPopupMenu *pu = new TDEPopupMenu(parent);
|
|
pu->insertItem(i18n("View Only"), this, TQT_SLOT(viewOnlyToggled()), 0, VIEW_ONLY_ID);
|
|
pu->setCheckable(true);
|
|
pu->setItemChecked(VIEW_ONLY_ID, m_view->viewOnly());
|
|
if (m_view->supportsLocalCursor()) {
|
|
pu->insertItem(i18n("Always Show Local Cursor"), this,
|
|
TQT_SLOT(showLocalCursorToggled()), 0,
|
|
SHOW_LOCAL_CURSOR_ID);
|
|
pu->setCheckable(true);
|
|
pu->setItemChecked(SHOW_LOCAL_CURSOR_ID,
|
|
m_view->dotCursorState() == DOT_CURSOR_ON);
|
|
}
|
|
return pu;
|
|
}
|
|
|
|
void KRDC::switchToFullscreen(bool scaling)
|
|
{
|
|
int x, y;
|
|
|
|
bool fromFullscreen = (m_isFullscreen == WINDOW_MODE_FULLSCREEN);
|
|
|
|
TQDesktopWidget* desktopWidget = TQApplication::desktop();
|
|
//int activeXineramaScreen = desktopWidget->screenNumber(this);
|
|
int activeXineramaScreen = desktopWidget->screenNumber(TQCursor::pos());
|
|
if (activeXineramaScreen < 0) {
|
|
activeXineramaScreen = 0;
|
|
}
|
|
TQRect desktopScreenGeometry = desktopWidget->screenGeometry(activeXineramaScreen);
|
|
TQSize ds = desktopScreenGeometry.size();
|
|
|
|
TQSize fbs = m_view->framebufferSize();
|
|
bool scalingPossible = m_view->supportsScaling() &&
|
|
((fbs.width() >= ds.width()) || (fbs.height() >= ds.height()));
|
|
|
|
if (!fromFullscreen) {
|
|
hide();
|
|
m_oldResolution = vidmodeFullscreenSwitch(tqt_xdisplay(),
|
|
m_desktopWidget.screenNumber(this),
|
|
fbs.width(),
|
|
fbs.height(),
|
|
x, y);
|
|
if (m_oldResolution.valid) {
|
|
m_fullscreenResolution = TQSize(x, y);
|
|
}
|
|
else {
|
|
m_fullscreenResolution = ds;
|
|
}
|
|
m_isFullscreen = WINDOW_MODE_FULLSCREEN;
|
|
if (!scalingPossible) {
|
|
m_windowScaling = m_view->scaling();
|
|
}
|
|
}
|
|
|
|
if (m_toolbar) {
|
|
m_toolbar->hide();
|
|
m_toolbar->deleteLater();
|
|
m_toolbar = 0;
|
|
m_dockArea->hide();
|
|
m_dockArea->deleteLater();
|
|
m_dockArea = 0;
|
|
}
|
|
if (m_popup) {
|
|
m_popup->deleteLater();
|
|
m_popup = 0;
|
|
}
|
|
if (m_fsToolbar) {
|
|
m_fsToolbar->hide();
|
|
m_fsToolbar->deleteLater();
|
|
m_fsToolbar = 0;
|
|
}
|
|
|
|
if (m_layout)
|
|
delete m_layout;
|
|
m_layout = new TQVBoxLayout(this);
|
|
m_layout->addWidget(m_scrollView);
|
|
|
|
if (scalingPossible) {
|
|
m_view->enableScaling(scaling);
|
|
if (scaling)
|
|
m_view->resize(ds);
|
|
else
|
|
m_view->resize(fbs);
|
|
repositionView(true);
|
|
}
|
|
else {
|
|
m_view->enableScaling(false);
|
|
}
|
|
|
|
m_fsToolbar = new KFullscreenPanel(this, "fstoolbar", m_fullscreenResolution);
|
|
connect(m_fsToolbar, TQT_SIGNAL(mouseEnter()), TQT_SLOT(showFullscreenToolbar()));
|
|
connect(m_fsToolbar, TQT_SIGNAL(mouseLeave()), TQT_SLOT(hideFullscreenToolbarDelayed()));
|
|
|
|
TDEToolBar *t = new TDEToolBar(m_fsToolbar);
|
|
m_fsToolbarWidget = t;
|
|
t->setIconSize(16);
|
|
|
|
TQIconSet pinIconSet;
|
|
pinIconSet.setPixmap(m_pinup, TQIconSet::Automatic, TQIconSet::Normal, TQIconSet::On);
|
|
pinIconSet.setPixmap(m_pindown, TQIconSet::Automatic, TQIconSet::Normal, TQIconSet::Off);
|
|
t->insertButton("pinup", FS_AUTOHIDE_ID);
|
|
TDEToolBarButton *pinButton = t->getButton(FS_AUTOHIDE_ID);
|
|
pinButton->setIconSet(pinIconSet);
|
|
TQToolTip::add(pinButton, i18n("Autohide on/off"));
|
|
t->setToggle(FS_AUTOHIDE_ID);
|
|
t->addConnection(FS_AUTOHIDE_ID, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(setFsToolbarAutoHide(bool)));
|
|
|
|
t->insertButton("view-restore", FS_FULLSCREEN_ID);
|
|
TDEToolBarButton *fullscreenButton = t->getButton(FS_FULLSCREEN_ID);
|
|
TQToolTip::add(fullscreenButton, i18n("Fullscreen"));
|
|
t->setToggle(FS_FULLSCREEN_ID);
|
|
t->setButton(FS_FULLSCREEN_ID, true);
|
|
t->addConnection(FS_FULLSCREEN_ID, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(enableFullscreen(bool)));
|
|
|
|
m_popup = createPopupMenu(t);
|
|
t->insertButton("configure", FS_ADVANCED_ID, m_popup, true, i18n("Advanced options"));
|
|
TDEToolBarButton *advancedButton = t->getButton(FS_ADVANCED_ID);
|
|
TQToolTip::add(advancedButton, i18n("Advanced options"));
|
|
|
|
TQLabel *hostLabel = new TQLabel(t);
|
|
hostLabel->setName("tde toolbar widget");
|
|
hostLabel->setAlignment(TQt::AlignCenter);
|
|
hostLabel->setText(" "+m_host+" ");
|
|
t->insertWidget(FS_HOSTLABEL_ID, 150, hostLabel);
|
|
t->setItemAutoSized(FS_HOSTLABEL_ID, true);
|
|
|
|
if (scalingPossible) {
|
|
t->insertButton("zoom-fit-best", FS_SCALE_ID);
|
|
TDEToolBarButton *scaleButton = t->getButton(FS_SCALE_ID);
|
|
TQToolTip::add(scaleButton, i18n("Scale view"));
|
|
t->setToggle(FS_SCALE_ID);
|
|
t->setButton(FS_SCALE_ID, scaling);
|
|
t->addConnection(FS_SCALE_ID, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(switchToFullscreen(bool)));
|
|
}
|
|
|
|
t->insertButton("iconify", FS_ICONIFY_ID);
|
|
TDEToolBarButton *iconifyButton = t->getButton(FS_ICONIFY_ID);
|
|
TQToolTip::add(iconifyButton, i18n("Minimize"));
|
|
t->addConnection(FS_ICONIFY_ID, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(iconify()));
|
|
|
|
t->insertButton("close", FS_CLOSE_ID);
|
|
TDEToolBarButton *closeButton = t->getButton(FS_CLOSE_ID);
|
|
TQToolTip::add(closeButton, i18n("Close"));
|
|
t->addConnection(FS_CLOSE_ID, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(quit()));
|
|
|
|
m_fsToolbar->setChild(t);
|
|
|
|
repositionView(true);
|
|
|
|
setMaximumSize(m_fullscreenResolution.width(),
|
|
m_fullscreenResolution.height());
|
|
setGeometry(desktopScreenGeometry.x(), desktopScreenGeometry.y(), m_fullscreenResolution.width(),
|
|
m_fullscreenResolution.height());
|
|
|
|
KWin::setState(winId(), NET::StaysOnTop);
|
|
|
|
if (m_ftAutoHide == false) {
|
|
showFullscreenToolbar();
|
|
}
|
|
else {
|
|
t->setButton(FS_AUTOHIDE_ID, true);
|
|
}
|
|
|
|
if (!fromFullscreen) {
|
|
if (m_oldResolution.valid)
|
|
grabInput(tqt_xdisplay(), winId());
|
|
m_view->grabKeyboard();
|
|
}
|
|
|
|
showFullScreen();
|
|
|
|
m_view->switchFullscreen( true );
|
|
}
|
|
|
|
void KRDC::switchToNormal(bool scaling)
|
|
{
|
|
bool fromFullscreen = (m_isFullscreen == WINDOW_MODE_FULLSCREEN);
|
|
bool scalingChanged = (scaling != m_view->scaling());
|
|
m_windowScaling = false; // delete remembered scaling value
|
|
if (fromFullscreen) {
|
|
KWin::clearState(winId(), NET::StaysOnTop);
|
|
hide();
|
|
}
|
|
m_isFullscreen = WINDOW_MODE_NORMAL;
|
|
m_view->enableScaling(scaling);
|
|
|
|
m_view->releaseKeyboard();
|
|
if (m_oldResolution.valid) {
|
|
ungrabInput(tqt_xdisplay());
|
|
vidmodeNormalSwitch(tqt_xdisplay(), m_oldResolution);
|
|
m_oldResolution = Resolution();
|
|
}
|
|
|
|
if (m_fsToolbar) {
|
|
m_fsToolbar->hide();
|
|
m_fsToolbar->deleteLater();
|
|
m_fsToolbar = 0;
|
|
}
|
|
|
|
if (!m_toolbar) {
|
|
m_dockArea = new TQDockArea(Qt::Horizontal, TQDockArea::Normal, this);
|
|
m_dockArea->setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding,
|
|
TQSizePolicy::Fixed));
|
|
TDEToolBar *t = new TDEToolBar(m_dockArea);
|
|
m_toolbar = t;
|
|
t->setIconText(TDEToolBar::IconTextRight);
|
|
connect(t, TQT_SIGNAL(placeChanged(TQDockWindow::Place)), TQT_SLOT(toolbarChanged()));
|
|
t->insertButton("view-fullscreen", 0, true, i18n("Fullscreen"));
|
|
TDEToolBarButton *fullscreenButton = t->getButton(0);
|
|
TQToolTip::add(fullscreenButton, i18n("Fullscreen"));
|
|
TQWhatsThis::add(fullscreenButton, i18n("Switches to full screen. If the remote desktop has a different screen resolution, Remote Desktop Connection will automatically switch to the nearest resolution."));
|
|
t->setToggle(0);
|
|
t->setButton(0, false);
|
|
t->addConnection(0, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(enableFullscreen(bool)));
|
|
|
|
if (m_view->supportsScaling()) {
|
|
t->insertButton("zoom-fit-best", 1, true, i18n("Scale"));
|
|
TDEToolBarButton *scaleButton = t->getButton(1);
|
|
TQToolTip::add(scaleButton, i18n("Scale view"));
|
|
TQWhatsThis::add(scaleButton, i18n("This option scales the remote screen to fit your window size."));
|
|
t->setToggle(1);
|
|
t->setButton(1, scaling);
|
|
t->addConnection(1, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(switchToNormal(bool)));
|
|
}
|
|
|
|
t->insertButton("key_enter", 2, true, i18n("Special Keys"));
|
|
TDEToolBarButton *skButton = t->getButton(2);
|
|
TQToolTip::add(skButton, i18n("Enter special keys."));
|
|
TQWhatsThis::add(skButton, i18n("This option allows you to send special key combinations like Ctrl-Alt-Del to the remote host."));
|
|
t->addConnection(2, TQT_SIGNAL(clicked()), TQT_TQOBJECT(m_keyCaptureDialog), TQT_SLOT(execute()));
|
|
|
|
if (m_popup) {
|
|
m_popup->deleteLater();
|
|
m_popup = 0;
|
|
}
|
|
|
|
m_popup = createPopupMenu(t);
|
|
t->insertButton("configure", 3, m_popup, true, i18n("Advanced"));
|
|
TDEToolBarButton *advancedButton = t->getButton(3);
|
|
TQToolTip::add(advancedButton, i18n("Advanced options"));
|
|
|
|
if (m_layout)
|
|
delete m_layout;
|
|
m_layout = new TQVBoxLayout(this);
|
|
m_layout->addWidget(m_dockArea);
|
|
m_layout->addWidget(m_scrollView);
|
|
m_layout->setGeometry(TQRect(0, 0, m_scrollView->width(),
|
|
m_dockArea->height() + m_scrollView->height()));
|
|
}
|
|
|
|
if (scaling) {
|
|
m_scrollView->installEventFilter(this);
|
|
m_view->resize(m_scrollView->size());
|
|
}
|
|
else {
|
|
m_scrollView->removeEventFilter(this);
|
|
m_view->resize(m_view->framebufferSize());
|
|
}
|
|
|
|
setMaximumSize(sizeHint());
|
|
|
|
repositionView(false);
|
|
|
|
|
|
if (!fromFullscreen) {
|
|
if (m_initialWindowSize.isValid()) {
|
|
resize(m_initialWindowSize);
|
|
m_initialWindowSize = TQSize();
|
|
}
|
|
else if (!scalingChanged)
|
|
resize(sizeHint());
|
|
show();
|
|
if (scalingChanged)
|
|
m_view->update();
|
|
}
|
|
else
|
|
showNormal();
|
|
}
|
|
|
|
void KRDC::viewOnlyToggled() {
|
|
bool s = !m_view->viewOnly();
|
|
m_popup->setItemChecked(VIEW_ONLY_ID, s);
|
|
m_view->setViewOnly(s);
|
|
}
|
|
|
|
void KRDC::showLocalCursorToggled() {
|
|
bool s = (m_view->dotCursorState() != DOT_CURSOR_ON);
|
|
m_popup->setItemChecked(SHOW_LOCAL_CURSOR_ID, s);
|
|
m_view->showDotCursor(s ? DOT_CURSOR_ON : DOT_CURSOR_AUTO);
|
|
}
|
|
|
|
void KRDC::iconify()
|
|
{
|
|
KWin::clearState(winId(), NET::StaysOnTop);
|
|
|
|
m_view->releaseKeyboard();
|
|
if (m_oldResolution.valid)
|
|
ungrabInput(tqt_xdisplay());
|
|
|
|
vidmodeNormalSwitch(tqt_xdisplay(), m_oldResolution);
|
|
m_oldResolution = Resolution();
|
|
showNormal();
|
|
showMinimized();
|
|
m_fullscreenMinimized = true;
|
|
}
|
|
|
|
void KRDC::toolbarChanged() {
|
|
setMaximumSize(sizeHint());
|
|
|
|
// resize window when toolbar is docked and it was maximized
|
|
TQSize fs = m_view->framebufferSize();
|
|
TQSize cs = size();
|
|
TQSize cs1(cs.width(), cs.height()-1); // adjusted for TQDockArea.height()==1
|
|
if ((fs == cs) || (fs == cs1))
|
|
resize(sizeHint());
|
|
}
|
|
|
|
|
|
bool KRDC::event(TQEvent *e) {
|
|
/* used to change resolution when fullscreen was minimized */
|
|
if ((!m_fullscreenMinimized) || (e->type() != TQEvent::WindowActivate))
|
|
return TQWidget::event(e);
|
|
|
|
m_fullscreenMinimized = false;
|
|
int x, y;
|
|
m_oldResolution = vidmodeFullscreenSwitch(tqt_xdisplay(),
|
|
m_desktopWidget.screenNumber(this),
|
|
m_view->width(),
|
|
m_view->height(),
|
|
x, y);
|
|
if (m_oldResolution.valid) {
|
|
m_fullscreenResolution = TQSize(x, y);
|
|
}
|
|
else {
|
|
m_fullscreenResolution = TQApplication::desktop()->size();
|
|
}
|
|
|
|
showFullScreen();
|
|
setGeometry(0, 0, m_fullscreenResolution.width(),
|
|
m_fullscreenResolution.height());
|
|
if (m_oldResolution.valid)
|
|
grabInput(tqt_xdisplay(), winId());
|
|
m_view->switchFullscreen( true );
|
|
KWin::setState(winId(), NET::StaysOnTop);
|
|
|
|
return TQWidget::event(e);
|
|
}
|
|
|
|
bool KRDC::eventFilter(TQObject *watched, TQEvent *e) {
|
|
/* used to get events from TQScrollView on resize for scale mode*/
|
|
if (TQT_BASE_OBJECT(watched) != TQT_BASE_OBJECT(m_scrollView))
|
|
return false;
|
|
if (e->type() != TQEvent::Resize)
|
|
return false;
|
|
|
|
TQResizeEvent *re = (TQResizeEvent*) e;
|
|
m_view->resize(re->size());
|
|
return false;
|
|
}
|
|
|
|
void KRDC::setSize(int w, int h)
|
|
{
|
|
int dw, dh;
|
|
|
|
TQWidget *desktop = TQT_TQWIDGET(TQApplication::desktop());
|
|
dw = desktop->width();
|
|
dh = desktop->height();
|
|
|
|
switch (m_isFullscreen) {
|
|
case WINDOW_MODE_AUTO:
|
|
if ((w > dw) || (h > dh))
|
|
switchToFullscreen(m_windowScaling);
|
|
else
|
|
switchToNormal(m_windowScaling);
|
|
break;
|
|
case WINDOW_MODE_NORMAL:
|
|
switchToNormal(m_windowScaling);
|
|
break;
|
|
case WINDOW_MODE_FULLSCREEN:
|
|
switchToFullscreen(m_windowScaling);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void KRDC::repositionView(bool fullscreen) {
|
|
int ox = 0;
|
|
int oy = 0;
|
|
|
|
if (!m_scrollView)
|
|
return;
|
|
|
|
TQSize s = m_view->size();
|
|
|
|
if (fullscreen) {
|
|
TQSize d = m_fullscreenResolution;
|
|
bool margin = false;
|
|
if (d.width() > s.width())
|
|
ox = (d.width() - s.width()) / 2;
|
|
else if (d.width() < s.width())
|
|
margin = true;
|
|
|
|
if (d.height() > s.height())
|
|
oy = (d.height() - s.height()) / 2;
|
|
else if (d.height() < s.height())
|
|
margin = true;
|
|
|
|
if (margin)
|
|
m_layout->setMargin(1);
|
|
}
|
|
|
|
m_scrollView->moveChild(m_view, ox, oy);
|
|
}
|
|
|
|
void KRDC::toggleFsToolbarAutoHide() {
|
|
setFsToolbarAutoHide(!m_ftAutoHide);
|
|
}
|
|
|
|
void KRDC::setFsToolbarAutoHide(bool on) {
|
|
|
|
if (on == m_ftAutoHide)
|
|
return;
|
|
if (m_isFullscreen != WINDOW_MODE_FULLSCREEN)
|
|
return;
|
|
|
|
m_ftAutoHide = on;
|
|
if (!on)
|
|
showFullscreenToolbar();
|
|
}
|
|
|
|
void KRDC::hideFullscreenToolbarNow() {
|
|
if (m_fsToolbar && m_ftAutoHide)
|
|
m_fsToolbar->startHide();
|
|
}
|
|
|
|
void KRDC::bumpScroll() {
|
|
int x = TQCursor::pos().x();
|
|
int y = TQCursor::pos().y();
|
|
TQSize s = m_view->size();
|
|
TQSize d = m_fullscreenResolution;
|
|
|
|
if (d.width() < s.width()) {
|
|
if (x == 0)
|
|
m_scrollView->scrollBy(-BUMP_SCROLL_CONSTANT, 0);
|
|
else if (x == d.width()-1)
|
|
m_scrollView->scrollBy(BUMP_SCROLL_CONSTANT, 0);
|
|
}
|
|
if (d.height() < s.height()) {
|
|
if (y == 0)
|
|
m_scrollView->scrollBy(0, -BUMP_SCROLL_CONSTANT);
|
|
else if (y == d.height()-1)
|
|
m_scrollView->scrollBy(0, BUMP_SCROLL_CONSTANT);
|
|
}
|
|
|
|
m_bumpScrollTimer.start(333, true);
|
|
}
|
|
|
|
void KRDC::showFullscreenToolbar() {
|
|
m_fsToolbar->startShow();
|
|
m_autoHideTimer.stop();
|
|
}
|
|
|
|
void KRDC::hideFullscreenToolbarDelayed() {
|
|
if (!m_autoHideTimer.isActive())
|
|
m_autoHideTimer.start(TOOLBAR_AUTOHIDE_TIMEOUT, true);
|
|
}
|
|
|
|
void KRDC::mouseMoveEvent(TQMouseEvent *e) {
|
|
if (m_isFullscreen != WINDOW_MODE_FULLSCREEN)
|
|
return;
|
|
|
|
int x = e->x();
|
|
int y = e->y();
|
|
|
|
/* Bump Scrolling */
|
|
|
|
TQSize s = m_view->size();
|
|
TQSize d = m_fullscreenResolution;
|
|
if ((d.width() < s.width()) || d.height() < s.height()) {
|
|
if ((x == 0) || (x >= d.width()-1) ||
|
|
(y == 0) || (y >= d.height()-1))
|
|
bumpScroll();
|
|
else
|
|
m_bumpScrollTimer.stop();
|
|
}
|
|
|
|
/* Toolbar autohide */
|
|
|
|
if (!m_ftAutoHide)
|
|
return;
|
|
|
|
int dw = d.width();
|
|
int w = m_fsToolbar->width();
|
|
int x1 = (dw - w)/4;
|
|
int x2 = dw - x1;
|
|
|
|
if (((y <= 0) && (x >= x1) && (x <= x2)))
|
|
showFullscreenToolbar();
|
|
else
|
|
hideFullscreenToolbarDelayed();
|
|
e->accept();
|
|
}
|
|
|
|
void KRDC::setLastHost(const TQString &lastHost) {
|
|
m_lastHost = lastHost;
|
|
}
|
|
|
|
#include "krdc.moc"
|