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