Exemplo n.º 1
0
bool
QLuaApplication::close()
{
  if (! d->closingDown)
    {
      d->closingDown = true;
      QCloseEvent ev;
      sendEvent(this, &ev);
      d->closingDown = ev.isAccepted();
      if (d->closingDown)
        {
          sendPostedEvents();
          QTimer::singleShot(0, this, SLOT(quit()));
        }
    }
  return d->closingDown;
}
Exemplo n.º 2
0
void 
QLuaApplication::Private::ttyEndOfFile()
{
  if (++ttyEofCount > 8)
    {
      sendPostedEvents();
      theApp->quit();
    }
  else if (ttyConsole && interactionStarted)
    {
      accepting = false;
      emit theApp->acceptingCommands(false);
      luaInput.clear();
      QByteArray prompt = "Really quit [y/N]? ";
      ttyEofReceived = true;
      theConsole->abortReadLine();
      theConsole->readLine(prompt);
    }
}
Exemplo n.º 3
0
unsigned int EventLoop::exec(int timeoutTime)
{
    int quitTimerId = -1;
    if (timeoutTime != -1)
        quitTimerId = registerTimer([=](int) { timeout = true; quit(); }, timeoutTime, Timer::SingleShot);

    unsigned int ret = 0;

#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE)
    enum { MaxEvents = 64 };
    NativeEvent events[MaxEvents];
#endif

    for (;;) {
        for (;;) {
            if (!sendPostedEvents() && !sendTimers())
                break;
        }
        int waitUntil = -1;
        {
            std::lock_guard<std::mutex> locker(mutex);

            // check if we're stopped
            if (stop) {
                stop = false;
                if (timeout) {
                    timeout = false;
                    ret = Timeout;
                } else {
                    ret = Success;
                }
                break;
            }

            const auto timer = timersByTime.begin();
            if (timer != timersByTime.end()) {
                const uint64_t now = currentTime();
                waitUntil = std::max<int>((*timer)->when - now, 0);
            }
        }
        int eventCount;
#if defined(HAVE_EPOLL)
        eintrwrap(eventCount, epoll_wait(pollFd, events, MaxEvents, waitUntil));
#elif defined(HAVE_KQUEUE)
        timespec timeout;
        timespec* timeptr = 0;
        if (waitUntil != -1) {
            timeout.tv_sec = waitUntil / 1000;
            timeout.tv_nsec = (waitUntil % 1000LLU) * 1000000;
            timeptr = &timeout;
        }
        eintrwrap(eventCount, kevent(pollFd, 0, 0, events, MaxEvents, timeptr));
#elif defined(HAVE_SELECT)
        timeval timeout;
        timeval* timeptr = 0;
        if (waitUntil != -1) {
            timeout.tv_sec = waitUntil / 1000;
            timeout.tv_usec = (waitUntil % 1000LLU) * 1000;
            timeptr = &timeout;
        }

        fd_set rdfd, wrfd;
        fd_set* wrfdp = 0;
        FD_ZERO(&rdfd);
        FD_ZERO(&wrfd);
        int max = eventPipe[0];
        FD_SET(max, &rdfd);
        {
            std::lock_guard<std::mutex> locker(mutex);
            auto s = sockets.begin();
            const auto e = sockets.end();
            while (s != e) {
                if (s->second.first & SocketRead) {
                    FD_SET(s->first, &rdfd);
                }
                if (s->second.first & SocketWrite) {
                    if (!wrfdp)
                        wrfdp = &wrfd;
                    FD_SET(s->first, wrfdp);
                }
                max = std::max(max, s->first);
                ++s;
            }
        }

        eintrwrap(eventCount, select(max + 1, &rdfd, wrfdp, 0, timeptr));
#endif
        if (eventCount < 0) {
            // bad
            ret = GeneralError;
            break;
        } else if (eventCount) {
#if defined(HAVE_SELECT)
            NativeEvent event;
            event.rdfd = &rdfd;
            event.wrfd = wrfdp;
            NativeEvent* events = &event;
#endif
            ret = processSocketEvents(events, eventCount);
            if (ret & (Success|GeneralError|Timeout))
                break;
        }
    }

    if (quitTimerId != -1)
        clearTimer(quitTimerId);
    return ret;
}
Exemplo n.º 4
0
bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
{
    Q_D(QEventDispatcherWin32);

    if (!d->internalHwnd)
        createInternalHwnd();

    d->interrupt = false;
    emit awake();

    bool canWait;
    bool retVal = false;
    bool seenWM_QT_SENDPOSTEDEVENTS = false;
    bool needWM_QT_SENDPOSTEDEVENTS = false;
    do {
        DWORD waitRet = 0;
        HANDLE pHandles[MAXIMUM_WAIT_OBJECTS - 1];
        QVarLengthArray<MSG> processedTimers;
        while (!d->interrupt) {
            DWORD nCount = d->winEventNotifierList.count();
            Q_ASSERT(nCount < MAXIMUM_WAIT_OBJECTS - 1);

            MSG msg;
            bool haveMessage;

            if (!(flags & QEventLoop::ExcludeUserInputEvents) && !d->queuedUserInputEvents.isEmpty()) {
                // process queued user input events
                haveMessage = true;
                msg = d->queuedUserInputEvents.takeFirst();
            } else if(!(flags & QEventLoop::ExcludeSocketNotifiers) && !d->queuedSocketEvents.isEmpty()) {
                // process queued socket events
                haveMessage = true;
                msg = d->queuedSocketEvents.takeFirst();
            } else {
                haveMessage = PeekMessage(&msg, 0, 0, 0, PM_REMOVE);
                if (haveMessage && (flags & QEventLoop::ExcludeUserInputEvents)
                    && ((msg.message >= WM_KEYFIRST
                         && msg.message <= WM_KEYLAST)
                        || (msg.message >= WM_MOUSEFIRST
                            && msg.message <= WM_MOUSELAST)
                        || msg.message == WM_MOUSEWHEEL
                        || msg.message == WM_MOUSEHWHEEL
                        || msg.message == WM_TOUCH
#ifndef QT_NO_GESTURES
                        || msg.message == WM_GESTURE
                        || msg.message == WM_GESTURENOTIFY
#endif
                        || msg.message == WM_CLOSE)) {
                    // queue user input events for later processing
                    haveMessage = false;
                    d->queuedUserInputEvents.append(msg);
                }
                if (haveMessage && (flags & QEventLoop::ExcludeSocketNotifiers)
                    && (msg.message == WM_QT_SOCKETNOTIFIER && msg.hwnd == d->internalHwnd)) {
                    // queue socket events for later processing
                    haveMessage = false;
                    d->queuedSocketEvents.append(msg);
                }
            }
            if (!haveMessage) {
                // no message - check for signalled objects
                for (int i=0; i<(int)nCount; i++)
                    pHandles[i] = d->winEventNotifierList.at(i)->handle();
                waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, 0, QS_ALLINPUT, MWMO_ALERTABLE);
                if ((haveMessage = (waitRet == WAIT_OBJECT_0 + nCount))) {
                    // a new message has arrived, process it
                    continue;
                }
            }
            if (haveMessage) {
#ifdef Q_OS_WINCE
                // WinCE doesn't support hooks at all, so we have to call this by hand :(
                (void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg);
#endif

                if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
                    if (seenWM_QT_SENDPOSTEDEVENTS) {
                        // when calling processEvents() "manually", we only want to send posted
                        // events once
                        needWM_QT_SENDPOSTEDEVENTS = true;
                        continue;
                    }
                    seenWM_QT_SENDPOSTEDEVENTS = true;
                } else if (msg.message == WM_TIMER) {
                    // avoid live-lock by keeping track of the timers we've already sent
                    bool found = false;
                    for (int i = 0; !found && i < processedTimers.count(); ++i) {
                        const MSG processed = processedTimers.constData()[i];
                        found = (processed.wParam == msg.wParam && processed.hwnd == msg.hwnd && processed.lParam == msg.lParam);
                    }
                    if (found)
                        continue;
                    processedTimers.append(msg);
                } else if (msg.message == WM_QUIT) {
                    if (QCoreApplication::instance())
                        QCoreApplication::instance()->quit();
                    return false;
                }

                if (!filterNativeEvent(QByteArrayLiteral("windows_generic_MSG"), &msg, 0)) {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            } else if (waitRet - WAIT_OBJECT_0 < nCount) {
                d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
            } else {
                // nothing todo so break
                break;
            }
            retVal = true;
        }

        // still nothing - wait for message or signalled objects
        canWait = (!retVal
                   && !d->interrupt
                   && (flags & QEventLoop::WaitForMoreEvents));
        if (canWait) {
            DWORD nCount = d->winEventNotifierList.count();
            Q_ASSERT(nCount < MAXIMUM_WAIT_OBJECTS - 1);
            for (int i=0; i<(int)nCount; i++)
                pHandles[i] = d->winEventNotifierList.at(i)->handle();

            emit aboutToBlock();
            waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
            emit awake();
            if (waitRet - WAIT_OBJECT_0 < nCount) {
                d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
                retVal = true;
            }
        }
    } while (canWait);

    if (!seenWM_QT_SENDPOSTEDEVENTS && (flags & QEventLoop::EventLoopExec) == 0) {
        // when called "manually", always send posted events
        sendPostedEvents();
    }

    if (needWM_QT_SENDPOSTEDEVENTS)
        PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0);

    return retVal;
}