source: trunk/src/gui/kernel/qapplication_qws.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 116.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qglobal.h"
43#include "qlibrary.h"
44#include "qcursor.h"
45#include "qapplication.h"
46#include "private/qapplication_p.h"
47#include "qwidget.h"
48#include "qbitarray.h"
49#include "qpainter.h"
50#include "qpixmapcache.h"
51#include "qdatetime.h"
52#include "qtextcodec.h"
53#include "qdatastream.h"
54#include "qbuffer.h"
55#include "qsocketnotifier.h"
56#include "qsessionmanager.h"
57#include "qclipboard.h"
58#include "qbitmap.h"
59#include "qwssocket_qws.h"
60#include "qtransportauth_qws.h"
61#include "private/qtransportauth_qws_p.h"
62#include "qwsevent_qws.h"
63#include "private/qwscommand_qws_p.h"
64#include "qwsproperty_qws.h"
65#include "qscreen_qws.h"
66#include "qscreenproxy_qws.h"
67#include "qcopchannel_qws.h"
68#include "private/qlock_p.h"
69#include "private/qwslock_p.h"
70//#include "qmemorymanager_qws.h"
71#include "qwsmanager_qws.h"
72//#include "qwsregionmanager_qws.h"
73#include "qwindowsystem_qws.h"
74#include "private/qwindowsystem_p.h"
75#include "qdecorationfactory_qws.h"
76
77#include "qwsdisplay_qws.h"
78#include "private/qwsdisplay_qws_p.h"
79#include "private/qwsinputcontext_p.h"
80#include "qfile.h"
81#include "qhash.h"
82#include "qdesktopwidget.h"
83#include "qcolormap.h"
84#include "private/qcursor_p.h"
85#include "qsettings.h"
86#include "qdebug.h"
87#include "qeventdispatcher_qws_p.h"
88#if !defined(QT_NO_GLIB)
89# include "qeventdispatcher_glib_qws_p.h"
90#endif
91
92
93#include "private/qwidget_p.h"
94#include "private/qbackingstore_p.h"
95#include "private/qwindowsurface_qws_p.h"
96#include "private/qfont_p.h"
97
98#include <unistd.h>
99#include <stdio.h>
100#include <stdlib.h>
101#include <string.h>
102#include <locale.h>
103#include <errno.h>
104#include <fcntl.h>
105#ifdef Q_OS_VXWORKS
106# include <sys/times.h>
107#else
108# include <sys/time.h>
109#endif
110#include <sys/stat.h>
111#include <sys/types.h>
112
113#include <qvfbhdr.h>
114
115#ifndef QT_NO_QWS_MULTIPROCESS
116#ifdef QT_NO_QSHM
117#include <sys/ipc.h>
118#include <sys/shm.h>
119#ifndef Q_OS_DARWIN
120# include <sys/sem.h>
121#endif
122#include <sys/socket.h>
123#else
124#include "private/qwssharedmemory_p.h"
125#endif
126#endif
127
128QT_BEGIN_NAMESPACE
129
130#ifndef QT_NO_DIRECTPAINTER
131class QDirectPainter;
132extern void qt_directpainter_region(QDirectPainter *dp, const QRegion &alloc, int type);
133#ifndef QT_NO_QWSEMBEDWIDGET
134extern void qt_directpainter_embedevent(QDirectPainter *dp,
135 const QWSEmbedEvent *e);
136#endif
137#endif // QT_NO_DIRECTPAINTER
138
139const int qwsSharedRamSize = 1 * 1024; // misc data, written by server, read by clients
140
141extern QApplication::Type qt_appType;
142extern QDesktopWidget *qt_desktopWidget;
143
144//these used to be environment variables, they are initialized from
145//environment variables in
146
147bool qws_savefonts = false;
148bool qws_screen_is_interlaced=false; //### should be detected
149bool qws_shared_memory = false;
150bool qws_sw_cursor = true;
151bool qws_accel = true; // ### never set
152QByteArray qws_display_spec(":0");
153Q_GUI_EXPORT int qws_display_id = 0;
154Q_GUI_EXPORT int qws_client_id = 0;
155QWidget *qt_pressGrab = 0;
156QWidget *qt_mouseGrb = 0;
157int *qt_last_x = 0;
158int *qt_last_y = 0;
159
160static int mouse_x_root = -1;
161static int mouse_y_root = -1;
162static int mouse_state = 0;
163static int mouse_double_click_distance = 5;
164
165int qt_servershmid = -1;
166
167bool qws_overrideCursor = false;
168#ifndef QT_NO_QWS_MANAGER
169
170extern Q_GUI_EXPORT QWSServer *qwsServer;
171
172static QDecoration *qws_decoration = 0;
173#endif
174
175#if defined(QT_DEBUG)
176/*
177extern "C" void dumpmem(const char* m)
178{
179 static int init=0;
180 static int prev=0;
181 FILE* f = fopen("/proc/meminfo","r");
182 // char line[100];
183 int total=0,used=0,free=0,shared=0,buffers=0,cached=0;
184 fscanf(f,"%*[^M]Mem: %d %d %d %d %d %d",&total,&used,&free,&shared,&buffers,&cached);
185 used -= buffers + cached;
186 if (!init) {
187 init=used;
188 } else {
189 printf("%40s: %+8d = %8d\n",m,used-init-prev,used-init);
190 prev = used-init;
191 }
192 fclose(f);
193}
194*/
195#endif
196
197// Get the name of the directory where Qt for Embedded Linux temporary data should
198// live.
199QString qws_dataDir()
200{
201 static QString result;
202 if (!result.isEmpty())
203 return result;
204 result = QT_VFB_DATADIR(qws_display_id);
205 QByteArray dataDir = result.toLocal8Bit();
206
207 if (QT_MKDIR(dataDir, 0700)) {
208 if (errno != EEXIST) {
209 qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData());
210 }
211 }
212
213 QT_STATBUF buf;
214 if (QT_LSTAT(dataDir, &buf))
215 qFatal("stat failed for Qt for Embedded Linux data directory: %s", dataDir.constData());
216
217 if (!S_ISDIR(buf.st_mode))
218 qFatal("%s is not a directory", dataDir.constData());
219
220#if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS)
221 if (buf.st_uid != getuid())
222 qFatal("Qt for Embedded Linux data directory is not owned by user %d", getuid());
223
224 if ((buf.st_mode & 0677) != 0600)
225 qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData());
226#endif
227
228 result.append("/");
229 return result;
230}
231
232// Get the filename of the pipe Qt for Embedded Linux uses for server/client comms
233Q_GUI_EXPORT QString qws_qtePipeFilename()
234{
235 qws_dataDir();
236 return QTE_PIPE(qws_display_id);
237}
238
239static void setMaxWindowRect(const QRect &rect)
240{
241 const QList<QScreen*> subScreens = qt_screen->subScreens();
242 QScreen *screen = qt_screen;
243 int screenNo = 0;
244 for (int i = 0; i < subScreens.size(); ++i) {
245 if (subScreens.at(i)->region().contains(rect)) {
246 screen = subScreens.at(i);
247 screenNo = i;
248 break;
249 }
250 }
251
252 QApplicationPrivate *ap = QApplicationPrivate::instance();
253 ap->setMaxWindowRect(screen, screenNo, rect);
254}
255
256void QApplicationPrivate::setMaxWindowRect(const QScreen *screen, int screenNo,
257 const QRect &rect)
258{
259 if (maxWindowRects.value(screen) == rect)
260 return;
261
262 maxWindowRects[screen] = rect;
263
264 // Re-resize any maximized windows
265 QWidgetList l = QApplication::topLevelWidgets();
266 for (int i = 0; i < l.size(); ++i) {
267 QWidget *w = l.at(i);
268 QScreen *s = w->d_func()->getScreen();
269 if (w->isMaximized() && s == screen)
270 w->d_func()->setMaxWindowState_helper();
271 }
272
273 if ( qt_desktopWidget ) // XXX workaround crash
274 emit QApplication::desktop()->workAreaResized(screenNo);
275}
276
277#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
278
279typedef void (*TransformFunc)(QScreen *, int);
280#ifndef QT_NO_QWS_TRANSFORMED
281extern "C" void qws_setScreenTransformation(QScreen *, int);
282#endif
283static TransformFunc getTransformationFunction()
284{
285 static TransformFunc func = 0;
286
287 if (!func) {
288#ifdef QT_NO_QWS_TRANSFORMED
289# ifndef QT_NO_LIBRARY
290 // symbol is not built into the library, search for the plugin
291 const QStringList paths = QApplication::libraryPaths();
292 foreach (const QString &path, paths) {
293 const QString file = path + QLatin1String("/gfxdrivers/libqgfxtransformed");
294 func = (TransformFunc)QLibrary::resolve(file,
295 "qws_setScreenTransformation");
296 if (func)
297 break;
298 }
299# endif
300#else
301 func = qws_setScreenTransformation;
302#endif
303 if (!func)
304 func = (TransformFunc)-1;
305 }
306
307 if (func == (TransformFunc)-1)
308 return 0;
309
310 return func;
311}
312
313static void setScreenTransformation(int screenNo, int transformation)
314{
315 QScreen *screen = QScreen::instance();
316 const QList<QScreen*> subScreens = screen->subScreens();
317
318 if (screenNo == -1)
319 screenNo = 0;
320
321 if (screenNo == -1 && !subScreens.isEmpty())
322 screenNo = 0;
323
324 if (subScreens.isEmpty() && screenNo == 0) {
325 // nothing
326 } else if (screenNo < 0 || screenNo >= subScreens.size()) {
327 qWarning("setScreenTransformation: invalid screen %i", screenNo);
328 return;
329 }
330
331 if (screenNo < subScreens.size())
332 screen = subScreens.at(screenNo);
333
334 QApplicationPrivate *ap = QApplicationPrivate::instance();
335 ap->setScreenTransformation(screen, screenNo, transformation);
336}
337
338void QApplicationPrivate::setScreenTransformation(QScreen *screen,
339 int screenNo,
340 int transformation)
341{
342 QScreen *transformed = screen;
343
344 while (transformed->classId() == QScreen::ProxyClass)
345 transformed = static_cast<QProxyScreen*>(transformed)->screen();
346
347 if (transformed->classId() != QScreen::TransformedClass)
348 return;
349
350 TransformFunc setScreenTransformation = getTransformationFunction();
351 if (!setScreenTransformation)
352 return;
353
354 setScreenTransformation(transformed, transformation);
355
356 // need to re-configure() proxies bottom-up
357 if (screen->classId() == QScreen::ProxyClass) {
358 QList<QProxyScreen*> proxies;
359 QScreen *s = screen;
360
361 do {
362 QProxyScreen *proxy = static_cast<QProxyScreen*>(s);
363 proxies.append(proxy);
364 s = proxy->screen();
365 } while (s->classId() == QScreen::ProxyClass);
366
367 do {
368 QProxyScreen *proxy = proxies.takeLast();
369 proxy->setScreen(proxy->screen()); // triggers configure()
370 } while (!proxies.isEmpty());
371 }
372
373 if (qt_desktopWidget) { // XXX workaround crash for early screen transform events
374 QDesktopWidget *desktop = QApplication::desktop();
375
376 emit desktop->resized(screenNo);
377 if (maxWindowRect(screen).isEmpty()) // not explicitly set
378 emit desktop->workAreaResized(screenNo);
379 }
380
381 QWSServer *server = QWSServer::instance();
382 if (server) {
383 server->updateWindowRegions();
384 QRegion r = screen->region();
385 server->refresh(r);
386 }
387
388 // make sure maximized and fullscreen windows are updated
389 QWidgetList list = QApplication::topLevelWidgets();
390 for (int i = list.size() - 1; i >= 0; --i) {
391 QWidget *w = list.at(i);
392 if (w->isFullScreen())
393 w->d_func()->setFullScreenSize_helper();
394 else if (w->isMaximized())
395 w->d_func()->setMaxWindowState_helper();
396 }
397}
398
399#endif // QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
400
401/*****************************************************************************
402 Internal variables and functions
403 *****************************************************************************/
404
405
406static QString appName; // application name
407static const char *appFont = 0; // application font
408static const char *appBGCol = 0; // application bg color
409static const char *appFGCol = 0; // application fg color
410static const char *appBTNCol = 0; // application btn color
411static const char *mwGeometry = 0; // main widget geometry
412static const char *mwTitle = 0; // main widget title
413//static bool mwIconic = false; // main widget iconified
414
415static bool app_do_modal = false; // modal mode
416Q_GUI_EXPORT QWSDisplay *qt_fbdpy = 0; // QWS `display'
417QLock *QWSDisplay::lock = 0;
418
419static int mouseButtonPressed = 0; // last mouse button pressed
420static int mouseButtonPressTime = 0; // when was a button pressed
421static short mouseXPos, mouseYPos; // mouse position in act window
422
423extern QWidgetList *qt_modal_stack; // stack of modal widgets
424
425static QWidget *popupButtonFocus = 0;
426static QWidget *popupOfPopupButtonFocus = 0;
427static bool popupCloseDownMode = false;
428static bool popupGrabOk;
429static QPointer<QWidget> *mouseInWidget = 0;
430QPointer<QWidget> qt_last_mouse_receiver = 0;
431
432static bool sm_blockUserInput = false; // session management
433
434QWidget *qt_button_down = 0; // widget got last button-down
435WId qt_last_cursor = 0xffffffff; // Was -1, but WIds are unsigned
436
437class QWSMouseEvent;
438class QWSKeyEvent;
439
440class QETWidget : public QWidget // event translator widget
441{
442public:
443 bool translateMouseEvent(const QWSMouseEvent *, int oldstate);
444 bool translateKeyEvent(const QWSKeyEvent *, bool grab);
445 bool translateRegionEvent(const QWSRegionEvent *);
446#ifndef QT_NO_QWSEMBEDWIDGET
447 void translateEmbedEvent(const QWSEmbedEvent *event);
448#endif
449 bool translateWheelEvent(const QWSMouseEvent *me);
450 void repaintDecoration(QRegion r, bool post);
451 void updateRegion();
452
453 bool raiseOnClick()
454 {
455 // With limited windowmanagement/taskbar/etc., raising big windows
456 // (eg. spreadsheet) over the top of everything else (eg. calculator)
457 // is just annoying.
458 return !isMaximized() && !isFullScreen();
459 }
460};
461
462void QApplicationPrivate::createEventDispatcher()
463{
464 Q_Q(QApplication);
465#if !defined(QT_NO_GLIB)
466 if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
467 eventDispatcher = (q->type() != QApplication::Tty
468 ? new QWSEventDispatcherGlib(q)
469 : new QEventDispatcherGlib(q));
470 else
471#endif
472 eventDispatcher = (q->type() != QApplication::Tty
473 ? new QEventDispatcherQWS(q)
474 : new QEventDispatcherUNIX(q));
475}
476
477// Single-process stuff. This should maybe move into qwindowsystem_qws.cpp
478
479static bool qws_single_process;
480static QList<QWSEvent*> incoming;
481static QList<QWSCommand*> outgoing;
482
483void qt_client_enqueue(const QWSEvent *event)
484{
485 QWSEvent *copy = QWSEvent::factory(event->type);
486 copy->copyFrom(event);
487 incoming.append(copy);
488}
489
490QList<QWSCommand*> *qt_get_server_queue()
491{
492 return &outgoing;
493}
494
495void qt_server_enqueue(const QWSCommand *command)
496{
497 QWSCommand *copy = QWSCommand::factory(command->type);
498 QT_TRY {
499 copy->copyFrom(command);
500 outgoing.append(copy);
501 } QT_CATCH(...) {
502 delete copy;
503 QT_RETHROW;
504 }
505}
506
507QWSDisplay::Data::Data(QObject* parent, bool singleProcess)
508{
509#ifdef QT_NO_QWS_MULTIPROCESS
510 Q_UNUSED(parent);
511 Q_UNUSED(singleProcess);
512#else
513 if (singleProcess)
514 csocket = 0;
515 else {
516 csocket = new QWSSocket(parent);
517 QObject::connect(csocket, SIGNAL(disconnected()),
518 qApp, SLOT(quit()));
519 }
520 clientLock = 0;
521#endif
522 init();
523}
524
525QWSDisplay::Data::~Data()
526{
527// delete rgnMan; rgnMan = 0;
528// delete memorymanager; memorymanager = 0;
529 qt_screen->disconnect();
530 delete qt_screen; qt_screen = 0;
531#ifndef QT_NO_QWS_CURSOR
532 delete qt_screencursor; qt_screencursor = 0;
533#endif
534#ifndef QT_NO_QWS_MULTIPROCESS
535 shm.detach();
536 if (csocket) {
537 QWSCommand shutdownCmd(QWSCommand::Shutdown, 0, 0);
538 shutdownCmd.write(csocket);
539 csocket->flush(); // may be pending QCop message, eg.
540 delete csocket;
541 }
542 delete clientLock;
543 clientLock = 0;
544#endif
545 delete connected_event;
546 delete mouse_event;
547 delete current_event;
548 qDeleteAll(queue);
549#ifndef QT_NO_COP
550 delete qcop_response;
551#endif
552}
553
554#ifndef QT_NO_QWS_MULTIPROCESS
555bool QWSDisplay::Data::lockClient(QWSLock::LockType type, int timeout)
556{
557 return !clientLock || clientLock->lock(type, timeout);
558}
559
560void QWSDisplay::Data::unlockClient(QWSLock::LockType type)
561{
562 if (clientLock) clientLock->unlock(type);
563}
564
565bool QWSDisplay::Data::waitClient(QWSLock::LockType type, int timeout)
566{
567 return !clientLock || clientLock->wait(type, timeout);
568}
569
570QWSLock* QWSDisplay::Data::getClientLock()
571{
572 return clientLock;
573}
574#endif // QT_NO_QWS_MULTIPROCESS
575
576void QWSDisplay::Data::flush()
577{
578#ifndef QT_NO_QWS_MULTIPROCESS
579 if (csocket) {
580 csocket->waitForReadyRead(0);
581 csocket->flush();
582 }
583#endif
584}
585
586#if 0
587void QWSDisplay::Data::debugQueue() {
588 for (int i = 0; i < queue.size(); ++i) {
589 QWSEvent *e = queue.at(i);
590 qDebug( " ev %d type %d sl %d rl %d", i, e->type, e->simpleLen, e->rawLen);
591 }
592}
593#endif
594
595bool QWSDisplay::Data::queueNotEmpty()
596{
597 return mouse_event/*||region_event*/||queue.count() > 0;
598}
599QWSEvent* QWSDisplay::Data::dequeue()
600{
601 QWSEvent *r=0;
602 if (queue.count()) {
603 r = queue.first();
604 queue.removeFirst();
605 if (r->type == QWSEvent::Region)
606 region_events_count--;
607 } else if (mouse_event) {
608 r = mouse_event;
609 mouse_event = 0;
610#ifdef QAPPLICATION_EXTRA_DEBUG
611 mouse_event_count = 0;
612#endif
613 }
614 return r;
615}
616
617QWSEvent* QWSDisplay::Data::peek()
618{
619 return queue.first();
620}
621
622bool QWSDisplay::Data::directServerConnection()
623{
624#ifndef QT_NO_QWS_MULTIPROCESS
625 return csocket == 0;
626#else
627 return true;
628#endif
629}
630
631void QWSDisplay::Data::create(int n)
632{
633 QWSCreateCommand cmd(n);
634 sendCommand(cmd);
635}
636
637void QWSDisplay::Data::flushCommands()
638{
639#ifndef QT_NO_QWS_MULTIPROCESS
640 if (csocket)
641 csocket->flush();
642#endif
643}
644
645void QWSDisplay::Data::sendCommand(QWSCommand & cmd)
646{
647#ifndef QT_NO_QWS_MULTIPROCESS
648 if (csocket)
649 cmd.write(csocket);
650 else
651#endif
652 qt_server_enqueue(&cmd);
653}
654
655void QWSDisplay::Data::sendSynchronousCommand(QWSCommand & cmd)
656{
657#ifndef QT_NO_QWS_MULTIPROCESS
658 if (csocket) {
659 lockClient(QWSLock::Communication);
660 cmd.write(csocket);
661 bool ok = true;
662 while (csocket->bytesToWrite() > 0) {
663 if (!csocket->waitForBytesWritten(-1)) {
664 qCritical("QWSDisplay::Data::sendSynchronousCommand: %s",
665 qPrintable(csocket->errorString()));
666 ok = false;
667 break;
668 }
669 }
670 if (ok)
671 waitClient(QWSLock::Communication);
672 } else
673#endif
674 qt_server_enqueue(&cmd);
675}
676
677int QWSDisplay::Data::takeId()
678{
679 int unusedIdCount = unused_identifiers.count();
680 if (unusedIdCount <= 10)
681 create(15);
682 if (unusedIdCount == 0) {
683 create(1); // Make sure we have an incoming id to wait for, just in case we're recursive
684 waitForCreation();
685 }
686
687 return unused_identifiers.takeFirst();
688}
689
690void QWSDisplay::Data::setMouseFilter(void (*filter)(QWSMouseEvent*))
691{
692 mouseFilter = filter;
693}
694
695#ifndef QT_NO_QWS_MULTIPROCESS
696
697QWSLock* QWSDisplay::Data::clientLock = 0;
698
699void Q_GUI_EXPORT qt_app_reinit( const QString& newAppName )
700{
701 qt_fbdpy->d->reinit( newAppName );
702}
703
704#endif // QT_NO_QWS_MULTIPROCESS
705
706class QDesktopWidget;
707
708#ifndef QT_NO_QWS_MULTIPROCESS
709void QWSDisplay::Data::reinit( const QString& newAppName )
710{
711 Q_ASSERT(csocket);
712
713 delete connected_event;
714 connected_event = 0;
715 region_events_count = 0;
716// region_ack = 0;
717 delete mouse_event;
718 mouse_event = 0;
719// region_event = 0;
720 region_offset_window = 0;
721#ifndef QT_NO_COP
722 delete qcop_response;
723 qcop_response = 0;
724#endif
725 delete current_event;
726 current_event = 0;
727#ifdef QAPPLICATION_EXTRA_DEBUG
728 mouse_event_count = 0;
729#endif
730 mouseFilter = 0;
731
732 qt_desktopWidget = 0;
733 delete QWSDisplay::Data::clientLock;
734 QWSDisplay::Data::clientLock = 0;
735
736 QString pipe = qws_qtePipeFilename();
737
738 // QWS client
739 // Cleanup all cached ids
740 unused_identifiers.clear();
741 delete csocket;
742
743 appName = newAppName;
744 qApp->setObjectName( appName );
745
746 csocket = new QWSSocket();
747 QObject::connect(csocket, SIGNAL(disconnected()),
748 qApp, SLOT(quit()));
749 csocket->connectToLocalFile(pipe);
750
751 QWSDisplay::Data::clientLock = new QWSLock();
752
753 QWSIdentifyCommand cmd;
754 cmd.setId(appName, QWSDisplay::Data::clientLock->id());
755
756#ifndef QT_NO_SXE
757 QTransportAuth *a = QTransportAuth::getInstance();
758 QTransportAuth::Data *d = a->connectTransport(
759 QTransportAuth::UnixStreamSock |
760 QTransportAuth::Trusted,
761 csocket->socketDescriptor());
762 QAuthDevice *ad = a->authBuf( d, csocket );
763 ad->setClient( csocket );
764
765 cmd.write(ad);
766#else
767 cmd.write(csocket);
768#endif
769
770 // wait for connect confirmation
771 waitForConnection();
772
773 qws_client_id = connected_event->simpleData.clientId;
774
775 if (!QWSDisplay::initLock(pipe, false))
776 qFatal("Cannot get display lock");
777
778 if (shm.attach(connected_event->simpleData.servershmid)) {
779 sharedRam = static_cast<uchar *>(shm.address());
780 QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
781 if (s)
782 sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
783 } else {
784 perror("QWSDisplay::Data::init");
785 qFatal("Client can't attach to main ram memory.");
786 }
787
788 qApp->desktop();
789
790 // We wait for creation mainly so that we can process important
791 // initialization events such as MaxWindowRect that are sent
792 // before object id creation. Waiting here avoids later window
793 // resizing since we have the MWR before windows are displayed.
794 waitForCreation();
795
796 sharedRamSize -= sizeof(int);
797 qt_last_x = reinterpret_cast<int *>(sharedRam + sharedRamSize);
798 sharedRamSize -= sizeof(int);
799 qt_last_y = reinterpret_cast<int *>(sharedRam + sharedRamSize);
800
801#ifndef QT_NO_COP
802 QCopChannel::reregisterAll();
803#endif
804 csocket->flush();
805}
806#endif
807
808void QWSDisplay::Data::init()
809{
810 connected_event = 0;
811 region_events_count = 0;
812// region_ack = 0;
813 mouse_event = 0;
814 mouse_state = -1;
815 mouse_winid = 0;
816// region_event = 0;
817 region_offset_window = 0;
818#ifndef QT_NO_COP
819 qcop_response = 0;
820#endif
821 current_event = 0;
822#ifdef QAPPLICATION_EXTRA_DEBUG
823 mouse_event_count = 0;
824#endif
825 mouseFilter = 0;
826
827 QString pipe = qws_qtePipeFilename();
828
829 sharedRamSize = qwsSharedRamSize;
830
831#ifndef QT_NO_QWS_MULTIPROCESS
832 if (csocket) {
833 // QWS client
834
835 connectToPipe();
836
837 QWSDisplay::Data::clientLock = new QWSLock();
838
839 QWSIdentifyCommand cmd;
840 cmd.setId(appName, QWSDisplay::Data::clientLock->id());
841#ifndef QT_NO_SXE
842 QTransportAuth *a = QTransportAuth::getInstance();
843 QTransportAuth::Data *d = a->connectTransport(
844 QTransportAuth::UnixStreamSock |
845 QTransportAuth::Trusted,
846 csocket->socketDescriptor());
847 QAuthDevice *ad = a->authBuf( d, csocket );
848 ad->setClient( csocket );
849 cmd.write(ad);
850#else
851 cmd.write(csocket);
852#endif
853
854 // create(30); // not necessary, server will send ids anyway
855 waitForConnection();
856
857 qws_client_id = connected_event->simpleData.clientId;
858
859 // now we want to get the exact display spec to use if we haven't
860 // specified anything.
861 if (qws_display_spec.at(0) == ':')
862 qws_display_spec = connected_event->display;
863
864 if (!QWSDisplay::initLock(pipe, false))
865 qFatal("Cannot get display lock");
866
867 if (shm.attach(connected_event->simpleData.servershmid)) {
868 sharedRam = static_cast<uchar *>(shm.address());
869 QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
870 if (s)
871 sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
872 } else {
873 perror("QWSDisplay::Data::init");
874 qFatal("Client can't attach to main ram memory.");
875 }
876
877 // We wait for creation mainly so that we can process important
878 // initialization events such as MaxWindowRect that are sent
879 // before object id creation. Waiting here avoids later window
880 // resizing since we have the MWR before windows are displayed.
881 waitForCreation();
882 } else
883#endif
884 {
885 create(30);
886
887 // QWS server
888 if (!QWSDisplay::initLock(pipe, true))
889 qFatal("Cannot get display lock");
890
891 QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
892 if (s)
893 sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
894
895#ifndef QT_NO_QWS_MULTIPROCESS
896
897 if (!shm.create(sharedRamSize)) {
898 perror("Cannot create main ram shared memory\n");
899 qFatal("Unable to allocate %d bytes of shared memory", sharedRamSize);
900 }
901 qt_servershmid = shm.id();
902 sharedRam = static_cast<uchar *>(shm.address());
903#else
904 sharedRam=static_cast<uchar *>(malloc(sharedRamSize));
905#endif
906 // Need to zero index count at end of block, might as well zero
907 // the rest too
908 memset(sharedRam,0,sharedRamSize);
909
910 QWSIdentifyCommand cmd;
911 cmd.setId(appName, -1);
912 qt_server_enqueue(&cmd);
913 }
914
915 // Allow some memory for the graphics driver too
916 //### Note that sharedRamSize() has side effects; it must be called
917 //### once, and only once, and before initDevice()
918 sharedRamSize -= qt_screen->sharedRamSize(sharedRam+sharedRamSize);
919
920#ifndef QT_NO_QWS_MULTIPROCESS
921 if(!csocket)
922#endif
923 {
924 //QWS server process
925 if (!qt_screen->initDevice())
926 qFatal("Unable to initialize screen driver!");
927 }
928
929 sharedRamSize -= sizeof(int);
930 qt_last_x = reinterpret_cast<int *>(sharedRam + sharedRamSize);
931 sharedRamSize -= sizeof(int);
932 qt_last_y = reinterpret_cast<int *>(sharedRam + sharedRamSize);
933
934 /* Initialise framebuffer memory manager */
935 /* Add 4k for luck and to avoid clobbering hardware cursor */
936// int screensize=qt_screen->screenSize();
937// memorymanager=new QMemoryManager(qt_screen->base()+screensize+4096,
938// qt_screen->totalSize()-(screensize+4096),0);
939
940// #ifndef QT_NO_QWS_MULTIPROCESS
941// rgnMan = new QWSRegionManager(pipe, csocket);
942// #else
943// rgnMan = new QWSRegionManager(pipe, 0); //####### not necessary
944// #endif
945#ifndef QT_NO_QWS_MULTIPROCESS
946 if (csocket)
947 csocket->flush();
948#endif
949}
950
951
952QWSEvent* QWSDisplay::Data::readMore()
953{
954#ifdef QT_NO_QWS_MULTIPROCESS
955 return incoming.isEmpty() ? 0 : incoming.takeFirst();
956#else
957 if (!csocket)
958 return incoming.isEmpty() ? 0 : incoming.takeFirst();
959 // read next event
960 if (!current_event) {
961 int event_type = qws_read_uint(csocket);
962
963 if (event_type >= 0) {
964 current_event = QWSEvent::factory(event_type);
965 }
966 }
967
968 if (current_event) {
969 if (current_event->read(csocket)) {
970 // Finished reading a whole event.
971 QWSEvent* result = current_event;
972 current_event = 0;
973 return result;
974 }
975 }
976
977 // Not finished reading a whole event.
978 return 0;
979#endif
980}
981
982void QWSDisplay::Data::fillQueue()
983{
984 QWSServer::processEventQueue();
985 QWSEvent *e = readMore();
986#ifndef QT_NO_QWS_MULTIPROCESS
987 int bytesAvailable = csocket ? csocket->bytesAvailable() : 0;
988 int bytesRead = 0;
989#endif
990 while (e) {
991#ifndef QT_NO_QWS_MULTIPROCESS
992 bytesRead += QWS_PROTOCOL_ITEM_SIZE((*e));
993#endif
994 if (e->type == QWSEvent::Connected) {
995 connected_event = static_cast<QWSConnectedEvent *>(e);
996 return;
997 } else if (e->type == QWSEvent::Creation) {
998 QWSCreationEvent *ce = static_cast<QWSCreationEvent*>(e);
999 int id = ce->simpleData.objectid;
1000 int count = ce->simpleData.count;
1001 for (int i = 0; i < count; ++i)
1002 unused_identifiers.append(id++);
1003 delete e;
1004 } else if (e->type == QWSEvent::Mouse) {
1005 if (!qt_screen) {
1006 delete e;
1007 } else {
1008 QWSMouseEvent *me = static_cast<QWSMouseEvent*>(e);
1009 if (mouseFilter)
1010 mouseFilter(me);
1011#ifdef QAPPLICATION_EXTRA_DEBUG
1012 static const char *defaultAction= "INITIAL";
1013 const char * action = defaultAction;
1014#endif
1015 delete mouse_event;
1016 if (mouse_winid != me->window ()
1017 || mouse_state != me->simpleData.state) {
1018 queue.append(me);
1019 mouse_winid = me->window();
1020 mouse_state = me->simpleData.state;
1021 mouse_event = 0;
1022#ifdef QAPPLICATION_EXTRA_DEBUG
1023 mouse_event_count = 0;
1024 action = "ENQUEUE";
1025#endif
1026 } else {
1027#ifdef QAPPLICATION_EXTRA_DEBUG
1028 if (mouse_event)
1029 action = "COMPRESS";
1030 mouse_event_count++;
1031#endif
1032 mouse_event = me;
1033 }
1034#ifdef QAPPLICATION_EXTRA_DEBUG
1035 if (me->simpleData.state !=0 || action != defaultAction || mouse_event_count != 0)
1036 qDebug("fillQueue %s (%d,%d), state %x win %d count %d", action,
1037 me->simpleData.x_root, me->simpleData.y_root, me->simpleData.state,
1038 me->window(), mouse_event_count);
1039#endif
1040 }
1041#ifndef QT_NO_QWS_MULTIPROCESS
1042 } else if (e->type == QWSEvent::Region && clientLock) {
1043 // not really an unlock, decrements the semaphore
1044 region_events_count++;
1045 clientLock->unlock(QWSLock::RegionEvent);
1046 queue.append(e);
1047#endif
1048#ifndef QT_NO_QWS_PROPERTIES
1049 } else if (e->type == QWSEvent::PropertyReply) {
1050 QWSPropertyReplyEvent *pe = static_cast<QWSPropertyReplyEvent*>(e);
1051 int len = pe->simpleData.len;
1052 char *data;
1053 if (len <= 0) {
1054 data = 0;
1055 } else {
1056 data = new char[len];
1057 memcpy(data, pe->data, len) ;
1058 }
1059 QPaintDevice::qwsDisplay()->getPropertyLen = len;
1060 QPaintDevice::qwsDisplay()->getPropertyData = data;
1061 delete e;
1062#endif // QT_NO_QWS_PROPERTIES
1063 } else if (e->type==QWSEvent::MaxWindowRect && qt_screen) {
1064 // Process this ASAP, in case new widgets are created (startup)
1065 setMaxWindowRect((static_cast<QWSMaxWindowRectEvent*>(e))->simpleData.rect);
1066 delete e;
1067#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
1068 } else if (e->type == QWSEvent::ScreenTransformation) {
1069 QWSScreenTransformationEvent *pe = static_cast<QWSScreenTransformationEvent*>(e);
1070 setScreenTransformation(pe->simpleData.screen,
1071 pe->simpleData.transformation);
1072 delete e;
1073#endif
1074#ifndef QT_NO_COP
1075 } else if (e->type == QWSEvent::QCopMessage) {
1076 QWSQCopMessageEvent *pe = static_cast<QWSQCopMessageEvent*>(e);
1077 if (pe->simpleData.is_response) {
1078 qcop_response = pe;
1079 } else {
1080 queue.append(e);
1081 }
1082#endif
1083 } else {
1084 queue.append(e);
1085 }
1086 //debugQueue();
1087#ifndef QT_NO_QWS_MULTIPROCESS
1088 if (csocket && bytesRead >= bytesAvailable)
1089 break;
1090#endif
1091 e = readMore();
1092 }
1093}
1094
1095#ifndef QT_NO_QWS_MULTIPROCESS
1096
1097static int qws_connection_timeout = 5;
1098
1099void QWSDisplay::Data::connectToPipe()
1100{
1101 Q_ASSERT(csocket);
1102
1103 int timeout = qgetenv("QWS_CONNECTION_TIMEOUT").toInt();
1104 if (timeout)
1105 qws_connection_timeout = timeout;
1106
1107 const QString pipe = qws_qtePipeFilename();
1108 int i = 0;
1109 while (!csocket->connectToLocalFile(pipe)) {
1110 if (++i > qws_connection_timeout) {
1111 qWarning("No Qt for Embedded Linux server appears to be running.");
1112 qWarning("If you want to run this program as a server,");
1113 qWarning("add the \"-qws\" command-line option.");
1114 exit(1);
1115 }
1116 sleep(1);
1117 }
1118}
1119
1120void QWSDisplay::Data::waitForConnection()
1121{
1122 connected_event = 0;
1123
1124 for (int i = 0; i < qws_connection_timeout; i++) {
1125 fillQueue();
1126 if (connected_event)
1127 return;
1128 csocket->flush();
1129 csocket->waitForReadyRead(1000);
1130 }
1131
1132 csocket->flush();
1133 if (!connected_event)
1134 qFatal("Did not receive a connection event from the qws server");
1135}
1136
1137void QWSDisplay::Data::waitForRegionAck(int winId)
1138{
1139 QWSEvent *ack = 0;
1140
1141 if (csocket) { // GuiClient
1142 int i = 0;
1143 while (!ack) {
1144 fillQueue();
1145
1146 while (i < queue.size()) {
1147 QWSEvent *e = queue.at(i);
1148 if (e->type == QWSEvent::Region && e->window() == winId) {
1149 ack = e;
1150 queue.removeAt(i);
1151 break;
1152 }
1153 ++i;
1154 }
1155
1156 if (!ack) {
1157 csocket->flush();
1158 csocket->waitForReadyRead(1000);
1159 }
1160 }
1161 } else { // GuiServer
1162 fillQueue();
1163 for (int i = 0; i < queue.size(); /* nothing */) {
1164 QWSEvent *e = queue.at(i);
1165 if (e->type == QWSEvent::Region && e->window() == winId) {
1166 ack = e;
1167 queue.removeAt(i);
1168 break;
1169 }
1170 ++i;
1171 }
1172 if (!ack) // already processed
1173 return;
1174 }
1175
1176 Q_ASSERT(ack);
1177
1178 qApp->qwsProcessEvent(ack);
1179 delete ack;
1180 region_events_count--;
1181}
1182
1183void QWSDisplay::Data::waitForRegionEvents(int winId, bool ungrabDisplay)
1184{
1185 if (!clientLock)
1186 return;
1187
1188 int removedEventsCount = 0;
1189
1190 // fill queue with unreceived region events
1191 if (!clientLock->hasLock(QWSLock::RegionEvent)) {
1192 bool ungrabbed = false;
1193 if (ungrabDisplay && QWSDisplay::grabbed()) {
1194 QWSDisplay::ungrab();
1195 ungrabbed = true;
1196 }
1197
1198 for (;;) {
1199 fillQueue();
1200 if (clientLock->hasLock(QWSLock::RegionEvent))
1201 break;
1202 csocket->flush();
1203 csocket->waitForReadyRead(1000);
1204 }
1205
1206 if (ungrabbed)
1207 QWSDisplay::grab(true);
1208 }
1209
1210 // check the queue for pending region events
1211 QWSEvent *regionEvent = 0;
1212 for (int i = 0; i < queue.size(); /* nothing */) {
1213 QWSEvent *e = queue.at(i);
1214 if (e->type == QWSEvent::Region && e->window() == winId) {
1215 QWSRegionEvent *re = static_cast<QWSRegionEvent*>(e);
1216 if (re->simpleData.type == QWSRegionEvent::Allocation) {
1217 delete regionEvent;
1218 regionEvent = re;
1219 }
1220 queue.removeAt(i);
1221 removedEventsCount++;
1222 } else {
1223 ++i;
1224 }
1225 }
1226
1227 if (regionEvent) {
1228 qApp->qwsProcessEvent(regionEvent);
1229 delete regionEvent;
1230 }
1231 region_events_count -= removedEventsCount;
1232}
1233
1234bool QWSDisplay::Data::hasPendingRegionEvents() const
1235{
1236 if (clientLock && !clientLock->hasLock(QWSLock::RegionEvent))
1237 return true;
1238
1239 return region_events_count > 0;
1240}
1241
1242#endif // QT_NO_QWS_MULTIPROCESS
1243
1244void QWSDisplay::Data::waitForCreation()
1245{
1246 fillQueue();
1247#ifndef QT_NO_QWS_MULTIPROCESS
1248 while (unused_identifiers.count() == 0) {
1249 if (csocket) {
1250 csocket->flush();
1251 csocket->waitForReadyRead(1000);
1252 }
1253 fillQueue();
1254 }
1255#endif
1256}
1257
1258
1259#ifndef QT_NO_QWS_MULTIPROCESS
1260void QWSDisplay::Data::waitForPropertyReply()
1261{
1262 if (!csocket)
1263 return;
1264 fillQueue();
1265 while (qt_fbdpy->getPropertyLen == -2) {
1266 csocket->flush();
1267 csocket->waitForReadyRead(1000);
1268 fillQueue();
1269 }
1270}
1271#endif
1272
1273#ifndef QT_NO_COP
1274void QWSDisplay::Data::waitForQCopResponse()
1275{
1276 for (;;) {
1277 fillQueue();
1278 if (qcop_response)
1279 break;
1280#ifndef QT_NO_QWS_MULTIPROCESS
1281 if (csocket) {
1282 csocket->flush();
1283 csocket->waitForReadyRead(1000);
1284 }
1285#endif
1286 }
1287 queue.prepend(qcop_response);
1288 qcop_response = 0;
1289}
1290#endif
1291
1292/*!
1293 \class QWSDisplay
1294 \brief The QWSDisplay class provides a display for QWS; it is an internal class.
1295
1296 \internal
1297
1298 \ingroup qws
1299*/
1300
1301QWSDisplay::QWSDisplay()
1302{
1303 d = new Data(0, qws_single_process);
1304}
1305
1306QWSDisplay::~QWSDisplay()
1307{
1308 delete d;
1309 delete lock;
1310 lock = 0;
1311}
1312
1313bool QWSDisplay::grabbed()
1314{
1315 return lock->locked();
1316}
1317
1318void QWSDisplay::grab()
1319{
1320 lock->lock(QLock::Read);
1321}
1322
1323void QWSDisplay::grab(bool write)
1324{
1325 lock->lock(write ? QLock::Write : QLock::Read);
1326
1327}
1328void QWSDisplay::ungrab()
1329{
1330 lock->unlock();
1331}
1332
1333#if 0
1334QWSRegionManager *QWSDisplay::regionManager() const
1335{
1336 return d->rgnMan;
1337}
1338#endif
1339
1340bool QWSDisplay::eventPending() const
1341{
1342#ifndef QT_NO_QWS_MULTIPROCESS
1343 d->flush();
1344#endif
1345 d->fillQueue();
1346 return d->queueNotEmpty();
1347}
1348
1349
1350/*
1351 Caller must delete return value!
1352 */
1353QWSEvent *QWSDisplay::getEvent()
1354{
1355 d->fillQueue();
1356 Q_ASSERT(d->queueNotEmpty());
1357 QWSEvent* e = d->dequeue();
1358
1359 return e;
1360}
1361
1362uchar* QWSDisplay::frameBuffer() const { return qt_screen->base(); }
1363int QWSDisplay::width() const { return qt_screen->width(); }
1364int QWSDisplay::height() const { return qt_screen->height(); }
1365int QWSDisplay::depth() const { return qt_screen->depth(); }
1366int QWSDisplay::pixmapDepth() const { return qt_screen->pixmapDepth(); }
1367bool QWSDisplay::supportsDepth(int depth) const { return qt_screen->supportsDepth(depth); }
1368uchar *QWSDisplay::sharedRam() const { return d->sharedRam; }
1369int QWSDisplay::sharedRamSize() const { return d->sharedRamSize; }
1370
1371#ifndef QT_NO_QWS_PROPERTIES
1372
1373void QWSDisplay::addProperty(int winId, int property)
1374{
1375 QWSAddPropertyCommand cmd;
1376 cmd.simpleData.windowid = winId;
1377 cmd.simpleData.property = property;
1378 d->sendCommand(cmd);
1379}
1380
1381void QWSDisplay::setProperty(int winId, int property, int mode, const QByteArray &data)
1382{
1383 QWSSetPropertyCommand cmd;
1384 cmd.simpleData.windowid = winId;
1385 cmd.simpleData.property = property;
1386 cmd.simpleData.mode = mode;
1387 cmd.setData(data.constData(), data.size());
1388 d->sendCommand(cmd);
1389}
1390
1391void QWSDisplay::setProperty(int winId, int property, int mode,
1392 const char * data)
1393{
1394 QWSSetPropertyCommand cmd;
1395 cmd.simpleData.windowid = winId;
1396 cmd.simpleData.property = property;
1397 cmd.simpleData.mode = mode;
1398 cmd.setData(data, strlen(data));
1399 d->sendCommand(cmd);
1400}
1401
1402void QWSDisplay::removeProperty(int winId, int property)
1403{
1404 QWSRemovePropertyCommand cmd;
1405 cmd.simpleData.windowid = winId;
1406 cmd.simpleData.property = property;
1407 d->sendCommand(cmd);
1408}
1409
1410/*
1411 It is the caller's responsibility to delete[] \a data.
1412 */
1413bool QWSDisplay::getProperty(int winId, int property, char *&data, int &len)
1414{
1415 if (d->directServerConnection()) {
1416 const char *propertyData;
1417 bool retval = qwsServer->d_func()->get_property(winId, property, propertyData, len);
1418 if (len <= 0) {
1419 data = 0;
1420 } else {
1421 data = new char[len];
1422 memcpy(data, propertyData, len) ;
1423 }
1424 return retval;
1425 }
1426 QWSGetPropertyCommand cmd;
1427 cmd.simpleData.windowid = winId;
1428 cmd.simpleData.property = property;
1429 d->sendCommand(cmd);
1430
1431 getPropertyLen = -2;
1432 getPropertyData = 0;
1433
1434#ifndef QT_NO_QWS_MULTIPROCESS
1435 d->waitForPropertyReply();
1436#endif
1437
1438 len = getPropertyLen;
1439 data = getPropertyData;
1440
1441 getPropertyLen = -2;
1442 getPropertyData = 0;
1443
1444 return len != -1;
1445}
1446
1447#endif // QT_NO_QWS_PROPERTIES
1448
1449void QWSDisplay::setAltitude(int winId, int alt, bool fixed)
1450{
1451 QWSChangeAltitudeCommand cmd;
1452#ifdef QT_DEBUG
1453 memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
1454#endif
1455 cmd.simpleData.windowid = winId;
1456 cmd.simpleData.altitude = QWSChangeAltitudeCommand::Altitude(alt);
1457 cmd.simpleData.fixed = fixed;
1458 if (d->directServerConnection()) {
1459 qwsServer->d_func()->set_altitude(&cmd);
1460 } else {
1461 d->sendSynchronousCommand(cmd);
1462 }
1463}
1464
1465void QWSDisplay::setOpacity(int winId, int opacity)
1466{
1467 QWSSetOpacityCommand cmd;
1468 cmd.simpleData.windowid = winId;
1469 cmd.simpleData.opacity = opacity;
1470 if (d->directServerConnection()) {
1471 qwsServer->d_func()->set_opacity(&cmd);
1472 } else {
1473 d->sendCommand(cmd);
1474 }
1475}
1476
1477
1478
1479void QWSDisplay::requestFocus(int winId, bool get)
1480{
1481 QWSRequestFocusCommand cmd;
1482 cmd.simpleData.windowid = winId;
1483 cmd.simpleData.flag = get;
1484 if (d->directServerConnection())
1485 qwsServer->d_func()->request_focus(&cmd);
1486 else
1487 d->sendCommand(cmd);
1488}
1489
1490void QWSDisplay::setIdentity(const QString &appName)
1491{
1492 QWSIdentifyCommand cmd;
1493#ifdef QT_NO_QWS_MULTIPROCESS
1494 const int id = -1;
1495#else
1496 const int id = QWSDisplay::Data::clientLock ? QWSDisplay::Data::clientLock->id() : -1;
1497#endif
1498 cmd.setId(appName, id);
1499 if (d->directServerConnection())
1500 qwsServer->d_func()->set_identity(&cmd);
1501 else
1502 d->sendCommand(cmd);
1503}
1504
1505void QWSDisplay::nameRegion(int winId, const QString& n, const QString &c)
1506{
1507 QWSRegionNameCommand cmd;
1508 cmd.simpleData.windowid = winId;
1509 cmd.setName(n, c);
1510 if (d->directServerConnection())
1511 qwsServer->d_func()->name_region(&cmd);
1512 else
1513 d->sendCommand(cmd);
1514}
1515
1516void QWSDisplay::requestRegion(int winId, const QString &surfaceKey,
1517 const QByteArray &surfaceData,
1518 const QRegion &region)
1519{
1520 if (d->directServerConnection()) {
1521 qwsServer->d_func()->request_region(winId, surfaceKey,
1522 surfaceData, region);
1523 } else {
1524 QWSRegionCommand cmd;
1525 cmd.setData(winId, surfaceKey, surfaceData, region);
1526 d->sendSynchronousCommand(cmd);
1527 }
1528}
1529
1530void QWSDisplay::repaintRegion(int winId, int windowFlags, bool opaque, QRegion r)
1531{
1532 if (d->directServerConnection()) {
1533 qwsServer->d_func()->repaint_region(winId, windowFlags, opaque, r);
1534 } else {
1535 QVector<QRect> ra = r.rects();
1536
1537 /*
1538 for (int i = 0; i < ra.size(); i++) {
1539 QRect r(ra[i]);
1540 qDebug("rect: %d %d %d %d", r.x(), r.y(), r.right(), r.bottom());
1541 }
1542 */
1543
1544 QWSRepaintRegionCommand cmd;
1545 /* XXX QWSRegionCommand is padded out in a compiler dependent way.
1546 Zeroed out to avoid valgrind reporting uninitialized memory usage.
1547 */
1548#ifdef QT_DEBUG
1549 memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
1550#endif
1551 cmd.simpleData.windowid = winId;
1552 cmd.simpleData.windowFlags = windowFlags;
1553 cmd.simpleData.opaque = opaque;
1554 cmd.simpleData.nrectangles = ra.count();
1555 cmd.setData(reinterpret_cast<const char *>(ra.constData()),
1556 ra.count() * sizeof(QRect), false);
1557
1558 d->sendSynchronousCommand(cmd);
1559 }
1560}
1561
1562
1563void QWSDisplay::moveRegion(int winId, int dx, int dy)
1564{
1565 QWSRegionMoveCommand cmd;
1566 cmd.simpleData.windowid = winId;
1567 cmd.simpleData.dx = dx;
1568 cmd.simpleData.dy = dy;
1569
1570 if (d->directServerConnection()) {
1571 qwsServer->d_func()->move_region(&cmd);
1572 } else {
1573 d->sendSynchronousCommand(cmd);
1574 }
1575// d->offsetPendingExpose(winId, QPoint(cmd.simpleData.dx, cmd.simpleData.dy));
1576}
1577
1578void QWSDisplay::destroyRegion(int winId)
1579{
1580 QWSRegionDestroyCommand cmd;
1581 cmd.simpleData.windowid = winId;
1582 if (d->directServerConnection()) {
1583 qwsServer->d_func()->destroy_region(&cmd);
1584 } else {
1585 d->sendCommand(cmd);
1586 }
1587}
1588
1589#ifndef QT_NO_QWS_INPUTMETHODS
1590
1591void QWSDisplay::sendIMUpdate(int type, int winId, int widgetid)
1592{
1593 QWSIMUpdateCommand cmd;
1594 cmd.simpleData.windowid = winId;
1595 cmd.simpleData.widgetid = widgetid;
1596
1597 cmd.simpleData.type = type;
1598
1599 if (d->directServerConnection()) {
1600 qwsServer->d_func()->im_update(&cmd);
1601 } else {
1602 d->sendCommand(cmd);
1603 }
1604}
1605
1606void QWSDisplay::sendIMResponse(int winId, int property, const QVariant &result)
1607{
1608 QWSIMResponseCommand cmd;
1609 cmd.simpleData.windowid = winId;
1610 cmd.simpleData.property = property;
1611
1612 cmd.setResult(result);
1613
1614 if (d->directServerConnection()) {
1615 qwsServer->d_func()->im_response(&cmd);
1616 } else {
1617 d->sendCommand(cmd);
1618 }
1619}
1620
1621void QWSDisplay::resetIM()
1622{
1623 sendIMUpdate(QWSInputMethod::Reset, -1, -1);
1624}
1625
1626void QWSDisplay::sendIMMouseEvent(int index, bool isPress)
1627{
1628 QWSIMMouseCommand cmd;
1629 cmd.simpleData.index = index;
1630 cmd.simpleData.state = isPress ? QWSServer::MousePress : QWSServer::MouseRelease;
1631 if (d->directServerConnection()) {
1632 qwsServer->d_func()->send_im_mouse(&cmd);
1633 } else {
1634 d->sendCommand(cmd);
1635 }
1636}
1637
1638#endif
1639
1640int QWSDisplay::takeId()
1641{
1642 return d->takeId();
1643}
1644
1645bool QWSDisplay::initLock(const QString &filename, bool create)
1646{
1647 if (!lock) {
1648 lock = new QLock(filename, 'd', create);
1649
1650 if (!lock->isValid()) {
1651 delete lock;
1652 lock = 0;
1653 return false;
1654 }
1655 }
1656
1657 return true;
1658}
1659
1660void QWSDisplay::setSelectionOwner(int winId, const QTime &time)
1661{
1662 QWSSetSelectionOwnerCommand cmd;
1663 cmd.simpleData.windowid = winId;
1664 cmd.simpleData.hour = time.hour();
1665 cmd.simpleData.minute = time.minute();
1666 cmd.simpleData.sec = time.second();
1667 cmd.simpleData.ms = time.msec();
1668 d->sendCommand(cmd);
1669}
1670
1671void QWSDisplay::convertSelection(int winId, int selectionProperty, const QString &mimeTypes)
1672{
1673#ifdef QT_NO_QWS_PROPERTIES
1674 Q_UNUSED(mimeTypes);
1675#else
1676 // ### we need the atom/property thingy like in X here
1677 addProperty(winId, QT_QWS_PROPERTY_CONVERTSELECTION);
1678 setProperty(winId, QT_QWS_PROPERTY_CONVERTSELECTION,
1679 int(QWSPropertyManager::PropReplace), mimeTypes.toLatin1());
1680#endif
1681 QWSConvertSelectionCommand cmd;
1682 cmd.simpleData.requestor = winId;
1683 cmd.simpleData.selection = selectionProperty;
1684 cmd.simpleData.mimeTypes = QT_QWS_PROPERTY_CONVERTSELECTION;
1685 d->sendCommand(cmd);
1686}
1687
1688void QWSDisplay::defineCursor(int id, const QBitmap &curs, const QBitmap &mask,
1689 int hotX, int hotY)
1690{
1691 const QImage cursImg = curs.toImage().convertToFormat(QImage::Format_MonoLSB);
1692 const QImage maskImg = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
1693
1694 QWSDefineCursorCommand cmd;
1695 cmd.simpleData.width = curs.width();
1696 cmd.simpleData.height = curs.height();
1697 cmd.simpleData.hotX = hotX;
1698 cmd.simpleData.hotY = hotY;
1699 cmd.simpleData.id = id;
1700
1701
1702 // must copy each scanline since there might be gaps between them
1703 const int height = curs.height();
1704 const int width = curs.width();
1705 const int dst_bpl = (width + 7) / 8;
1706
1707 int dataLen = dst_bpl * height;
1708 uchar *data = new uchar[dataLen*2];
1709 uchar *dst = data;
1710
1711 int src_bpl = cursImg.bytesPerLine();
1712 const uchar *cursSrc = cursImg.bits();
1713 for (int i = 0; i < height; ++i) {
1714 memcpy(dst, cursSrc + i*src_bpl, dst_bpl);
1715 dst += dst_bpl;
1716 }
1717
1718 src_bpl = maskImg.bytesPerLine();
1719 const uchar *maskSrc = maskImg.bits();
1720 for (int i = 0; i < height; ++i) {
1721 memcpy(dst, maskSrc + i*src_bpl, dst_bpl);
1722 dst += dst_bpl;
1723 }
1724
1725 cmd.setData(reinterpret_cast<char*>(data), dataLen*2);
1726 delete [] data;
1727 d->sendCommand(cmd);
1728}
1729
1730void QWSDisplay::destroyCursor(int id)
1731{
1732 QWSDefineCursorCommand cmd;
1733 cmd.simpleData.width = 0;
1734 cmd.simpleData.height = 0;
1735 cmd.simpleData.hotX = 0;
1736 cmd.simpleData.hotY = 0;
1737 cmd.simpleData.id = id;
1738 cmd.setData(0, 0);
1739
1740 d->sendCommand(cmd);
1741}
1742
1743#ifndef QT_NO_SOUND
1744void QWSDisplay::playSoundFile(const QString& f)
1745{
1746 QWSPlaySoundCommand cmd;
1747 cmd.setFileName(f);
1748 d->sendCommand(cmd);
1749}
1750#endif
1751
1752#ifndef QT_NO_COP
1753void QWSDisplay::registerChannel(const QString& channel)
1754{
1755 QWSQCopRegisterChannelCommand reg;
1756 reg.setChannel(channel);
1757 qt_fbdpy->d->sendCommand(reg);
1758}
1759
1760void QWSDisplay::sendMessage(const QString &channel, const QString &msg,
1761 const QByteArray &data)
1762{
1763 QWSQCopSendCommand com;
1764 com.setMessage(channel, msg, data);
1765 qt_fbdpy->d->sendCommand(com);
1766}
1767
1768void QWSDisplay::flushCommands()
1769{
1770 qt_fbdpy->d->flushCommands();
1771}
1772
1773/*
1774 caller deletes result
1775*/
1776QWSQCopMessageEvent* QWSDisplay::waitForQCopResponse()
1777{
1778 qt_fbdpy->d->waitForQCopResponse();
1779 QWSQCopMessageEvent *e = static_cast<QWSQCopMessageEvent*>(qt_fbdpy->d->dequeue());
1780 Q_ASSERT(e->type == QWSEvent::QCopMessage);
1781 return e;
1782}
1783#endif
1784
1785void QWSDisplay::sendFontCommand(int type, const QByteArray &fontName)
1786{
1787 QWSFontCommand cmd;
1788 cmd.simpleData.type = type;
1789 cmd.setFontName(fontName);
1790 d->sendCommand(cmd);
1791}
1792
1793void QWSDisplay::setWindowCaption(QWidget *w, const QString &c)
1794{
1795 if (w->isWindow()) {
1796 nameRegion(w->internalWinId(), w->objectName(), c);
1797 static_cast<QETWidget *>(w)->repaintDecoration(qApp->desktop()->rect(), true);
1798 }
1799}
1800
1801void QWSDisplay::selectCursor(QWidget *w, unsigned int cursId)
1802{
1803 if (cursId != qt_last_cursor)
1804 {
1805 QWidget *top = w->window();
1806 qt_last_cursor = cursId;
1807 QWSSelectCursorCommand cmd;
1808 cmd.simpleData.windowid = top->internalWinId();
1809 cmd.simpleData.id = cursId;
1810 d->sendCommand(cmd);
1811 d->flush();
1812 }
1813}
1814
1815void QWSDisplay::setCursorPosition(int x, int y)
1816{
1817 QWSPositionCursorCommand cmd;
1818 cmd.simpleData.newX = x;
1819 cmd.simpleData.newY = y;
1820 d->sendCommand(cmd);
1821 d->flush();
1822}
1823
1824void QWSDisplay::grabMouse(QWidget *w, bool grab)
1825{
1826 QWidget *top = w->window();
1827 QWSGrabMouseCommand cmd;
1828#ifdef QT_DEBUG
1829 memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
1830#endif
1831 cmd.simpleData.windowid = top->winId();
1832 cmd.simpleData.grab = grab;
1833 d->sendCommand(cmd);
1834 d->flush();
1835}
1836
1837void QWSDisplay::grabKeyboard(QWidget *w, bool grab)
1838{
1839 QWidget *top = w->window();
1840 QWSGrabKeyboardCommand cmd;
1841#ifdef QT_DEBUG
1842 memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
1843#endif
1844 cmd.simpleData.windowid = top->winId();
1845 cmd.simpleData.grab = grab;
1846 d->sendCommand(cmd);
1847 d->flush();
1848}
1849
1850QList<QWSWindowInfo> QWSDisplay::windowList()
1851{
1852 QList<QWSWindowInfo> ret;
1853 if(d->directServerConnection()) {
1854 QList<QWSInternalWindowInfo*> * qin=QWSServer::windowList();
1855 for (int i = 0; i < qin->count(); ++i) {
1856 QWSInternalWindowInfo * qwi = qin->at(i);
1857 QWSWindowInfo tmp;
1858 tmp.winid = qwi->winid;
1859 tmp.clientid = qwi->clientid;
1860 tmp.name = QString(qwi->name);
1861 ret.append(tmp);
1862 }
1863 qDeleteAll(*qin);
1864 delete qin;
1865 }
1866 return ret;
1867}
1868
1869int QWSDisplay::windowAt(const QPoint &p)
1870{
1871 //### currently only implemented for the server process
1872 int ret = 0;
1873 if(d->directServerConnection()) {
1874 QWSWindow *win = qwsServer->windowAt(p);
1875 if (win)
1876 return win->winId();
1877 }
1878 return ret;
1879}
1880
1881void QWSDisplay::setRawMouseEventFilter(void (*filter)(QWSMouseEvent *))
1882{
1883 if (qt_fbdpy)
1884 qt_fbdpy->d->setMouseFilter(filter);
1885}
1886
1887/*!
1888 \relates QScreen
1889
1890 Here it is. \a transformation and \a screenNo
1891 */
1892void QWSDisplay::setTransformation(int transformation, int screenNo)
1893{
1894 QWSScreenTransformCommand cmd;
1895 cmd.setTransformation(screenNo, transformation);
1896 QWSDisplay::instance()->d->sendCommand(cmd);
1897}
1898
1899static bool qt_try_modal(QWidget *, QWSEvent *);
1900
1901/*****************************************************************************
1902 qt_init() - initializes Qt/FB
1903 *****************************************************************************/
1904
1905static void qt_set_qws_resources()
1906
1907{
1908 if (QApplication::desktopSettingsAware())
1909 QApplicationPrivate::qws_apply_settings();
1910
1911 if (appFont)
1912 QApplication::setFont(QFont(QString::fromLocal8Bit(appFont)));
1913
1914 if (appBGCol || appBTNCol || appFGCol) {
1915 (void) QApplication::style(); // trigger creation of application style and system palettes
1916 QColor btn;
1917 QColor bg;
1918 QColor fg;
1919 if (appBGCol)
1920 bg = QColor(appBGCol);
1921 else
1922 bg = QApplicationPrivate::sys_pal->color(QPalette::Window);
1923 if (appFGCol)
1924 fg = QColor(appFGCol);
1925 else
1926 fg = QApplicationPrivate::sys_pal->color(QPalette::WindowText);
1927 if (appBTNCol)
1928 btn = QColor(appBTNCol);
1929 else
1930 btn = QApplicationPrivate::sys_pal->color(QPalette::Button);
1931
1932 int h,s,v;
1933 fg.getHsv(&h,&s,&v);
1934 QColor base = Qt::white;
1935 bool bright_mode = false;
1936 if (v >= 255 - 50) {
1937 base = btn.darker(150);
1938 bright_mode = true;
1939 }
1940
1941 QPalette pal(fg, btn, btn.lighter(), btn.darker(), btn.darker(150), fg, Qt::white, base, bg);
1942 if (bright_mode) {
1943 pal.setColor(QPalette::HighlightedText, base);
1944 pal.setColor(QPalette::Highlight, Qt::white);
1945 } else {
1946 pal.setColor(QPalette::HighlightedText, Qt::white);
1947 pal.setColor(QPalette::Highlight, Qt::darkBlue);
1948 }
1949 QColor disabled((fg.red() + btn.red()) / 2,
1950 (fg.green() + btn.green())/ 2,
1951 (fg.blue() + btn.blue()) / 2);
1952 pal.setColorGroup(QPalette::Disabled, disabled, btn, btn.lighter(125),
1953 btn.darker(), btn.darker(150), disabled, Qt::white, Qt::white, bg);
1954 if (bright_mode) {
1955 pal.setColor(QPalette::Disabled, QPalette::HighlightedText, base);
1956 pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::white);
1957 } else {
1958 pal.setColor(QPalette::Disabled, QPalette::HighlightedText, Qt::white);
1959 pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
1960 }
1961 QApplicationPrivate::setSystemPalette(pal);
1962
1963 }
1964}
1965
1966void QApplicationPrivate::initializeWidgetPaletteHash()
1967{
1968}
1969
1970/*! \internal
1971 apply the settings to the application
1972*/
1973bool QApplicationPrivate::qws_apply_settings()
1974{
1975#ifndef QT_NO_SETTINGS
1976 QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
1977 settings.beginGroup(QLatin1String("Qt"));
1978
1979 QStringList strlist;
1980 int i;
1981 QPalette pal(Qt::black);
1982 int groupCount = 0;
1983 strlist = settings.value(QLatin1String("Palette/active")).toStringList();
1984 if (strlist.count() == QPalette::NColorRoles) {
1985 ++groupCount;
1986 for (i = 0; i < QPalette::NColorRoles; i++)
1987 pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
1988 QColor(strlist[i]));
1989 }
1990 strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
1991 if (strlist.count() == QPalette::NColorRoles) {
1992 ++groupCount;
1993 for (i = 0; i < QPalette::NColorRoles; i++)
1994 pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
1995 QColor(strlist[i]));
1996 }
1997 strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
1998 if (strlist.count() == QPalette::NColorRoles) {
1999 ++groupCount;
2000 for (i = 0; i < QPalette::NColorRoles; i++)
2001 pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
2002 QColor(strlist[i]));
2003 }
2004
2005
2006 if (groupCount == QPalette::NColorGroups)
2007 QApplicationPrivate::setSystemPalette(pal);
2008
2009 QString str = settings.value(QLatin1String("font")).toString();
2010 if (!str.isEmpty()) {
2011 QFont font(QApplication::font());
2012 font.fromString(str);
2013 QApplicationPrivate::setSystemFont(font);
2014 }
2015
2016 // read library (ie. plugin) path list
2017 QString libpathkey =
2018 QString::fromLatin1("%1.%2/libraryPath")
2019 .arg(QT_VERSION >> 16)
2020 .arg((QT_VERSION & 0xff00) >> 8);
2021 QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
2022#ifndef QT_NO_LIBRARY
2023 if (! pathlist.isEmpty()) {
2024 QStringList::ConstIterator it = pathlist.constBegin();
2025 while (it != pathlist.constEnd())
2026 QApplication::addLibraryPath(*it++);
2027 }
2028#endif
2029
2030 // read new QStyle
2031 QString stylename = settings.value(QLatin1String("style")).toString();
2032 if (QCoreApplication::startingUp()) {
2033 if (!stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull())
2034 QApplicationPrivate::styleOverride = stylename;
2035 } else {
2036 QApplication::setStyle(stylename);
2037 }
2038
2039 int num =
2040 settings.value(QLatin1String("doubleClickInterval"),
2041 QApplication::doubleClickInterval()).toInt();
2042 QApplication::setDoubleClickInterval(num);
2043
2044 num =
2045 settings.value(QLatin1String("cursorFlashTime"),
2046 QApplication::cursorFlashTime()).toInt();
2047 QApplication::setCursorFlashTime(num);
2048
2049#ifndef QT_NO_WHEELEVENT
2050 num =
2051 settings.value(QLatin1String("wheelScrollLines"),
2052 QApplication::wheelScrollLines()).toInt();
2053 QApplication::setWheelScrollLines(num);
2054#endif
2055
2056 QString colorspec = settings.value(QLatin1String("colorSpec"),
2057 QVariant(QLatin1String("default"))).toString();
2058 if (colorspec == QLatin1String("normal"))
2059 QApplication::setColorSpec(QApplication::NormalColor);
2060 else if (colorspec == QLatin1String("custom"))
2061 QApplication::setColorSpec(QApplication::CustomColor);
2062 else if (colorspec == QLatin1String("many"))
2063 QApplication::setColorSpec(QApplication::ManyColor);
2064 else if (colorspec != QLatin1String("default"))
2065 colorspec = QLatin1String("default");
2066
2067#ifndef QT_NO_TEXTCODEC
2068 QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
2069 QVariant(QLatin1String("none"))).toString();
2070 if (defaultcodec != QLatin1String("none")) {
2071 QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
2072 if (codec)
2073 QTextCodec::setCodecForTr(codec);
2074 }
2075#endif
2076
2077 int w = settings.value(QLatin1String("globalStrut/width")).toInt();
2078 int h = settings.value(QLatin1String("globalStrut/height")).toInt();
2079 QSize strut(w, h);
2080 if (strut.isValid())
2081 QApplication::setGlobalStrut(strut);
2082
2083 QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
2084 QApplication::setEffectEnabled(Qt::UI_General,
2085 effects.contains(QLatin1String("general")));
2086 QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
2087 effects.contains(QLatin1String("animatemenu")));
2088 QApplication::setEffectEnabled(Qt::UI_FadeMenu,
2089 effects.contains(QLatin1String("fademenu")));
2090 QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
2091 effects.contains(QLatin1String("animatecombo")));
2092 QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
2093 effects.contains(QLatin1String("animatetooltip")));
2094 QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
2095 effects.contains(QLatin1String("fadetooltip")));
2096 QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
2097 effects.contains(QLatin1String("animatetoolbox")));
2098
2099 settings.beginGroup(QLatin1String("Font Substitutions"));
2100 QStringList fontsubs = settings.childKeys();
2101 if (!fontsubs.isEmpty()) {
2102 QStringList::Iterator it = fontsubs.begin();
2103 for (; it != fontsubs.end(); ++it) {
2104 QString fam = *it;
2105 QStringList subs = settings.value(fam).toStringList();
2106 QFont::insertSubstitutions(fam, subs);
2107 }
2108 }
2109 settings.endGroup();
2110
2111 settings.endGroup(); // Qt
2112
2113 settings.beginGroup(QLatin1String("QWS Font Fallbacks"));
2114 if (!settings.childKeys().isEmpty()) {
2115 // from qfontdatabase_qws.cpp
2116 extern void qt_applyFontDatabaseSettings(const QSettings &);
2117 qt_applyFontDatabaseSettings(settings);
2118 }
2119 settings.endGroup();
2120
2121 return true;
2122#else
2123 return false;
2124#endif // QT_NO_SETTINGS
2125}
2126
2127
2128
2129static void init_display()
2130{
2131 if (qt_fbdpy) return; // workaround server==client case
2132
2133 // Connect to FB server
2134 qt_fbdpy = new QWSDisplay();
2135
2136 // Get display parameters
2137 // Set paintdevice parameters
2138 // XXX initial info sent from server
2139 // Misc. initialization
2140
2141 QColormap::initialize();
2142 QFont::initialize();
2143#ifndef QT_NO_CURSOR
2144 QCursorData::initialize();
2145#endif
2146
2147 qApp->setObjectName(appName);
2148
2149 if (!QApplicationPrivate::sys_font) {
2150#ifdef QT_NO_FREETYPE
2151 QFont f = QFont(QLatin1String("helvetica"), 10);
2152#else
2153 QFont f = QFont(QLatin1String("DejaVu Sans"), 12);
2154#endif
2155 QApplicationPrivate::setSystemFont(f);
2156 }
2157 qt_set_qws_resources();
2158}
2159
2160void qt_init_display()
2161{
2162 qt_is_gui_used = true;
2163 qws_single_process = true;
2164 init_display();
2165}
2166
2167static bool read_bool_env_var(const char *var, bool defaultvalue)
2168{
2169 // returns true if env variable is set to non-zero
2170 // returns false if env var is set to zero
2171 // returns defaultvalue if env var not set
2172 char *x = ::getenv(var);
2173 return (x && *x) ? (strcmp(x,"0") != 0) : defaultvalue;
2174}
2175
2176static int read_int_env_var(const char *var, int defaultvalue)
2177{
2178 bool ok;
2179 int r = qgetenv(var).toInt(&ok);
2180 return ok ? r : defaultvalue;
2181}
2182
2183void qt_init(QApplicationPrivate *priv, int type)
2184{
2185#ifdef QT_NO_QWS_MULTIPROCESS
2186 if (type == QApplication::GuiClient)
2187 type = QApplication::GuiServer;
2188#endif
2189 if (type == QApplication::GuiServer)
2190 qt_is_gui_used = false; //we'll turn it on in a second
2191 qws_sw_cursor = read_bool_env_var("QWS_SW_CURSOR",qws_sw_cursor);
2192 qws_screen_is_interlaced = read_bool_env_var("QWS_INTERLACE",false);
2193
2194 const char *display = ::getenv("QWS_DISPLAY");
2195 if (display)
2196 qws_display_spec = display; // since we setenv later!
2197
2198 //qws_savefonts = qgetenv("QWS_SAVEFONTS") != 0;
2199 //qws_shared_memory = qgetenv("QWS_NOSHARED") == 0;
2200
2201 mouse_double_click_distance = read_int_env_var("QWS_DBLCLICK_DISTANCE", 5);
2202
2203 priv->inputContext = 0;
2204
2205 int flags = 0;
2206 char *p;
2207 int argc = priv->argc;
2208 char **argv = priv->argv;
2209 int j;
2210
2211 // Set application name
2212
2213 if (argv && *argv) { //apparently, we allow people to pass 0 on the other platforms
2214 p = strrchr(argv[0], '/');
2215 appName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
2216 }
2217
2218 // Get command line params
2219
2220 j = argc ? 1 : 0;
2221 QString decoration;
2222 for (int i=1; i<argc; i++) {
2223 if (argv[i] && *argv[i] != '-') {
2224 argv[j++] = argv[i];
2225 continue;
2226 }
2227 QByteArray arg = argv[i];
2228 if (arg == "-fn" || arg == "-font") {
2229 if (++i < argc)
2230 appFont = argv[i];
2231 } else if (arg == "-bg" || arg == "-background") {
2232 if (++i < argc)
2233 appBGCol = argv[i];
2234 } else if (arg == "-btn" || arg == "-button") {
2235 if (++i < argc)
2236 appBTNCol = argv[i];
2237 } else if (arg == "-fg" || arg == "-foreground") {
2238 if (++i < argc)
2239 appFGCol = argv[i];
2240 } else if (arg == "-name") {
2241 if (++i < argc)
2242 appName = QString::fromLocal8Bit(argv[i]);
2243 } else if (arg == "-title") {
2244 if (++i < argc)
2245 mwTitle = argv[i];
2246 } else if (arg == "-geometry") {
2247 if (++i < argc)
2248 mwGeometry = argv[i];
2249 } else if (arg == "-shared") {
2250 qws_shared_memory = true;
2251 } else if (arg == "-noshared") {
2252 qws_shared_memory = false;
2253 } else if (arg == "-savefonts") {
2254 qws_savefonts = true;
2255 } else if (arg == "-nosavefonts") {
2256 qws_savefonts = false;
2257 } else if (arg == "-swcursor") {
2258 qws_sw_cursor = true;
2259 } else if (arg == "-noswcursor") {
2260 qws_sw_cursor = false;
2261 } else if (arg == "-keyboard") {
2262 flags &= ~QWSServer::DisableKeyboard;
2263 } else if (arg == "-nokeyboard") {
2264 flags |= QWSServer::DisableKeyboard;
2265 } else if (arg == "-mouse") {
2266 flags &= ~QWSServer::DisableMouse;
2267 } else if (arg == "-nomouse") {
2268 flags |= QWSServer::DisableMouse;
2269 } else if (arg == "-qws") {
2270 type = QApplication::GuiServer;
2271 } else if (arg == "-interlaced") {
2272 qws_screen_is_interlaced = true;
2273 } else if (arg == "-display") {
2274 if (++i < argc)
2275 qws_display_spec = argv[i];
2276 } else if (arg == "-decoration") {
2277 if (++i < argc)
2278 decoration = QString::fromLocal8Bit(argv[i]);
2279 } else {
2280 argv[j++] = argv[i];
2281 }
2282 }
2283 if(j < priv->argc) {
2284 priv->argv[j] = 0;
2285 priv->argc = j;
2286 }
2287
2288 mouseInWidget = new QPointer<QWidget>;
2289
2290 const QString disp = QString::fromLatin1(qws_display_spec);
2291 QRegExp regexp(QLatin1String(":(\\d+)$"));
2292 if (regexp.lastIndexIn(disp) != -1) {
2293 const QString capture = regexp.cap(1);
2294 bool ok = false;
2295 int id = capture.toInt(&ok);
2296 if (ok)
2297 qws_display_id = id;
2298 }
2299
2300 if (type == QApplication::GuiServer) {
2301 qt_appType = QApplication::Type(type);
2302 qws_single_process = true;
2303 QWSServer::startup(flags);
2304 if (!display) // if not already set
2305 qputenv("QWS_DISPLAY", qws_display_spec);
2306 }
2307
2308 if(qt_is_gui_used) {
2309 init_display();
2310#ifndef QT_NO_QWS_MANAGER
2311 if (decoration.isEmpty() && !qws_decoration) {
2312 const QStringList keys = QDecorationFactory::keys();
2313 if (!keys.isEmpty())
2314 decoration = keys.first();
2315 }
2316 if (!decoration.isEmpty())
2317 qws_decoration = QApplication::qwsSetDecoration(decoration);
2318#endif // QT_NO_QWS_MANAGER
2319#ifndef QT_NO_QWS_INPUTMETHODS
2320 qApp->setInputContext(new QWSInputContext(qApp));
2321#endif
2322 }
2323
2324/*### convert interlace style
2325 if (qws_screen_is_interlaced)
2326 QApplication::setStyle(new QInterlaceStyle);
2327*/
2328}
2329
2330/*****************************************************************************
2331 qt_cleanup() - cleans up when the application is finished
2332 *****************************************************************************/
2333
2334void qt_cleanup()
2335{
2336 QPixmapCache::clear();
2337#ifndef QT_NO_CURSOR
2338 QCursorData::cleanup();
2339#endif
2340 QFont::cleanup();
2341 QColormap::cleanup();
2342
2343 if (qws_single_process) {
2344 QWSServer::closedown();
2345 }
2346
2347 qDeleteAll(outgoing);
2348 outgoing.clear();
2349 qDeleteAll(incoming);
2350 incoming.clear();
2351
2352 if (qt_is_gui_used) {
2353 delete qt_fbdpy;
2354 }
2355 qt_fbdpy = 0;
2356
2357#ifndef QT_NO_QWS_MANAGER
2358 delete qws_decoration;
2359 qws_decoration = 0;
2360#endif
2361
2362 delete mouseInWidget;
2363 mouseInWidget = 0;
2364
2365#if !defined(QT_NO_IM)
2366 delete QApplicationPrivate::inputContext;
2367 QApplicationPrivate::inputContext = 0;
2368#endif
2369}
2370
2371
2372/*****************************************************************************
2373 Platform specific global and internal functions
2374 *****************************************************************************/
2375
2376QString QApplicationPrivate::appName() const // get application name
2377{
2378 return QT_PREPEND_NAMESPACE(appName);
2379}
2380
2381/*****************************************************************************
2382 Platform specific QApplication members
2383 *****************************************************************************/
2384
2385#define NoValue 0x0000
2386#define XValue 0x0001
2387#define YValue 0x0002
2388#define WidthValue 0x0004
2389#define HeightValue 0x0008
2390#define AllValues 0x000F
2391#define XNegative 0x0010
2392#define YNegative 0x0020
2393
2394/* Copyright notice for ReadInteger and parseGeometry
2395
2396Copyright (c) 1985, 1986, 1987 X Consortium
2397
2398Permission is hereby granted, free of charge, to any person obtaining
2399a copy of this software and associated documentation files (the
2400"Software"), to deal in the Software without restriction, including
2401without limitation the rights to use, copy, modify, merge, publish,
2402distribute, sublicense, and/or sell copies of the Software, and to
2403permit persons to whom the Software is furnished to do so, subject to
2404the following conditions:
2405
2406The above copyright notice and this permission notice shall be included
2407in all copies or substantial portions of the Software.
2408
2409THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2410OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2411MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2412IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
2413OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2414ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2415OTHER DEALINGS IN THE SOFTWARE.
2416
2417Except as contained in this notice, the name of the X Consortium shall
2418not be used in advertising or otherwise to promote the sale, use or
2419other dealings in this Software without prior written authorization
2420from the X Consortium.
2421
2422*/
2423/*
2424 * XParseGeometry parses strings of the form
2425 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
2426 * width, height, xoffset, and yoffset are unsigned integers.
2427 * Example: "=80x24+300-49"
2428 * The equal sign is optional.
2429 * It returns a bitmask that indicates which of the four values
2430 * were actually found in the string. For each value found,
2431 * the corresponding argument is updated; for each value
2432 * not found, the corresponding argument is left unchanged.
2433 */
2434
2435static int
2436ReadInteger(char *string, char **NextString)
2437{
2438 register int Result = 0;
2439 int Sign = 1;
2440
2441 if (*string == '+')
2442 string++;
2443 else if (*string == '-')
2444 {
2445 string++;
2446 Sign = -1;
2447 }
2448 for (; (*string >= '0') && (*string <= '9'); string++)
2449 {
2450 Result = (Result * 10) + (*string - '0');
2451 }
2452 *NextString = string;
2453 if (Sign >= 0)
2454 return Result;
2455 else
2456 return -Result;
2457}
2458
2459static int parseGeometry(const char* string,
2460 int* x, int* y, int* width, int* height)
2461{
2462 int mask = NoValue;
2463 register char *strind;
2464 unsigned int tempWidth=0, tempHeight=0;
2465 int tempX=0, tempY=0;
2466 char *nextCharacter;
2467
2468 if (!string || (*string == '\0')) return mask;
2469 if (*string == '=')
2470 string++; /* ignore possible '=' at beg of geometry spec */
2471
2472 strind = const_cast<char *>(string);
2473 if (*strind != '+' && *strind != '-' && *strind != 'x') {
2474 tempWidth = ReadInteger(strind, &nextCharacter);
2475 if (strind == nextCharacter)
2476 return 0;
2477 strind = nextCharacter;
2478 mask |= WidthValue;
2479 }
2480
2481 if (*strind == 'x' || *strind == 'X') {
2482 strind++;
2483 tempHeight = ReadInteger(strind, &nextCharacter);
2484 if (strind == nextCharacter)
2485 return 0;
2486 strind = nextCharacter;
2487 mask |= HeightValue;
2488 }
2489
2490 if ((*strind == '+') || (*strind == '-')) {
2491 if (*strind == '-') {
2492 strind++;
2493 tempX = -ReadInteger(strind, &nextCharacter);
2494 if (strind == nextCharacter)
2495 return 0;
2496 strind = nextCharacter;
2497 mask |= XNegative;
2498
2499 }
2500 else
2501 { strind++;
2502 tempX = ReadInteger(strind, &nextCharacter);
2503 if (strind == nextCharacter)
2504 return 0;
2505 strind = nextCharacter;
2506 }
2507 mask |= XValue;
2508 if ((*strind == '+') || (*strind == '-')) {
2509 if (*strind == '-') {
2510 strind++;
2511 tempY = -ReadInteger(strind, &nextCharacter);
2512 if (strind == nextCharacter)
2513 return 0;
2514 strind = nextCharacter;
2515 mask |= YNegative;
2516
2517 }
2518 else
2519 {
2520 strind++;
2521 tempY = ReadInteger(strind, &nextCharacter);
2522 if (strind == nextCharacter)
2523 return 0;
2524 strind = nextCharacter;
2525 }
2526 mask |= YValue;
2527 }
2528 }
2529
2530 /* If strind isn't at the end of the string then it's an invalid
2531 geometry specification. */
2532
2533 if (*strind != '\0') return 0;
2534
2535 if (mask & XValue)
2536 *x = tempX;
2537 if (mask & YValue)
2538 *y = tempY;
2539 if (mask & WidthValue)
2540 *width = tempWidth;
2541 if (mask & HeightValue)
2542 *height = tempHeight;
2543 return mask;
2544}
2545
2546#ifdef QT3_SUPPORT
2547void QApplication::setMainWidget(QWidget *mainWidget)
2548{
2549 QApplicationPrivate::main_widget = mainWidget;
2550 if (QApplicationPrivate::main_widget) // give WM command line
2551 QApplicationPrivate::applyQWSSpecificCommandLineArguments(QApplicationPrivate::main_widget);
2552}
2553#endif
2554
2555void QApplicationPrivate::applyQWSSpecificCommandLineArguments(QWidget *main_widget)
2556{
2557 static bool beenHereDoneThat = false;
2558 if (beenHereDoneThat)
2559 return;
2560 beenHereDoneThat = true;
2561 if (qApp->windowIcon().isNull() && main_widget->testAttribute(Qt::WA_SetWindowIcon))
2562 qApp->setWindowIcon(main_widget->windowIcon());
2563 if (mwTitle) // && main_widget->windowTitle().isEmpty())
2564 main_widget->setWindowTitle(QString::fromLocal8Bit(mwTitle));
2565 if (mwGeometry) { // parse geometry
2566 int x = 0;
2567 int y = 0;
2568 int w = 0;
2569 int h = 0;
2570 int m = parseGeometry(mwGeometry, &x, &y, &w, &h);
2571 QSize minSize = main_widget->minimumSize();
2572 QSize maxSize = main_widget->maximumSize();
2573 if ((m & XValue) == 0)
2574 x = main_widget->geometry().x();
2575 if ((m & YValue) == 0)
2576 y = main_widget->geometry().y();
2577 if ((m & WidthValue) == 0)
2578 w = main_widget->width();
2579 if ((m & HeightValue) == 0)
2580 h = main_widget->height();
2581 w = qMin(w,maxSize.width());
2582 h = qMin(h,maxSize.height());
2583 w = qMax(w,minSize.width());
2584 h = qMax(h,minSize.height());
2585 if ((m & XNegative)) {
2586 x = qApp->desktop()->width() + x - w;
2587 x -= (main_widget->frameGeometry().width() - main_widget->width()) / 2;
2588 } else {
2589 x += (main_widget->geometry().x() - main_widget->x());
2590 }
2591 if ((m & YNegative)) {
2592 y = qApp->desktop()->height() + y - h;
2593 } else {
2594 y += (main_widget->geometry().y() - main_widget->y());
2595 }
2596
2597 main_widget->setGeometry(x, y, w, h);
2598 }
2599}
2600
2601/*****************************************************************************
2602 QApplication cursor stack
2603 *****************************************************************************/
2604#ifndef QT_NO_CURSOR
2605void QApplication::setOverrideCursor(const QCursor &cursor)
2606{
2607 qApp->d_func()->cursor_list.prepend(cursor);
2608
2609 QWidget *w = QWidget::mouseGrabber();
2610 if (!w && qt_last_x)
2611 w = topLevelAt(*qt_last_x, *qt_last_y);
2612 if (!w)
2613 w = desktop();
2614 QPaintDevice::qwsDisplay()->selectCursor(w, qApp->d_func()->cursor_list.first().handle());
2615}
2616
2617void QApplication::restoreOverrideCursor()
2618{
2619 if (qApp->d_func()->cursor_list.isEmpty())
2620 return;
2621 qApp->d_func()->cursor_list.removeFirst();
2622
2623 QWidget *w = QWidget::mouseGrabber();
2624 if (!w && qt_last_x)
2625 w = topLevelAt(*qt_last_x, *qt_last_y);
2626 if (!w)
2627 w = desktop();
2628
2629 int cursor_handle = Qt::ArrowCursor;
2630 if (qApp->d_func()->cursor_list.isEmpty()) {
2631 qws_overrideCursor = false;
2632 QWidget *upw = QApplication::widgetAt(*qt_last_x, *qt_last_y);
2633 if (upw)
2634 cursor_handle = upw->cursor().handle();
2635 } else {
2636 cursor_handle = qApp->d_func()->cursor_list.first().handle();
2637 }
2638 QPaintDevice::qwsDisplay()->selectCursor(w, cursor_handle);
2639}
2640#endif// QT_NO_CURSOR
2641
2642
2643
2644/*****************************************************************************
2645 Routines to find a Qt widget from a screen position
2646 *****************************************************************************/
2647
2648/*!
2649 \internal
2650*/
2651QWidget *QApplicationPrivate::findWidget(const QObjectList& list,
2652 const QPoint &pos, bool rec)
2653{
2654 QWidget *w;
2655
2656 for (int i = list.size()-1; i >= 0; --i) {
2657 if (list.at(i)->isWidgetType()) {
2658 w = static_cast<QWidget*>(list.at(i));
2659 if (w->isVisible() && !w->testAttribute(Qt::WA_TransparentForMouseEvents) && w->geometry().contains(pos)
2660 && (!w->d_func()->extra || w->d_func()->extra->mask.isEmpty() || w->d_func()->extra->mask.contains(pos - w->geometry().topLeft()) )) {
2661 if (!rec)
2662 return w;
2663 QWidget *c = w->childAt(w->mapFromParent(pos));
2664 return c ? c : w;
2665 }
2666 }
2667 }
2668 return 0;
2669}
2670
2671
2672QWidget *QApplication::topLevelAt(const QPoint &pos)
2673{
2674 //### QWSDisplay::windowAt() is currently only implemented in the server process
2675 int winId = QPaintDevice::qwsDisplay()->windowAt(pos);
2676 if (winId !=0)
2677 return QWidget::find(winId);
2678
2679#if 1
2680 // fallback implementation for client processes
2681//### This is slightly wrong: we have no guarantee that the list is in
2682//### stacking order, so if the topmost window is transparent, we may
2683//### return the wrong widget
2684
2685 QWidgetList list = topLevelWidgets();
2686 for (int i = list.size()-1; i >= 0; --i) {
2687 QWidget *w = list[i];
2688 if (w != QApplication::desktop() &&
2689 w->isVisible() && w->d_func()->localAllocatedRegion().contains(w->mapFromParent(pos))
2690 )
2691 return w;
2692 }
2693#endif
2694 return 0;
2695}
2696
2697void QApplication::beep()
2698{
2699}
2700
2701void QApplication::alert(QWidget *, int)
2702{
2703}
2704
2705int QApplication::qwsProcessEvent(QWSEvent* event)
2706{
2707 Q_D(QApplication);
2708 QScopedLoopLevelCounter loopLevelCounter(d->threadData);
2709 int oldstate = -1;
2710 bool isMove = false;
2711 if (event->type == QWSEvent::Mouse) {
2712 QWSMouseEvent::SimpleData &mouse = event->asMouse()->simpleData;
2713 isMove = mouse_x_root != mouse.x_root || mouse_y_root != mouse.y_root;
2714 oldstate = mouse_state;
2715 mouse_x_root = mouse.x_root;
2716 mouse_y_root = mouse.y_root;
2717 mouse_state = mouse.state;
2718 }
2719
2720 long unused;
2721 if (filterEvent(event, &unused)) // send through app filter
2722 return 1;
2723
2724 if (qwsEventFilter(event)) // send through app filter
2725 return 1;
2726
2727
2728#ifndef QT_NO_QWS_PROPERTIES
2729 if (event->type == QWSEvent::PropertyNotify) {
2730 QWSPropertyNotifyEvent *e = static_cast<QWSPropertyNotifyEvent*>(event);
2731 if (e->simpleData.property == 424242) { // Clipboard
2732#ifndef QT_NO_CLIPBOARD
2733 if (qt_clipboard) {
2734 QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
2735 QApplication::sendEvent(qt_clipboard, &e);
2736 }
2737#endif
2738 }
2739 }
2740#endif //QT_NO_QWS_PROPERTIES
2741#ifndef QT_NO_COP
2742 else if (event->type == QWSEvent::QCopMessage) {
2743 QWSQCopMessageEvent *e = static_cast<QWSQCopMessageEvent*>(event);
2744 QCopChannel::sendLocally(QLatin1String(e->channel), QLatin1String(e->message), e->data);
2745 return 0;
2746 }
2747#endif
2748#if !defined(QT_NO_QWS_QPF2)
2749 else if (event->type == QWSEvent::Font) {
2750 QWSFontEvent *e = static_cast<QWSFontEvent *>(event);
2751 if (e->simpleData.type == QWSFontEvent::FontRemoved) {
2752 QFontCache::instance()->removeEngineForFont(e->fontName);
2753 }
2754 }
2755#endif
2756
2757 QPointer<QETWidget> widget = static_cast<QETWidget*>(QWidget::find(WId(event->window())));
2758#ifdef Q_BACKINGSTORE_SUBSURFACES
2759 if (!widget) { // XXX: hw: hack for accessing subsurfaces
2760 extern QWSWindowSurface* qt_findWindowSurface(int);
2761 QWSWindowSurface *s = qt_findWindowSurface(event->window());
2762 if (s)
2763 widget = static_cast<QETWidget*>(s->window());
2764 }
2765#endif
2766
2767#ifndef QT_NO_DIRECTPAINTER
2768 if (!widget && d->directPainters) {
2769 QDirectPainter *dp = d->directPainters->value(WId(event->window()));
2770 if (dp == 0) {
2771 } else if (event->type == QWSEvent::Region) {
2772 QWSRegionEvent *e = static_cast<QWSRegionEvent*>(event);
2773 QRegion reg;
2774 reg.setRects(e->rectangles, e->simpleData.nrectangles);
2775 qt_directpainter_region(dp, reg, e->simpleData.type);
2776 return 1;
2777#ifndef QT_NO_QWSEMBEDWIDGET
2778 } else if (event->type == QWSEvent::Embed) {
2779 QWSEmbedEvent *e = static_cast<QWSEmbedEvent*>(event);
2780 qt_directpainter_embedevent(dp, e);
2781 return 1;
2782 #endif // QT_NO_QWSEMBEDWIDGET
2783 }
2784 }
2785#endif // QT_NO_DIRECTPAINTER
2786
2787#ifndef QT_NO_QWS_MANAGER
2788 if (d->last_manager && event->type == QWSEvent::Mouse) {
2789 QPoint pos(event->asMouse()->simpleData.x_root, event->asMouse()->simpleData.y_root);
2790 if (!d->last_manager->cachedRegion().contains(pos)) {
2791 // MouseEvent not yet delivered, so QCursor::pos() is not yet updated, sending 2 x pos
2792 QMouseEvent outside(QEvent::MouseMove, pos, pos, Qt::NoButton, 0, 0);
2793 QApplication::sendSpontaneousEvent(d->last_manager, &outside);
2794 d->last_manager = 0;
2795 qt_last_cursor = 0xffffffff; //decoration is like another window; must redo cursor
2796 }
2797 }
2798#endif // QT_NO_QWS_MANAGER
2799
2800 QETWidget *keywidget=0;
2801 bool grabbed=false;
2802 if (event->type==QWSEvent::Key || event->type == QWSEvent::IMEvent || event->type == QWSEvent::IMQuery) {
2803 keywidget = static_cast<QETWidget*>(QWidget::keyboardGrabber());
2804 if (keywidget) {
2805 grabbed = true;
2806 } else {
2807 if (QWidget *popup = QApplication::activePopupWidget()) {
2808 if (popup->focusWidget())
2809 keywidget = static_cast<QETWidget*>(popup->focusWidget());
2810 else
2811 keywidget = static_cast<QETWidget*>(popup);
2812 } else if (QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget->isVisible())
2813 keywidget = static_cast<QETWidget*>(QApplicationPrivate::focus_widget);
2814 else if (widget)
2815 keywidget = static_cast<QETWidget*>(widget->window());
2816 }
2817 } else if (event->type==QWSEvent::MaxWindowRect) {
2818 QRect r = static_cast<QWSMaxWindowRectEvent*>(event)->simpleData.rect;
2819 setMaxWindowRect(r);
2820 return 0;
2821#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
2822 } else if (event->type == QWSEvent::ScreenTransformation) {
2823 QWSScreenTransformationEvent *pe = static_cast<QWSScreenTransformationEvent*>(event);
2824 setScreenTransformation(pe->simpleData.screen,
2825 pe->simpleData.transformation);
2826 return 0;
2827#endif
2828 } else if (widget && event->type==QWSEvent::Mouse) {
2829 // The mouse event is to one of my top-level widgets
2830 // which one?
2831 const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton;
2832 QPoint p(event->asMouse()->simpleData.x_root,
2833 event->asMouse()->simpleData.y_root);
2834 int mouseButtonState = event->asMouse()->simpleData.state & btnMask;
2835 static int btnstate = 0;
2836
2837 QETWidget *w = static_cast<QETWidget*>(QWidget::mouseGrabber());
2838 if (w && !mouseButtonState && qt_pressGrab == w)
2839 qt_pressGrab = 0;
2840#ifndef QT_NO_QWS_MANAGER
2841 if (!w)
2842 w = static_cast<QETWidget*>(QWSManager::grabbedMouse());
2843#endif
2844 if (w) {
2845 // Our mouse is grabbed - send it.
2846 widget = w;
2847 btnstate = mouseButtonState;
2848 } else {
2849 static QWidget *gw = 0;
2850 // Three jobs to do here:
2851 // 1. find the child widget this event belongs to.
2852 // 2. make sure the cursor is correct.
2853 // 3. handle implicit mouse grab due to button press.
2854 w = widget; // w is the widget the cursor is in.
2855
2856 //### ??? alloc_region
2857 //#### why should we get events outside alloc_region ????
2858 if (1 /*widget->data->alloc_region.contains(dp) */) {
2859 // Find the child widget that the cursor is in.
2860 w = static_cast<QETWidget*>(widget->childAt(widget->mapFromParent(p)));
2861 if (!w)
2862 w = widget;
2863#ifndef QT_NO_CURSOR
2864 // Update Cursor.
2865 if (!gw || gw != w || qt_last_cursor == 0xffffffff) {
2866 QCursor *curs = 0;
2867 if (!qApp->d_func()->cursor_list.isEmpty())
2868 curs = &qApp->d_func()->cursor_list.first();
2869 else if (w->d_func()->extraData())
2870 curs = w->d_func()->extraData()->curs;
2871 QWidget *pw = w;
2872 // If this widget has no cursor set, try parent.
2873 while (!curs) {
2874 pw = pw->parentWidget();
2875 if (!pw)
2876 break;
2877 if (pw->d_func()->extraData())
2878 curs = pw->d_func()->extraData()->curs;
2879 }
2880 if (!qws_overrideCursor) {
2881 if (curs)
2882 QPaintDevice::qwsDisplay()->selectCursor(widget, curs->handle());
2883 else
2884 QPaintDevice::qwsDisplay()->selectCursor(widget, Qt::ArrowCursor);
2885 }
2886 }
2887#endif
2888 gw = w;
2889 } else {
2890 // This event is not for any of our widgets
2891 gw = 0;
2892 }
2893 if (mouseButtonState && !btnstate) {
2894 // The server has grabbed the mouse for us.
2895 // Remember which of my widgets has it.
2896 qt_pressGrab = w;
2897 if (!widget->isActiveWindow() &&
2898 (!app_do_modal || QApplication::activeModalWidget() == widget) &&
2899 !((widget->windowFlags() & Qt::FramelessWindowHint) || (widget->windowType() == Qt::Tool))) {
2900 widget->activateWindow();
2901 if (widget->raiseOnClick())
2902 widget->raise();
2903 }
2904 }
2905 btnstate = mouseButtonState;
2906 widget = w;
2907 }
2908 }
2909
2910 if (!widget) { // don't know this window
2911 if (!QWidget::mouseGrabber()
2912#ifndef QT_NO_QWS_MANAGER
2913 && !QWSManager::grabbedMouse()
2914#endif
2915 ) {
2916 qt_last_cursor = 0xffffffff; // cursor can be changed by another application
2917 }
2918
2919 QWidget* popup = QApplication::activePopupWidget();
2920 if (popup) {
2921
2922 /*
2923 That is more than suboptimal. The real solution should
2924 do some keyevent and buttonevent translation, so that
2925 the popup still continues to work as the user expects.
2926 Unfortunately this translation is currently only
2927 possible with a known widget. I'll change that soon
2928 (Matthias).
2929 */
2930
2931 // Danger - make sure we don't lock the server
2932 switch (event->type) {
2933 case QWSEvent::Mouse:
2934 case QWSEvent::Key:
2935 do {
2936 popup->close();
2937 } while ((popup = qApp->activePopupWidget()));
2938 return 1;
2939 }
2940 }
2941 if (event->type == QWSEvent::Mouse && *mouseInWidget) {
2942 QApplicationPrivate::dispatchEnterLeave(0, *mouseInWidget);
2943 (*mouseInWidget) = 0;
2944 }
2945 return -1;
2946 }
2947
2948 if (app_do_modal) // modal event handling
2949 if (!qt_try_modal(widget, event)) {
2950 return 1;
2951 }
2952
2953 if (widget->qwsEvent(event)) // send through widget filter
2954 return 1;
2955 switch (event->type) {
2956
2957 case QWSEvent::Mouse: { // mouse event
2958 QWSMouseEvent *me = event->asMouse();
2959 QWSMouseEvent::SimpleData &mouse = me->simpleData;
2960
2961 // Translate a QWS event into separate move
2962 // and press/release events
2963 // Beware of reentrancy: we can enter a modal state
2964 // inside translateMouseEvent
2965
2966 if (isMove) {
2967 QWSMouseEvent move = *me;
2968 move.simpleData.state = oldstate;
2969 widget->translateMouseEvent(&move, oldstate);
2970 }
2971 if ((mouse.state&Qt::MouseButtonMask) != (oldstate&Qt::MouseButtonMask)) {
2972 widget->translateMouseEvent(me, oldstate);
2973 }
2974
2975 if (mouse.delta != 0)
2976 widget->translateWheelEvent(me);
2977
2978 if (qt_button_down && (mouse_state & Qt::MouseButtonMask) == 0)
2979 qt_button_down = 0;
2980
2981 break;
2982 }
2983 case QWSEvent::Key: // keyboard event
2984 if (keywidget) // should always exist
2985 keywidget->translateKeyEvent(static_cast<QWSKeyEvent*>(event), grabbed);
2986 break;
2987
2988#ifndef QT_NO_QWS_INPUTMETHODS
2989 case QWSEvent::IMEvent:
2990 if (keywidget) // should always exist
2991 QWSInputContext::translateIMEvent(keywidget, static_cast<QWSIMEvent*>(event));
2992 break;
2993
2994 case QWSEvent::IMQuery:
2995 if (keywidget) // should always exist
2996 QWSInputContext::translateIMQueryEvent(keywidget, static_cast<QWSIMQueryEvent*>(event));
2997 break;
2998
2999 case QWSEvent::IMInit:
3000 QWSInputContext::translateIMInitEvent(static_cast<QWSIMInitEvent*>(event));
3001 break;
3002#endif
3003 case QWSEvent::Region:
3004 widget->translateRegionEvent(static_cast<QWSRegionEvent*>(event));
3005 break;
3006 case QWSEvent::Focus:
3007 if ((static_cast<QWSFocusEvent*>(event))->simpleData.get_focus) {
3008 if (widget == static_cast<QWidget *>(desktop()))
3009 return true; // not interesting
3010 if (activeWindow() != widget) {
3011 setActiveWindow(widget);
3012 if (QApplicationPrivate::active_window)
3013 static_cast<QETWidget *>(QApplicationPrivate::active_window)->repaintDecoration(desktop()->rect(), false);
3014 if (widget && !d->inPopupMode()) {
3015 QWidget *w = widget->focusWidget();
3016 while (w && w->focusProxy())
3017 w = w->focusProxy();
3018 if (w && (w->focusPolicy() != Qt::NoFocus))
3019 w->setFocus();
3020 else
3021 widget->QWidget::focusNextPrevChild(true);
3022 if (!QApplicationPrivate::focus_widget) {
3023 if (widget->focusWidget())
3024 widget->focusWidget()->setFocus();
3025 else
3026 widget->window()->setFocus();
3027 }
3028 }
3029 }
3030 } else { // lost focus
3031 if (widget == static_cast<QWidget *>(desktop()))
3032 return true; // not interesting
3033 if (QApplicationPrivate::focus_widget) {
3034 QETWidget *old = static_cast<QETWidget *>(QApplicationPrivate::active_window);
3035 setActiveWindow(0);
3036 qt_last_cursor = 0xffffffff;
3037 //QApplicationPrivate::active_window = 0;
3038 if (old)
3039 old->repaintDecoration(desktop()->rect(), false);
3040 /* activateWindow() sends focus events
3041 QApplication::setFocusWidget(0);
3042 */
3043 }
3044 }
3045 break;
3046
3047 case QWSEvent::WindowOperation:
3048 if (static_cast<QWidget *>(widget) == desktop())
3049 return true;
3050 switch ((static_cast<QWSWindowOperationEvent *>(event))->simpleData.op) {
3051 case QWSWindowOperationEvent::Show:
3052 widget->show();
3053 break;
3054 case QWSWindowOperationEvent::Hide:
3055 widget->hide();
3056 break;
3057 case QWSWindowOperationEvent::ShowMaximized:
3058 widget->showMaximized();
3059 break;
3060 case QWSWindowOperationEvent::ShowMinimized:
3061 widget->showMinimized();
3062 break;
3063 case QWSWindowOperationEvent::ShowNormal:
3064 widget->showNormal();
3065 break;
3066 case QWSWindowOperationEvent::Close:
3067 widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
3068 break;
3069 }
3070 break;
3071#ifndef QT_NO_QWSEMBEDWIDGET
3072 case QWSEvent::Embed:
3073 widget->translateEmbedEvent(static_cast<QWSEmbedEvent*>(event));
3074 break;
3075#endif
3076 default:
3077 break;
3078 }
3079
3080 return 0;
3081}
3082
3083bool QApplication::qwsEventFilter(QWSEvent *)
3084{
3085 return false;
3086}
3087
3088void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors)
3089{
3090 if (start < 0 || start > 39) {
3091 qWarning("QApplication::qwsSetCustomColors: start < 0 || start > 39");
3092 return;
3093 }
3094 if (start + numColors > 40) {
3095 numColors = 40 - start;
3096 qWarning("QApplication::qwsSetCustomColors: Too many colors");
3097 }
3098 start += 216;
3099 for (int i = 0; i < numColors; i++) {
3100 qt_screen->set(start + i, qRed(colorTable[i]), qGreen(colorTable[i]),
3101 qBlue(colorTable[i]));
3102 }
3103}
3104
3105#ifndef QT_NO_QWS_MANAGER
3106QDecoration &QApplication::qwsDecoration()
3107{
3108 return *qws_decoration;
3109}
3110
3111void QApplication::qwsSetDecoration(QDecoration *dec)
3112{
3113 if (dec) {
3114 delete qws_decoration;
3115 qws_decoration = dec;
3116 QWidgetList widgets = topLevelWidgets();
3117 for (int i = 0; i < widgets.size(); ++i) {
3118 QWidget *w = widgets[i];
3119 if (w->isVisible() && w != desktop()) {
3120 static_cast<QETWidget *>(w)->updateRegion();
3121 static_cast<QETWidget *>(w)->repaintDecoration(desktop()->rect(), false);
3122 if (w->isMaximized())
3123 w->showMaximized();
3124 }
3125 }
3126 }
3127}
3128
3129QDecoration* QApplication::qwsSetDecoration(const QString &decoration)
3130{
3131 QDecoration *decore = QDecorationFactory::create(decoration);
3132 if (!decore)
3133 return 0;
3134
3135 qwsSetDecoration(decore);
3136 return decore;
3137}
3138
3139#endif
3140
3141bool QApplicationPrivate::modalState()
3142{
3143 return app_do_modal;
3144}
3145
3146void QApplicationPrivate::enterModal_sys(QWidget *widget)
3147{
3148 if (!qt_modal_stack)
3149 qt_modal_stack = new QWidgetList;
3150 qt_modal_stack->insert(0, widget);
3151 app_do_modal = true;
3152}
3153
3154void QApplicationPrivate::leaveModal_sys(QWidget *widget)
3155{
3156 if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
3157 if (qt_modal_stack->isEmpty()) {
3158 delete qt_modal_stack;
3159 qt_modal_stack = 0;
3160 }
3161 }
3162 app_do_modal = qt_modal_stack != 0;
3163}
3164
3165static bool qt_try_modal(QWidget *widget, QWSEvent *event)
3166{
3167 QWidget * top = 0;
3168
3169 if (QApplicationPrivate::tryModalHelper(widget, &top))
3170 return true;
3171
3172 bool block_event = false;
3173 bool paint_event = false;
3174
3175 switch (event->type) {
3176 case QWSEvent::Focus:
3177 if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus)
3178 break;
3179 // drop through
3180 case QWSEvent::Mouse: // disallow mouse/key events
3181 case QWSEvent::Key:
3182 block_event = true;
3183 break;
3184 }
3185
3186 if (top->parentWidget() == 0 && (block_event || paint_event))
3187 top->raise();
3188
3189 return !block_event;
3190}
3191
3192static int openPopupCount = 0;
3193void QApplicationPrivate::openPopup(QWidget *popup)
3194{
3195 openPopupCount++;
3196 if (!popupWidgets) { // create list
3197 popupWidgets = new QWidgetList;
3198
3199 /* only grab if you are the first/parent popup */
3200 QPaintDevice::qwsDisplay()->grabMouse(popup,true);
3201 QPaintDevice::qwsDisplay()->grabKeyboard(popup,true);
3202 popupGrabOk = true;
3203 }
3204 popupWidgets->append(popup); // add to end of list
3205
3206 // popups are not focus-handled by the window system (the first
3207 // popup grabbed the keyboard), so we have to do that manually: A
3208 // new popup gets the focus
3209 if (popup->focusWidget()) {
3210 popup->focusWidget()->setFocus(Qt::PopupFocusReason);
3211 } else if (popupWidgets->count() == 1) { // this was the first popup
3212 if (QWidget *fw = QApplication::focusWidget()) {
3213 QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
3214 QApplication::sendEvent(fw, &e);
3215 }
3216 }
3217}
3218
3219void QApplicationPrivate::closePopup(QWidget *popup)
3220{
3221 if (!popupWidgets)
3222 return;
3223
3224 popupWidgets->removeAll(popup);
3225 if (popup == popupOfPopupButtonFocus) {
3226 popupButtonFocus = 0;
3227 popupOfPopupButtonFocus = 0;
3228 }
3229 if (popupWidgets->count() == 0) { // this was the last popup
3230 popupCloseDownMode = true; // control mouse events
3231 delete popupWidgets;
3232 popupWidgets = 0;
3233 if (popupGrabOk) { // grabbing not disabled
3234 QPaintDevice::qwsDisplay()->grabMouse(popup,false);
3235 QPaintDevice::qwsDisplay()->grabKeyboard(popup,false);
3236 popupGrabOk = false;
3237 // XXX ungrab keyboard
3238 }
3239 if (active_window) {
3240 if (QWidget *fw = active_window->focusWidget()) {
3241 if (fw != QApplication::focusWidget()) {
3242 fw->setFocus(Qt::PopupFocusReason);
3243 } else {
3244 QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
3245 QApplication::sendEvent(fw, &e);
3246 }
3247 }
3248 }
3249 } else {
3250 // popups are not focus-handled by the window system (the
3251 // first popup grabbed the keyboard), so we have to do that
3252 // manually: A popup was closed, so the previous popup gets
3253 // the focus.
3254 QWidget* aw = popupWidgets->last();
3255 if (QWidget *fw = aw->focusWidget())
3256 fw->setFocus(Qt::PopupFocusReason);
3257 }
3258}
3259
3260/*****************************************************************************
3261 Event translation; translates FB events to Qt events
3262 *****************************************************************************/
3263
3264//
3265// Mouse event translation
3266//
3267// FB doesn't give mouse double click events, so we generate them by
3268// comparing window, time and position between two mouse press events.
3269//
3270
3271
3272// Needed for QCursor::pos
3273
3274static const int AnyButton = (Qt::LeftButton | Qt::MidButton | Qt::RightButton);
3275
3276
3277
3278//
3279// Wheel event translation
3280//
3281bool QETWidget::translateWheelEvent(const QWSMouseEvent *me)
3282{
3283#ifdef QT_NO_WHEELEVENT
3284 Q_UNUSED(me);
3285 return false;
3286#else
3287 const QWSMouseEvent::SimpleData &mouse = me->simpleData;
3288
3289 // Figure out wheeling direction:
3290 // Horizontal wheel w/o Alt
3291 // OR Vertical wheel w/ Alt ==> Horizontal wheeling
3292 // ..all other permutations ==> Vertical wheeling
3293 int axis = mouse.delta / 120; // WHEEL_DELTA?
3294 Qt::Orientation orient = ((axis == 2 || axis == -2) && ((mouse.state & Qt::AltModifier) == 0))
3295 ||((axis == 1 || axis == -1) && mouse.state & Qt::AltModifier)
3296 ? Qt::Horizontal : Qt::Vertical;
3297
3298 QPoint mousePoint = QPoint(mouse.x_root, mouse.y_root);
3299
3300 // send the event to the widget or its ancestors
3301 QWidget* popup = qApp->activePopupWidget();
3302 if (popup && window() != popup)
3303 popup->close();
3304 QWheelEvent we(mapFromGlobal(mousePoint), mousePoint, mouse.delta,
3305 Qt::MouseButtons(mouse.state & Qt::MouseButtonMask),
3306 Qt::KeyboardModifiers(mouse.state & Qt::KeyboardModifierMask), orient);
3307 if (QApplication::sendSpontaneousEvent(this, &we))
3308 return true;
3309
3310 // send the event to the widget that has the focus or its ancestors, if different
3311 QWidget *w = this;
3312 if (w != qApp->focusWidget() && (w = qApp->focusWidget())) {
3313 QWidget* popup = qApp->activePopupWidget();
3314 if (popup && w != popup)
3315 popup->hide();
3316 if (QApplication::sendSpontaneousEvent(w, &we))
3317 return true;
3318 }
3319 return false;
3320#endif
3321}
3322
3323bool QETWidget::translateMouseEvent(const QWSMouseEvent *event, int prevstate)
3324{
3325 static bool manualGrab = false;
3326 QPoint pos;
3327 QPoint globalPos;
3328 int button = 0;
3329
3330 if (sm_blockUserInput) // block user interaction during session management
3331 return true;
3332 const QWSMouseEvent::SimpleData &mouse = event->simpleData;
3333 pos = mapFromGlobal(QPoint(mouse.x_root, mouse.y_root));
3334// if (qt_last_x) {
3335// *qt_last_x=mouse.x_root;
3336// *qt_last_y=mouse.y_root;
3337// }
3338 globalPos.rx() = mouse.x_root;
3339 globalPos.ry() = mouse.y_root;
3340
3341 QEvent::Type type = QEvent::None;
3342
3343 Qt::MouseButtons buttonstate = Qt::MouseButtons(mouse.state & Qt::MouseButtonMask);
3344 Qt::KeyboardModifiers keystate = Qt::KeyboardModifiers(mouse.state & Qt::KeyboardModifierMask);
3345
3346 if (mouse.state == prevstate) {
3347 // mouse move
3348 type = QEvent::MouseMove;
3349 } else if ((mouse.state&AnyButton) != (prevstate&AnyButton)) {
3350 Qt::MouseButtons current_buttons = Qt::MouseButtons(prevstate&Qt::MouseButtonMask);
3351 for (button = Qt::LeftButton; !type && button <= Qt::MidButton; button<<=1) {
3352 if ((mouse.state&button) != (current_buttons&button)) {
3353 // button press or release
3354 current_buttons = Qt::MouseButtons(current_buttons ^ button);
3355
3356#ifndef QT_NO_QWS_INPUTMETHODS
3357 //############ We used to do a QInputContext::reset(oldFocus);
3358 // when we changed the focus widget. See change 93389 for where the
3359 // focus code went. The IM code was (after testing for ClickToFocus):
3360 //if (mouse.state&button && w != QInputContext::microFocusWidget()) //button press
3361 // QInputContext::reset(oldFocus);
3362
3363#endif
3364 if (mouse.state&button) { //button press
3365 qt_button_down = childAt(pos);
3366 if (!qt_button_down)
3367 qt_button_down = this;
3368 if (/*XXX mouseActWindow == this &&*/
3369 mouseButtonPressed == button &&
3370 long(mouse.time) -long(mouseButtonPressTime)
3371 < QApplication::doubleClickInterval() &&
3372 qAbs(mouse.x_root - mouseXPos) < mouse_double_click_distance &&
3373 qAbs(mouse.y_root - mouseYPos) < mouse_double_click_distance ) {
3374 type = QEvent::MouseButtonDblClick;
3375 mouseButtonPressTime -= 2000; // no double-click next time
3376 } else {
3377 type = QEvent::MouseButtonPress;
3378 mouseButtonPressTime = mouse.time;
3379 }
3380 mouseButtonPressed = button; // save event params for
3381 mouseXPos = globalPos.x(); // future double click tests
3382 mouseYPos = globalPos.y();
3383 } else { // mouse button released
3384 if (manualGrab) { // release manual grab
3385 manualGrab = false;
3386 // XXX XUngrabPointer(x11Display(), CurrentTime);
3387 }
3388
3389 type = QEvent::MouseButtonRelease;
3390 }
3391 }
3392 }
3393 button >>= 1;
3394 }
3395 //XXX mouseActWindow = winId(); // save some event params
3396
3397 if (type == 0) { // event consumed
3398 return false; //EXIT in the normal case
3399 }
3400
3401 if (qApp->d_func()->inPopupMode()) { // in popup mode
3402 QWidget *popup = qApp->activePopupWidget();
3403 // in X11, this would be the window we are over.
3404 // in QWS this is the top level popup. to allow mouse
3405 // events to other widgets, need to go through qApp->QApplicationPrivate::popupWidgets.
3406 QSize s(qt_screen->width(), qt_screen->height());
3407 for (int i = 0; i < QApplicationPrivate::popupWidgets->size(); ++i) {
3408 QWidget *w = QApplicationPrivate::popupWidgets->at(i);
3409
3410 if ((w->windowType() == Qt::Popup) && w->d_func()->localAllocatedRegion().contains(globalPos - w->geometry().topLeft()))
3411 {
3412 popup = w;
3413 break;
3414 }
3415 }
3416 pos = popup->mapFromGlobal(globalPos);
3417 bool releaseAfter = false;
3418 QWidget *popupChild = popup->childAt(pos);
3419 QWidget *popupTarget = popupChild ? popupChild : popup;
3420
3421 if (popup != popupOfPopupButtonFocus){
3422 popupButtonFocus = 0;
3423 popupOfPopupButtonFocus = 0;
3424 }
3425
3426 if (!popupTarget->isEnabled()) {
3427 return false; //EXIT special case
3428 }
3429
3430 switch (type) {
3431 case QEvent::MouseButtonPress:
3432 case QEvent::MouseButtonDblClick:
3433 popupButtonFocus = popupChild;
3434 popupOfPopupButtonFocus = popup;
3435 break;
3436 case QEvent::MouseButtonRelease:
3437 releaseAfter = true;
3438 break;
3439 default:
3440 break; // nothing for mouse move
3441 }
3442
3443 int oldOpenPopupCount = openPopupCount;
3444
3445 if (popupButtonFocus) {
3446 QMouseEvent e(type, popupButtonFocus->mapFromGlobal(globalPos),
3447 globalPos, Qt::MouseButton(button), buttonstate, keystate);
3448 QApplication::sendSpontaneousEvent(popupButtonFocus, & e);
3449 if (releaseAfter) {
3450 popupButtonFocus = 0;
3451 popupOfPopupButtonFocus = 0;
3452 }
3453 } else if (popupChild) {
3454 QMouseEvent e(type, popupChild->mapFromGlobal(globalPos),
3455 globalPos, Qt::MouseButton(button), buttonstate, keystate);
3456 QApplication::sendSpontaneousEvent(popupChild, & e);
3457 } else {
3458 QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button), buttonstate, keystate);
3459 QApplication::sendSpontaneousEvent(popupChild ? popupChild : popup, & e);
3460 }
3461#ifndef QT_NO_CONTEXTMENU
3462 if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
3463 QWidget *popupEvent = popup;
3464 if(popupButtonFocus)
3465 popupEvent = popupButtonFocus;
3466 else if(popupChild)
3467 popupEvent = popupChild;
3468 QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, keystate);
3469 QApplication::sendSpontaneousEvent(popupEvent, &e);
3470 }
3471#endif // QT_NO_CONTEXTMENU
3472
3473 if (releaseAfter)
3474 qt_button_down = 0;
3475
3476 } else { //qApp not in popup mode
3477 QWidget *widget = this;
3478 QWidget *w = QWidget::mouseGrabber();
3479 if (!w && qt_button_down)
3480 w = qt_button_down;
3481 if (w && w != this) {
3482 widget = w;
3483 pos = mapToGlobal(pos);
3484 pos = w->mapFromGlobal(pos);
3485 }
3486
3487 if (popupCloseDownMode) {
3488 popupCloseDownMode = false;
3489 if ((windowType() == Qt::Popup)) // ignore replayed event
3490 return true; //EXIT
3491 }
3492
3493 QPointer<QWidget> leaveAfterRelease = 0;
3494 if (type == QEvent::MouseButtonRelease &&
3495 (mouse.state & (~button) & (Qt::LeftButton |
3496 Qt::MidButton |
3497 Qt::RightButton)) == 0) {
3498 // Button released outside the widget -> leave the widget after the
3499 // release event has been delivered.
3500 if (widget == qt_button_down && (pos.x() < 0 || pos.y() < 0))
3501 leaveAfterRelease = qt_button_down;
3502 qt_button_down = 0;
3503 }
3504
3505 int oldOpenPopupCount = openPopupCount;
3506
3507 QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button), buttonstate, keystate);
3508#ifndef QT_NO_QWS_MANAGER
3509 if (widget->isWindow() && widget->d_func()->topData()->qwsManager
3510 && (widget->d_func()->topData()->qwsManager->region().contains(globalPos)
3511 || QWSManager::grabbedMouse() )) {
3512 if ((*mouseInWidget)) {
3513 QApplicationPrivate::dispatchEnterLeave(0, *mouseInWidget);
3514 (*mouseInWidget) = 0;
3515 }
3516 QApplication::sendSpontaneousEvent(widget->d_func()->topData()->qwsManager, &e);
3517 qApp->d_func()->last_manager = widget->d_func()->topData()->qwsManager;
3518 } else
3519#endif
3520 {
3521 if (widget != (*mouseInWidget)) {
3522 QApplicationPrivate::dispatchEnterLeave(widget, *mouseInWidget);
3523 (*mouseInWidget) = widget;
3524 qt_last_mouse_receiver = widget;
3525 }
3526 QApplication::sendSpontaneousEvent(widget, &e);
3527 if (leaveAfterRelease && !QWidget::mouseGrabber()) {
3528 *mouseInWidget = QApplication::widgetAt(globalPos);
3529 qt_last_mouse_receiver = *mouseInWidget;
3530 QApplicationPrivate::dispatchEnterLeave(*mouseInWidget, leaveAfterRelease);
3531 leaveAfterRelease = 0;
3532 }
3533 }
3534#ifndef QT_NO_CONTEXTMENU
3535 if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
3536 QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, keystate);
3537 QApplication::sendSpontaneousEvent(widget, &e);
3538 }
3539#endif // QT_NO_CONTEXTMENU
3540 }
3541 return true;
3542}
3543
3544
3545bool QETWidget::translateKeyEvent(const QWSKeyEvent *event, bool grab) /* grab is used in the #ifdef */
3546{
3547 int code = -1;
3548 //### Qt assumes keyboard state is state *before*, while QWS uses state after the event
3549 static Qt::KeyboardModifiers oldstate;
3550 Qt::KeyboardModifiers state = oldstate;
3551 oldstate = event->simpleData.modifiers;
3552
3553 if (sm_blockUserInput) // block user interaction during session management
3554 return true;
3555
3556 if (!isEnabled())
3557 return true;
3558
3559 QEvent::Type type = event->simpleData.is_press ?
3560 QEvent::KeyPress : QEvent::KeyRelease;
3561 bool autor = event->simpleData.is_auto_repeat;
3562 QString text;
3563 char ascii = 0;
3564 if (event->simpleData.unicode) {
3565 QChar ch(event->simpleData.unicode);
3566 if (ch.unicode() != 0xffff)
3567 text += ch;
3568 ascii = ch.toLatin1();
3569 }
3570 code = event->simpleData.keycode;
3571
3572#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
3573 if (type == QEvent::KeyPress && !grab
3574 && static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->use_compat()) {
3575 // send accel events if the keyboard is not grabbed
3576 QKeyEvent a(type, code, state, text, autor, int(text.length()));
3577 if (static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->qt_tryAccelEvent(this, &a))
3578 return true;
3579 }
3580#else
3581 Q_UNUSED(grab);
3582#endif
3583 if (!text.isEmpty() && testAttribute(Qt::WA_KeyCompression)) {
3584 // the widget wants key compression so it gets it
3585
3586 // XXX not implemented
3587 }
3588
3589 QKeyEvent e(type, code, state, text, autor, int(text.length()));
3590 return QApplication::sendSpontaneousEvent(this, &e);
3591}
3592
3593bool QETWidget::translateRegionEvent(const QWSRegionEvent *event)
3594{
3595 QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(windowSurface());
3596 Q_ASSERT(surface);
3597
3598 QRegion region;
3599 region.setRects(event->rectangles, event->simpleData.nrectangles);
3600
3601 switch (event->simpleData.type) {
3602 case QWSRegionEvent::Allocation:
3603 region.translate(-mapToGlobal(QPoint()));
3604 surface->setClipRegion(region);
3605 break;
3606#ifdef QT_QWS_CLIENTBLIT
3607 case QWSRegionEvent::DirectPaint:
3608 surface->setDirectRegion(region, event->simpleData.id);
3609 break;
3610#endif
3611 default:
3612 break;
3613 }
3614
3615 return true;
3616}
3617
3618#ifndef QT_NO_QWSEMBEDWIDGET
3619void QETWidget::translateEmbedEvent(const QWSEmbedEvent *event)
3620{
3621 if (event->simpleData.type | QWSEmbedEvent::Region) {
3622 const QRegion region = event->region;
3623 setGeometry(region.boundingRect());
3624 setVisible(!region.isEmpty());
3625 }
3626}
3627#endif // QT_NO_QWSEMBEDWIDGET
3628
3629void QETWidget::repaintDecoration(QRegion r, bool post)
3630{
3631 Q_UNUSED(post);
3632#ifdef QT_NO_QWS_MANAGER
3633 Q_UNUSED(r);
3634#else
3635 //please note that qwsManager is a QObject, not a QWidget.
3636 //therefore, normal ways of painting do not work.
3637 // However, it does listen to paint events.
3638
3639 Q_D(QWidget);
3640 if (isWindow() && d->topData()->qwsManager && isVisible()) {
3641 QWSManager *manager = d->topData()->qwsManager;
3642 r &= manager->region();
3643 if (!r.isEmpty())
3644 manager->repaintRegion(QDecoration::All, QDecoration::Normal);
3645 }
3646#endif
3647}
3648
3649void QETWidget::updateRegion()
3650{
3651 Q_D(QWidget);
3652
3653 QTLWExtra *topextra = d->maybeTopData();
3654 if (!topextra)
3655 return;
3656
3657 QRegion myregion = d->localRequestedRegion();
3658 myregion.translate(geometry().topLeft());
3659
3660#ifndef QT_NO_QWS_MANAGER
3661 QWSManager *manager = topextra->qwsManager;
3662 if (manager)
3663 myregion += manager->region();
3664#endif
3665
3666 QRect br(myregion.boundingRect());
3667 topextra->frameStrut.setCoords(d->data.crect.x() - br.x(),
3668 d->data.crect.y() - br.y(),
3669 br.right() - d->data.crect.right(),
3670 br.bottom() - d->data.crect.bottom());
3671}
3672
3673void QApplication::setCursorFlashTime(int msecs)
3674{
3675 QApplicationPrivate::cursor_flash_time = msecs;
3676}
3677
3678
3679int QApplication::cursorFlashTime()
3680{
3681 return QApplicationPrivate::cursor_flash_time;
3682}
3683
3684void QApplication::setDoubleClickInterval(int ms)
3685{
3686 QApplicationPrivate::mouse_double_click_time = ms;
3687}
3688
3689int QApplication::doubleClickInterval()
3690{
3691 return QApplicationPrivate::mouse_double_click_time;
3692}
3693
3694void QApplication::setKeyboardInputInterval(int ms)
3695{
3696 QApplicationPrivate::keyboard_input_time = ms;
3697}
3698
3699int QApplication::keyboardInputInterval()
3700{
3701 return QApplicationPrivate::keyboard_input_time;
3702}
3703
3704#ifndef QT_NO_WHEELEVENT
3705void QApplication::setWheelScrollLines(int lines)
3706{
3707 QApplicationPrivate::wheel_scroll_lines = lines;
3708}
3709
3710int QApplication::wheelScrollLines()
3711{
3712 return QApplicationPrivate::wheel_scroll_lines;
3713}
3714#endif
3715
3716void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
3717{
3718 switch (effect) {
3719 case Qt::UI_AnimateMenu:
3720 QApplicationPrivate::animate_menu = enable;
3721 break;
3722 case Qt::UI_FadeMenu:
3723 if (enable)
3724 QApplicationPrivate::animate_menu = true;
3725 QApplicationPrivate::fade_menu = enable;
3726 break;
3727 case Qt::UI_AnimateCombo:
3728 QApplicationPrivate::animate_combo = enable;
3729 break;
3730 case Qt::UI_AnimateTooltip:
3731 QApplicationPrivate::animate_tooltip = enable;
3732 break;
3733 case Qt::UI_FadeTooltip:
3734 if (enable)
3735 QApplicationPrivate::animate_tooltip = true;
3736 QApplicationPrivate::fade_tooltip = enable;
3737 break;
3738 case Qt::UI_AnimateToolBox:
3739 QApplicationPrivate::animate_toolbox = enable;
3740 break;
3741 default:
3742 QApplicationPrivate::animate_ui = enable;
3743 break;
3744 }
3745}
3746
3747bool QApplication::isEffectEnabled(Qt::UIEffect effect)
3748{
3749 if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
3750 return false;
3751
3752 switch(effect) {
3753 case Qt::UI_AnimateMenu:
3754 return QApplicationPrivate::animate_menu;
3755 case Qt::UI_FadeMenu:
3756 return QApplicationPrivate::fade_menu;
3757 case Qt::UI_AnimateCombo:
3758 return QApplicationPrivate::animate_combo;
3759 case Qt::UI_AnimateTooltip:
3760 return QApplicationPrivate::animate_tooltip;
3761 case Qt::UI_FadeTooltip:
3762 return QApplicationPrivate::fade_tooltip;
3763 case Qt::UI_AnimateToolBox:
3764 return QApplicationPrivate::animate_toolbox;
3765 default:
3766 return QApplicationPrivate::animate_ui;
3767 }
3768}
3769
3770void QApplication::setArgs(int c, char **v)
3771{
3772 Q_D(QApplication);
3773 d->argc = c;
3774 d->argv = v;
3775}
3776
3777void QApplicationPrivate::initializeMultitouch_sys()
3778{ }
3779void QApplicationPrivate::cleanupMultitouch_sys()
3780{ }
3781
3782/* \internal
3783 This is used to clean up the qws server
3784 in case the QApplication constructor threw an exception
3785*/
3786QWSServerCleaner::~QWSServerCleaner()
3787{
3788 if (qwsServer && qws_single_process)
3789 QWSServer::closedown();
3790}
3791
3792QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.