Exemple #1
0
bool Window::waitEvent(WindowEvent &event) {
    if (mBase && mBase->popEvent(event, true)) {
        return filterEvent(event);
    } else {
        return false;
    }
}
Exemple #2
0
bool Window::pollEvent(WindowEvent &event) {
    if (mBase && mBase->popEvent(event, false)) {
        return filterEvent(event);
    } else {
        return false;
    }
}
void KisToolDyna::continuePrimaryAction(KoPointerEvent *event)
{
    setMousePosition(event->point);

    if (applyFilter(m_mousePos.x(), m_mousePos.y())) {
        KoPointerEvent newEvent = filterEvent(event);
        KisToolFreehand::continuePrimaryAction(&newEvent);
    }
}
Exemple #4
0
bool Window::waitEvent(Event& event)
{
    if (m_impl && m_impl->popEvent(event, true))
    {
        return filterEvent(event);
    }
    else
    {
        return false;
    }
}
Exemple #5
0
bool Window::pollEvent(Event& event)
{
    if (m_impl && m_impl->popEvent(event, false))
    {
        return filterEvent(event);
    }
    else
    {
        return false;
    }
}
bool QEventDispatcherQWS::processEvents(QEventLoop::ProcessEventsFlags flags)
{
    Q_D(QEventDispatcherQWS);
    // process events from the QWS server
    int           nevents = 0;

    // handle gui and posted events
    d->interrupt = false;
    QApplication::sendPostedEvents();

    while (!d->interrupt) {        // also flushes output buffer ###can be optimized
        QWSEvent *event;
        if (!(flags & QEventLoop::ExcludeUserInputEvents)
            && !d->queuedUserInputEvents.isEmpty()) {
            // process a pending user input event
            event = d->queuedUserInputEvents.takeFirst();
        } else if  (qt_fbdpy->eventPending()) {
            event = qt_fbdpy->getEvent();        // get next event
             if (flags & QEventLoop::ExcludeUserInputEvents) {
                 // queue user input events
                 if (event->type == QWSEvent::Mouse || event->type == QWSEvent::Key) {
                      d->queuedUserInputEvents.append(event);
                        continue;
                 }
             }
        } else {
            break;
        }

        if (filterEvent(event)) {
            delete event;
            continue;
        }
        nevents++;

        bool ret = qApp->qwsProcessEvent(event) == 1;
        delete event;
        if (ret) {
            return true;
        }
    }

    if (!d->interrupt) {
        extern QList<QWSCommand*> *qt_get_server_queue();
        if (!qt_get_server_queue()->isEmpty()) {
            QWSServer::processEventQueue();
        }

        if (QEventDispatcherUNIX::processEvents(flags))
            return true;
    }
    return (nevents > 0);
}
void KisToolDyna::mouseMoveEvent(KoPointerEvent *e)
{
    if(!MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
        KisToolFreehand::mouseMoveEvent(e);
        return;
    }

    setMousePosition(e->point);

    if (applyFilter(m_mousePos.x(), m_mousePos.y())) {
        KoPointerEvent newEvent = filterEvent(e);
        KisToolFreehand::mouseMoveEvent(&newEvent);
    }

    if (m_painter && m_painter->paintOp() && currentPaintOpPreset()->settings()->isAirbrushing()) {
        m_timer->start(m_rate);
    }
}
Exemple #8
0
void MidiJackDevice::recordEvent(MidiRecordEvent& event)/*{{{*/
{
    if (audio->isPlaying())
        event.setLoopNum(audio->loopCount());

    if (midiInputTrace)
    {
        printf("Jack MidiInput: ");
        event.dump();
    }

    int typ = event.type();

    if (_port != -1)
    {
        //call our midimonitor with the data, it can then decide what to do
        monitorEvent(event);
    }

    //
    //  process midi event input filtering and
    //    transformation
    //

    processMidiInputTransformPlugins(event);

    if (filterEvent(event, midiRecordType, false))
        return;

    if (!applyMidiInputTransformation(event))
    {
        if (midiInputTrace)
            printf("   midi input transformation: event filtered\n");
        return;
    }

    //
    // transfer noteOn events to gui for step recording and keyboard
    // remote control
    //
    if (typ == ME_NOTEON)
    {
        int pv = ((event.dataA() & 0xff) << 8) + (event.dataB() & 0xff);
        song->putEvent(pv);
    }
    //This was not sending noteoff events at all sometimes causing strange endless note in step rec
    else if(typ == ME_NOTEOFF)
    {
        int pv = ((event.dataA() & 0xff) << 8) + (0x00);
        song->putEvent(pv);
    }

    // Do not bother recording if it is NOT actually being used by a port.
    // Because from this point on, process handles things, by selected port.
    if (_port == -1)
        return;

    // Split the events up into channel fifos. Special 'channel' number 17 for sysex events.
    unsigned int ch = (typ == ME_SYSEX) ? kMaxMidiChannels : event.channel();
    if (_recordFifo[ch].put(MidiPlayEvent(event)))
        printf("MidiJackDevice::recordEvent: fifo channel %d overflow\n", ch);
}/*}}}*/
Exemple #9
0
void
CStreamFilter::handleUpstreamEvent(const CEvent& event, void*)
{
	filterEvent(event);
}
int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
                                       timeval *timeout)
{
    Q_UNUSED(nfds);

    // prepare file sets for bps callback
    Q_D(QEventDispatcherBlackberry);
    d->ioData->count = 0;
    d->ioData->readfds = readfds;
    d->ioData->writefds = writefds;
    d->ioData->exceptfds = exceptfds;

    // \TODO Remove this when bps is fixed
    //
    // Work around a bug in BPS with which if we register the thread_pipe[0] fd with bps in the
    // private class' ctor once only then we get spurious notifications that thread_pipe[0] is
    // ready for reading. The first time the notification is correct and the pipe is emptied in
    // the calling doSelect() function. The 2nd notification is an error and the resulting attempt
    // to read and call to wakeUps.testAndSetRelease(1, 0) fails as there has been no intervening
    // call to QEventDispatcherUNIX::wakeUp().
    //
    // Registering thread_pipe[0] here and unregistering it at the end of this call works around
    // this issue.
    int io_events = BPS_IO_INPUT;
    int result = bps_add_fd(d->thread_pipe[0], io_events, &bpsIOHandler, d->ioData.data());
    if (result != BPS_SUCCESS)
        qWarning() << Q_FUNC_INFO << "bps_add_fd() failed";

    // reset all file sets
    if (readfds)
        FD_ZERO(readfds);

    if (writefds)
        FD_ZERO(writefds);

    if (exceptfds)
        FD_ZERO(exceptfds);

    // convert timeout to milliseconds
    int timeout_ms = -1;
    if (timeout)
        timeout_ms = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000);

    QElapsedTimer timer;
    timer.start();

    do {
        // wait for event or file to be ready
        bps_event_t *event = NULL;

        // \TODO Remove this when bps is fixed
        // BPS has problems respecting timeouts.
        // Replace the bps_get_event statement
        // with the following commented version
        // once bps is fixed.
        // result = bps_get_event(&event, timeout_ms);
        result = bps_get_event(&event, 0);

        if (result != BPS_SUCCESS)
            qWarning("QEventDispatcherBlackberry::select: bps_get_event() failed");

        if (!event)
            break;

        // pass all received events through filter - except IO ready events
        if (event && bps_event_get_domain(event) != bpsIOReadyDomain)
            filterEvent((void*)event);
    } while (timer.elapsed() < timeout_ms);

    // \TODO Remove this when bps is fixed (see comment above)
    result = bps_remove_fd(d->thread_pipe[0]);
    if (result != BPS_SUCCESS)
        qWarning() << Q_FUNC_INFO << "bps_remove_fd() failed";

    // the number of bits set in the file sets
    return d->ioData->count;
}
Exemple #11
0
void MidiDevice::recordEvent(MidiRecordEvent& event)
      {
      if(MusEGlobal::audio->isPlaying())
        event.setLoopNum(MusEGlobal::audio->loopCount());
      
      if (MusEGlobal::midiInputTrace) {
            fprintf(stderr, "MidiInput: ");
            dumpMPEvent(&event);
            }

      int typ = event.type();
      
      if(_port != -1)
      {
        int idin = MusEGlobal::midiPorts[_port].syncInfo().idIn();
          
        //---------------------------------------------------
        // filter some SYSEX events
        //---------------------------------------------------
  
        if (typ == ME_SYSEX) {
              const unsigned char* p = event.data();
              int n = event.len();
              if (n >= 4) {
                    if ((p[0] == 0x7f)
                      && ((p[1] == 0x7f) || (idin == 0x7f) || (p[1] == idin))) {
                          if (p[2] == 0x06) {
                                MusEGlobal::midiSyncContainer.mmcInput(_port, p, n);
                                return;
                                }
                          if (p[2] == 0x01) {
                                MusEGlobal::midiSyncContainer.mtcInputFull(_port, p, n);
                                return;
                                }
                          }
                    else if (p[0] == 0x7e) {
                          MusEGlobal::midiSyncContainer.nonRealtimeSystemSysex(_port, p, n);
                          return;
                          }
                    }
          }
          else    
            // Trigger general activity indicator detector. Sysex has no channel, don't trigger.
            MusEGlobal::midiPorts[_port].syncInfo().trigActDetect(event.channel());
      }
      
      //
      //  process midi event input filtering and
      //    transformation
      //

      processMidiInputTransformPlugins(event);

      if (filterEvent(event, MusEGlobal::midiRecordType, false))
            return;

      if (!applyMidiInputTransformation(event)) {
            if (MusEGlobal::midiInputTrace)
                  fprintf(stderr, "   midi input transformation: event filtered\n");
            return;
            }

      //
      // transfer noteOn and Off events to gui for step recording and keyboard
      // remote control (changed by flo93: added noteOff-events)
      //
      if (typ == ME_NOTEON) {
            int pv = ((event.dataA() & 0xff)<<8) + (event.dataB() & 0xff);
            MusEGlobal::song->putEvent(pv);
            }
      else if (typ == ME_NOTEOFF) {
            int pv = ((event.dataA() & 0xff)<<8) + (0x00); //send an event with velo=0
            MusEGlobal::song->putEvent(pv);
            }
      
      // Do not bother recording if it is NOT actually being used by a port.
      // Because from this point on, process handles things, by selected port.
      if(_port == -1)
        return;
      
      // Split the events up into channel fifos. Special 'channel' number 17 for sysex events.
      unsigned int ch = (typ == ME_SYSEX)? MusECore::MUSE_MIDI_CHANNELS : event.channel();
      if(_recordFifo[ch].put(event))
        fprintf(stderr, "MidiDevice::recordEvent: fifo channel %d overflow\n", ch);
      }
bool QEventDispatcherGix::processEvents(QEventLoop::ProcessEventsFlags flags)
{
    Q_D(QEventDispatcherGix);
	int rv = 0;

    d->interrupt = false;
    QApplication::sendPostedEvents();
    int nevents = 0;

    do {
        while (!d->interrupt) {
            gi_msg_t event;
            if (!(flags & QEventLoop::ExcludeUserInputEvents)
                && !d->queuedUserInputEvents.isEmpty()) {
                // process a pending user input event
                event = d->queuedUserInputEvents.takeFirst();
            } else if (gi_peek_message(&event) > 0) {
                // process events from the X server
                gi_next_message( &event);

                if (flags & QEventLoop::ExcludeUserInputEvents) {
                    // queue user input events
                    switch (event.type) {
                    case GI_MSG_BUTTON_DOWN:
                    case GI_MSG_BUTTON_UP:
                    case GI_MSG_MOUSE_MOVE:
                    case GI_MSG_KEY_DOWN:
                    case GI_MSG_KEY_UP:
                    case GI_MSG_MOUSE_ENTER:
                    case GI_MSG_MOUSE_EXIT:
                        d->queuedUserInputEvents.append(event);
                        continue;

                    case GI_MSG_CLIENT_MSG:                        
                        d->queuedUserInputEvents.append(event);
                        continue;

                    default:
                        break;
                    }
                }
            } else {
                // no event to process
                break;
            }

            // send through event filter
            if (filterEvent(&event))
                continue;

            nevents++;
			rv = qApp->pfProcessEvent(&event);
            //if (rv == 1)
			{
              //  return true;
			}
        }
    } while (!d->interrupt && gi_get_event_cached(FALSE) > 0);	


 out:
    if (!d->interrupt) {

	 //QEventLoop::GixExcludeTimers 
        const uint exclude_all =
            QEventLoop::ExcludeSocketNotifiers |  QEventLoop::WaitForMoreEvents;
        if (nevents > 0 && ((uint)flags & exclude_all) == exclude_all) {
            QApplication::sendPostedEvents();
            return nevents > 0;
        }
        // return true if we handled events, false otherwise
        return QEventDispatcherUNIX::processEvents(flags) ||  (nevents > 0);
    }

	if (configRequests )                        // any pending configs?
        qWinProcessConfigRequests();

    return nevents > 0;
}
int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
                                       timeval *timeout)
{
    Q_UNUSED(nfds);
    Q_D(QEventDispatcherBlackberry);
    const BBScopedLoopLevelCounter bbLoopCounter(d);

    BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);

    // prepare file sets for bps callback
    d->ioData->count = 0;
    d->ioData->readfds = readfds;
    d->ioData->writefds = writefds;
    d->ioData->exceptfds = exceptfds;

    // reset all file sets
    if (readfds)
        FD_ZERO(readfds);

    if (writefds)
        FD_ZERO(writefds);

    if (exceptfds)
        FD_ZERO(exceptfds);

    bps_event_t *event = 0;
    unsigned int eventCount = 0;

    // If an event handler called through filterEvent() starts a nested event loop by creating a
    // new QEventLoop, we will recursively enter this function again.  However, each time
    // bps_get_event() is called, it destroys the last event it handed out before returning the
    // next event.  We don't want it to destroy the event that triggered the nested event loop,
    // since there may still be more handlers that need to get that event, once the nested event
    // loop is done and control returns to the outer event loop.
    //
    // So we move an event to a holding channel, which takes ownership of the event.  Putting
    // the event on our own channel allows us to manage when it is destroyed, keeping it alive
    // until we know we are done with it.  Each recursive call of this function needs to have
    // it's own holding channel, since a channel is a queue, not a stack.
    //
    // However, a recursive call into this function happens very rarely compared to the many
    // times this function is called.  We don't want to create a holding channel for each time
    // this function is called, only when it is called recursively.  Thus we have the instance
    // variable d->holding_channel to use in the common case.  We keep track of recursive calls
    // with d->loop_level.  If we are in a recursive call, then we create a new holding channel
    // for this run.
    int holding_channel = d->holding_channel;
    if ((d->loop_level > 1) &&
        Q_UNLIKELY(bps_channel_create(&holding_channel, 0) != BPS_SUCCESS)) {
        qWarning("QEventDispatcherBlackberry: bps_channel_create failed");
        holding_channel = -1;
    }

    // Convert timeout to milliseconds
    int timeoutTotal = -1;
    if (timeout)
        timeoutTotal = timevalToMillisecs(*timeout);
    int timeoutLeft = timeoutTotal;
    timeval startTime = qt_gettime();

    // This loop exists such that we can drain the bps event queue of all native events
    // more efficiently than if we were to return control to Qt after each event. This
    // is important for handling touch events which can come in rapidly.
    forever {
        // Only emit the awake() and aboutToBlock() signals in the second iteration. For the
        // first iteration, the UNIX event dispatcher will have taken care of that already.
        // Also native events are actually processed one loop iteration after they were
        // retrieved with bps_get_event().

        // Filtering the native event should happen between the awake() and aboutToBlock()
        // signal emissions. The calls awake() - filterNativeEvent() - aboutToBlock() -
        // bps_get_event() need not to be interrupted by a break or return statement.
        if (eventCount > 0) {
            if (event) {
                emit awake();
                filterEvent(static_cast<void*>(event));
                emit aboutToBlock();

                if (Q_LIKELY(holding_channel != -1)) {
                    // We are now done with this BPS event.  Destroy it.
                    destroyHeldBpsEvent(holding_channel);
                }
            }

            // Update the timeout
            // Clock source is monotonic, so we can recalculate how much timeout is left
            if (timeoutTotal != -1) {
                timeval t2 = qt_gettime();
                timeoutLeft = timeoutTotal
                              - (timevalToMillisecs(t2) - timevalToMillisecs(startTime));
                if (timeoutLeft < 0)
                    timeoutLeft = 0;
            }

            timeval tnext;
            if (d->timerList.timerWait(tnext)) {
                int timeoutNext = timevalToMillisecs(tnext);
                if (timeoutNext < timeoutLeft || timeoutTotal == -1) {
                    timeoutTotal = timeoutLeft = timeoutNext;
                    startTime = qt_gettime();
                }
            }
        }

        event = 0;
        {   // We need to increase loop level in this scope,
            // because bps_get_event can also invoke callbacks
            QScopedLoopLevelCounter loopLevelCounter(d->threadData);

            // Wait for event or file to be ready
            const int result = bps_get_event(&event, timeoutLeft);
            if (Q_UNLIKELY(result != BPS_SUCCESS))
                qWarning("QEventDispatcherBlackberry: bps_get_event failed");
        }

        if (!event)    // In case of !event, we break out of the loop to let Qt process the timers
            break;     // (since timeout has expired) and socket notifiers that are now ready.

        if (bps_event_get_domain(event) == bpsUnblockDomain) {
            timeoutTotal = 0;   // in order to immediately drain the event queue of native events
            event = 0;          // (especially touch move events) we don't break out here
        } else {
            // Move the event to our holding channel so we can manage when it is destroyed.
            if (Q_LIKELY(holding_channel != 1) &&
                Q_UNLIKELY(bps_channel_push_event(holding_channel, event) != BPS_SUCCESS)) {
                qWarning("QEventDispatcherBlackberry: bps_channel_push_event failed");
            }
        }

        ++eventCount;

        // Make sure we are not trapped in this loop due to continuous native events
        // also we cannot recalculate the timeout without a monotonic clock as the time may have changed
        const unsigned int maximumEventCount = 12;
        if (Q_UNLIKELY((eventCount > maximumEventCount && timeoutLeft == 0)
                       || !QElapsedTimer::isMonotonic())) {
            if (event) {
                filterEvent(static_cast<void*>(event));

                if (Q_LIKELY(holding_channel != -1)) {
                    // We are now done with this BPS event.  Destroy it.
                    destroyHeldBpsEvent(holding_channel);
                }
            }
            break;
        }
    }

    // If this was a recursive call into this function, a new holding channel was created for
    // this run, so destroy it now.
    if ((holding_channel != d->holding_channel) &&
        Q_LIKELY(holding_channel != -1) &&
        Q_UNLIKELY(bps_channel_destroy(holding_channel) != BPS_SUCCESS)) {
        qWarning("QEventDispatcherBlackberry: bps_channel_destroy failed");
    }

    // the number of bits set in the file sets
    return d->ioData->count;
}
void
StreamFilter::handleUpstreamEvent(const Event& event, void* /*unused*/)
{
    filterEvent(event);
}
Exemple #15
0
int main(int argc, char *argv[])
{
  FILE *f;
  //int start = 0, fc = 0, fo = 0, opt, i;
  long long int res = 0, done = 0;
  int first_param;

  first_param = param(argc, argv);
  if (argc - first_param < 1) {
    help(argv[0]);
  }

  createPidsFilter(relevant_pids);

  if (strcmp(argv[first_param], "-")) {
    f = fopen(argv[first_param], "r");
  } else {
    f = stdin;
  }
  if (f == NULL) {
    perror("Cannot open input file");

    return -1;
  }

  while (!done) {
    struct event *e;

    switch (trace_type) {
      case FTRACE:
	res = ftrace_parse(f);
	break;
      case OFTRACE:
	res = oftrace_parse(f);
	break;
      case JTRACE:
	res = jtrace_read(f);
	break;
      case L4TRACE:
        res = l4trace_parse(f);
	break;
      case TRCUTILS:
	res = trace_read(f, 0);
	break;
      case XTRACE:
	res = trace_read(f, 1);
	break;
      default:
	fprintf(stderr,
		"Unknown trace type: this shouldn't have happened...\n");
	exit(-1);
    }
    while (e = evt_get()) {
      filterEvent(e);
      trc_write(e);
      free(e);
    }
    done = feof(f) || (res < 0);
  }

//    endAllTask(time);

  destroyPidsFilter();

  return 0;
}
bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags)
{
    Q_D(QEventDispatcherMac);
#if 0
    //TrackDrag says you may not use the EventManager things..
    if(qt_mac_in_drag) {
        qWarning("Qt: Cannot process events whilst dragging!");
        return false;
    }
#endif
    d->interrupt = false;
    emit awake();

#ifndef QT_MAC_NO_QUICKDRAW
    if(!qt_mac_safe_pdev) { //create an empty widget and this can be used for a port anytime
        QWidget *tlw = new QWidget;
        tlw->setAttribute(Qt::WA_DeleteOnClose);
        tlw->setObjectName(QLatin1String("empty_widget"));
        tlw->hide();
        qt_mac_safe_pdev = tlw;
    }
#endif

    bool retVal = false;
    for (;;) {
        QApplicationPrivate::sendPostedEvents(0, 0, d->threadData);

        if (d->activateTimers() > 0) //send null timers
            retVal = true;

        do {
            EventRef event;
            if (!(flags & QEventLoop::ExcludeUserInputEvents)
                    && !d->queuedUserInputEvents.isEmpty()) {
                // process a pending user input event
                event = d->queuedUserInputEvents.takeFirst();
            } else {
                OSStatus err = ReceiveNextEvent(0,0, kEventDurationNoWait, true, &event);
                if(err != noErr)
                    continue;
                // else
                if (flags & QEventLoop::ExcludeUserInputEvents) {
                     UInt32 ekind = GetEventKind(event),
                            eclass = GetEventClass(event);
                     switch(eclass) {
                         case kEventClassQt:
                             if(ekind != kEventQtRequestContext)
                                 break;
                             // fall through
                         case kEventClassMouse:
                         case kEventClassKeyboard:
                             d->queuedUserInputEvents.append(event);
                             continue;
                     }
                }
            }

            if (!filterEvent(&event) && qt_mac_send_event(flags, event))
                retVal = true;
            ReleaseEvent(event);
        } while(!d->interrupt && GetNumEventsInQueue(GetMainEventQueue()) > 0);

        bool canWait = (d->threadData->canWait
                        && !retVal
                        && !d->interrupt
                        && (flags & QEventLoop::WaitForMoreEvents)
                        && !d->zero_timer_count);
        if (canWait) {
            emit aboutToBlock();
            while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e20, true) == kCFRunLoopRunTimedOut);
            flags &= ~QEventLoop::WaitForMoreEvents;
            emit awake();
        } else {
            CFRunLoopRunInMode(kCFRunLoopDefaultMode, kEventDurationNoWait, true);
            break;
        }
    }
    return retVal;
}
bool QEventDispatcherX11::processEvents(QEventLoop::ProcessEventsFlags flags)
{
    Q_D(QEventDispatcherX11);

    d->interrupt = false;
    QApplication::sendPostedEvents();

    ulong marker = XNextRequest(X11->display);
    int nevents = 0;
    do {
        while (!d->interrupt) {
            XEvent event;
            if (!(flags & QEventLoop::ExcludeUserInputEvents)
                && !d->queuedUserInputEvents.isEmpty()) {
                // process a pending user input event
                event = d->queuedUserInputEvents.takeFirst();
            } else if (XEventsQueued(X11->display, QueuedAlready)) {
                // process events from the X server
                XNextEvent(X11->display, &event);

                if (flags & QEventLoop::ExcludeUserInputEvents) {
                    // queue user input events
                    switch (event.type) {
                    case ButtonPress:
                    case ButtonRelease:
                    case MotionNotify:
                    case XKeyPress:
                    case XKeyRelease:
                    case EnterNotify:
                    case LeaveNotify:
                        d->queuedUserInputEvents.append(event);
                        continue;

                    case ClientMessage:
                        // only keep the wm_take_focus and
                        // _qt_scrolldone protocols, queue all other
                        // client messages
                        if (event.xclient.format == 32) {
                            if (event.xclient.message_type == ATOM(WM_PROTOCOLS) &&
                                (Atom) event.xclient.data.l[0] == ATOM(WM_TAKE_FOCUS)) {
                                break;
                            } else if (event.xclient.message_type == ATOM(_QT_SCROLL_DONE)) {
                                break;
                            }
                        }
                        d->queuedUserInputEvents.append(event);
                        continue;

                    default:
                        break;
                    }
                }
            } else {
                // no event to process
                break;
            }

            // send through event filter
            if (filterEvent(&event))
                continue;

            nevents++;
            if (qApp->x11ProcessEvent(&event) == 1)
                return true;

            if (event.xany.serial >= marker) {
                if (XEventsQueued(X11->display, QueuedAfterFlush))
                    flags &= ~QEventLoop::WaitForMoreEvents;
                goto out;
            }
        }
    } while (!d->interrupt && XEventsQueued(X11->display, QueuedAfterFlush));

 out:
    if (!d->interrupt) {
        const uint exclude_all =
            QEventLoop::ExcludeSocketNotifiers | QEventLoop::X11ExcludeTimers | QEventLoop::WaitForMoreEvents;
        if (nevents > 0 && ((uint)flags & exclude_all) == exclude_all) {
            QApplication::sendPostedEvents();
            return nevents > 0;
        }
        // return true if we handled events, false otherwise
        return QEventDispatcherUNIX::processEvents(flags) ||  (nevents > 0);
    }
    return nevents > 0;
}
Exemple #18
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 (!filterEvent(&msg)) {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            } else if (waitRet >= WAIT_OBJECT_0 && 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 && 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
        QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
    }

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

    return retVal;
}