diff options
Diffstat (limited to 'src/gui/embedded/qwindowsystem_qws.cpp')
-rw-r--r-- | src/gui/embedded/qwindowsystem_qws.cpp | 4960 |
1 files changed, 0 insertions, 4960 deletions
diff --git a/src/gui/embedded/qwindowsystem_qws.cpp b/src/gui/embedded/qwindowsystem_qws.cpp deleted file mode 100644 index 0e4e27c852..0000000000 --- a/src/gui/embedded/qwindowsystem_qws.cpp +++ /dev/null @@ -1,4960 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qplatformdefs.h" - -#include "qwindowsystem_qws.h" -#include "qwsevent_qws.h" -#include "qwscommand_qws_p.h" -#include "qtransportauth_qws_p.h" -#include "qwsutils_qws.h" -#include "qwscursor_qws.h" -#include "qwsdisplay_qws.h" -#include "qmouse_qws.h" -#include "qcopchannel_qws.h" -#include "qwssocket_qws.h" - -#include "qapplication.h" -#include "private/qapplication_p.h" -#include "qsocketnotifier.h" -#include "qpolygon.h" -#include "qimage.h" -#include "qcursor.h" -#include <private/qpaintengine_raster_p.h> -#include "qscreen_qws.h" -#include "qwindowdefs.h" -#include "private/qlock_p.h" -#include "qwslock_p.h" -#include "qfile.h" -#include "qtimer.h" -#include "qpen.h" -#include "qdesktopwidget.h" -#include "qevent.h" -#include "qinputcontext.h" -#include "qpainter.h" - -#include <qdebug.h> - -#include "qkbddriverfactory_qws.h" -#include "qmousedriverfactory_qws.h" - -#include <qbuffer.h> -#include <qdir.h> - -#include <private/qwindowsurface_qws_p.h> -#include <private/qfontengine_qpf_p.h> - -#include "qwindowsystem_p.h" - - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> - -#ifndef QT_NO_QWS_MULTIPROCESS -#include <sys/param.h> -#include <sys/mount.h> -#endif - -#if !defined(QT_NO_SOUND) && !defined(Q_OS_DARWIN) -#ifdef QT_USE_OLD_QWS_SOUND -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/soundcard.h> -#else -#include "qsoundqss_qws.h" -#endif -#endif - -//#define QWS_DEBUG_FONTCLEANUP - -QT_BEGIN_NAMESPACE - -QWSServer Q_GUI_EXPORT *qwsServer=0; -static QWSServerPrivate *qwsServerPrivate=0; - -#define MOUSE 0 -#define KEY 1 -//#define EVENT_BLOCK_DEBUG - -QWSScreenSaver::~QWSScreenSaver() -{ -} - -extern QByteArray qws_display_spec; -extern void qt_init_display(); //qapplication_qws.cpp -extern QString qws_qtePipeFilename(); - -extern void qt_client_enqueue(const QWSEvent *); //qapplication_qws.cpp -extern QList<QWSCommand*> *qt_get_server_queue(); - -Q_GLOBAL_STATIC_WITH_ARGS(QString, defaultMouse, (QLatin1String("Auto"))) -Q_GLOBAL_STATIC_WITH_ARGS(QString, defaultKeyboard, (QLatin1String("TTY"))) -static const int FontCleanupInterval = 60 * 1000; - -static int qws_keyModifiers = 0; - -static QWSWindow *keyboardGrabber; -static bool keyboardGrabbing; - -static int get_object_id(int count = 1) -{ - static int next=1000; - int n = next; - next += count; - return n; -} -#ifndef QT_NO_QWS_INPUTMETHODS -static QWSInputMethod *current_IM = 0; - -static QWSWindow *current_IM_composing_win = 0; -static int current_IM_winId = -1; -static bool force_reject_strokeIM = false; -#endif - -static void cleanupFontsDir(); - -//#define QWS_REGION_DEBUG - -/*! - \class QWSScreenSaver - \ingroup qws - - \brief The QWSScreenSaver class is a base class for screensavers - in Qt for Embedded Linux. - - When running \l{Qt for Embedded Linux} applications, it is the server - application that installs and controls the screensaver. - \l{Qt for Embedded Linux} supports multilevel screen saving; i.e., it is possible to - specify several different levels of screen responsiveness. For - example, you can choose to first turn off the light before you - fully activate the screensaver. - - Note that there exists no default screensaver implementation. - - To create a custom screensaver, derive from this class and - reimplement the restore() and save() functions. These functions - are called whenever the screensaver is activated or deactivated, - respectively. Once an instance of your custom screensaver is - created, you can use the QWSServer::setScreenSaver() function to - install it. - - \sa QWSServer, QScreen, {Qt for Embedded Linux} -*/ - -/*! - \fn QWSScreenSaver::~QWSScreenSaver() - - Reimplement this function to destroy the screensaver. -*/ - -/*! - \fn QWSScreenSaver::restore() - - Implement this function to deactivate the screensaver, restoring - the previously saved screen. - - \sa save(), QWSServer::screenSaverActivate() -*/ - -/*! - \fn QWSScreenSaver::save(int level) - - Implement this function to activate the screensaver, saving the - current screen. - - \l{Qt for Embedded Linux} supports multilevel screen saving; i.e., it is - possible to specify several different levels of screen - responsiveness. For example, you can choose to first turn off the - light before you fully activate the screensaver. Use the - QWSServer::setScreenSaverIntervals() to specify the time intervals - between the different levels. - - This function should return true if the screensaver successfully - enters the given \a level; otherwise it should return false. - - \sa restore(), QWSServer::screenSaverActivate() -*/ - -class QWSWindowPrivate -{ -public: - QWSWindowPrivate(); - -#ifdef QT_QWS_CLIENTBLIT - QRegion directPaintRegion; -#endif - QRegion allocatedRegion; -#ifndef QT_NO_QWSEMBEDWIDGET - QList<QWSWindow*> embedded; - QWSWindow *embedder; -#endif - QWSWindow::State state; - Qt::WindowFlags windowFlags; - QRegion dirtyOnScreen; - bool painted; -}; - -QWSWindowPrivate::QWSWindowPrivate() - : -#ifndef QT_NO_QWSEMBEDWIDGET - embedder(0), state(QWSWindow::NoState), -#endif - painted(false) -{ -} - -/*! - \class QWSWindow - \ingroup qws - - \brief The QWSWindow class encapsulates a top-level window in - Qt for Embedded Linux. - - When you run a \l{Qt for Embedded Linux} application, it either runs as a - server or connects to an existing server. As applications add and - remove windows, the server process maintains information about - each window. In \l{Qt for Embedded Linux}, top-level windows are - encapsulated as QWSWindow objects. Note that you should never - construct the QWSWindow class yourself; the current top-level - windows can be retrieved using the QWSServer::clientWindows() - function. - - With a window at hand, you can retrieve its caption, name, opacity - and ID using the caption(), name(), opacity() and winId() - functions, respectively. Use the client() function to retrieve a - pointer to the client that owns the window. - - Use the isVisible() function to find out if the window is - visible. You can find out if the window is completely obscured by - another window or by the bounds of the screen, using the - isFullyObscured() function. The isOpaque() function returns true - if the window has an alpha channel equal to 255. Finally, the - requestedRegion() function returns the region of the display the - window wants to draw on. - - \sa QWSServer, QWSClient, {Qt for Embedded Linux Architecture} -*/ - -/*! - \fn int QWSWindow::winId() const - - Returns the window's ID. - - \sa name(), caption() -*/ - -/*! - \fn const QString &QWSWindow::name() const - - Returns the window's name, which is taken from the \l {QWidget::}{objectName()} - at the time of \l {QWidget::}{show()}. - - \sa caption(), winId() -*/ - -/*! - \fn const QString &QWSWindow::caption() const - - Returns the window's caption. - - \sa name(), winId() -*/ - -/*! - \fn QWSClient* QWSWindow::client() const - - Returns a reference to the QWSClient object that owns this window. - - \sa requestedRegion() -*/ - -/*! - \fn QRegion QWSWindow::requestedRegion() const - - Returns the region that the window has requested to draw onto, - including any window decorations. - - \sa client() -*/ - -/*! - \fn bool QWSWindow::isVisible() const - - Returns true if the window is visible; otherwise returns false. - - \sa isFullyObscured() -*/ - -/*! - \fn bool QWSWindow::isOpaque() const - - Returns true if the window is opaque, i.e., if its alpha channel - equals 255; otherwise returns false. - - \sa opacity() -*/ - -/*! - \fn uint QWSWindow::opacity () const - - Returns the window's alpha channel value. - - \sa isOpaque() -*/ - -/*! - \fn bool QWSWindow::isPartiallyObscured() const - \internal - - Returns true if the window is partially obsured by another window - or by the bounds of the screen; otherwise returns false. -*/ - -/*! - \fn bool QWSWindow::isFullyObscured() const - - Returns true if the window is completely obsured by another window - or by the bounds of the screen; otherwise returns false. - - \sa isVisible() -*/ - -/*! - \fn QWSWindowSurface* QWSWindow::windowSurface() const - \internal -*/ - -QWSWindow::QWSWindow(int i, QWSClient* client) - : id(i), modified(false), - onTop(false), c(client), last_focus_time(0), _opacity(255), - opaque(true), d(new QWSWindowPrivate) -{ - surface = 0; -} - - -/*! - \enum QWSWindow::State - - This enum describes the state of a window. Most of the - transitional states are set just before a call to - QScreen::exposeRegion() and reset immediately afterwards. - - \value NoState Initial state before the window is properly initialized. - \value Hidden The window is not visible. - \value Showing The window is being shown. - \value Visible The window is visible, and not in a transition. - \value Hiding The window is being hidden. - \value Raising The windoe is being raised. - \value Lowering The window is being raised. - \value Moving The window is being moved. - \value ChangingGeometry The window's geometry is being changed. - \value Destroyed The window is destroyed. - - \sa state(), QScreen::exposeRegion() -*/ - -/*! - Returns the current state of the window. - - \since 4.3 -*/ -QWSWindow::State QWSWindow::state() const -{ - return d->state; -} - -/*! - Returns the window flags of the window. This value is only available - after the first paint event. - - \since 4.3 -*/ -Qt::WindowFlags QWSWindow::windowFlags() const -{ - return d->windowFlags; -} - -/*! - Returns the region that has been repainted since the previous - QScreen::exposeRegion(), and needs to be copied to the screen. - \since 4.3 -*/ -QRegion QWSWindow::dirtyOnScreen() const -{ - return d->dirtyOnScreen; -} - -void QWSWindow::createSurface(const QString &key, const QByteArray &data) -{ -#ifndef QT_NO_QWS_MULTIPROCESS - if (surface && !surface->isBuffered()) - c->removeUnbufferedSurface(); -#endif - - delete surface; - surface = qt_screen->createSurface(key); - surface->setPermanentState(data); - -#ifndef QT_NO_QWS_MULTIPROCESS - if (!surface->isBuffered()) - c->addUnbufferedSurface(); -#endif -} - -/*! - \internal - Raises the window above all other windows except "Stay on top" windows. -*/ -void QWSWindow::raise() -{ - qwsServerPrivate->raiseWindow(this); -#ifndef QT_NO_QWSEMBEDWIDGET - const int n = d->embedded.size(); - for (int i = 0; i < n; ++i) - d->embedded.at(i)->raise(); -#endif -} - -/*! - \internal - Lowers the window below other windows. -*/ -void QWSWindow::lower() -{ - qwsServerPrivate->lowerWindow(this); -#ifndef QT_NO_QWSEMBEDWIDGET - const int n = d->embedded.size(); - for (int i = 0; i < n; ++i) - d->embedded.at(i)->lower(); -#endif -} - -/*! - \internal - Shows the window. -*/ -void QWSWindow::show() -{ - operation(QWSWindowOperationEvent::Show); -#ifndef QT_NO_QWSEMBEDWIDGET - const int n = d->embedded.size(); - for (int i = 0; i < n; ++i) - d->embedded.at(i)->show(); -#endif -} - -/*! - \internal - Hides the window. -*/ -void QWSWindow::hide() -{ - operation(QWSWindowOperationEvent::Hide); -#ifndef QT_NO_QWSEMBEDWIDGET - const int n = d->embedded.size(); - for (int i = 0; i < n; ++i) - d->embedded.at(i)->hide(); -#endif -} - -/*! - \internal - Make this the active window (i.e., sets the keyboard focus to this - window). -*/ -void QWSWindow::setActiveWindow() -{ - qwsServerPrivate->setFocus(this, true); -#ifndef QT_NO_QWSEMBEDWIDGET - const int n = d->embedded.size(); - for (int i = 0; i < n; ++i) - d->embedded.at(i)->setActiveWindow(); -#endif -} - -void QWSWindow::setName(const QString &n) -{ - rgnName = n; -} - -/*! - \internal - Sets the window's caption to \a c. -*/ -void QWSWindow::setCaption(const QString &c) -{ - rgnCaption = c; -} - - -static int global_focus_time_counter=100; - -void QWSWindow::focus(bool get) -{ - if (get) - last_focus_time = global_focus_time_counter++; - if (c) { - QWSFocusEvent event; - event.simpleData.window = id; - event.simpleData.get_focus = get; - c->sendEvent(&event); - } -} - -void QWSWindow::operation(QWSWindowOperationEvent::Operation o) -{ - if (!c) - return; - QWSWindowOperationEvent event; - event.simpleData.window = id; - event.simpleData.op = o; - c->sendEvent(&event); -} - -/*! - \internal - Destructor. -*/ -QWSWindow::~QWSWindow() -{ -#ifndef QT_NO_QWS_INPUTMETHODS - if (current_IM_composing_win == this) - current_IM_composing_win = 0; -#endif -#ifndef QT_NO_QWSEMBEDWIDGET - QWSWindow *embedder = d->embedder; - if (embedder) { - embedder->d->embedded.removeAll(this); - d->embedder = 0; - } - while (!d->embedded.isEmpty()) - stopEmbed(d->embedded.first()); -#endif - -#ifndef QT_NO_QWS_MULTIPROCESS - if (surface && !surface->isBuffered()) { - if (c && c->d_func()) // d_func() will be 0 if client is deleted - c->removeUnbufferedSurface(); - } -#endif - - delete surface; - delete d; -} - -/*! - \internal - - Returns the region that the window is allowed to draw onto, - including any window decorations but excluding regions covered by - other windows. - - \sa paintedRegion(), requestedRegion() -*/ -QRegion QWSWindow::allocatedRegion() const -{ - return d->allocatedRegion; -} - -#ifdef QT_QWS_CLIENTBLIT -QRegion QWSWindow::directPaintRegion() const -{ - return d->directPaintRegion; -} - -inline void QWSWindow::setDirectPaintRegion(const QRegion &r) -{ - d->directPaintRegion = r; -} -#endif - -/*! - \internal - - Returns the region that the window is known to have drawn into. - - \sa allocatedRegion(), requestedRegion() -*/ -QRegion QWSWindow::paintedRegion() const -{ - return (d->painted ? d->allocatedRegion : QRegion()); -} - -inline void QWSWindow::setAllocatedRegion(const QRegion ®ion) -{ - d->allocatedRegion = region; -} - -#ifndef QT_NO_QWSEMBEDWIDGET -inline void QWSWindow::startEmbed(QWSWindow *w) -{ - d->embedded.append(w); - w->d->embedder = this; -} - -inline void QWSWindow::stopEmbed(QWSWindow *w) -{ - w->d->embedder = 0; - w->client()->sendEmbedEvent(w->winId(), QWSEmbedEvent::Region, QRegion()); - d->embedded.removeAll(w); -} -#endif // QT_NO_QWSEMBEDWIDGET - -/********************************************************************* - * - * Class: QWSClient - * - *********************************************************************/ - -class QWSClientPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QWSClient) - -public: - QWSClientPrivate(); - ~QWSClientPrivate(); - - void setLockId(int id); - void unlockCommunication(); - -private: -#ifndef QT_NO_QWS_MULTIPROCESS - QWSLock *clientLock; - bool shutdown; - int numUnbufferedSurfaces; -#endif - QSet<QByteArray> usedFonts; - friend class QWSServerPrivate; -}; - -QWSClientPrivate::QWSClientPrivate() -{ -#ifndef QT_NO_QWS_MULTIPROCESS - clientLock = 0; - shutdown = false; - numUnbufferedSurfaces = 0; -#endif -} - -QWSClientPrivate::~QWSClientPrivate() -{ -#ifndef QT_NO_QWS_MULTIPROCESS - delete clientLock; -#endif -} - -void QWSClientPrivate::setLockId(int id) -{ -#ifdef QT_NO_QWS_MULTIPROCESS - Q_UNUSED(id); -#else - clientLock = new QWSLock(id); -#endif -} - -void QWSClientPrivate::unlockCommunication() -{ -#ifndef QT_NO_QWS_MULTIPROCESS - if (clientLock) - clientLock->unlock(QWSLock::Communication); -#endif -} - -/*! - \class QWSClient - \ingroup qws - - \brief The QWSClient class encapsulates a client process in Qt for Embedded Linux. - - When you run a \l{Qt for Embedded Linux} application, it either runs as a - server or connects to an existing server. The server and client - processes have different responsibilities: The client process - performs all application specific operations. The server process - is responsible for managing the clients as well as taking care of - the pointer handling, character input, and screen output. In - addition, the server provides functionality to handle input - methods. - - As applications add and remove windows, the server process - maintains information about each window. In \l{Qt for Embedded Linux}, - top-level windows are encapsulated as QWSWindow objects. A list of - the current windows can be retrieved using the - QWSServer::clientWindows() function, and each window can tell - which client that owns it through its QWSWindow::client() - function. - - A QWSClient object has an unique ID that can be retrieved using - its clientId() function. QWSClient also provides the identity() - function which typically returns the name of this client's running - application. - - \sa QWSServer, QWSWindow, {Qt for Embedded Linux Architecture} -*/ - -/*! - \internal -*/ -//always use frame buffer -QWSClient::QWSClient(QObject* parent, QWS_SOCK_BASE* sock, int id) - : QObject(*new QWSClientPrivate, parent), command(0), cid(id) -{ -#ifdef QT_NO_QWS_MULTIPROCESS - Q_UNUSED(sock); - isClosed = false; -#else - csocket = 0; - if (!sock) { - socketDescriptor = -1; - isClosed = false; - } else { - csocket = static_cast<QWSSocket*>(sock); //### - isClosed = false; - - csocket->flush(); - socketDescriptor = csocket->socketDescriptor(); - connect(csocket, SIGNAL(readyRead()), this, SIGNAL(readyRead())); - connect(csocket, SIGNAL(disconnected()), this, SLOT(closeHandler())); - connect(csocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(errorHandler())); - } -#endif //QT_NO_QWS_MULTIPROCESS -} - -/*! - \internal -*/ -QWSClient::~QWSClient() -{ - qDeleteAll(cursors); - delete command; -#ifndef QT_NO_QWS_MULTIPROCESS - delete csocket; -#endif -} - -#ifndef QT_NO_QWS_MULTIPROCESS -void QWSClient::removeUnbufferedSurface() -{ - Q_D(QWSClient); - --d->numUnbufferedSurfaces; -} - -void QWSClient::addUnbufferedSurface() -{ - Q_D(QWSClient); - ++d->numUnbufferedSurfaces; -} -#endif // QT_NO_QWS_MULTIPROCESS - -/*! - \internal -*/ -void QWSClient::setIdentity(const QString& i) -{ - id = i; -} - -void QWSClient::closeHandler() -{ - isClosed = true; - emit connectionClosed(); -} - -void QWSClient::errorHandler() -{ -#if defined(QWS_SOCKET_DEBUG) - qDebug("Client %p error %s", this, csocket ? csocket->errorString().toLatin1().constData() : "(no socket)"); -#endif - isClosed = true; -//####Do we need to clean out the pipes? - - emit connectionClosed(); -} - -/*! - \internal -*/ -int QWSClient::socket() const -{ - return socketDescriptor; -} - -/*! - \internal -*/ -void QWSClient::sendEvent(QWSEvent* event) -{ -#ifndef QT_NO_QWS_MULTIPROCESS - if (csocket) { - // qDebug() << "QWSClient::sendEvent type " << event->type << " socket state " << csocket->state(); - if ((QAbstractSocket::SocketState)(csocket->state()) == QAbstractSocket::ConnectedState) { - event->write(csocket); - } - } - else -#endif - { - qt_client_enqueue(event); - } -} - -/*! - \internal -*/ -void QWSClient::sendRegionEvent(int winid, QRegion rgn, int type -#ifdef QT_QWS_CLIENTBLIT - , int id -#endif - ) -{ -#ifndef QT_NO_QWS_MULTIPROCESS - Q_D(QWSClient); - if (d->clientLock) - d->clientLock->lock(QWSLock::RegionEvent); -#endif - - QWSRegionEvent event; - event.setData(winid, rgn, type); -#ifdef QT_QWS_CLIENTBLIT - event.simpleData.id = id; -#endif - -// qDebug() << "Sending Region event to" << winid << "rgn" << rgn << "type" << type; - - sendEvent(&event); -} - -extern int qt_servershmid; - -/*! - \internal -*/ -void QWSClient::sendConnectedEvent(const char *display_spec) -{ - QWSConnectedEvent event; - event.simpleData.window = 0; - event.simpleData.len = strlen(display_spec) + 1; - event.simpleData.clientId = cid; - event.simpleData.servershmid = qt_servershmid; - char * tmp=(char *)display_spec; - event.setData(tmp, event.simpleData.len); - sendEvent(&event); -} - -/*! - \internal -*/ -void QWSClient::sendMaxWindowRectEvent(const QRect &rect) -{ - QWSMaxWindowRectEvent event; - event.simpleData.window = 0; - event.simpleData.rect = rect; - sendEvent(&event); -} - -/*! - \internal -*/ -#ifndef QT_NO_QWS_PROPERTIES -void QWSClient::sendPropertyNotifyEvent(int property, int state) -{ - QWSPropertyNotifyEvent event; - event.simpleData.window = 0; // not used yet - event.simpleData.property = property; - event.simpleData.state = state; - sendEvent(&event); -} - -/*! - \internal -*/ -void QWSClient::sendPropertyReplyEvent(int property, int len, const char *data) -{ - QWSPropertyReplyEvent event; - event.simpleData.window = 0; // not used yet - event.simpleData.property = property; - event.simpleData.len = len; - event.setData(data, len); - sendEvent(&event); -} -#endif //QT_NO_QWS_PROPERTIES - -/*! - \internal -*/ -void QWSClient::sendSelectionClearEvent(int windowid) -{ - QWSSelectionClearEvent event; - event.simpleData.window = windowid; - sendEvent(&event); -} - -/*! - \internal -*/ -void QWSClient::sendSelectionRequestEvent(QWSConvertSelectionCommand *cmd, int windowid) -{ - QWSSelectionRequestEvent event; - event.simpleData.window = windowid; - event.simpleData.requestor = cmd->simpleData.requestor; - event.simpleData.property = cmd->simpleData.selection; - event.simpleData.mimeTypes = cmd->simpleData.mimeTypes; - sendEvent(&event); -} - -#ifndef QT_NO_QWSEMBEDWIDGET -/*! - \internal -*/ -void QWSClient::sendEmbedEvent(int windowid, QWSEmbedEvent::Type type, - const QRegion ®ion) -{ - QWSEmbedEvent event; - event.setData(windowid, type, region); - sendEvent(&event); -} -#endif // QT_NO_QWSEMBEDWIDGET - -/*! - \fn void QWSClient::connectionClosed() - \internal -*/ - -/*! - \fn void QWSClient::readyRead(); - \internal -*/ - -/*! - \fn int QWSClient::clientId () const - - Returns an integer uniquely identfying this client. -*/ - -/*! - \fn QString QWSClient::identity () const - - Returns the name of this client's running application. -*/ -/********************************************************************* - * - * Class: QWSServer - * - *********************************************************************/ - -/*! - \class QWSServer - \brief The QWSServer class encapsulates a server process in Qt for Embedded Linux. - - \ingroup qws - - When you run a \l{Qt for Embedded Linux} application, it either runs as a - server or connects to an existing server. The server and client - processes have different responsibilities: The client process - performs all application specific operations. The server process - is responsible for managing the clients as well as taking care of - the pointer handling, character input, and screen output. In - addition, the server provides functionality to handle input - methods. - - In \l{Qt for Embedded Linux}, all system generated events are passed to the - server application which then propagates the event to the - appropriate client. See the \l{Qt for Embedded Linux Architecture} - documentation for details. - - Note that this class is instantiated by QApplication for - \l{Qt for Embedded Linux} server processes; you should never construct this - class yourself. Use the instance() function to retrieve a pointer - to the server object. - - Note that the static functions of the QWSServer class can only be - used in the server process. - - \tableofcontents - - \section1 Client Administration - - As applications add and remove windows, the server process - maintains information about each window. In \l{Qt for Embedded Linux}, - top-level windows are encapsulated as QWSWindow objects. Each - window can tell which client that owns it through its - QWSWindow::client() function. Use the clientWindows() function to - retrieve a list of the current top-level windows. Given a - particular position on the display, the window containing it can - be retrieved using the windowAt() function. - - QWSServer also provides the windowEvent() signal which is emitted - whenever something happens to a top level window; the WindowEvent - enum describes the various types of events that the signal - recognizes. In addition, the server class provides the - markedText() signal which is emitted whenever some text has been - selected in any of the windows, passing the selection as - parameter. - - The QCopChannel class and the QCOP communication protocol enable - transfer of messages between clients. QWSServer provides the - newChannel() and removedChannel() signals that is emitted whenever - a new QCopChannel object is created or destroyed, respectively. - - See also: QWSWindow, QWSClient and QCopChannel. - - - \section1 Mouse Handling - - The mouse driver (represented by an instance of the - QWSMouseHandler class) is loaded by the server application when it - starts running, using Qt's \l {How to Create Qt Plugins}{plugin - system}. A mouse driver receives mouse events from the device and - encapsulates each event with an instance of the QWSEvent class - which it then passes to the server. - - The openMouse() function opens the mouse devices specified by the - QWS_MOUSE_PROTO environment variable, and the setMouseHandler() - functions sets the primary mouse driver. Alternatively, the static - setDefaultMouse() function provides means of specifying the mouse - driver to use if the QWS_MOUSE_PROTO variable is not defined (note - that the default is otherwise platform dependent). The primary - mouse driver can be retrieved using the static mouseHandler() - function. Use the closeMouse() function to delete the mouse - drivers. - - In addition, the QWSServer class can control the flow of mouse - input using the suspendMouse() and resumeMouse() functions. - - See also: QWSMouseHandler and \l{Qt for Embedded Linux Pointer Handling}. - - \section1 Keyboard Handling - - The keyboard driver (represented by an instance of the - QWSKeyboardHandler class) is loaded by the server application when - it starts running, using Qt's \l {How to Create Qt Plugins}{plugin - system}. A keyboard driver receives keyboard events from the - device and encapsulates each event with an instance of the - QWSEvent class which it then passes to the server. - - The openKeyboard() function opens the keyboard devices specified - by the QWS_KEYBOARD environment variable, and the - setKeyboardHandler() functions sets the primary keyboard - driver. Alternatively, the static setDefaultKeyboard() function - provides means of specifying the keyboard driver to use if the - QWS_KEYBOARD variable is not defined (note again that the default - is otherwise platform dependent). The primary keyboard driver can - be retrieved using the static keyboardHandler() function. Use the - closeKeyboard() function to delete the keyboard drivers. - - In addition, the QWSServer class can handle key events from both - physical and virtual keyboards using the processKeyEvent() and - sendKeyEvent() functions, respectively. Use the - addKeyboardFilter() function to filter the key events from - physical keyboard drivers, the most recently added filter can be - removed and deleted using the removeKeyboardFilter() function. - - See also: QWSKeyboardHandler and \l{Qt for Embedded Linux Character Input}. - - \section1 Display Handling - - When a screen update is required, the server runs through all the - top-level windows that intersect with the region that is about to - be updated, and ensures that the associated clients have updated - their memory buffer. Then the server uses the screen driver - (represented by an instance of the QScreen class) to copy the - content of the memory to the screen. - - In addition, the QWSServer class provides some means of managing - the screen output: Use the refresh() function to refresh the - entire display, or alternatively a specified region of it. The - enablePainting() function can be used to disable (and enable) - painting onto the screen. QWSServer also provide the - setMaxWindowRect() function restricting the area of the screen - which \l{Qt for Embedded Linux} applications will consider to be the - maximum area to use for windows. To set the brush used as the - background in the absence of obscuring windows, QWSServer provides - the static setBackground() function. The corresponding - backgroundBrush() function returns the currently set brush. - - QWSServer also controls the screen saver: Use the setScreenSaver() - to install a custom screen saver derived from the QWSScreenSaver - class. Once installed, the screensaver can be activated using the - screenSaverActivate() function, and the screenSaverActive() - function returns its current status. Use the - setScreenSaverInterval() function to specify the timeout interval. - \l{Qt for Embedded Linux} also supports multilevel screen saving, use the - setScreenSaverIntervals() function to specify the various levels - and their timeout intervals. - - Finally, the QWSServer class controls the cursor's appearance, - i.e., use the setCursorVisible() function to hide or show the - cursor, and the isCursorVisible() function to determine whether - the cursor is visible on the display or not. - - See also: QScreen and \l{Qt for Embedded Linux Display Management}. - - \section1 Input Method Handling - - Whenever the server receives an event, it queries its stack of - top-level windows to find the window containing the event's - position (each window can identify the client application that - created it). Then the server forwards the event to the appropriate - client. If an input method is installed, it is used as a filter - between the server and the client application. - - Derive from the QWSInputMethod class to create custom input - methods, and use the server's setCurrentInputMethod() function to - install it. Use the sendIMEvent() and sendIMQuery() functions to - send input method events and queries. - - QWSServer provides the IMMouse enum describing the various mouse - events recognized by the QWSInputMethod::mouseHandler() - function. The latter function allows subclasses of QWSInputMethod - to handle mouse events within the preedit text. - - \sa QWSInputMethod -*/ - -/*! - \enum QWSServer::IMState - \obsolete - - This enum describes the various states of an input method. - - \value IMCompose Composing. - \value IMStart Equivalent to IMCompose. - \value IMEnd Finished composing. - - \sa QWSInputMethod::sendIMEvent() -*/ - -/*! - \enum QWSServer::IMMouse - - This enum describes the various types of mouse events recognized - by the QWSInputMethod::mouseHandler() function. - - \value MousePress An event generated by pressing a mouse button. - \value MouseRelease An event generated by relasing a mouse button. - \value MouseMove An event generated by moving the mouse cursor. - \value MouseOutside This value is only reserved, i.e., it is not used in - current implementations. - - \sa QWSInputMethod, setCurrentInputMethod() -*/ - -/*! - \enum QWSServer::ServerFlags - \internal - - This enum is used to pass various options to the window system - server. - - \value DisableKeyboard Ignore all keyboard input. - \value DisableMouse Ignore all mouse input. -*/ - -/*! - \enum QWSServer::WindowEvent - - This enum specifies the various events that can occur in a - top-level window. - - \value Create A new window has been created (by the QWidget constructor). - \value Destroy The window has been closed and deleted (by the QWidget destructor). - \value Hide The window has been hidden using the QWidget::hide() function. - \value Show The window has been shown using the QWidget::show() function or similar. - \value Raise The window has been raised to the top of the desktop. - \value Lower The window has been lowered. - \value Geometry The window has changed size or position. - \value Active The window has become the active window (i.e., it has keyboard focus). - \value Name The window has been named. - - \sa windowEvent() -*/ - -/*! - \fn void QWSServer::markedText(const QString &selection) - - This signal is emitted whenever some text is selected in any of - the running applications, passing the selected text in the \a - selection parameter. - - \sa windowEvent() -*/ - -/*! - \fn const QList<QWSWindow*> &QWSServer::clientWindows() - - Returns the list of current top-level windows. - - Note that the collection of top-level windows changes as - applications add and remove widgets so it should not be stored for - future use. The windows are sorted in stacking order from top-most - to bottom-most. - - Use the QWSWindow::client() function to retrieve the client - application that owns a given window. - - \sa windowAt(), instance() -*/ - -/*! - \fn void QWSServer::newChannel(const QString& channel) - - This signal is emitted whenever a new QCopChannel object is - created, passing the channel's name in the \a channel parameter. - - \sa removedChannel() -*/ - -/*! - \fn void QWSServer::removedChannel(const QString& channel) - - This signal is emitted immediately after the given the QCopChannel - object specified by \a channel, is destroyed. - - Note that a channel is not destroyed until all its listeners have - been unregistered. - - \sa newChannel() -*/ - -/*! - \fn QWSServer::QWSServer(int flags, QObject *parent) - \internal - - Construct a QWSServer object with the given \a parent. The \a - flags are used for keyboard and mouse settings. - - \warning This class is instantiated by QApplication for - \l{Qt for Embedded Linux} server processes. You should never construct - this class yourself. - - \sa {Running Applications} -*/ - -/*! - \fn static QWSServer* QWSServer::instance() - \since 4.2 - - Returns a pointer to the server instance. - - Note that the pointer will be 0 if the application is not the - server, i.e., if the QApplication::type() function doesn't return - QApplication::GuiServer. - - \sa clientWindows(), windowAt() -*/ - -struct QWSCommandStruct -{ - QWSCommandStruct(QWSCommand *c, QWSClient *cl) :command(c),client(cl){} - ~QWSCommandStruct() { delete command; } - - QWSCommand *command; - QWSClient *client; - -}; - -QWSServer::QWSServer(int flags, QObject *parent) : - QObject(*new QWSServerPrivate, parent) -{ - Q_D(QWSServer); - QT_TRY { - d->initServer(flags); - } QT_CATCH(...) { - qwsServer = 0; - qwsServerPrivate = 0; - QT_RETHROW; - } -} - -#ifdef QT3_SUPPORT -/*! - Use the two-argument overload and call the - QObject::setObjectName() function instead. -*/ -QWSServer::QWSServer(int flags, QObject *parent, const char *name) : - QObject(*new QWSServerPrivate, parent) -{ - Q_D(QWSServer); - setObjectName(QString::fromAscii(name)); - d->initServer(flags); -} -#endif - - -#ifndef QT_NO_QWS_MULTIPROCESS -static void ignoreSignal(int) {} // Used to eat SIGPIPE signals below -#endif - -bool QWSServerPrivate::screensaverblockevent( int index, int *screensaverinterval, bool isDown ) -{ - static bool ignoreEvents[2] = { false, false }; - if ( isDown ) { - if ( !ignoreEvents[index] ) { - bool wake = false; - if ( screensaverintervals ) { - if ( screensaverinterval != screensaverintervals ) { - wake = true; - } - } - if ( screensaverblockevents && wake ) { -#ifdef EVENT_BLOCK_DEBUG - qDebug( "waking the screen" ); -#endif - ignoreEvents[index] = true; - } else if ( !screensaverblockevents ) { -#ifdef EVENT_BLOCK_DEBUG - qDebug( "the screen was already awake" ); -#endif - ignoreEvents[index] = false; - } - } - } else { - if ( ignoreEvents[index] ) { -#ifdef EVENT_BLOCK_DEBUG - qDebug( "mouseup?" ); -#endif - ignoreEvents[index] = false; - return true; - } - } - return ignoreEvents[index]; -} - -void QWSServerPrivate::initServer(int flags) -{ - Q_Q(QWSServer); - Q_ASSERT(!qwsServer); - qwsServer = q; - qwsServerPrivate = this; - disablePainting = false; -#ifndef QT_NO_QWS_MULTIPROCESS - ssocket = new QWSServerSocket(qws_qtePipeFilename(), q); - QObject::connect(ssocket, SIGNAL(newConnection()), q, SLOT(_q_newConnection())); - - if ( !ssocket->isListening()) { - perror("QWSServerPrivate::initServer: server socket not listening"); - qFatal("Failed to bind to %s", qws_qtePipeFilename().toLatin1().constData()); - } - - struct linger tmp; - tmp.l_onoff=1; - tmp.l_linger=0; - setsockopt(ssocket->socketDescriptor(),SOL_SOCKET,SO_LINGER,(char *)&tmp,sizeof(tmp)); - - - signal(SIGPIPE, ignoreSignal); //we get it when we read -#endif - focusw = 0; - mouseGrabber = 0; - mouseGrabbing = false; - inputMethodMouseGrabbed = false; - keyboardGrabber = 0; - keyboardGrabbing = false; -#ifndef QT_NO_QWS_CURSOR - haveviscurs = false; - cursor = 0; - nextCursor = 0; -#endif - -#ifndef QT_NO_QWS_MULTIPROCESS - - if (!geteuid()) { -#if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE) - if(mount(0,"/var/shm", "shm", 0, 0)) { - /* This just confuses people with 2.2 kernels - if (errno != EBUSY) - qDebug("Failed mounting shm fs on /var/shm: %s",strerror(errno)); - */ - } -#endif - } -#endif - - // no selection yet - selectionOwner.windowid = -1; - selectionOwner.time.set(-1, -1, -1, -1); - - cleanupFontsDir(); - - // initialize the font database - // from qfontdatabase_qws.cpp - extern void qt_qws_init_fontdb(); - qt_qws_init_fontdb(); - - openDisplay(); - - screensavertimer = new QTimer(q); - screensavertimer->setSingleShot(true); - QObject::connect(screensavertimer, SIGNAL(timeout()), q, SLOT(_q_screenSaverTimeout())); - _q_screenSaverWake(); - - clientMap[-1] = new QWSClient(q, 0, 0); - - if (!bgBrush) - bgBrush = new QBrush(QColor(0x20, 0xb0, 0x50)); - - initializeCursor(); - - // input devices - if (!(flags&QWSServer::DisableMouse)) { - q->openMouse(); - } -#ifndef QT_NO_QWS_KEYBOARD - if (!(flags&QWSServer::DisableKeyboard)) { - q->openKeyboard(); - } -#endif - -#if !defined(QT_NO_SOUND) && !defined(QT_EXTERNAL_SOUND_SERVER) && !defined(Q_OS_DARWIN) - soundserver = new QWSSoundServer(q); -#endif -} - -/*! - \internal - Destructs this server. -*/ -QWSServer::~QWSServer() -{ - closeMouse(); -#ifndef QT_NO_QWS_KEYBOARD - closeKeyboard(); -#endif - d_func()->cleanupFonts(/*force =*/true); -} - -/*! - \internal - */ -void QWSServer::timerEvent(QTimerEvent *e) -{ - Q_D(QWSServer); - if (e->timerId() == d->fontCleanupTimer.timerId()) { - d->cleanupFonts(); - d->fontCleanupTimer.stop(); - } else { - QObject::timerEvent(e); - } -} - -const QList<QWSWindow*> &QWSServer::clientWindows() -{ - Q_D(QWSServer); - return d->windows; -} - -/*! - \internal -*/ -void QWSServerPrivate::releaseMouse(QWSWindow* w) -{ - if (w && mouseGrabber == w) { - mouseGrabber = 0; - mouseGrabbing = false; -#ifndef QT_NO_QWS_CURSOR - if (nextCursor) { - // Not grabbing -> set the correct cursor - setCursor(nextCursor); - nextCursor = 0; - } -#endif - } -} - -/*! - \internal -*/ -void QWSServerPrivate::releaseKeyboard(QWSWindow* w) -{ - if (keyboardGrabber == w) { - keyboardGrabber = 0; - keyboardGrabbing = false; - } -} - -void QWSServerPrivate::handleWindowClose(QWSWindow *w) -{ - w->shuttingDown(); - if (focusw == w) - setFocus(w,false); - if (mouseGrabber == w) - releaseMouse(w); - if (keyboardGrabber == w) - releaseKeyboard(w); -} - - -#ifndef QT_NO_QWS_MULTIPROCESS -/*! - \internal -*/ -void QWSServerPrivate::_q_newConnection() -{ - Q_Q(QWSServer); - while (QWS_SOCK_BASE *sock = ssocket->nextPendingConnection()) { - int socket = sock->socketDescriptor(); - sock->setParent(0); - - QWSClient *client = new QWSClient(q,sock, get_object_id()); - clientMap[socket] = client; - -#ifndef QT_NO_SXE -#ifdef QTRANSPORTAUTH_DEBUG - qDebug( "Transport auth connected: unix stream socket %d", socket ); -#endif - // get a handle to the per-process authentication service - QTransportAuth *a = QTransportAuth::getInstance(); - - // assert that this transport is trusted - QTransportAuth::Data *d = a->connectTransport( - QTransportAuth::UnixStreamSock | - QTransportAuth::Trusted, socket ); - - QAuthDevice *ad = a->recvBuf( d, sock ); - ad->setClient(client); - - QObject::connect(ad, SIGNAL(readyRead()), - q, SLOT(_q_doClient())); - - QObject::connect(client, SIGNAL(connectionClosed()), - q, SLOT(_q_clientClosed())); -#else - QObject::connect(client, SIGNAL(readyRead()), - q, SLOT(_q_doClient())); - QObject::connect(client, SIGNAL(connectionClosed()), - q, SLOT(_q_clientClosed())); -#endif // QT_NO_SXE - - client->sendConnectedEvent(qws_display_spec.constData()); - - if (clientMap.contains(socket)) { - QList<QScreen*> screens = qt_screen->subScreens(); - if (screens.isEmpty()) - screens.append(qt_screen); - for (int i = 0; i < screens.size(); ++i) { - const QApplicationPrivate *ap = QApplicationPrivate::instance(); - QScreen *screen = screens.at(i); - const QRect rect = ap->maxWindowRect(screen); - if (!rect.isEmpty()) - client->sendMaxWindowRectEvent(rect); - if (screen->isTransformed()) { - QWSScreenTransformationEvent event; - event.simpleData.screen = i; - event.simpleData.transformation = screen->transformOrientation(); - client->sendEvent(&event); - } - } - } - - // pre-provide some object id's - QWSCreateCommand cmd(30); - invokeCreate(&cmd, client); - } -} -/*! - \internal -*/ -void QWSServerPrivate::_q_clientClosed() -{ - Q_Q(QWSServer); - QWSClient* cl = (QWSClient*)q->sender(); - - // Remove any queued commands for this client - int i = 0; - while (i < commandQueue.size()) { - QWSCommandStruct *cs = commandQueue.at(i); - if (cs->client == cl) { - commandQueue.removeAt(i); - delete cs; - } else { - ++i; - } - } - -#ifndef QT_NO_COP - // Enfore unsubscription from all channels. - QCopChannel::detach(cl); -#endif - - // Shut down all windows for this client - for (int i = 0; i < windows.size(); ++i) { - QWSWindow* w = windows.at(i); - if (w->forClient(cl)) - w->shuttingDown(); - } - - // Delete all windows for this client - QRegion exposed; - i = 0; - while (i < windows.size()) { - QWSWindow* w = windows.at(i); - if (w->forClient(cl)) { - windows.takeAt(i); - w->c = 0; //so we don't send events to it anymore - releaseMouse(w); - releaseKeyboard(w); - exposed += w->allocatedRegion(); -// rgnMan->remove(w->allocationIndex()); - if (focusw == w) - setFocus(focusw,0); - if (mouseGrabber == w) - releaseMouse(w); - if (i < nReserved) - --nReserved; -#ifndef QT_NO_QWS_PROPERTIES - propertyManager.removeProperties(w->winId()); -#endif - emit q->windowEvent(w, QWSServer::Destroy); - w->d->state = QWSWindow::Destroyed; //??? - deletedWindows.append(w); - } else { - ++i; - } - } - if (deletedWindows.count()) - QTimer::singleShot(0, q, SLOT(_q_deleteWindowsLater())); - - QWSClientPrivate *clientPrivate = cl->d_func(); - if (!clientPrivate->shutdown) { -#if defined(QWS_DEBUG_FONTCLEANUP) - qDebug() << "client" << cl->clientId() << "crashed"; -#endif - // this would be the place to emit a signal to notify about the - // crash of a client - crashedClientIds.append(cl->clientId()); - fontCleanupTimer.start(10, q_func()); - } - clientPrivate->shutdown = true; - - while (!clientPrivate->usedFonts.isEmpty()) { - const QByteArray font = *clientPrivate->usedFonts.begin(); -#if defined(QWS_DEBUG_FONTCLEANUP) - qDebug() << "dereferencing font" << font << "from disconnected client"; -#endif - dereferenceFont(clientPrivate, font); - } - clientPrivate->usedFonts.clear(); - - //qDebug("removing client %d with socket %d", cl->clientId(), cl->socket()); - clientMap.remove(cl->socket()); - if (cl == cursorClient) - cursorClient = 0; - if (qt_screen->clearCacheFunc) - (qt_screen->clearCacheFunc)(qt_screen, cl->clientId()); // remove any remaining cache entries. - cl->deleteLater(); - - update_regions(); - exposeRegion(exposed); -} - -void QWSServerPrivate::_q_deleteWindowsLater() -{ - qDeleteAll(deletedWindows); - deletedWindows.clear(); -} - -#endif //QT_NO_QWS_MULTIPROCESS - -void QWSServerPrivate::referenceFont(QWSClientPrivate *client, const QByteArray &font) -{ - if (!client->usedFonts.contains(font)) { - client->usedFonts.insert(font); - - ++fontReferenceCount[font]; -#if defined(QWS_DEBUG_FONTCLEANUP) - qDebug() << "Client" << client->q_func()->clientId() << "added font" << font; - qDebug() << "Refcount is" << fontReferenceCount[font]; -#endif - } -} - -void QWSServerPrivate::dereferenceFont(QWSClientPrivate *client, const QByteArray &font) -{ - if (client->usedFonts.contains(font)) { - client->usedFonts.remove(font); - - Q_ASSERT(fontReferenceCount[font]); - if (!--fontReferenceCount[font] && !fontCleanupTimer.isActive()) - fontCleanupTimer.start(FontCleanupInterval, q_func()); - -#if defined(QWS_DEBUG_FONTCLEANUP) - qDebug() << "Client" << client->q_func()->clientId() << "removed font" << font; - qDebug() << "Refcount is" << fontReferenceCount[font]; -#endif - } -} - -static void cleanupFontsDir() -{ - static bool dontDelete = !qgetenv("QWS_KEEP_FONTS").isEmpty(); - if (dontDelete) - return; - - extern QString qws_fontCacheDir(); - QDir dir(qws_fontCacheDir(), QLatin1String("*.qsf")); - for (uint i = 0; i < dir.count(); ++i) { -#if defined(QWS_DEBUG_FONTCLEANUP) - qDebug() << "removing stale font file" << dir[i]; -#endif - dir.remove(dir[i]); - } -} - -void QWSServerPrivate::cleanupFonts(bool force) -{ - static bool dontDelete = !qgetenv("QWS_KEEP_FONTS").isEmpty(); - if (dontDelete) - return; - -#if defined(QWS_DEBUG_FONTCLEANUP) - qDebug() << "cleanupFonts()"; -#endif - if (!fontReferenceCount.isEmpty()) { - QMap<QByteArray, int>::Iterator it = fontReferenceCount.begin(); - while (it != fontReferenceCount.end()) { - if (it.value() && !force) { - ++it; - continue; - } - - const QByteArray &fontName = it.key(); -#if defined(QWS_DEBUG_FONTCLEANUP) - qDebug() << "removing unused font file" << fontName; -#endif - QT_TRY { - QFile::remove(QFile::decodeName(fontName)); - sendFontRemovedEvent(fontName); - - it = fontReferenceCount.erase(it); - } QT_CATCH(...) { - // so we were not able to remove the font. - // don't be angry and just continue with the next ones. - ++it; - } - } - } - - if (crashedClientIds.isEmpty()) - return; - - QList<QByteArray> removedFonts; -#if !defined(QT_NO_QWS_QPF2) && !defined(QT_FONTS_ARE_RESOURCES) - removedFonts = QFontEngineQPF::cleanUpAfterClientCrash(crashedClientIds); -#endif - crashedClientIds.clear(); - - for (int i = 0; i < removedFonts.count(); ++i) - sendFontRemovedEvent(removedFonts.at(i)); -} - -void QWSServerPrivate::sendFontRemovedEvent(const QByteArray &font) -{ - QWSFontEvent event; - event.simpleData.type = QWSFontEvent::FontRemoved; - event.setData(font.constData(), font.length(), false); - - QMap<int,QWSClient*>::const_iterator it = clientMap.constBegin(); - for (; it != clientMap.constEnd(); ++it) - (*it)->sendEvent(&event); -} - -/*! - \internal -*/ -QWSCommand* QWSClient::readMoreCommand() -{ -#ifndef QT_NO_QWS_MULTIPROCESS - QIODevice *socket = 0; -#endif -#ifndef QT_NO_SXE - if (socketDescriptor != -1) // not server socket - socket = QTransportAuth::getInstance()->passThroughByClient( this ); -#if QTRANSPORTAUTH_DEBUG - if (socket) { - char displaybuf[1024]; - qint64 bytes = socket->bytesAvailable(); - if ( bytes > 511 ) bytes = 511; - hexstring( displaybuf, ((unsigned char *)(reinterpret_cast<QAuthDevice*>(socket)->buffer().constData())), bytes ); - qDebug( "readMoreCommand: %lli bytes - %s", socket->bytesAvailable(), displaybuf ); - } -#endif -#endif // QT_NO_SXE - -#ifndef QT_NO_QWS_MULTIPROCESS - if (!socket) - socket = csocket; // server socket - if (socket) { - // read next command - if (!command) { - int command_type = qws_read_uint(socket); - - if (command_type >= 0) - command = QWSCommand::factory(command_type); - } - if (command) { - if (command->read(socket)) { - // Finished reading a whole command. - QWSCommand* result = command; - command = 0; - return result; - } - } - - // Not finished reading a whole command. - return 0; - } else -#endif // QT_NO_QWS_MULTIPROCESS - { - QList<QWSCommand*> *serverQueue = qt_get_server_queue(); - return serverQueue->isEmpty() ? 0 : serverQueue->takeFirst(); - } -} - - -/*! - \internal -*/ -void QWSServer::processEventQueue() -{ - if (qwsServerPrivate) - qwsServerPrivate->doClient(qwsServerPrivate->clientMap.value(-1)); -} - - -#ifndef QT_NO_QWS_MULTIPROCESS -void QWSServerPrivate::_q_doClient() -{ - Q_Q(QWSServer); - - QWSClient* client; -#ifndef QT_NO_SXE - QAuthDevice *ad = qobject_cast<QAuthDevice*>(q->sender()); - if (ad) - client = (QWSClient*)ad->client(); - else -#endif - client = (QWSClient*)q->sender(); - - if (doClientIsActive) { - pendingDoClients.append(client); - return; - } - doClientIsActive = true; - - doClient(client); - - while (!pendingDoClients.isEmpty()) { - doClient(pendingDoClients.takeFirst()); - } - - doClientIsActive = false; -} -#endif // QT_NO_QWS_MULTIPROCESS - -void QWSServerPrivate::doClient(QWSClient *client) -{ - QWSCommand* command=client->readMoreCommand(); - - while (command) { - QWSCommandStruct *cs = new QWSCommandStruct(command, client); - commandQueue.append(cs); - // Try for some more... - command=client->readMoreCommand(); - } - - while (!commandQueue.isEmpty()) { - QWSCommandStruct *cs = commandQueue.takeAt(0); - switch (cs->command->type) { - case QWSCommand::Identify: - invokeIdentify((QWSIdentifyCommand*)cs->command, cs->client); - break; - case QWSCommand::Create: - invokeCreate((QWSCreateCommand*)cs->command, cs->client); - break; -#ifndef QT_NO_QWS_MULTIPROCESS - case QWSCommand::Shutdown: - cs->client->d_func()->shutdown = true; - break; -#endif - case QWSCommand::RegionName: - invokeRegionName((QWSRegionNameCommand*)cs->command, cs->client); - break; - case QWSCommand::Region: - invokeRegion((QWSRegionCommand*)cs->command, cs->client); - cs->client->d_func()->unlockCommunication(); - break; - case QWSCommand::RegionMove: - invokeRegionMove((QWSRegionMoveCommand*)cs->command, cs->client); - cs->client->d_func()->unlockCommunication(); - break; - case QWSCommand::RegionDestroy: - invokeRegionDestroy((QWSRegionDestroyCommand*)cs->command, cs->client); - break; -#ifndef QT_NO_QWS_PROPERTIES - case QWSCommand::AddProperty: - invokeAddProperty((QWSAddPropertyCommand*)cs->command); - break; - case QWSCommand::SetProperty: - invokeSetProperty((QWSSetPropertyCommand*)cs->command); - break; - case QWSCommand::RemoveProperty: - invokeRemoveProperty((QWSRemovePropertyCommand*)cs->command); - break; - case QWSCommand::GetProperty: - invokeGetProperty((QWSGetPropertyCommand*)cs->command, cs->client); - break; -#endif - case QWSCommand::SetSelectionOwner: - invokeSetSelectionOwner((QWSSetSelectionOwnerCommand*)cs->command); - break; - case QWSCommand::RequestFocus: - invokeSetFocus((QWSRequestFocusCommand*)cs->command, cs->client); - break; - case QWSCommand::ChangeAltitude: - invokeSetAltitude((QWSChangeAltitudeCommand*)cs->command, - cs->client); - cs->client->d_func()->unlockCommunication(); - break; - case QWSCommand::SetOpacity: - invokeSetOpacity((QWSSetOpacityCommand*)cs->command, - cs->client); - break; - -#ifndef QT_NO_QWS_CURSOR - case QWSCommand::DefineCursor: - invokeDefineCursor((QWSDefineCursorCommand*)cs->command, cs->client); - break; - case QWSCommand::SelectCursor: - invokeSelectCursor((QWSSelectCursorCommand*)cs->command, cs->client); - break; - case QWSCommand::PositionCursor: - invokePositionCursor((QWSPositionCursorCommand*)cs->command, cs->client); - break; -#endif - case QWSCommand::GrabMouse: - invokeGrabMouse((QWSGrabMouseCommand*)cs->command, cs->client); - break; - case QWSCommand::GrabKeyboard: - invokeGrabKeyboard((QWSGrabKeyboardCommand*)cs->command, cs->client); - break; -#if !defined(QT_NO_SOUND) && !defined(Q_OS_DARWIN) - case QWSCommand::PlaySound: - invokePlaySound((QWSPlaySoundCommand*)cs->command, cs->client); - break; -#endif -#ifndef QT_NO_COP - case QWSCommand::QCopRegisterChannel: - invokeRegisterChannel((QWSQCopRegisterChannelCommand*)cs->command, - cs->client); - break; - case QWSCommand::QCopSend: - invokeQCopSend((QWSQCopSendCommand*)cs->command, cs->client); - break; -#endif -#ifndef QT_NO_QWS_INPUTMETHODS - case QWSCommand::IMUpdate: - invokeIMUpdate((QWSIMUpdateCommand*)cs->command, cs->client); - break; - case QWSCommand::IMResponse: - invokeIMResponse((QWSIMResponseCommand*)cs->command, cs->client); - break; - case QWSCommand::IMMouse: - { - if (current_IM) { - QWSIMMouseCommand *cmd = (QWSIMMouseCommand *) cs->command; - current_IM->mouseHandler(cmd->simpleData.index, - cmd->simpleData.state); - } - } - break; -#endif - case QWSCommand::Font: - invokeFont((QWSFontCommand *)cs->command, cs->client); - break; - case QWSCommand::RepaintRegion: - invokeRepaintRegion((QWSRepaintRegionCommand*)cs->command, - cs->client); - cs->client->d_func()->unlockCommunication(); - break; -#ifndef QT_NO_QWSEMBEDWIDGET - case QWSCommand::Embed: - invokeEmbed(static_cast<QWSEmbedCommand*>(cs->command), - cs->client); - break; -#endif - case QWSCommand::ScreenTransform: - invokeScreenTransform(static_cast<QWSScreenTransformCommand*>(cs->command), - cs->client); - break; - } - delete cs; - } -} - - -void QWSServerPrivate::showCursor() -{ -#ifndef QT_NO_QWS_CURSOR - if (qt_screencursor) - qt_screencursor->show(); -#endif -} - -void QWSServerPrivate::hideCursor() -{ -#ifndef QT_NO_QWS_CURSOR - if (qt_screencursor) - qt_screencursor->hide(); -#endif -} - -/*! - \fn void QWSServer::enablePainting(bool enable) - - Enables painting onto the screen if \a enable is true; otherwise - painting is disabled. - - \sa {Qt for Embedded Linux Architecture#Drawing on Screen}{Qt for Embedded Linux - Architecture} -*/ -void QWSServer::enablePainting(bool enable) -{ - Q_D(QWSServer); - - if (d->disablePainting == !enable) - return; - - d->disablePainting = !enable; - - if (enable) { - // Reset the server side allocated regions to ensure update_regions() - // will send out region events. - for (int i = 0; i < d->windows.size(); ++i) { - QWSWindow *w = d->windows.at(i); - w->setAllocatedRegion(QRegion()); -#ifdef QT_QWS_CLIENTBLIT - w->setDirectPaintRegion(QRegion()); -#endif - } - d->update_regions(); - d->showCursor(); - } else { - // Disable painting by clients by taking away their allocated region. - // To ensure mouse events are still delivered to the correct windows, - // the allocated regions are not modified on the server. - for (int i = 0; i < d->windows.size(); ++i) { - QWSWindow *w = d->windows.at(i); - w->client()->sendRegionEvent(w->winId(), QRegion(), - QWSRegionEvent::Allocation); -#ifdef QT_QWS_CLIENTBLIT - w->client()->sendRegionEvent(w->winId(), QRegion(), - QWSRegionEvent::DirectPaint); -#endif - } - d->hideCursor(); - } -} - -/*! - Refreshes the display by making the screen driver update the - entire display. - - \sa QScreen::exposeRegion() -*/ -void QWSServer::refresh() -{ - Q_D(QWSServer); - d->exposeRegion(QScreen::instance()->region()); -//### send repaint to non-buffered windows -} - -/*! - \fn void QWSServer::refresh(QRegion & region) - \overload - - Refreshes the given \a region of the display. -*/ -void QWSServer::refresh(QRegion & r) -{ - Q_D(QWSServer); - d->exposeRegion(r); -//### send repaint to non-buffered windows -} - -/*! - \fn void QWSServer::setMaxWindowRect(const QRect& rectangle) - - Sets the maximum area of the screen that \l{Qt for Embedded Linux} - applications can use, to be the given \a rectangle. - - Note that this function can only be used in the server process. - - \sa QWidget::showMaximized() -*/ -void QWSServer::setMaxWindowRect(const QRect &rect) -{ - QList<QScreen*> subScreens = qt_screen->subScreens(); - if (subScreens.isEmpty() && qt_screen != 0) - subScreens.append(qt_screen); - - for (int i = 0; i < subScreens.size(); ++i) { - const QScreen *screen = subScreens.at(i); - const QRect r = (screen->region() & rect).boundingRect(); - if (r.isEmpty()) - continue; - - QApplicationPrivate *ap = QApplicationPrivate::instance(); - if (ap->maxWindowRect(screen) != r) { - ap->setMaxWindowRect(screen, i, r); - qwsServerPrivate->sendMaxWindowRectEvents(r); - } - } -} - -/*! - \internal -*/ -void QWSServerPrivate::sendMaxWindowRectEvents(const QRect &rect) -{ - QMap<int,QWSClient*>::const_iterator it = clientMap.constBegin(); - for (; it != clientMap.constEnd(); ++it) - (*it)->sendMaxWindowRectEvent(rect); -} - -/*! - \fn void QWSServer::setDefaultMouse(const char *mouseDriver) - - Sets the mouse driver that will be used if the QWS_MOUSE_PROTO - environment variable is not defined, to be the given \a - mouseDriver. - - Note that the default is platform-dependent. This function can - only be used in the server process. - - - \sa setMouseHandler(), {Qt for Embedded Linux Pointer Handling} -*/ -void QWSServer::setDefaultMouse(const char *m) -{ - *defaultMouse() = QString::fromAscii(m); -} - -/*! - \fn void QWSServer::setDefaultKeyboard(const char *keyboardDriver) - - Sets the keyboard driver that will be used if the QWS_KEYBOARD - environment variable is not defined, to be the given \a - keyboardDriver. - - Note that the default is platform-dependent. This function can - only be used in the server process. - - \sa setKeyboardHandler(), {Qt for Embedded Linux Character Input} -*/ -void QWSServer::setDefaultKeyboard(const char *k) -{ - *defaultKeyboard() = QString::fromAscii(k); -} - -#ifndef QT_NO_QWS_CURSOR -static bool prevWin; -#endif - - -extern int *qt_last_x,*qt_last_y; - - -/*! - \internal - - Send a mouse event. \a pos is the screen position where the mouse - event occurred and \a state is a mask indicating which buttons are - pressed. - - \a pos is in device coordinates -*/ -void QWSServer::sendMouseEvent(const QPoint& pos, int state, int wheel) -{ - bool block = qwsServerPrivate->screensaverblockevent(MOUSE, qwsServerPrivate->screensaverinterval, state); -#ifdef EVENT_BLOCK_DEBUG - qDebug() << "sendMouseEvent" << pos.x() << pos.y() << state << (block ? "block" : "pass"); -#endif - - if (state || wheel) - qwsServerPrivate->_q_screenSaverWake(); - - if ( block ) - return; - - QPoint tpos; - // transformations - if (qt_screen->isTransformed()) { - QSize s = QSize(qt_screen->deviceWidth(), qt_screen->deviceHeight()); - tpos = qt_screen->mapFromDevice(pos, s); - } else { - tpos = pos; - } - - if (qt_last_x) { - *qt_last_x = tpos.x(); - *qt_last_y = tpos.y(); - } - QWSServer::mousePosition = tpos; - qwsServerPrivate->mouseState = state; - -#ifndef QT_NO_QWS_INPUTMETHODS - const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton; - int stroke_count; // number of strokes to keep shown. - if (force_reject_strokeIM || !current_IM) - { - stroke_count = 0; - } else { - stroke_count = current_IM->filter(tpos, state, wheel); - } - - if (stroke_count == 0) { - if (state&btnMask) - force_reject_strokeIM = true; - QWSServerPrivate::sendMouseEventUnfiltered(tpos, state, wheel); - } - // stop force reject after stroke ends. - if (state&btnMask && force_reject_strokeIM) - force_reject_strokeIM = false; - // on end of stroke, force_rejct - // and once a stroke is rejected, do not try again till pen is lifted -#else - QWSServerPrivate::sendMouseEventUnfiltered(tpos, state, wheel); -#endif // end QT_NO_QWS_FSIM -} - -void QWSServerPrivate::sendMouseEventUnfiltered(const QPoint &pos, int state, int wheel) -{ - const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton; - QWSMouseEvent event; - - QWSWindow *win = qwsServer->windowAt(pos); - - QWSClient *serverClient = qwsServerPrivate->clientMap.value(-1); - QWSClient *winClient = win ? win->client() : 0; - - - bool imMouse = false; -#ifndef QT_NO_QWS_INPUTMETHODS - // check for input method window - if (current_IM && current_IM_winId != -1) { - QWSWindow *kbw = keyboardGrabber ? keyboardGrabber : - qwsServerPrivate->focusw; - - imMouse = kbw == win; - if ( !imMouse ) { - QWidget *target = winClient == serverClient ? - QApplication::widgetAt(pos) : 0; - imMouse = target && (target->testAttribute(Qt::WA_InputMethodTransparent)); - } - } -#endif - - //If grabbing window disappears, grab is still active until - //after mouse release. - if ( qwsServerPrivate->mouseGrabber && (!imMouse || qwsServerPrivate->inputMethodMouseGrabbed)) { - win = qwsServerPrivate->mouseGrabber; - winClient = win ? win->client() : 0; - } - event.simpleData.window = win ? win->id : 0; - -#ifndef QT_NO_QWS_CURSOR - if (qt_screencursor) - qt_screencursor->move(pos.x(),pos.y()); - - // Arrow cursor over desktop - // prevWin remembers if the last event was over a window - if (!win && prevWin) { - if (!qwsServerPrivate->mouseGrabber) - qwsServerPrivate->setCursor(QWSCursor::systemCursor(Qt::ArrowCursor)); - else - qwsServerPrivate->nextCursor = QWSCursor::systemCursor(Qt::ArrowCursor); - prevWin = false; - } - // reset prevWin - if (win && !prevWin) - prevWin = true; -#endif - - if ((state&btnMask) && !qwsServerPrivate->mouseGrabbing) { - qwsServerPrivate->mouseGrabber = win; - if (imMouse) - qwsServerPrivate->inputMethodMouseGrabbed = true; - } - if (!(state&btnMask)) - qwsServerPrivate->inputMethodMouseGrabbed = false; - - event.simpleData.x_root=pos.x(); - event.simpleData.y_root=pos.y(); - event.simpleData.state=state | qws_keyModifiers; - event.simpleData.delta = wheel; - event.simpleData.time=qwsServerPrivate->timer.elapsed(); - - static int oldstate = 0; - -#ifndef QT_NO_QWS_INPUTMETHODS - //tell the input method if we click on a different window that is not IM transparent - bool isPress = state > oldstate; - if (isPress && !imMouse && current_IM && current_IM_winId != -1) - current_IM->mouseHandler(-1, QWSServer::MouseOutside); -#endif - - if (serverClient) - serverClient->sendEvent(&event); - if (winClient && winClient != serverClient) - winClient->sendEvent(&event); - - if ( !imMouse ) { - // Make sure that if we leave a window, that window gets one last mouse - // event so that it knows the mouse has left. - QWSClient *oldClient = qwsServer->d_func()->cursorClient; - if (oldClient && oldClient != winClient && oldClient != serverClient) { - event.simpleData.state = oldstate | qws_keyModifiers; - oldClient->sendEvent(&event); - } - } - - oldstate = state; - if ( !imMouse ) - qwsServer->d_func()->cursorClient = winClient; - - if (!(state&btnMask) && !qwsServerPrivate->mouseGrabbing) - qwsServerPrivate->releaseMouse(qwsServerPrivate->mouseGrabber); -} - -/*! - Returns the primary mouse driver. - - Note that this function can only be used in the server process. - - \sa setMouseHandler(), openMouse(), closeMouse() -*/ -QWSMouseHandler *QWSServer::mouseHandler() -{ - if (qwsServerPrivate->mousehandlers.empty()) - return 0; - return qwsServerPrivate->mousehandlers.first(); -} - -/*! - \since 4.5 - - Returns list of all mouse handlers - - Note that this function can only be used in the server process. - - \sa mouseHandler(), setMouseHandler(), openMouse(), closeMouse() -*/ -const QList<QWSMouseHandler*>& QWSServer::mouseHandlers() -{ - return qwsServerPrivate->mousehandlers; -} - - -// called by QWSMouseHandler constructor, not user code. -/*! - \fn void QWSServer::setMouseHandler(QWSMouseHandler* driver) - - Sets the primary mouse driver to be the given \a driver. - - \l{Qt for Embedded Linux} provides several ready-made mouse drivers, and - custom drivers are typically added using Qt's plugin - mechanism. See the \l{Qt for Embedded Linux Pointer Handling} documentation - for details. - - Note that this function can only be used in the server process. - - \sa mouseHandler(), setDefaultMouse() -*/ -void QWSServer::setMouseHandler(QWSMouseHandler* mh) -{ - if (!mh) - return; - qwsServerPrivate->mousehandlers.removeAll(mh); - qwsServerPrivate->mousehandlers.prepend(mh); -} - -/*! - \internal - \obsolete - Caller owns data in list, and must delete contents -*/ -QList<QWSInternalWindowInfo*> * QWSServer::windowList() -{ - QList<QWSInternalWindowInfo*> * ret=new QList<QWSInternalWindowInfo*>; - for (int i=0; i < qwsServerPrivate->windows.size(); ++i) { - QWSWindow *window = qwsServerPrivate->windows.at(i); - QWSInternalWindowInfo * qwi=new QWSInternalWindowInfo(); - qwi->winid=window->winId(); - qwi->clientid=window->client()->clientId(); - ret->append(qwi); - } - return ret; -} - -#ifndef QT_NO_COP -/*! - \internal -*/ -void QWSServerPrivate::sendQCopEvent(QWSClient *c, const QString &ch, - const QString &msg, const QByteArray &data, - bool response) -{ - Q_ASSERT(c); - - QWSQCopMessageEvent event; - event.channel = ch.toLatin1(); - event.message = msg.toLatin1(); - event.data = data; - event.simpleData.is_response = response; - event.simpleData.lchannel = ch.length(); - event.simpleData.lmessage = msg.length(); - event.simpleData.ldata = data.size(); - int l = event.simpleData.lchannel + event.simpleData.lmessage + - event.simpleData.ldata; - - // combine channel, message and data into one block of raw bytes - char *tmp = new char [l]; - char *d = tmp; - memcpy(d, event.channel.constData(), event.simpleData.lchannel); - d += event.simpleData.lchannel; - memcpy(d, event.message.constData(), event.simpleData.lmessage); - d += event.simpleData.lmessage; - memcpy(d, data.constData(), event.simpleData.ldata); - - event.setDataDirect(tmp, l); - - c->sendEvent(&event); -} -#endif - -/*! - \fn QWSWindow *QWSServer::windowAt(const QPoint& position) - - Returns the window containing the given \a position. - - Note that if there is no window under the specified point this - function returns 0. - - \sa clientWindows(), instance() -*/ -QWSWindow *QWSServer::windowAt(const QPoint& pos) -{ - Q_D(QWSServer); - for (int i=0; i<d->windows.size(); ++i) { - QWSWindow* w = d->windows.at(i); - if (w->allocatedRegion().contains(pos)) - return w; - } - return 0; -} - -#ifndef QT_NO_QWS_KEYBOARD -static int keyUnicode(int keycode) -{ - int code = 0xffff; - - if (keycode >= Qt::Key_A && keycode <= Qt::Key_Z) - code = keycode - Qt::Key_A + 'a'; - else if (keycode >= Qt::Key_0 && keycode <= Qt::Key_9) - code = keycode - Qt::Key_0 + '0'; - - return code; -} -#endif - -/*! - Sends the given key event. The key is identified by its \a unicode - value and the given \a keycode, \a modifiers, \a isPress and \a - autoRepeat parameters. - - Use this function to send key events generated by "virtual - keyboards" (note that the processKeyEvent() function is - impelemented using this function). - - The \a keycode parameter is the Qt keycode value as defined by the - Qt::Key enum. The \a modifiers is an OR combination of - Qt::KeyboardModifier values, indicating whether \gui - Shift/Alt/Ctrl keys are pressed. The \a isPress parameter is true - if the event is a key press event and \a autoRepeat is true if the - event is caused by an auto-repeat mechanism and not an actual key - press. - - Note that this function can only be used in the server process. - - \sa processKeyEvent(), {Qt for Embedded Linux Character Input} -*/ -void QWSServer::sendKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers, - bool isPress, bool autoRepeat) -{ - qws_keyModifiers = modifiers; - - if (isPress) { - if (keycode != Qt::Key_F34 && keycode != Qt::Key_F35) - qwsServerPrivate->_q_screenSaverWake(); - } - -#ifndef QT_NO_QWS_INPUTMETHODS - - if (!current_IM || !current_IM->filter(unicode, keycode, modifiers, isPress, autoRepeat)) - QWSServerPrivate::sendKeyEventUnfiltered(unicode, keycode, modifiers, isPress, autoRepeat); -#else - QWSServerPrivate::sendKeyEventUnfiltered(unicode, keycode, modifiers, isPress, autoRepeat); -#endif -} - -void QWSServerPrivate::sendKeyEventUnfiltered(int unicode, int keycode, Qt::KeyboardModifiers modifiers, - bool isPress, bool autoRepeat) -{ - - QWSKeyEvent event; - QWSWindow *win = keyboardGrabber ? keyboardGrabber : - qwsServerPrivate->focusw; - - event.simpleData.window = win ? win->winId() : 0; - - event.simpleData.unicode = -#ifndef QT_NO_QWS_KEYBOARD - unicode < 0 ? keyUnicode(keycode) : -#endif - unicode; - event.simpleData.keycode = keycode; - event.simpleData.modifiers = modifiers; - event.simpleData.is_press = isPress; - event.simpleData.is_auto_repeat = autoRepeat; - - QWSClient *serverClient = qwsServerPrivate->clientMap.value(-1); - QWSClient *winClient = win ? win->client() : 0; - if (serverClient) - serverClient->sendEvent(&event); - if (winClient && winClient != serverClient) - winClient->sendEvent(&event); -} - -/*! - \internal -*/ -void QWSServer::beginDisplayReconfigure() -{ - qwsServer->enablePainting(false); -#ifndef QT_NO_QWS_CURSOR - if (qt_screencursor) - qt_screencursor->hide(); -#endif - QWSDisplay::grab(true); - qt_screen->disconnect(); -} - -/*! - \internal -*/ -void QWSServer::endDisplayReconfigure() -{ - qt_screen->connect(QString()); - qwsServerPrivate->swidth = qt_screen->deviceWidth(); - qwsServerPrivate->sheight = qt_screen->deviceHeight(); - - QWSDisplay::ungrab(); -#ifndef QT_NO_QWS_CURSOR - if (qt_screencursor) - qt_screencursor->show(); -#endif - QApplicationPrivate *ap = QApplicationPrivate::instance(); - ap->setMaxWindowRect(qt_screen, 0, - QRect(0, 0, qt_screen->width(), qt_screen->height())); - QSize olds = qApp->desktop()->size(); - qApp->desktop()->resize(qt_screen->width(), qt_screen->height()); - qApp->postEvent(qApp->desktop(), new QResizeEvent(qApp->desktop()->size(), olds)); - qwsServer->enablePainting(true); - qwsServer->refresh(); - qDebug("Desktop size: %dx%d", qApp->desktop()->width(), qApp->desktop()->height()); -} - -void QWSServerPrivate::resetEngine() -{ -#ifndef QT_NO_QWS_CURSOR - if (!qt_screencursor) - return; - qt_screencursor->hide(); - qt_screencursor->show(); -#endif -} - - -#ifndef QT_NO_QWS_CURSOR -/*! - \fn void QWSServer::setCursorVisible(bool visible) - - Shows the cursor if \a visible is true: otherwise the cursor is - hidden. - - Note that this function can only be used in the server process. - - \sa isCursorVisible() -*/ -void QWSServer::setCursorVisible(bool vis) -{ - if (qwsServerPrivate && qwsServerPrivate->haveviscurs != vis) { - QWSCursor* c = qwsServerPrivate->cursor; - qwsServerPrivate->setCursor(QWSCursor::systemCursor(Qt::BlankCursor)); - qwsServerPrivate->haveviscurs = vis; - qwsServerPrivate->setCursor(c); - } -} - -/*! - Returns true if the cursor is visible; otherwise returns false. - - Note that this function can only be used in the server process. - - \sa setCursorVisible() -*/ -bool QWSServer::isCursorVisible() -{ - return qwsServerPrivate ? qwsServerPrivate->haveviscurs : true; -} -#endif - -#ifndef QT_NO_QWS_INPUTMETHODS - - -/*! - \fn void QWSServer::sendIMEvent(const QInputMethodEvent *event) - - Sends the given input method \a event. - - The \c QInputMethodEvent class is derived from QWSEvent, i.e., it - is a QWSEvent object of the QWSEvent::IMEvent type. - - If there is a window actively composing the preedit string, the - event is sent to that window. Otherwise, the event is sent to the - window currently in focus. - - \sa sendIMQuery(), QWSInputMethod::sendEvent() -*/ -void QWSServer::sendIMEvent(const QInputMethodEvent *ime) -{ - QWSIMEvent event; - - QWSWindow *win = keyboardGrabber ? keyboardGrabber : - qwsServerPrivate->focusw; - - //if currently composing then event must go to the composing window - - if (current_IM_composing_win) - win = current_IM_composing_win; - - event.simpleData.window = win ? win->winId() : 0; - event.simpleData.replaceFrom = ime->replacementStart();; - event.simpleData.replaceLength = ime->replacementLength(); - - QBuffer buffer; - buffer.open(QIODevice::WriteOnly); - QDataStream out(&buffer); - - out << ime->preeditString(); - out << ime->commitString(); - - const QList<QInputMethodEvent::Attribute> &attributes = ime->attributes(); - for (int i = 0; i < attributes.count(); ++i) { - const QInputMethodEvent::Attribute &a = attributes.at(i); - out << a.type << a.start << a.length << a.value; - } - event.setData(buffer.data(), buffer.size()); - QWSClient *serverClient = qwsServerPrivate->clientMap.value(-1); - if (serverClient) - serverClient->sendEvent(&event); - if (win && win->client() && win->client() != serverClient) - win->client()->sendEvent(&event); - - current_IM_composing_win = ime->preeditString().isEmpty() ? 0 : win; - current_IM_winId = win ? win->winId() : 0; -} - - -/*! - Sends an input method query for the given \a property. - - To receive responses to input method queries, the virtual - QWSInputMethod::queryResponse() function must be reimplemented in - a QWSInputMethod subclass that is activated using the - setCurrentInputMethod() function. - - \sa sendIMEvent(), setCurrentInputMethod() -*/ -void QWSServer::sendIMQuery(int property) -{ - QWSIMQueryEvent event; - - QWSWindow *win = keyboardGrabber ? keyboardGrabber : - qwsServerPrivate->focusw; - if (current_IM_composing_win) - win = current_IM_composing_win; - - event.simpleData.window = win ? win->winId() : 0; - event.simpleData.property = property; - if (win && win->client()) - win->client()->sendEvent(&event); -} - - - -/*! - \fn void QWSServer::setCurrentInputMethod(QWSInputMethod *method) - - Sets the current input method to be the given \a method. - - Note that this function can only be used in the server process. - - \sa sendIMQuery(), sendIMEvent() -*/ -void QWSServer::setCurrentInputMethod(QWSInputMethod *im) -{ - if (current_IM) - current_IM->reset(); //??? send an update event instead ? - current_IM = im; -} - -/*! - \fn static void QWSServer::resetInputMethod() - - \internal -*/ - -#endif //QT_NO_QWS_INPUTMETHODS - -#ifndef QT_NO_QWS_PROPERTIES -/*! - \internal -*/ -void QWSServer::sendPropertyNotifyEvent(int property, int state) -{ - Q_D(QWSServer); - QWSServerPrivate::ClientIterator it = d->clientMap.begin(); - while (it != d->clientMap.end()) { - QWSClient *cl = *it; - ++it; - cl->sendPropertyNotifyEvent(property, state); - } -} -#endif - -void QWSServerPrivate::invokeIdentify(const QWSIdentifyCommand *cmd, QWSClient *client) -{ - client->setIdentity(cmd->id); -#ifndef QT_NO_QWS_MULTIPROCESS - if (client->clientId() > 0) - client->d_func()->setLockId(cmd->simpleData.idLock); -#endif -} - -void QWSServerPrivate::invokeCreate(QWSCreateCommand *cmd, QWSClient *client) -{ - QWSCreationEvent event; - event.simpleData.objectid = get_object_id(cmd->count); - event.simpleData.count = cmd->count; - client->sendEvent(&event); -} - -void QWSServerPrivate::invokeRegionName(const QWSRegionNameCommand *cmd, QWSClient *client) -{ - Q_Q(QWSServer); - QWSWindow* changingw = findWindow(cmd->simpleData.windowid, client); - if (changingw && (changingw->name() != cmd->name || changingw->caption() !=cmd->caption)) { - changingw->setName(cmd->name); - changingw->setCaption(cmd->caption); - emit q->windowEvent(changingw, QWSServer::Name); - } -} - -void QWSServerPrivate::invokeRegion(QWSRegionCommand *cmd, QWSClient *client) -{ -#ifdef QWS_REGION_DEBUG - qDebug("QWSServer::invokeRegion %d rects (%d)", - cmd->simpleData.nrectangles, cmd->simpleData.windowid); -#endif - - QWSWindow* changingw = findWindow(cmd->simpleData.windowid, 0); - if (!changingw) { - qWarning("Invalid window handle %08x",cmd->simpleData.windowid); - return; - } - if (!changingw->forClient(client)) { - qWarning("Disabled: clients changing other client's window region"); - return; - } - - request_region(cmd->simpleData.windowid, cmd->surfaceKey, cmd->surfaceData, - cmd->region); -} - -void QWSServerPrivate::invokeRegionMove(const QWSRegionMoveCommand *cmd, QWSClient *client) -{ - Q_Q(QWSServer); - QWSWindow* changingw = findWindow(cmd->simpleData.windowid, 0); - if (!changingw) { - qWarning("invokeRegionMove: Invalid window handle %d",cmd->simpleData.windowid); - return; - } - if (!changingw->forClient(client)) { - qWarning("Disabled: clients changing other client's window region"); - return; - } - -// changingw->setNeedAck(true); - moveWindowRegion(changingw, cmd->simpleData.dx, cmd->simpleData.dy); - emit q->windowEvent(changingw, QWSServer::Geometry); -} - -void QWSServerPrivate::invokeRegionDestroy(const QWSRegionDestroyCommand *cmd, QWSClient *client) -{ - Q_Q(QWSServer); - QWSWindow* changingw = findWindow(cmd->simpleData.windowid, 0); - if (!changingw) { - qWarning("invokeRegionDestroy: Invalid window handle %d",cmd->simpleData.windowid); - return; - } - if (!changingw->forClient(client)) { - qWarning("Disabled: clients changing other client's window region"); - return; - } - - setWindowRegion(changingw, QRegion()); -// rgnMan->remove(changingw->allocationIndex()); - for (int i = 0; i < windows.size(); ++i) { - if (windows.at(i) == changingw) { - windows.takeAt(i); - if (i < nReserved) - --nReserved; - break; - } - } - - handleWindowClose(changingw); -#ifndef QT_NO_QWS_PROPERTIES - propertyManager.removeProperties(changingw->winId()); -#endif - emit q->windowEvent(changingw, QWSServer::Destroy); - delete changingw; -} - -void QWSServerPrivate::invokeSetFocus(const QWSRequestFocusCommand *cmd, QWSClient *client) -{ - int winId = cmd->simpleData.windowid; - int gain = cmd->simpleData.flag; - - if (gain != 0 && gain != 1) { - qWarning("Only 0(lose) and 1(gain) supported"); - return; - } - - QWSWindow* changingw = findWindow(winId, 0); - if (!changingw) - return; - - if (!changingw->forClient(client)) { - qWarning("Disabled: clients changing other client's focus"); - return; - } - - setFocus(changingw, gain); -} - -void QWSServerPrivate::setFocus(QWSWindow* changingw, bool gain) -{ - Q_Q(QWSServer); -#ifndef QT_NO_QWS_INPUTMETHODS - /* - This is the logic: - QWSWindow *loser = 0; - if (gain && focusw != changingw) - loser = focusw; - else if (!gain && focusw == changingw) - loser = focusw; - But these five lines can be reduced to one: - */ - if (current_IM) { - QWSWindow *loser = (!gain == (focusw==changingw)) ? focusw : 0; - if (loser && loser->winId() == current_IM_winId) - current_IM->updateHandler(QWSInputMethod::FocusOut); - } -#endif - if (gain) { - if (focusw != changingw) { - if (focusw) focusw->focus(0); - focusw = changingw; - focusw->focus(1); - emit q->windowEvent(focusw, QWSServer::Active); - } - } else if (focusw == changingw) { - if (changingw->client()) - changingw->focus(0); - focusw = 0; - // pass focus to window which most recently got it... - QWSWindow* bestw=0; - for (int i=0; i<windows.size(); ++i) { - QWSWindow* w = windows.at(i); - if (w != changingw && !w->hidden() && - (!bestw || bestw->focusPriority() < w->focusPriority())) - bestw = w; - } - if (!bestw && changingw->focusPriority()) { // accept focus back? - bestw = changingw; // must be the only one - } - focusw = bestw; - if (focusw) { - focusw->focus(1); - emit q->windowEvent(focusw, QWSServer::Active); - } - } -} - - - -void QWSServerPrivate::invokeSetOpacity(const QWSSetOpacityCommand *cmd, QWSClient *client) -{ - Q_UNUSED( client ); - int winId = cmd->simpleData.windowid; - int opacity = cmd->simpleData.opacity; - - QWSWindow* changingw = findWindow(winId, 0); - - if (!changingw) { - qWarning("invokeSetOpacity: Invalid window handle %d", winId); - return; - } - - int altitude = windows.indexOf(changingw); - const bool wasOpaque = changingw->isOpaque(); - changingw->_opacity = opacity; - if (wasOpaque != changingw->isOpaque()) - update_regions(); - exposeRegion(changingw->allocatedRegion(), altitude); -} - -void QWSServerPrivate::invokeSetAltitude(const QWSChangeAltitudeCommand *cmd, - QWSClient *client) -{ - Q_UNUSED(client); - - int winId = cmd->simpleData.windowid; - int alt = cmd->simpleData.altitude; - bool fixed = cmd->simpleData.fixed; -#if 0 - qDebug("QWSServer::invokeSetAltitude winId %d alt %d)", winId, alt); -#endif - - if (alt < -1 || alt > 1) { - qWarning("QWSServer::invokeSetAltitude Only lower, raise and stays-on-top supported"); - return; - } - - QWSWindow* changingw = findWindow(winId, 0); - if (!changingw) { - qWarning("invokeSetAltitude: Invalid window handle %d", winId); - return; - } - - if (fixed && alt >= 1) { - changingw->onTop = true; - } - if (alt == QWSChangeAltitudeCommand::Lower) - changingw->lower(); - else - changingw->raise(); - -// if (!changingw->forClient(client)) { -// refresh(); -// } -} - -#ifndef QT_NO_QWS_PROPERTIES -void QWSServerPrivate::invokeAddProperty(QWSAddPropertyCommand *cmd) -{ - propertyManager.addProperty(cmd->simpleData.windowid, cmd->simpleData.property); -} - -void QWSServerPrivate::invokeSetProperty(QWSSetPropertyCommand *cmd) -{ - Q_Q(QWSServer); - if (propertyManager.setProperty(cmd->simpleData.windowid, - cmd->simpleData.property, - cmd->simpleData.mode, - cmd->data, - cmd->rawLen)) { - q->sendPropertyNotifyEvent(cmd->simpleData.property, - QWSPropertyNotifyEvent::PropertyNewValue); -#ifndef QT_NO_QWS_INPUTMETHODS - if (cmd->simpleData.property == QT_QWS_PROPERTY_MARKEDTEXT) { - QString s((const QChar*)cmd->data, cmd->rawLen/2); - emit q->markedText(s); - } -#endif - } -} - -void QWSServerPrivate::invokeRemoveProperty(QWSRemovePropertyCommand *cmd) -{ - Q_Q(QWSServer); - if (propertyManager.removeProperty(cmd->simpleData.windowid, - cmd->simpleData.property)) { - q->sendPropertyNotifyEvent(cmd->simpleData.property, - QWSPropertyNotifyEvent::PropertyDeleted); - } -} - - -bool QWSServerPrivate:: get_property(int winId, int property, const char *&data, int &len) -{ - return propertyManager.getProperty(winId, property, data, len); -} - - -void QWSServerPrivate::invokeGetProperty(QWSGetPropertyCommand *cmd, QWSClient *client) -{ - const char *data; - int len; - - if (propertyManager.getProperty(cmd->simpleData.windowid, - cmd->simpleData.property, - data, len)) { - client->sendPropertyReplyEvent(cmd->simpleData.property, len, data); - } else { - client->sendPropertyReplyEvent(cmd->simpleData.property, -1, 0); - } -} -#endif //QT_NO_QWS_PROPERTIES - -void QWSServerPrivate::invokeSetSelectionOwner(QWSSetSelectionOwnerCommand *cmd) -{ - qDebug("QWSServer::invokeSetSelectionOwner"); - - SelectionOwner so; - so.windowid = cmd->simpleData.windowid; - so.time.set(cmd->simpleData.hour, cmd->simpleData.minute, - cmd->simpleData.sec, cmd->simpleData.ms); - - if (selectionOwner.windowid != -1) { - QWSWindow *win = findWindow(selectionOwner.windowid, 0); - if (win) - win->client()->sendSelectionClearEvent(selectionOwner.windowid); - else - qDebug("couldn't find window %d", selectionOwner.windowid); - } - - selectionOwner = so; -} - -void QWSServerPrivate::invokeConvertSelection(QWSConvertSelectionCommand *cmd) -{ - qDebug("QWSServer::invokeConvertSelection"); - - if (selectionOwner.windowid != -1) { - QWSWindow *win = findWindow(selectionOwner.windowid, 0); - if (win) - win->client()->sendSelectionRequestEvent(cmd, selectionOwner.windowid); - else - qDebug("couldn't find window %d", selectionOwner.windowid); - } -} - -#ifndef QT_NO_QWS_CURSOR -void QWSServerPrivate::invokeDefineCursor(QWSDefineCursorCommand *cmd, QWSClient *client) -{ - if (cmd->simpleData.height > 64 || cmd->simpleData.width > 64) { - qDebug("Cannot define cursor size > 64x64"); - return; - } - - delete client->cursors.take(cmd->simpleData.id); - - int dataLen = cmd->simpleData.height * ((cmd->simpleData.width+7) / 8); - - if (dataLen > 0 && cmd->data) { - QWSCursor *curs = new QWSCursor(cmd->data, cmd->data + dataLen, - cmd->simpleData.width, cmd->simpleData.height, - cmd->simpleData.hotX, cmd->simpleData.hotY); - client->cursors.insert(cmd->simpleData.id, curs); - } -} - -void QWSServerPrivate::invokeSelectCursor(QWSSelectCursorCommand *cmd, QWSClient *client) -{ - int id = cmd->simpleData.id; - QWSCursor *curs = 0; - if (id <= Qt::LastCursor) { - curs = QWSCursor::systemCursor(id); - } - else { - QWSCursorMap cursMap = client->cursors; - QWSCursorMap::Iterator it = cursMap.find(id); - if (it != cursMap.end()) { - curs = it.value(); - } - } - if (curs == 0) { - curs = QWSCursor::systemCursor(Qt::ArrowCursor); - } - - QWSWindow* win = findWindow(cmd->simpleData.windowid, 0); - if (mouseGrabber) { - // If the mouse is being grabbed, we don't want just anyone to - // be able to change the cursor. We do want the cursor to be set - // correctly once mouse grabbing is stopped though. - if (win != mouseGrabber) - nextCursor = curs; - else - setCursor(curs); - } else if (win && win->allocatedRegion().contains(QWSServer::mousePosition)) { //##################### cursor - // A non-grabbing window can only set the cursor shape if the - // cursor is within its allocated region. - setCursor(curs); - } -} - -void QWSServerPrivate::invokePositionCursor(QWSPositionCursorCommand *cmd, QWSClient *) -{ - Q_Q(QWSServer); - QPoint newPos(cmd->simpleData.newX, cmd->simpleData.newY); - if (newPos != QWSServer::mousePosition) - q->sendMouseEvent(newPos, qwsServer->d_func()->mouseState); -} -#endif - -void QWSServerPrivate::invokeGrabMouse(QWSGrabMouseCommand *cmd, QWSClient *client) -{ - QWSWindow* win = findWindow(cmd->simpleData.windowid, 0); - if (!win) - return; - - if (cmd->simpleData.grab) { - if (!mouseGrabber || mouseGrabber->client() == client) { - mouseGrabbing = true; - mouseGrabber = win; - } - } else { - releaseMouse(mouseGrabber); - } -} - -void QWSServerPrivate::invokeGrabKeyboard(QWSGrabKeyboardCommand *cmd, QWSClient *client) -{ - QWSWindow* win = findWindow(cmd->simpleData.windowid, 0); - if (!win) - return; - - if (cmd->simpleData.grab) { - if (!keyboardGrabber || (keyboardGrabber->client() == client)) { - keyboardGrabbing = true; - keyboardGrabber = win; - } - } else { - releaseKeyboard(keyboardGrabber); - } -} - -#if !defined(QT_NO_SOUND) -void QWSServerPrivate::invokePlaySound(QWSPlaySoundCommand *cmd, QWSClient *) -{ -#if !defined(QT_EXTERNAL_SOUND_SERVER) && !defined(Q_OS_DARWIN) - soundserver->playFile( 1, cmd->filename ); -#else - Q_UNUSED(cmd); -#endif -} -#endif - -#ifndef QT_NO_COP -void QWSServerPrivate::invokeRegisterChannel(QWSQCopRegisterChannelCommand *cmd, - QWSClient *client) -{ - // QCopChannel will force us to emit the newChannel signal if this channel - // didn't already exist. - QCopChannel::registerChannel(cmd->channel, client); -} - -void QWSServerPrivate::invokeQCopSend(QWSQCopSendCommand *cmd, QWSClient *client) -{ - QCopChannel::answer(client, cmd->channel, cmd->message, cmd->data); -} - -#endif - -#ifndef QT_NO_QWS_INPUTMETHODS -void QWSServer::resetInputMethod() -{ - if (current_IM && qwsServer) { - current_IM->reset(); - } -} - -void QWSServerPrivate::invokeIMResponse(const QWSIMResponseCommand *cmd, - QWSClient *) -{ - if (current_IM) - current_IM->queryResponse(cmd->simpleData.property, cmd->result); -} - -void QWSServerPrivate::invokeIMUpdate(const QWSIMUpdateCommand *cmd, - QWSClient *) -{ - if (cmd->simpleData.type == QWSInputMethod::FocusIn) - current_IM_winId = cmd->simpleData.windowid; - - if (current_IM && (current_IM_winId == cmd->simpleData.windowid || cmd->simpleData.windowid == -1)) - current_IM->updateHandler(cmd->simpleData.type); -} - -#endif - -void QWSServerPrivate::invokeFont(const QWSFontCommand *cmd, QWSClient *client) -{ - QWSClientPrivate *priv = client->d_func(); - if (cmd->simpleData.type == QWSFontCommand::StartedUsingFont) { - referenceFont(priv, cmd->fontName); - } else if (cmd->simpleData.type == QWSFontCommand::StoppedUsingFont) { - dereferenceFont(priv, cmd->fontName); - } -} - -void QWSServerPrivate::invokeRepaintRegion(QWSRepaintRegionCommand * cmd, - QWSClient *) -{ - QRegion r; - r.setRects(cmd->rectangles,cmd->simpleData.nrectangles); - repaint_region(cmd->simpleData.windowid, cmd->simpleData.windowFlags, cmd->simpleData.opaque, r); -} - -#ifndef QT_NO_QWSEMBEDWIDGET -void QWSServerPrivate::invokeEmbed(QWSEmbedCommand *cmd, QWSClient *client) -{ - // Should find these two windows in a single loop - QWSWindow *embedder = findWindow(cmd->simpleData.embedder, client); - QWSWindow *embedded = findWindow(cmd->simpleData.embedded); - - if (!embedder) { - qWarning("QWSServer: Embed command from window %i failed: No such id.", - static_cast<int>(cmd->simpleData.embedder)); - return; - } - - if (!embedded) { - qWarning("QWSServer: Embed command on window %i failed: No such id.", - static_cast<int>(cmd->simpleData.embedded)); - return; - } - - switch (cmd->simpleData.type) { - case QWSEmbedEvent::StartEmbed: - embedder->startEmbed(embedded); - windows.removeAll(embedded); - windows.insert(windows.indexOf(embedder), embedded); - break; - case QWSEmbedEvent::StopEmbed: - embedder->stopEmbed(embedded); - break; - case QWSEmbedEvent::Region: - break; - } - - embedded->client()->sendEmbedEvent(embedded->winId(), - cmd->simpleData.type, cmd->region); - const QRegion oldAllocated = embedded->allocatedRegion(); - update_regions(); - exposeRegion(oldAllocated - embedded->allocatedRegion(), - windows.indexOf(embedded)); -} -#endif // QT_NO_QWSEMBEDWIDGET - -void QWSServerPrivate::invokeScreenTransform(const QWSScreenTransformCommand *cmd, - QWSClient *client) -{ - Q_UNUSED(client); - - QWSScreenTransformationEvent event; - event.simpleData.screen = cmd->simpleData.screen; - event.simpleData.transformation = cmd->simpleData.transformation; - - QMap<int, QWSClient*>::const_iterator it = clientMap.constBegin(); - for (; it != clientMap.constEnd(); ++it) - (*it)->sendEvent(&event); -} - -QWSWindow* QWSServerPrivate::newWindow(int id, QWSClient* client) -{ - Q_Q(QWSServer); - // Make a new window, put it on top. - QWSWindow* w = new QWSWindow(id,client); - - // insert after "stays on top" windows - bool added = false; - for (int i = nReserved; i < windows.size(); ++i) { - QWSWindow *win = windows.at(i); - if (!win->onTop) { - windows.insert(i, w); - added = true; - break; - } - } - if (!added) - windows.append(w); - emit q->windowEvent(w, QWSServer::Create); - return w; -} - -QWSWindow* QWSServerPrivate::findWindow(int windowid, QWSClient* client) -{ - for (int i=0; i<windows.size(); ++i) { - QWSWindow* w = windows.at(i); - if (w->winId() == windowid) - return w; - } - if (client) - return newWindow(windowid,client); - else - return 0; -} - -void QWSServerPrivate::raiseWindow(QWSWindow *changingw, int /*alt*/) -{ - Q_Q(QWSServer); - if (changingw == windows.first()) - return; - QWSWindow::State oldstate = changingw->d->state; - changingw->d->state = QWSWindow::Raising; - // Expose regions previously overlapped by transparent windows - const QRegion bound = changingw->allocatedRegion(); - QRegion expose; - int windowPos = 0; - - //change position in list: - for (int i = 0; i < windows.size(); ++i) { - QWSWindow *w = windows.at(i); - if (w == changingw) { - windowPos = i; - windows.takeAt(i); - break; - } - if (!w->isOpaque()) - expose += (w->allocatedRegion() & bound); - } - - bool onTop = changingw->onTop; - -#ifndef QT_NO_QWSEMBEDWIDGET - // an embedded window is on top if the embedder is on top - QWSWindow *embedder = changingw->d->embedder; - while (!onTop && embedder) { - onTop = embedder->onTop; - embedder = embedder->d->embedder; - } -#endif - - int newPos = -1; - if (onTop) { - windows.insert(nReserved, changingw); - newPos = nReserved; - } else { - // insert after "stays on top" windows - bool in = false; - for (int i = nReserved; i < windows.size(); ++i) { - QWSWindow *w = windows.at(i); - if (!w->onTop) { - windows.insert(i, changingw); - in = true; - newPos = i; - break; - } - } - if (!in) { - windows.append(changingw); - newPos = windows.size()-1; - } - } - - if (windowPos != newPos) { - update_regions(); - if (!expose.isEmpty()) - exposeRegion(expose, newPos); - } - changingw->d->state = oldstate; - emit q->windowEvent(changingw, QWSServer::Raise); -} - -void QWSServerPrivate::lowerWindow(QWSWindow *changingw, int /*alt*/) -{ - Q_Q(QWSServer); - if (changingw == windows.last()) - return; - QWSWindow::State oldstate = changingw->d->state; - changingw->d->state = QWSWindow::Lowering; - - int i = windows.indexOf(changingw); - int newIdx = windows.size()-1; - windows.move(i, newIdx); - - const QRegion bound = changingw->allocatedRegion(); - - update_regions(); - - // Expose regions previously overlapped by transparent window - if (!changingw->isOpaque()) { - QRegion expose; - for (int j = i; j < windows.size() - 1; ++j) - expose += (windows.at(j)->allocatedRegion() & bound); - if (!expose.isEmpty()) - exposeRegion(expose, newIdx); - } - - changingw->d->state = oldstate; - emit q->windowEvent(changingw, QWSServer::Lower); -} - -void QWSServerPrivate::update_regions() -{ - if (disablePainting) - return; - - QRegion available = QRect(0, 0, qt_screen->width(), qt_screen->height()); - QRegion transparentRegion; - - // only really needed if there are unbuffered surfaces... - const bool doLock = (clientMap.size() > 1); - if (doLock) - QWSDisplay::grab(true); - - for (int i = 0; i < windows.count(); ++i) { - QWSWindow *w = windows.at(i); - QRegion r = (w->requested_region & available); - -#ifndef QT_NO_QWSEMBEDWIDGET - // Subtract regions needed for embedded windows - const int n = w->d->embedded.size(); - for (int i = 0; i < n; ++i) - r -= w->d->embedded.at(i)->allocatedRegion(); - - // Limited to the embedder region - if (w->d->embedder) - r &= w->d->embedder->requested_region; -#endif // QT_NO_QWSEMBEDWIDGET - - QWSWindowSurface *surface = w->windowSurface(); - const bool opaque = w->isOpaque() - && (w->d->painted || !surface || !surface->isBuffered()); - - if (!opaque) { - transparentRegion += r; - } else { - if (surface && (surface->isRegionReserved() || !surface->isBuffered())) - r -= transparentRegion; - available -= r; - } - - if (r != w->allocatedRegion()) { - w->setAllocatedRegion(r); - w->client()->sendRegionEvent(w->winId(), r, - QWSRegionEvent::Allocation); - } - -#ifdef QT_QWS_CLIENTBLIT -#ifdef QT_NO_QWS_CURSOR - // This optimization only really works when there isn't a crazy cursor - // wizzing around. - QRegion directPaint = (r - transparentRegion); // in gloal coords - if(directPaint != w->directPaintRegion()) { - w->setDirectPaintRegion(directPaint); - static int id = 0; - surface->setDirectRegion(directPaint, ++id); - w->client()->sendRegionEvent(w->winId(), directPaint, - QWSRegionEvent::DirectPaint, id); - } -#endif -#endif - } - - if (doLock) - QWSDisplay::ungrab(); -} - -void QWSServerPrivate::moveWindowRegion(QWSWindow *changingw, int dx, int dy) -{ - if (!changingw) - return; - - QWSWindow::State oldState = changingw->d->state; - changingw->d->state = QWSWindow::Moving; - const QRegion oldRegion(changingw->allocatedRegion()); - changingw->requested_region.translate(dx, dy); - - // hw: Even if the allocated region doesn't change, the requested region - // region has changed and we need to send region events. - // Resetting the allocated region to force update_regions to send events. - changingw->setAllocatedRegion(QRegion()); - update_regions(); - const QRegion newRegion(changingw->allocatedRegion()); - - QWSWindowSurface *surface = changingw->windowSurface(); - QRegion expose; - if (surface) - expose = surface->move(QPoint(dx, dy), changingw->allocatedRegion()); - else - expose = oldRegion + newRegion; - - if (!changingw->d->painted && !expose.isEmpty()) - expose = oldRegion - newRegion; - - int idx = windows.indexOf(changingw); - exposeRegion(expose, idx); - changingw->d->state = oldState; -} - -/*! - Changes the requested region of window \a changingw to \a r - If \a changingw is 0, the server's reserved region is changed. -*/ -void QWSServerPrivate::setWindowRegion(QWSWindow* changingw, const QRegion &r) -{ - if (!changingw) { - qWarning("Not implemented in this release"); - return; - } - - if (changingw->requested_region == r) - return; - - const QRegion oldRegion(changingw->allocatedRegion()); - changingw->requested_region = r; - update_regions(); - const QRegion newRegion(changingw->allocatedRegion()); - - int idx = windows.indexOf(changingw); - exposeRegion(oldRegion - newRegion, idx); -} - - -void QWSServerPrivate::exposeRegion(const QRegion &r, int changing) -{ - if (disablePainting) - return; - - if (r.isEmpty()) - return; - - static bool initial = true; - if (initial) { - changing = 0; - initial = false; - qt_screen->exposeRegion(qt_screen->region(), changing); - } else { - qt_screen->exposeRegion(r, changing); - } -} - -/*! - Closes all pointer devices (specified by the QWS_MOUSE_PROTO - environment variable) by deleting the associated mouse drivers. - - \sa openMouse(), mouseHandler() -*/ -void QWSServer::closeMouse() -{ - Q_D(QWSServer); - qDeleteAll(d->mousehandlers); - d->mousehandlers.clear(); -} - -/*! - Opens the mouse devices specified by the QWS_MOUSE_PROTO - environment variable. Be advised that closeMouse() is called first - to delete all the existing mouse handlers. This behaviour could be - the cause of problems if you were not expecting it. - - \sa closeMouse(), mouseHandler() -*/ -void QWSServer::openMouse() -{ - Q_D(QWSServer); - QString mice = QString::fromLatin1(qgetenv("QWS_MOUSE_PROTO")); -#if defined(QT_QWS_CASSIOPEIA) - if (mice.isEmpty()) - mice = QLatin1String("TPanel:/dev/tpanel"); -#endif - if (mice.isEmpty()) - mice = *defaultMouse(); - closeMouse(); - bool needviscurs = true; - if (mice != QLatin1String("None")) { - const QStringList mouse = mice.split(QLatin1Char(' ')); - for (int i = mouse.size() - 1; i >= 0; --i) { - QWSMouseHandler *handler = d->newMouseHandler(mouse.at(i)); - setMouseHandler(handler); - /* XXX handle mouse cursor visibility sensibly - if (!h->inherits("QCalibratedMouseHandler")) - needviscurs = true; - */ - } - } -#ifndef QT_NO_QWS_CURSOR - setCursorVisible(needviscurs); -#else - Q_UNUSED(needviscurs) -#endif -} - -/*! - Suspends pointer handling by deactivating all the mouse drivers - registered by the QWS_MOUSE_PROTO environment variable. - - - \sa resumeMouse(), QWSMouseHandler::suspend() -*/ -void QWSServer::suspendMouse() -{ - Q_D(QWSServer); - for (int i=0; i < d->mousehandlers.size(); ++i) - d->mousehandlers.at(i)->suspend(); -} - -/*! - Resumes pointer handling by reactivating all the mouse drivers - registered by the QWS_MOUSE_PROTO environment variable. - - \sa suspendMouse(), QWSMouseHandler::resume() -*/ -void QWSServer::resumeMouse() -{ - Q_D(QWSServer); - for (int i=0; i < d->mousehandlers.size(); ++i) - d->mousehandlers.at(i)->resume(); -} - - - -QWSMouseHandler* QWSServerPrivate::newMouseHandler(const QString& spec) -{ - int c = spec.indexOf(QLatin1Char(':')); - QString mouseProto; - QString mouseDev; - if (c >= 0) { - mouseProto = spec.left(c); - mouseDev = spec.mid(c+1); - } else { - mouseProto = spec; - } - - int screen = -1; - const QList<QRegExp> regexps = QList<QRegExp>() - << QRegExp(QLatin1String(":screen=(\\d+)\\b")) - << QRegExp(QLatin1String("\\bscreen=(\\d+):")); - for (int i = 0; i < regexps.size(); ++i) { - QRegExp regexp = regexps.at(i); - if (regexp.indexIn(mouseDev) == -1) - continue; - screen = regexp.cap(1).toInt(); - mouseDev.remove(regexp.pos(0), regexp.matchedLength()); - break; - } - - QWSMouseHandler *handler = 0; - handler = QMouseDriverFactory::create(mouseProto, mouseDev); - if (screen != -1) - handler->setScreen(qt_screen->subScreens().at(screen)); - - return handler; -} - -#ifndef QT_NO_QWS_KEYBOARD - -/*! - Closes all the keyboard devices (specified by the QWS_KEYBOARD - environment variable) by deleting the associated keyboard - drivers. - - \sa openKeyboard(), keyboardHandler() -*/ -void QWSServer::closeKeyboard() -{ - Q_D(QWSServer); - qDeleteAll(d->keyboardhandlers); - d->keyboardhandlers.clear(); -} - -/*! - Returns the primary keyboard driver. - - Note that this function can only be used in the server process. - - \sa setKeyboardHandler(), openKeyboard(), closeKeyboard() -*/ -QWSKeyboardHandler* QWSServer::keyboardHandler() -{ - return qwsServerPrivate->keyboardhandlers.first(); -} - -/*! - \fn void QWSServer::setKeyboardHandler(QWSKeyboardHandler* driver) - - Sets the primary keyboard driver to be the given \a driver. - - \l{Qt for Embedded Linux} provides several ready-made keyboard drivers, and - custom drivers are typically added using Qt's plugin - mechanism. See the \l{Qt for Embedded Linux Character Input} documentation - for details. - - Note that this function can only be used in the server process. - - \sa keyboardHandler(), setDefaultKeyboard() -*/ -void QWSServer::setKeyboardHandler(QWSKeyboardHandler* kh) -{ - if (!kh) - return; - qwsServerPrivate->keyboardhandlers.removeAll(kh); - qwsServerPrivate->keyboardhandlers.prepend(kh); -} - -/*! - Opens the keyboard devices specified by the QWS_KEYBOARD - environment variable. - - \sa closeKeyboard(), keyboardHandler() -*/ -void QWSServer::openKeyboard() -{ - QString keyboards = QString::fromLatin1(qgetenv("QWS_KEYBOARD")); -#if defined(QT_QWS_CASSIOPEIA) - if (keyboards.isEmpty()) - keyboards = QLatin1String("Buttons"); -#endif - if (keyboards.isEmpty()) - keyboards = *defaultKeyboard(); - - closeKeyboard(); - if (keyboards == QLatin1String("None")) - return; - - QString device; - QString type; - QStringList keyboard = keyboards.split(QLatin1Char(' ')); - for (int i = keyboard.size() - 1; i >= 0; --i) { - const QString spec = keyboard.at(i); - int colon=spec.indexOf(QLatin1Char(':')); - if (colon>=0) { - type = spec.left(colon); - device = spec.mid(colon+1); - } else { - type = spec; - device = QString(); - } - QWSKeyboardHandler *handler = QKbdDriverFactory::create(type, device); - setKeyboardHandler(handler); - } -} - -#endif //QT_NO_QWS_KEYBOARD - -QPoint QWSServer::mousePosition; -QBrush *QWSServerPrivate::bgBrush = 0; - -void QWSServerPrivate::move_region(const QWSRegionMoveCommand *cmd) -{ - QWSClient *serverClient = clientMap.value(-1); - invokeRegionMove(cmd, serverClient); -} - -void QWSServerPrivate::set_altitude(const QWSChangeAltitudeCommand *cmd) -{ - QWSClient *serverClient = clientMap.value(-1); - invokeSetAltitude(cmd, serverClient); -} - -void QWSServerPrivate::set_opacity(const QWSSetOpacityCommand *cmd) -{ - QWSClient *serverClient = clientMap.value(-1); - invokeSetOpacity(cmd, serverClient); -} - - -void QWSServerPrivate::request_focus(const QWSRequestFocusCommand *cmd) -{ - invokeSetFocus(cmd, clientMap.value(-1)); -} - -void QWSServerPrivate::set_identity(const QWSIdentifyCommand *cmd) -{ - invokeIdentify(cmd, clientMap.value(-1)); -} - -void QWSServerPrivate::repaint_region(int wid, int windowFlags, bool opaque, - const QRegion ®ion) -{ - QWSWindow* changingw = findWindow(wid, 0); - if (!changingw) { - return; - } - - const bool isOpaque = changingw->opaque; - const bool wasPainted = changingw->d->painted; - changingw->opaque = opaque; - changingw->d->windowFlags = QFlag(windowFlags); - changingw->d->dirtyOnScreen |= region; - changingw->d->painted = true; - if (isOpaque != opaque || !wasPainted) - update_regions(); - - int level = windows.indexOf(changingw); - exposeRegion(region, level); - changingw->d->dirtyOnScreen = QRegion(); -} - -QRegion QWSServerPrivate::reserve_region(QWSWindow *win, const QRegion ®ion) -{ - QRegion r = region; - - int oldPos = windows.indexOf(win); - int newPos = oldPos < nReserved ? nReserved - 1 : nReserved; - for (int i = 0; i < nReserved; ++i) { - if (i != oldPos) { - QWSWindow *w = windows.at(i); - r -= w->requested_region; - } - } - windows.move(oldPos, newPos); - nReserved = newPos + 1; - - return r; -} - -void QWSServerPrivate::request_region(int wid, const QString &surfaceKey, - const QByteArray &surfaceData, - const QRegion ®ion) -{ - QWSWindow *changingw = findWindow(wid, 0); - if (!changingw) - return; - - Q_Q(QWSServer); - QWSWindow::State windowState = QWSWindow::NoState; - - if (region.isEmpty()) { - windowState = QWSWindow::Hiding; - emit q->windowEvent(changingw, QWSServer::Hide); - } - - const bool wasOpaque = changingw->opaque; - - changingw->createSurface(surfaceKey, surfaceData); - QWSWindowSurface *surface = changingw->windowSurface(); - - changingw->opaque = surface->isOpaque(); - - QRegion r; - if (surface->isRegionReserved()) - r = reserve_region(changingw, region); - else - r = region; - - if (!region.isEmpty()) { - if (changingw->isVisible()) - windowState = QWSWindow::ChangingGeometry; - else - windowState = QWSWindow::Showing; - } - changingw->d->state = windowState; - - if (!r.isEmpty() && wasOpaque != changingw->opaque && surface->isBuffered()) - changingw->requested_region = QRegion(); // XXX: force update_regions - - const QRegion oldAllocated = changingw->allocatedRegion(); - setWindowRegion(changingw, r); - if (oldAllocated == changingw->allocatedRegion()) { - // Always send region event to the requesting window even if the - // region didn't change. This is necessary as the client will reset - // the clip region until an event is received. - changingw->client()->sendRegionEvent(wid, changingw->allocatedRegion(), - QWSRegionEvent::Allocation); - } - - surface->QWindowSurface::setGeometry(r.boundingRect()); - - if (windowState == QWSWindow::Showing) - emit q->windowEvent(changingw, QWSServer::Show); - else if (windowState == QWSWindow::ChangingGeometry) - emit q->windowEvent(changingw, QWSServer::Geometry); - if (windowState == QWSWindow::Hiding) { - handleWindowClose(changingw); - changingw->d->state = QWSWindow::Hidden; - changingw->d->painted = false; - } else { - changingw->d->state = QWSWindow::Visible; - } -} - -void QWSServerPrivate::destroy_region(const QWSRegionDestroyCommand *cmd) -{ - invokeRegionDestroy(cmd, clientMap.value(-1)); -} - -void QWSServerPrivate::name_region(const QWSRegionNameCommand *cmd) -{ - invokeRegionName(cmd, clientMap.value(-1)); -} - -#ifndef QT_NO_QWS_INPUTMETHODS -void QWSServerPrivate::im_response(const QWSIMResponseCommand *cmd) - { - invokeIMResponse(cmd, clientMap.value(-1)); -} - -void QWSServerPrivate::im_update(const QWSIMUpdateCommand *cmd) -{ - invokeIMUpdate(cmd, clientMap.value(-1)); -} - -void QWSServerPrivate::send_im_mouse(const QWSIMMouseCommand *cmd) -{ - if (current_IM) - current_IM->mouseHandler(cmd->simpleData.index, cmd->simpleData.state); -} -#endif - -void QWSServerPrivate::openDisplay() -{ - qt_init_display(); - -// rgnMan = qt_fbdpy->regionManager(); - swidth = qt_screen->deviceWidth(); - sheight = qt_screen->deviceHeight(); -} - -void QWSServerPrivate::closeDisplay() -{ - if (qt_screen) - qt_screen->shutdownDevice(); -} - -/*! - Returns the brush used as background in the absence of obscuring - windows. - - \sa setBackground() -*/ -const QBrush &QWSServer::backgroundBrush() const -{ - return *QWSServerPrivate::bgBrush; -} - -/*! - Sets the brush used as background in the absence of obscuring - windows, to be the given \a brush. - - Note that this function can only be used in the server process. - - \sa backgroundBrush() -*/ -void QWSServer::setBackground(const QBrush &brush) -{ - if (!QWSServerPrivate::bgBrush) - QWSServerPrivate::bgBrush = new QBrush(brush); - else - *QWSServerPrivate::bgBrush = brush; - if (!qwsServer) - return; - qt_screen->exposeRegion(QRect(0,0,qt_screen->width(), qt_screen->height()), 0); -} - - -#ifdef QT3_SUPPORT -/*! - \fn void QWSServer::setDesktopBackground(const QImage &image) - - Sets the image used as background in the absence of obscuring - windows, to be the given \a image. - - Use the setBackground() function instead. - - \oldcode - QImage image; - setDesktopBackground(image); - \newcode - QImage image; - setBackground(QBrush(image)); - \endcode -*/ -void QWSServer::setDesktopBackground(const QImage &img) -{ - if (img.isNull()) - setBackground(Qt::NoBrush); - else - setBackground(QBrush(QPixmap::fromImage(img))); -} - -/*! - \fn void QWSServer::setDesktopBackground(const QColor &color) - \overload - - Sets the color used as background in the absence of obscuring - windows, to be the given \a color. - - Use the setBackground() function instead. - - \oldcode - QColor color; - setDesktopBackground(color); - \newcode - QColor color; - setBackground(QBrush(color)); - \endcode -*/ -void QWSServer::setDesktopBackground(const QColor &c) -{ - setBackground(QBrush(c)); -} -#endif //QT3_SUPPORT - -/*! - \internal - */ -void QWSServer::startup(int flags) -{ - if (qwsServer) - return; - unlink(qws_qtePipeFilename().toLatin1().constData()); - (void)new QWSServer(flags); -} - -/*! - \internal -*/ - -void QWSServer::closedown() -{ - QScopedPointer<QWSServer> server(qwsServer); - qwsServer = 0; - QT_TRY { - unlink(qws_qtePipeFilename().toLatin1().constData()); - } QT_CATCH(const std::bad_alloc &) { - // ### TODO - what to do when we run out of memory - // when calling toLatin1? - } -} - -void QWSServerPrivate::emergency_cleanup() -{ -#ifndef QT_NO_QWS_KEYBOARD - if (qwsServer) - qwsServer->closeKeyboard(); -#endif -} - -#ifndef QT_NO_QWS_KEYBOARD -static QList<QWSServer::KeyboardFilter*> *keyFilters = 0; - -/*! - Processes the given key event. The key is identified by its \a - unicode value and the given \a keycode, \a modifiers, \a isPress - and \a autoRepeat parameters. - - The \a keycode parameter is the Qt keycode value as defined by the - Qt::Key enum. The \a modifiers is an OR combination of - Qt::KeyboardModifier values, indicating whether \gui - Shift/Alt/Ctrl keys are pressed. The \a isPress parameter is true - if the event is a key press event and \a autoRepeat is true if the - event is caused by an auto-repeat mechanism and not an actual key - press. - - This function is typically called internally by keyboard drivers. - Note that this function can only be used in the server process. - - \sa sendKeyEvent(), {Qt for Embedded Linux Character Input} -*/ -void QWSServer::processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers, - bool isPress, bool autoRepeat) -{ - bool block; - // Don't block the POWER or LIGHT keys - if ( keycode == Qt::Key_F34 || keycode == Qt::Key_F35 ) - block = false; - else - block = qwsServerPrivate->screensaverblockevent(KEY, qwsServerPrivate->screensaverinterval, isPress); - -#ifdef EVENT_BLOCK_DEBUG - qDebug() << "processKeyEvent" << unicode << keycode << modifiers << isPress << autoRepeat << (block ? "block" : "pass"); -#endif - - // If we press a key and it's going to be blocked, wake up the screen - if ( block && isPress ) - qwsServerPrivate->_q_screenSaverWake(); - - if ( block ) - return; - - if (keyFilters) { - for (int i = 0; i < keyFilters->size(); ++i) { - QWSServer::KeyboardFilter *keyFilter = keyFilters->at(i); - if (keyFilter->filter(unicode, keycode, modifiers, isPress, autoRepeat)) - return; - } - } - sendKeyEvent(unicode, keycode, modifiers, isPress, autoRepeat); -} - -/*! - \fn void QWSServer::addKeyboardFilter(KeyboardFilter *filter) - - Activates the given keyboard \a filter all key events generated by - physical keyboard drivers (i.e., events sent using the - processKeyEvent() function). - - Note that the filter is not invoked for keys generated by \e - virtual keyboard drivers (i.e., events sent using the - sendKeyEvent() function). - - Note that this function can only be used in the server process. - - \sa removeKeyboardFilter() -*/ -void QWSServer::addKeyboardFilter(KeyboardFilter *f) -{ - if (!keyFilters) - keyFilters = new QList<QWSServer::KeyboardFilter*>; - if (f) { - keyFilters->prepend(f); - } -} - -/* -//####### - We should probably obsolete the whole keyboard filter thing since - it's not useful for input methods anyway - - We could do removeKeyboardFilter(KeyboardFilter *f), but - the "remove and delete the filter" concept does not match "user - remembers the pointer". -*/ - -/*! - Removes and deletes the most recently added filter. - - Note that the programmer is responsible for removing each added - keyboard filter. - - Note that this function can only be used in the server process. - - \sa addKeyboardFilter() -*/ -void QWSServer::removeKeyboardFilter() -{ - if (!keyFilters || keyFilters->isEmpty()) - return; - delete keyFilters->takeAt(0); -} -#endif // QT_NO_QWS_KEYBOARD - -/*! - \fn void QWSServer::setScreenSaverIntervals(int* intervals) - - Specifies the time \a intervals (in milliseconds) between the - different levels of screen responsiveness. - - \l{Qt for Embedded Linux} supports multilevel screen saving, i.e., it is - possible to specify several different levels of screen - responsiveness by implementing the QWSScreenSaver::save() - function. For example, you can choose to first turn off the light - before you fully activate the screensaver. See the QWSScreenSaver - documentation for details. - - Note that an interval of 0 milliseconds will turn off the - screensaver, and that the \a intervals array must be 0-terminated. - This function can only be used in the server process. - - \sa setScreenSaverInterval(), setScreenSaverBlockLevel() -*/ -void QWSServer::setScreenSaverIntervals(int* ms) -{ - if (!qwsServerPrivate) - return; - - delete [] qwsServerPrivate->screensaverintervals; - if (ms) { - int* t=ms; - int n=0; - while (*t++) n++; - if (n) { - n++; // the 0 - qwsServerPrivate->screensaverintervals = new int[n]; - memcpy(qwsServerPrivate->screensaverintervals, ms, n*sizeof(int)); - } else { - qwsServerPrivate->screensaverintervals = 0; - } - } else { - qwsServerPrivate->screensaverintervals = 0; - } - qwsServerPrivate->screensaverinterval = 0; - - qwsServerPrivate->screensavertimer->stop(); - qt_screen->blank(false); - qwsServerPrivate->_q_screenSaverWake(); -} - -/*! - \fn void QWSServer::setScreenSaverInterval(int milliseconds) - - Sets the timeout interval for the screensaver to the specified \a - milliseconds. To turn off the screensaver, set the timout interval - to 0. - - Note that this function can only be used in the server process. - - \sa setScreenSaverIntervals(), setScreenSaverBlockLevel() -*/ -void QWSServer::setScreenSaverInterval(int ms) -{ - int v[2]; - v[0] = ms; - v[1] = 0; - setScreenSaverIntervals(v); -} - -/*! - Block the key or mouse event that wakes the system from level \a eventBlockLevel or higher. - To completely disable event blocking (the default behavior), set \a eventBlockLevel to -1. - - The algorithm blocks the "down", "up" as well as any "repeat" events for the same key - but will not block other key events after the initial "down" event. For mouse events, the - algorithm blocks all mouse events until an event with no buttons pressed is received. - - There are 2 keys that are never blocked, Qt::Key_F34 (POWER) and Qt::Key_F35 (LIGHT). - - Example usage: - - \snippet doc/src/snippets/code/src_gui_embedded_qwindowsystem_qws.cpp 0 - - Note that this function can only be used in the server process. - - \sa setScreenSaverIntervals(), setScreenSaverInterval() -*/ -void QWSServer::setScreenSaverBlockLevel(int eventBlockLevel) -{ - if (!qwsServerPrivate) - return; - qwsServerPrivate->screensavereventblocklevel = eventBlockLevel; -#ifdef EVENT_BLOCK_DEBUG - qDebug() << "QWSServer::setScreenSaverBlockLevel() " << eventBlockLevel; -#endif -} - -extern bool qt_disable_lowpriority_timers; //in qeventloop_unix.cpp - -void QWSServerPrivate::_q_screenSaverWake() -{ - if (screensaverintervals) { - if (screensaverinterval != screensaverintervals) { - if (saver) saver->restore(); - screensaverinterval = screensaverintervals; - screensaverblockevents = false; - } else { - if (!screensavertimer->isActive()) { - qt_screen->blank(false); - if (saver) saver->restore(); - } - } - screensavertimer->start(*screensaverinterval); - screensavertime.start(); - } - qt_disable_lowpriority_timers=false; -} - -void QWSServerPrivate::_q_screenSaverSleep() -{ - qt_screen->blank(true); -#if !defined(QT_QWS_IPAQ) && !defined(QT_QWS_EBX) - screensavertimer->stop(); -#else - if (screensaverinterval) { - screensavertimer->start(*screensaverinterval); - screensavertime.start(); - } else { - screensavertimer->stop(); - } -#endif - qt_disable_lowpriority_timers=true; -} - -/*! - \fn void QWSServer::setScreenSaver(QWSScreenSaver* screenSaver) - - Installs the given \a screenSaver, deleting the current screen - saver. - - Note that this function can only be used in the server process. - - \sa screenSaverActivate(), setScreenSaverInterval(), setScreenSaverIntervals(), setScreenSaverBlockLevel() -*/ -void QWSServer::setScreenSaver(QWSScreenSaver* ss) -{ - QWSServerPrivate *qd = qwsServer->d_func(); - delete qd->saver; - qd->saver = ss; -} - -void QWSServerPrivate::screenSave(int level) -{ - if (saver) { - // saver->save() may call QCoreApplication::processEvents, - // block event before calling saver->save(). - bool oldScreensaverblockevents = screensaverblockevents; - if (*screensaverinterval >= 1000) { - screensaverblockevents = (screensavereventblocklevel >= 0 && screensavereventblocklevel <= level); -#ifdef EVENT_BLOCK_DEBUG - if (screensaverblockevents) - qDebug("ready to block events"); -#endif - } - int *oldScreensaverinterval = screensaverinterval; - if (saver->save(level)) { - // only update screensaverinterval if it hasn't already changed - if (oldScreensaverinterval == screensaverinterval) { - if (screensaverinterval && screensaverinterval[1]) { - screensavertimer->start(*++screensaverinterval); - screensavertime.start(); - } else { - screensaverinterval = 0; - } - } - } else { - // restore previous state - screensaverblockevents = oldScreensaverblockevents; - - // for some reason, the saver don't want us to change to the - // next level, so we'll stay at this level for another interval - if (screensaverinterval && *screensaverinterval) { - screensavertimer->start(*screensaverinterval); - screensavertime.start(); - } - } - } else { - screensaverinterval = 0;//screensaverintervals; - screensaverblockevents = false; - _q_screenSaverSleep(); - } -} - -void QWSServerPrivate::_q_screenSaverTimeout() -{ - if (screensaverinterval) { - if (screensavertime.elapsed() > *screensaverinterval*2) { - // bogus (eg. unsuspend, system time changed) - _q_screenSaverWake(); // try again - return; - } - screenSave(screensaverinterval - screensaverintervals); - } -} - -/*! - Returns true if the screen saver is active; otherwise returns - false. - - Note that this function can only be used in the server process. - - \sa screenSaverActivate() -*/ -bool QWSServer::screenSaverActive() -{ - return qwsServerPrivate->screensaverinterval - && !qwsServerPrivate->screensavertimer->isActive(); -} - -/*! - \internal -*/ -void QWSServer::updateWindowRegions() const -{ - qwsServerPrivate->update_regions(); -} - -/*! - Activates the screen saver if \a activate is true; otherwise it is - deactivated. - - Note that this function can only be used in the server process. - - \sa screenSaverActive(), setScreenSaver() -*/ -void QWSServer::screenSaverActivate(bool activate) -{ - if (activate) - qwsServerPrivate->_q_screenSaverSleep(); - else - qwsServerPrivate->_q_screenSaverWake(); -} - -void QWSServerPrivate::disconnectClient(QWSClient *c) -{ - QTimer::singleShot(0, c, SLOT(closeHandler())); -} - -void QWSServerPrivate::updateClientCursorPos() -{ - Q_Q(QWSServer); - QWSWindow *win = qwsServerPrivate->mouseGrabber ? qwsServerPrivate->mouseGrabber : qwsServer->windowAt(QWSServer::mousePosition); - QWSClient *winClient = win ? win->client() : 0; - if (winClient && winClient != cursorClient) - q->sendMouseEvent(QWSServer::mousePosition, mouseState); -} - -#ifndef QT_NO_QWS_INPUTMETHODS - -/*! - \class QWSInputMethod - \preliminary - \ingroup qws - - \brief The QWSInputMethod class provides international input methods - in Qt for Embedded Linux. - - Note that this class is only available in \l{Qt for Embedded Linux}. - - A \l{Qt for Embedded Linux} application requires a server application to be - running, or to be the server application itself. All system - generated events, including keyboard and mouse events, are passed - to the server application which then propagates the event to the - appropriate client. - - An input method consists of a filter and optionally a graphical - interface, and is used to filter input events between the server - and the client application. - - \tableofcontents - - \section1 Creating Custom Input Methods - - To implement a custom input method, derive from the QWSInputMethod - class, and use the server's \l - {QWSServer::}{setCurrentInputMethod()} function to install it. - - When subclassing QWSInputMethod, you can reimplement the filter() - functions to handle input from both physical and virtual keyboards - as well as mouse devices. Note that the default implementations do - nothing. Use the setInputResolution() function to control the - number of bits shifted when filtering mouse input, i.e., when - going from pointer resolution to screen resolution (the current - resolution can be retrieved using the inputResolutionShift() - function). - - Reimplement the reset() function to restore the state of the input - method. Note that the default implementation calls the sendEvent() - function with empty preedit and commit strings if the input method - is in compose mode (i.e., if the input method is actively - composing a preedit string). - - To receive replies to an input method query (sent using the - sendQuery() function), you must reimplement the queryResponse() - function, while the mouseHandler() function must be reimplemented - if you want to handle mouse events within the preedit - text. Reimplement the updateHandler() function to handle update - events including resets and focus changes. The UpdateType enum - describes the various types of update events recognized by the - input method. - - \section1 Using Input Methods - - In addition to the filter(), reset(), queryResponse(), - mouseHandler() and updateHandler() function mentioned in the - previous section, the QWSInputMethod provides several other - functions helping the window system to manage the installed input - methods. - - The sendEvent() function sends the given event to the focus - widget, while the sendPreeditString() function sends the given - preedit text (encapsulated by an event). QWSInputMethod also - provides the sendCommitString() convenience function which sends - an event encapsulating the given commit string to the current - focus widget, and the sendMouseEvent() function which sends the - given mouse event. - - Finally, the QWSInputMethod class provides the sendQuery() - function for sending input method queries. This function - encapsulates the event with a QWSEvent instance of the \l - {QWSEvent::}{IMQuery} type. - - \sa QWSServer, {Qt for Embedded Linux Architecture} -*/ - -/*! - Constructs a new input method. - - Use the QWSServer::setCurrentInputMethod() function to install it. -*/ - -QWSInputMethod::QWSInputMethod() -{ - -} - -/*! - Destroys this input method, uninstalling it if it is installed. -*/ -QWSInputMethod::~QWSInputMethod() -{ - if (current_IM == this) - current_IM = 0; -} - -/*! - Filters the key input identified by the given \a unicode, \a - keycode, \a modifiers, \a isPress and \a autoRepeat parameters. - - Note that the default implementation does nothing; reimplement - this function to handle input from both physical and virtual - devices. - - The \a keycode is a Qt::Key value, and the \a modifiers is an OR - combination of Qt::KeyboardModifiers. The \a isPress parameter is - telling whether the input is a key press or key release, and the - \a autoRepeat parameter determines whether the input is - autorepeated ( i.e., in which case the - QWSKeyboardHandler::beginAutoRepeat() function has been called). - - To block the event from further processing, return true when - reimplementing this function; the default implementation returns - false. - - \sa setInputResolution(), inputResolutionShift() -*/ -bool QWSInputMethod::filter(int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat) -{ - Q_UNUSED(unicode); - Q_UNUSED(keycode); - Q_UNUSED(modifiers); - Q_UNUSED(isPress); - Q_UNUSED(autoRepeat); - return false; -} - -/*! - \overload - - Filters the mouse input identified by the given \a position, \a - state, and \a wheel parameters. -*/ -bool QWSInputMethod::filter(const QPoint &position, int state, int wheel) -{ - Q_UNUSED(position); - Q_UNUSED(state); - Q_UNUSED(wheel); - return false; -} - -/*! - Resets the state of the input method. - - If the input method is in compose mode, i.e., the input method is - actively composing a preedit string, the default implementation - calls sendEvent() with empty preedit and commit strings; otherwise - it does nothing. Reimplement this function to alter this behavior. - - \sa sendEvent() -*/ -void QWSInputMethod::reset() -{ - if (current_IM_composing_win) { - QInputMethodEvent ime; - sendEvent(&ime); - } -} - -/*! - \enum QWSInputMethod::UpdateType - - This enum describes the various types of update events recognized - by the input method. - - \value Update The input widget is updated in some way; use sendQuery() with - Qt::ImMicroFocus as an argument for more information. - \value FocusIn A new input widget receives focus. - \value FocusOut The input widget loses focus. - \value Reset The input method should be reset. - \value Destroyed The input widget is destroyed. - - \sa updateHandler() -*/ - -/*! - Handles update events including resets and focus changes. The - update events are specified by the given \a type which is one of - the UpdateType enum values. - - Note that reimplementations of this function must call the base - implementation for all cases that it does not handle itself. - - \sa UpdateType -*/ -void QWSInputMethod::updateHandler(int type) -{ - switch (type) { - case FocusOut: - case Reset: - reset(); - break; - - default: - break; - } -} - - -/*! - Receive replies to an input method query. - - Note that the default implementation does nothing; reimplement - this function to receive such replies. - - Internally, an input method query is passed encapsulated by an \l - {QWSEvent::IMQuery}{IMQuery} event generated by the sendQuery() - function. The queried property and the result is passed in the \a - property and \a result parameters. - - \sa sendQuery(), QWSServer::sendIMQuery() -*/ -void QWSInputMethod::queryResponse(int property, const QVariant &result) -{ - Q_UNUSED(property); - Q_UNUSED(result); -} - - - -/*! - \fn void QWSInputMethod::mouseHandler(int offset, int state) - - Handles mouse events within the preedit text. - - Note that the default implementation resets the input method on - all mouse presses; reimplement this function to alter this - behavior. - - The \a offset parameter specifies the position of the mouse event - within the string, and \a state specifies the type of the mouse - event as described by the QWSServer::IMMouse enum. If \a state is - less than 0, the mouse event is inside the associated widget, but - outside the preedit text. When clicking in a different widget, the - \a state is QWSServer::MouseOutside. - - \sa sendPreeditString(), reset() -*/ -void QWSInputMethod::mouseHandler(int, int state) -{ - if (state == QWSServer::MousePress || state == QWSServer::MouseOutside) - reset(); -} - - -/*! - Sends an event encapsulating the given \a preeditString, to the - focus widget. - - The specified \a selectionLength is the number of characters to be - marked as selected (starting at the given \a cursorPosition). If - \a selectionLength is negative, the text \e before \a - cursorPosition is marked. - - The preedit string is marked with QInputContext::PreeditFormat, - and the selected part is marked with - QInputContext::SelectionFormat. - - Sending an input method event with a non-empty preedit string will - cause the input method to enter compose mode. Sending an input - method event with an empty preedit string will cause the input - method to leave compose mode, i.e., the input method will no longer - be actively composing the preedit string. - - Internally, the event is represented by a QWSEvent object of the - \l {QWSEvent::IMEvent}{IMEvent} type. - - \sa sendEvent(), sendCommitString() -*/ - -void QWSInputMethod::sendPreeditString(const QString &preeditString, int cursorPosition, int selectionLength) -{ - QList<QInputMethodEvent::Attribute> attributes; - - int selPos = cursorPosition; - if (selectionLength == 0) { - selPos = 0; - } else if (selectionLength < 0) { - selPos += selectionLength; - selectionLength = -selectionLength; - } - if (selPos > 0) - attributes += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, selPos, - QVariant(int(QInputContext::PreeditFormat))); - - if (selectionLength) - attributes += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selPos, selectionLength, - QVariant(int(QInputContext::SelectionFormat))); - - if (selPos + selectionLength < preeditString.length()) - attributes += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, - selPos + selectionLength, - preeditString.length() - selPos - selectionLength, - QVariant(int(QInputContext::PreeditFormat))); - - attributes += QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPosition, 0, QVariant()); - - QInputMethodEvent ime(preeditString, attributes); - qwsServer->sendIMEvent(&ime); -} - -/*! - \fn void QWSInputMethod::sendCommitString(const QString &commitString, int replaceFromPosition, int replaceLength) - - Sends an event encapsulating the given \a commitString, to the - focus widget. - - Note that this will cause the input method to leave compose mode, - i.e., the input method will no longer be actively composing the - preedit string. - - If the specified \a replaceLength is greater than 0, the commit - string will replace the given number of characters of the - receiving widget's previous text, starting at the given \a - replaceFromPosition relative to the start of the current preedit - string. - - Internally, the event is represented by a QWSEvent object of the - \l {QWSEvent::IMEvent}{IMEvent} type. - - \sa sendEvent(), sendPreeditString() -*/ -void QWSInputMethod::sendCommitString(const QString &commitString, int replaceFrom, int replaceLength) -{ - QInputMethodEvent ime; - ime.setCommitString(commitString, replaceFrom, replaceLength); - qwsServer->sendIMEvent(&ime); -} - -/*! - \fn QWSInputMethod::sendIMEvent(QWSServer::IMState state, const QString &text, int cursorPosition, int selectionLength) - \obsolete - - Sends a QInputMethodEvent object to the focus widget. - - If the specified \a state is QWSServer::IMCompose, \a text is a - preedit string, \a cursorPosition is the cursor's position within - the preedit string, and \a selectionLength is the number of - characters (starting at \a cursorPosition) that should be marked - as selected by the input widget receiving the event. If the - specified \a state is QWSServer::IMEnd, \a text is a commit - string. - - Use sendEvent(), sendPreeditString() or sendCommitString() instead. -*/ - -/*! - \fn QWSInputMethod::sendEvent(const QInputMethodEvent *event) - - Sends the given \a event to the focus widget. - - The \c QInputMethodEvent class is derived from QWSEvent, i.e., the - given \a event is a QWSEvent object of the \l - {QWSEvent::IMEvent}{IMEvent} type. - - \sa sendPreeditString(), sendCommitString(), reset() -*/ - - -/*! - \fn void QWSInputMethod::sendQuery(int property) - - Sends an input method query (internally encapsulated by a QWSEvent - of the \l {QWSEvent::IMQuery}{IMQuery} type) for the specified \a - property. - - To receive responses to input method queries, the virtual - queryResponse() function must be reimplemented. - - \sa queryResponse(), QWSServer::sendIMQuery() -*/ - -/*! - Sets and returns the number of bits shifted to go from pointer - resolution to screen resolution when filtering mouse input. - - If \a isHigh is true and the device has a pointer device - resolution twice or more of the screen resolution, the positions - passed to the filter() function will be presented at the higher - resolution; otherwise the resolution will be equal to that of the - screen resolution. - - \sa inputResolutionShift(), filter() -*/ -uint QWSInputMethod::setInputResolution(bool isHigh) -{ - mIResolution = isHigh; - return inputResolutionShift(); -} - -/*! - Returns the number of bits shifted to go from pointer resolution - to screen resolution when filtering mouse input. - - \sa setInputResolution(), filter() -*/ -uint QWSInputMethod::inputResolutionShift() const -{ - return 0; // default for devices with single resolution. -} - -/*! - \fn void QWSInputMethod::sendMouseEvent( const QPoint &position, int state, int wheel ) - - Sends a mouse event specified by the given \a position, \a state - and \a wheel parameters. - - The given \a position will be transformed if the screen - coordinates do not match the pointer device coordinates. - - Note that the event will be not be tested by the active input - method, but calling the QWSServer::sendMouseEvent() function will - make the current input method filter the event. - - \sa mouseHandler(), sendEvent() -*/ -void QWSInputMethod::sendMouseEvent( const QPoint &pos, int state, int wheel ) -{ - if (qt_last_x) { - *qt_last_x = pos.x(); - *qt_last_y = pos.y(); - } - QWSServer::mousePosition = pos; - qwsServerPrivate->mouseState = state; - QWSServerPrivate::sendMouseEventUnfiltered(pos, state, wheel); -} -#endif // QT_NO_QWS_INPUTMETHODS - -/*! - \fn QWSWindow::QWSWindow(int i, QWSClient * client) - \internal - - Constructs a new top-level window, associated with the client \a - client and giving it the id \a i. -*/ - -/*! - \fn QWSServer::windowEvent(QWSWindow * window, QWSServer::WindowEvent eventType) - - This signal is emitted whenever something happens to a top-level - window (e.g., it's created or destroyed), passing a pointer to the - window and the event's type in the \a window and \a eventType - parameters, respectively. - - \sa markedText() -*/ - -/*! - \class QWSServer::KeyboardFilter - \ingroup qws - - \brief The KeyboardFilter class is a base class for global - keyboard event filters in Qt for Embedded Linux. - - Note that this class is only available in \l{Qt for Embedded Linux}. - - In \l{Qt for Embedded Linux}, all system generated events, including - keyboard events, are passed to the server application which then - propagates the event to the appropriate client. The KeyboardFilter - class is used to implement a global, low-level filter on the - server side. The server applies the filter to all keyboard events - before passing them on to the clients: - - \image qwsserver_keyboardfilter.png - - This feature can, for example, be used to filter things like APM - (advanced power management) suspended from a button without having - to filter for it in all applications. - - To add a new keyboard filter you must first create the filter by - deriving from this class, reimplementing the pure virtual filter() - function. Then you can install the filter on the server using - QWSServer's \l {QWSServer::}{addKeyboardFilter()} - function. QWSServer also provides a \l - {QWSServer::}{removeKeyboardFilter()} function. - - \sa {Qt for Embedded Linux Architecture}, QWSServer, QWSInputMethod -*/ - -/*! - \fn QWSServer::KeyboardFilter::~KeyboardFilter() - - Destroys the keyboard filter. -*/ - -/*! - \fn bool QWSServer::KeyboardFilter::filter(int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat) - - Implement this function to return true if a given key event should - be stopped from being processed any further; otherwise it should - return false. - - A key event can be identified by the given \a unicode value and - the \a keycode, \a modifiers, \a isPress and \a autoRepeat - parameters. - - The \a keycode parameter is the Qt keycode value as defined by the - Qt::Key enum. The \a modifiers is an OR combination of - Qt::KeyboardModifier values, indicating whether \gui - Shift/Alt/Ctrl keys are pressed. The \a isPress parameter is true - if the event is a key press event and \a autoRepeat is true if the - event is caused by an auto-repeat mechanism and not an actual key - press. -*/ - -QT_END_NAMESPACE - -#include "moc_qwindowsystem_qws.cpp" |