int AbstractXApplication::exec() {
    /* Show window */
    XMapWindow(_display, _window);

    while(!(_flags & Flag::Exit)) {
        XEvent event;

        /* Closed window */
        if(XCheckTypedWindowEvent(_display, _window, ClientMessage, &event) &&
                Atom(event.xclient.data.l[0]) == _deleteWindow) {
            return 0;
        }

        while(XCheckWindowEvent(_display, _window, INPUT_MASK, &event)) {
            switch(event.type) {
            /* Window resizing */
            case ConfigureNotify: {
                Vector2i size(event.xconfigure.width, event.xconfigure.height);
                if(size != _viewportSize) {
                    _viewportSize = size;
                    viewportEvent(size);
                    _flags |= Flag::Redraw;
                }
            }
            break;

            /* Key/mouse events */
            case KeyPress:
            case KeyRelease: {
                KeyEvent e(static_cast<KeyEvent::Key>(XLookupKeysym(&event.xkey, 0)), static_cast<InputEvent::Modifier>(event.xkey.state), {event.xkey.x, event.xkey.y});
                event.type == KeyPress ? keyPressEvent(e) : keyReleaseEvent(e);
            }
            break;
            case ButtonPress:
            case ButtonRelease: {
                MouseEvent e(static_cast<MouseEvent::Button>(event.xbutton.button), static_cast<InputEvent::Modifier>(event.xkey.state), {event.xbutton.x, event.xbutton.y});
                event.type == ButtonPress ? mousePressEvent(e) : mouseReleaseEvent(e);
            }
            break;

            /* Mouse move events */
            case MotionNotify: {
                MouseMoveEvent e(static_cast<InputEvent::Modifier>(event.xmotion.state), {event.xmotion.x, event.xmotion.y});
                mouseMoveEvent(e);
            }
            break;
            }
        }

        if(_flags & Flag::Redraw) {
            _flags &= ~Flag::Redraw;
            drawEvent();
        } else Utility::sleep(5);
    }

    return 0;
}
예제 #2
0
void NaClApplication::DidChangeView(const pp::View& view) {
    /* Fullscreen switch in progress */
    if(_flags & Flag::FullscreenSwitchInProgress) {
        /* Done, remove the progress flag */
        if(isFullscreen() == bool(_flags & Flag::WillBeFullscreen)) {
            _flags &= ~Flag::FullscreenSwitchInProgress;
            _flags |= Flag::Redraw;
        }

        /* Don't process anything during the switch */
        else return;
    }

    Vector2i size(view.GetRect().width(), view.GetRect().height());

    /* Canvas resized */
    if(_viewportSize != size) {
        _graphics->ResizeBuffers(size.x(), size.y());
        viewportEvent(_viewportSize = size);
    }

    drawEvent();
}
예제 #3
0
void Sdl2Application::mainLoop() {
    #ifndef CORRADE_TARGET_EMSCRIPTEN
    const UnsignedInt timeBefore = _minimalLoopPeriod ? SDL_GetTicks() : 0;
    #endif

    SDL_Event event;
    while(SDL_PollEvent(&event)) {
        switch(event.type) {
            case SDL_WINDOWEVENT:
                switch(event.window.event) {
                    case SDL_WINDOWEVENT_RESIZED: {
                        #ifndef CORRADE_TARGET_IOS
                        viewportEvent({event.window.data1, event.window.data2});
                        #else
                        /* On iOS the window event is in points and not pixels,
                           but we need pixels to call glViewport() properly */
                        Vector2i drawableSize;
                        SDL_GL_GetDrawableSize(_window, &drawableSize.x(), &drawableSize.y());
                        viewportEvent(drawableSize);
                        #endif
                        _flags |= Flag::Redraw;
                    } break;
                    case SDL_WINDOWEVENT_EXPOSED:
                        _flags |= Flag::Redraw;
                        break;
                } break;

            case SDL_KEYDOWN:
            case SDL_KEYUP: {
                KeyEvent e(static_cast<KeyEvent::Key>(event.key.keysym.sym), fixedModifiers(event.key.keysym.mod));
                event.type == SDL_KEYDOWN ? keyPressEvent(e) : keyReleaseEvent(e);
            } break;

            case SDL_MOUSEBUTTONDOWN:
            case SDL_MOUSEBUTTONUP: {
                MouseEvent e(static_cast<MouseEvent::Button>(event.button.button), {event.button.x, event.button.y});
                event.type == SDL_MOUSEBUTTONDOWN ? mousePressEvent(e) : mouseReleaseEvent(e);
            } break;

            case SDL_MOUSEWHEEL:
                if(event.wheel.y != 0) {
                    MouseEvent e(event.wheel.y > 0 ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, {event.wheel.x, event.wheel.y});
                    mousePressEvent(e);
                } break;

            case SDL_MOUSEMOTION: {
                MouseMoveEvent e({event.motion.x, event.motion.y}, {event.motion.xrel, event.motion.yrel}, static_cast<MouseMoveEvent::Button>(event.motion.state));
                mouseMoveEvent(e);
                break;
            }

            case SDL_QUIT:
                #ifndef CORRADE_TARGET_EMSCRIPTEN
                _flags |= Flag::Exit;
                #else
                emscripten_cancel_main_loop();
                #endif
                return;
        }
    }

    /* Tick event */
    if(!(_flags & Flag::NoTickEvent)) tickEvent();

    /* Draw event */
    if(_flags & Flag::Redraw) {
        _flags &= ~Flag::Redraw;
        drawEvent();

        #ifndef CORRADE_TARGET_EMSCRIPTEN
        /* If VSync is not enabled, delay to prevent CPU hogging (if set) */
        if(!(_flags & Flag::VSyncEnabled) && _minimalLoopPeriod) {
            const UnsignedInt loopTime = SDL_GetTicks() - timeBefore;
            if(loopTime < _minimalLoopPeriod)
                SDL_Delay(_minimalLoopPeriod - loopTime);
        }
        #endif

        return;
    }

    #ifndef CORRADE_TARGET_EMSCRIPTEN
    /* If not drawing anything, delay to prevent CPU hogging (if set) */
    if(_minimalLoopPeriod) {
        const UnsignedInt loopTime = SDL_GetTicks() - timeBefore;
        if(loopTime < _minimalLoopPeriod)
            SDL_Delay(_minimalLoopPeriod - loopTime);
    }

    /* Then, if the tick event doesn't need to be called periodically, wait
       indefinitely for next input event */
    if(_flags & Flag::NoTickEvent) SDL_WaitEvent(nullptr);
    #endif
}
예제 #4
0
bool DhQScrollArea::DvhviewportEvent(QEvent* x1) {
  return viewportEvent(x1);
}