📄 qwindowsystem_qws.cpp
字号:
}#endif }#endif // no selection yet selectionOwner.windowid = -1; selectionOwner.time.set(-1, -1, -1, -1); cleanupFontsDir(); // initialize the font database // from qfontdatabase_qws.cpp extern void qt_qws_init_fontdb(); qt_qws_init_fontdb(); openDisplay(); screensavertimer = new QTimer(q); screensavertimer->setSingleShot(true); QObject::connect(screensavertimer, SIGNAL(timeout()), q, SLOT(_q_screenSaverTimeout())); _q_screenSaverWake(); clientMap[-1] = new QWSClient(q, 0, 0); if (!bgBrush) bgBrush = new QBrush(QColor(0x20, 0xb0, 0x50)); initializeCursor(); // input devices if (!(flags&QWSServer::DisableMouse)) { q->openMouse(); }#ifndef QT_NO_QWS_KEYBOARD if (!(flags&QWSServer::DisableKeyboard)) { q->openKeyboard(); }#endif#if !defined(QT_NO_SOUND) && !defined(QT_EXTERNAL_SOUND_SERVER) && !defined(Q_OS_DARWIN) soundserver = new QWSSoundServer(q);#endif}/*! \internal Destructs this server.*/QWSServer::~QWSServer(){ closeMouse();#ifndef QT_NO_QWS_KEYBOARD closeKeyboard();#endif d_func()->cleanupFonts(/*force =*/true);}/*! \internal */void QWSServer::timerEvent(QTimerEvent *e){ Q_D(QWSServer); if (e->timerId() == d->fontCleanupTimer.timerId()) { d->cleanupFonts(); d->fontCleanupTimer.stop(); } else { QObject::timerEvent(e); }}const QList<QWSWindow*> &QWSServer::clientWindows(){ Q_D(QWSServer); return d->windows;}/*! \internal*/void QWSServerPrivate::releaseMouse(QWSWindow* w){ if (w && mouseGrabber == w) { mouseGrabber = 0; mouseGrabbing = false;#ifndef QT_NO_QWS_CURSOR if (nextCursor) { // Not grabbing -> set the correct cursor setCursor(nextCursor); nextCursor = 0; }#endif }}/*! \internal*/void QWSServerPrivate::releaseKeyboard(QWSWindow* w){ if (keyboardGrabber == w) { keyboardGrabber = 0; keyboardGrabbing = false; }}void QWSServerPrivate::handleWindowClose(QWSWindow *w){ w->shuttingDown(); if (focusw == w) setFocus(w,false); if (mouseGrabber == w) releaseMouse(w); if (keyboardGrabber == w) releaseKeyboard(w);}#ifndef QT_NO_QWS_MULTIPROCESS/*! \internal*/void QWSServerPrivate::_q_newConnection(){ Q_Q(QWSServer); while (QWS_SOCK_BASE *sock = ssocket->nextPendingConnection()) { int socket = sock->socketDescriptor(); sock->setParent(0); QWSClient *client = new QWSClient(q,sock, get_object_id()); clientMap[socket] = client;#ifndef QT_NO_SXE#ifdef QTRANSPORTAUTH_DEBUG qDebug( "Transport auth connected: unix stream socket %d", socket );#endif // get a handle to the per-process authentication service QTransportAuth *a = QTransportAuth::getInstance(); // assert that this transport is trusted QTransportAuth::Data *d = a->connectTransport( QTransportAuth::UnixStreamSock | QTransportAuth::Trusted, socket ); QAuthDevice *ad = a->recvBuf( d, sock ); ad->setClient(client); QObject::connect(ad, SIGNAL(readyRead()), q, SLOT(_q_doClient())); QObject::connect(client, SIGNAL(connectionClosed()), q, SLOT(_q_clientClosed()));#else QObject::connect(client, SIGNAL(readyRead()), q, SLOT(_q_doClient())); QObject::connect(client, SIGNAL(connectionClosed()), q, SLOT(_q_clientClosed()));#endif // QT_NO_SXE client->sendConnectedEvent(qws_display_spec.constData()); if (clientMap.contains(socket)) { QList<QScreen*> screens = qt_screen->subScreens(); if (screens.isEmpty()) screens.append(qt_screen); for (int i = 0; i < screens.size(); ++i) { const QApplicationPrivate *ap = QApplicationPrivate::instance(); const QRect rect = ap->maxWindowRect(screens.at(i)); if (!rect.isEmpty()) client->sendMaxWindowRectEvent(rect); } } // pre-provide some object id's QWSCreateCommand cmd(30); invokeCreate(&cmd, client); }}/*! \internal*/void QWSServerPrivate::_q_clientClosed(){ Q_Q(QWSServer); QWSClient* cl = (QWSClient*)q->sender(); // Remove any queued commands for this client int i = 0; while (i < commandQueue.size()) { QWSCommandStruct *cs = commandQueue.at(i); if (cs->client == cl) { commandQueue.removeAt(i); delete cs; } else { ++i; } }#ifndef QT_NO_COP // Enfore unsubscription from all channels. QCopChannel::detach(cl);#endif // Shut down all windows for this client for (int i = 0; i < windows.size(); ++i) { QWSWindow* w = windows.at(i); if (w->forClient(cl)) w->shuttingDown(); } // Delete all windows for this client QRegion exposed; i = 0; while (i < windows.size()) { QWSWindow* w = windows.at(i); if (w->forClient(cl)) { w->c = 0; //so we don't send events to it anymore releaseMouse(w); releaseKeyboard(w); exposed += w->allocatedRegion();// rgnMan->remove(w->allocationIndex()); if (focusw == w) setFocus(focusw,0); if (mouseGrabber == w) releaseMouse(w); windows.takeAt(i); if (i < nReserved) --nReserved;#ifndef QT_NO_QWS_PROPERTIES propertyManager.removeProperties(w->winId());#endif emit q->windowEvent(w, QWSServer::Destroy); w->d->state = QWSWindow::Destroyed; //??? deletedWindows.append(w); } else { ++i; } } if (deletedWindows.count()) QTimer::singleShot(0, q, SLOT(_q_deleteWindowsLater())); QWSClientPrivate *clientPrivate = cl->d_func(); if (!clientPrivate->shutdown) {#if defined(QWS_DEBUG_FONTCLEANUP) qDebug() << "client" << cl->clientId() << "crashed";#endif // this would be the place to emit a signal to notify about the // crash of a client crashedClientIds.append(cl->clientId()); fontCleanupTimer.start(10, q_func()); } clientPrivate->shutdown = true; while (!clientPrivate->usedFonts.isEmpty()) { const QByteArray font = *clientPrivate->usedFonts.begin();#if defined(QWS_DEBUG_FONTCLEANUP) qDebug() << "dereferencing font" << font << "from disconnected client";#endif dereferenceFont(clientPrivate, font); } clientPrivate->usedFonts.clear(); //qDebug("removing client %d with socket %d", cl->clientId(), cl->socket()); clientMap.remove(cl->socket()); if (cl == cursorClient) cursorClient = 0; if (qt_screen->clearCacheFunc) (qt_screen->clearCacheFunc)(qt_screen, cl->clientId()); // remove any remaining cache entries. cl->deleteLater(); update_regions(); exposeRegion(exposed);}void QWSServerPrivate::_q_deleteWindowsLater(){ qDeleteAll(deletedWindows); deletedWindows.clear();}#endif //QT_NO_QWS_MULTIPROCESSvoid QWSServerPrivate::referenceFont(QWSClientPrivate *client, const QByteArray &font){ if (!client->usedFonts.contains(font)) { client->usedFonts.insert(font); ++fontReferenceCount[font];#if defined(QWS_DEBUG_FONTCLEANUP) qDebug() << "Client" << client->q_func()->clientId() << "added font" << font; qDebug() << "Refcount is" << fontReferenceCount[font];#endif }}void QWSServerPrivate::dereferenceFont(QWSClientPrivate *client, const QByteArray &font){ if (client->usedFonts.contains(font)) { client->usedFonts.remove(font); Q_ASSERT(fontReferenceCount[font]); if (!--fontReferenceCount[font] && !fontCleanupTimer.isActive()) fontCleanupTimer.start(FontCleanupInterval, q_func());#if defined(QWS_DEBUG_FONTCLEANUP) qDebug() << "Client" << client->q_func()->clientId() << "removed font" << font; qDebug() << "Refcount is" << fontReferenceCount[font];#endif }}static void cleanupFontsDir(){ static bool dontDelete = !qgetenv("QWS_KEEP_FONTS").isEmpty(); if (dontDelete) return; extern QString qws_fontCacheDir(); QDir dir(qws_fontCacheDir(), QLatin1String("*.qsf")); for (uint i = 0; i < dir.count(); ++i) {#if defined(QWS_DEBUG_FONTCLEANUP) qDebug() << "removing stale font file" << dir[i];#endif dir.remove(dir[i]); }}void QWSServerPrivate::cleanupFonts(bool force){ static bool dontDelete = !qgetenv("QWS_KEEP_FONTS").isEmpty(); if (dontDelete) return;#if defined(QWS_DEBUG_FONTCLEANUP) qDebug() << "cleanupFonts()";#endif QMap<QByteArray, int>::Iterator it = fontReferenceCount.begin(); while (it != fontReferenceCount.end()) { if (it.value() && !force) { ++it; continue; } const QByteArray &fontName = it.key();#if defined(QWS_DEBUG_FONTCLEANUP) qDebug() << "removing unused font file" << fontName;#endif QFile::remove(QFile::decodeName(fontName)); sendFontRemovedEvent(fontName); it = fontReferenceCount.erase(it); } if (crashedClientIds.isEmpty()) return; QList<QByteArray> removedFonts;#ifndef QT_NO_QWS_QPF removedFonts = QFontEngineQPF::cleanUpAfterClientCrash(crashedClientIds);#endif crashedClientIds.clear(); for (int i = 0; i < removedFonts.count(); ++i) sendFontRemovedEvent(removedFonts.at(i));}void QWSServerPrivate::sendFontRemovedEvent(const QByteArray &font){ QWSFontEvent event; event.simpleData.type = QWSFontEvent::FontRemoved; event.setData(font.constData(), font.length(), false); QMap<int,QWSClient*>::const_iterator it = clientMap.constBegin(); for (; it != clientMap.constEnd(); ++it) (*it)->sendEvent(&event);}/*! \internal*/QWSCommand* QWSClient::readMoreCommand(){#ifndef QT_NO_QWS_MULTIPROCESS QIODevice *socket = 0;#endif#ifndef QT_NO_SXE if (socketDescriptor != -1) // not server socket socket = QTransportAuth::getInstance()->passThroughByClient( this );#if QTRANSPORTAUTH_DEBUG if (socket) { char displaybuf[1024]; qint64 bytes = socket->bytesAvailable(); if ( bytes > 511 ) bytes = 511; hexstring( displaybuf, ((unsigned char *)(reinterpret_cast<QAuthDevice*>(socket)->buffer().constData())), bytes ); qDebug( "readMoreCommand: %lli bytes - %s", socket->bytesAvailable(), displaybuf ); }#endif#endif // QT_NO_SXE#ifndef QT_NO_QWS_MULTIPROCESS if (!socket) socket = csocket; // server socket if (socket) { // read next command if (!command) { int command_type = qws_read_uint(socket); if (command_type >= 0) command = QWSCommand::factory(command_type); } if (command) { if (command->read(socket)) { // Finished reading a whole command. QWSCommand* result = command; command = 0; return result; } } // Not finished reading a whole command. return 0; } else#endif // QT_NO_QWS_MULTIPROCESS { QList<QWSCommand*> *serverQueue = qt_get_server_queue(); return serverQueue->isEmpty() ? 0 : serverQueue->takeFirst(); }}/*! \internal*/void QWSServer::processEventQueue(){ if (qwsServerPrivate) qwsServerPrivate->doClient(qwsServerPrivate->clientMap.value(-1));}#ifndef QT_NO_QWS_MULTIPROCESSvoid QWSServerPrivate::_q_doClient(){ Q_Q(QWSServer); QWSClient* client;#ifndef QT_NO_SXE QAuthDevice *ad = qobject_cast<QAuthDevice*>(q->sender()); if (ad) client = (QWSClient*)ad->client(); else#endif client = (QWSClient*)q->sender(); if (doClientIsActive) { pendingDoClients.append(client); return; } doClientIsActive = true; doClient(client);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -