Esempio n. 1
0
int
SDL_SetRelativeMouseMode(int index, SDL_bool enabled)
{
    SDL_Mouse *mouse = SDL_GetMouse(index);

    if (!mouse) {
        return -1;
    }

    /* Flush pending mouse motion */
    mouse->flush_motion = SDL_TRUE;
    SDL_PumpEvents();
    mouse->flush_motion = SDL_FALSE;
    SDL_FilterEvents(FlushMouseMotion, mouse);

    /* Set the relative mode */
    mouse->relative_mode = enabled;

    /* Update cursor visibility */
    SDL_SetCursor(NULL);

    if (!enabled) {
        /* Restore the expected mouse position */
        SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
    }
    return 0;
}
Esempio n. 2
0
/*
 * SDL.filterEvents(func)
 *
 * The func must have the following signature:
 * 	function filter(event) -> return false to disable
 *
 * Arguments:
 *	func the function
 */
static int
l_event_filterEvents(lua_State *L)
{
	Filter f;

	luaL_checktype(L, 1, LUA_TFUNCTION);

	f.L = L;
	f.type = EventTypeFilter;

	/* Push the temporarly function */
	lua_pushvalue(L, 1);
	f.ref = luaL_ref(L, LUA_REGISTRYINDEX);

	SDL_FilterEvents((SDL_EventFilter)eventFilter, &f);
	luaL_unref(L, LUA_REGISTRYINDEX, f.ref);

	return 0;
}
Esempio n. 3
0
void FilterEvents(void *data)
{
	SDL_FilterEvents(eventFilter, data);
}
Esempio n. 4
0
int
SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
                    int data2)
{
    int posted;

    if (!window) {
        return 0;
    }
    switch (windowevent) {
    case SDL_WINDOWEVENT_SHOWN:
        if (window->flags & SDL_WINDOW_SHOWN) {
            return 0;
        }
        window->flags &= ~SDL_WINDOW_HIDDEN;
        window->flags |= SDL_WINDOW_SHOWN;
        SDL_OnWindowShown(window);
        break;
    case SDL_WINDOWEVENT_HIDDEN:
        if (!(window->flags & SDL_WINDOW_SHOWN)) {
            return 0;
        }
        window->flags &= ~SDL_WINDOW_SHOWN;
        window->flags |= SDL_WINDOW_HIDDEN;
        SDL_OnWindowHidden(window);
        break;
    case SDL_WINDOWEVENT_MOVED:
        if (SDL_WINDOWPOS_ISUNDEFINED(data1) ||
            SDL_WINDOWPOS_ISUNDEFINED(data2)) {
            return 0;
        }
        if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
            window->windowed.x = data1;
            window->windowed.y = data2;
        }
        if (data1 == window->x && data2 == window->y) {
            return 0;
        }
        window->x = data1;
        window->y = data2;
        break;
    case SDL_WINDOWEVENT_RESIZED:
        if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
            window->windowed.w = data1;
            window->windowed.h = data2;
        }
        if (data1 == window->w && data2 == window->h) {
            return 0;
        }
        window->w = data1;
        window->h = data2;
        SDL_OnWindowResized(window);
        break;
    case SDL_WINDOWEVENT_MINIMIZED:
        if (window->flags & SDL_WINDOW_MINIMIZED) {
            return 0;
        }
        window->flags &= ~SDL_WINDOW_MAXIMIZED;
        window->flags |= SDL_WINDOW_MINIMIZED;
        SDL_OnWindowMinimized(window);
        break;
    case SDL_WINDOWEVENT_MAXIMIZED:
        if (window->flags & SDL_WINDOW_MAXIMIZED) {
            return 0;
        }
        window->flags &= ~SDL_WINDOW_MINIMIZED;
        window->flags |= SDL_WINDOW_MAXIMIZED;
        break;
    case SDL_WINDOWEVENT_RESTORED:
        if (!(window->flags & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED))) {
            return 0;
        }
        window->flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED);
        SDL_OnWindowRestored(window);
        break;
    case SDL_WINDOWEVENT_ENTER:
        if (window->flags & SDL_WINDOW_MOUSE_FOCUS) {
            return 0;
        }
        window->flags |= SDL_WINDOW_MOUSE_FOCUS;
        SDL_OnWindowEnter(window);
        break;
    case SDL_WINDOWEVENT_LEAVE:
        if (!(window->flags & SDL_WINDOW_MOUSE_FOCUS)) {
            return 0;
        }
        window->flags &= ~SDL_WINDOW_MOUSE_FOCUS;
        SDL_OnWindowLeave(window);
        break;
    case SDL_WINDOWEVENT_FOCUS_GAINED:
        if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
            return 0;
        }
        window->flags |= SDL_WINDOW_INPUT_FOCUS;
        SDL_OnWindowFocusGained(window);
        break;
    case SDL_WINDOWEVENT_FOCUS_LOST:
        if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
            return 0;
        }
        window->flags &= ~SDL_WINDOW_INPUT_FOCUS;
        SDL_OnWindowFocusLost(window);
        break;
    }

    /* Post the event, if desired */
    posted = 0;
    if (SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE) {
        SDL_Event event;
        event.type = SDL_WINDOWEVENT;
        event.window.event = windowevent;
        event.window.data1 = data1;
        event.window.data2 = data2;
        event.window.windowID = window->id;

        /* Fixes queue overflow with resize events that aren't processed */
        if (windowevent == SDL_WINDOWEVENT_RESIZED) {
            SDL_FilterEvents(RemovePendingResizedEvents, &event);
        }
        if (windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) {
            SDL_FilterEvents(RemovePendingSizeChangedEvents, &event);
        }
        if (windowevent == SDL_WINDOWEVENT_MOVED) {
            SDL_FilterEvents(RemovePendingMoveEvents, &event);
        }
        if (windowevent == SDL_WINDOWEVENT_EXPOSED) {
            SDL_FilterEvents(RemovePendingExposedEvents, &event);
        }
        posted = (SDL_PushEvent(&event) > 0);
    }

    if (windowevent == SDL_WINDOWEVENT_CLOSE) {
        if ( !window->prev && !window->next ) {
            /* This is the last window in the list so send the SDL_QUIT event */
            SDL_SendQuit();
        }
    }

    return (posted);
}
Esempio n. 5
0
    void window::update()
    {
        input_state.advance_frame();

        SDL_PumpEvents();

        SDL_FilterEvents
        (
            [] (void* userdata, SDL_Event* event) -> int
            {
                // Return 0 to remove an event from the queue, anything else to
                // keep the event in the queue.

                auto&& window = static_cast<class window*>(userdata);
                auto&& window_id = SDL_GetWindowID(window->handle.get());

                switch (event->type)
                {
                    case SDL_KEYDOWN:
                    case SDL_KEYUP:
                    {
                        if (event->key.windowID != window_id)
                        {
                            return 1;
                        }

                        auto&& keycode = input::sdl_keycode_to_polygonist_keycode(event->key.keysym.sym);

                        if (event->key.state == SDL_PRESSED)
                        {
                            window->input_state.key_press(keycode);
                        }
                        else if (event->key.state == SDL_RELEASED)
                        {
                            window->input_state.key_release(keycode);
                        }

                        break;
                    }

                    case SDL_MOUSEBUTTONDOWN:
                    case SDL_MOUSEBUTTONUP:
                    {
                        if (event->button.windowID != window_id)
                        {
                            return 1;
                        }

                        auto&& button = input::sdl_button_to_polygonist_mouse_button(event->button.button);
                        auto&& button_index = static_cast<size_t>(button);

                        if (event->button.state == SDL_PRESSED)
                        {
                            window->input_state.mouse_press(button, event->button.clicks);
                        }
                        else if (event->button.state == SDL_RELEASED)
                        {
                            window->input_state.mouse_release(button);
                        }

                        break;
                    }

                    case SDL_MOUSEWHEEL:
                    {
                        if (event->wheel.windowID != window_id)
                        {
                            return 1;
                        }

                        // TODO: Use preciseX and preciseY after SDL 2.1 comes
                        // out. https://bugzilla.libsdl.org/show_bug.cgi?id=2293

                        // TODO: do we need to DPI scale these values?

                        if (event->wheel.direction == SDL_MOUSEWHEEL_FLIPPED)
                        {
                            window->input_state.mouse_wheel(-event->wheel.x, -event->wheel.y);
                        }
                        else
                        {
                            window->input_state.mouse_wheel(event->wheel.x, event->wheel.y);
                        }

                        break;
                    }

                    case SDL_TEXTINPUT:
                    {
                        if (event->text.windowID != window_id)
                        {
                            return 1;
                        }

                        window->input_state.text_input(event->text.text);

                        break;
                    }

                    case SDL_TEXTEDITING:
                    {
                        if (event->edit.windowID != window_id)
                        {
                            return 1;
                        }

                        window->input_state.text_composition(event->edit.text, event->edit.start, event->edit.length);

                        break;
                    }

                    case SDL_WINDOWEVENT:

                        if (event->window.windowID != window_id)
                        {
                            return 1;
                        }

                        switch (event->window.event)
                        {
                            case SDL_WINDOWEVENT_MOVED:
                            {
                                auto&& x = static_cast<unsigned int>(event->window.data1);
                                auto&& y = static_cast<unsigned int>(event->window.data2);

                                window->move_event.fire(x, y);

                                break;
                            }

                            case SDL_WINDOWEVENT_SIZE_CHANGED:
                            {
                                auto&& width = static_cast<unsigned int>(event->window.data1);
                                auto&& height = static_cast<unsigned int>(event->window.data2);

                                window->size = { width, height };
                                window->aspect_ratio = static_cast<float>(width) / static_cast<float>(height);
                                window->cache_backbuffer_size();

                                window->resize_event.fire(width, height);

                                break;
                            }

                            case SDL_WINDOWEVENT_CLOSE:

                                window->close();
                                break;

                            case SDL_WINDOWEVENT_ENTER:

                                mouse_focus_window = window;
                                break;

                            case SDL_WINDOWEVENT_LEAVE:

                                // mouse_focus_window = nullptr;
                                break;

                            case SDL_WINDOWEVENT_FOCUS_GAINED:

                                keyboard_focus_window = window;
                                break;

                            case SDL_WINDOWEVENT_FOCUS_LOST:

                                keyboard_focus_window = nullptr;
                                break;
                        }

                        break;

                    case SDL_SYSWMEVENT:

                        return get_application_menu()->handle_event(event->syswm.msg);

                    case SDL_QUIT:

                        window->close();

                        // Don't remove quit events from the queue. All windows
                        // need to handle them.

                        return 1;
                }

                return 0;
            },

            this
        );

        // TODO: On Windows we can use WM_DPICHANGED to detect this.

        auto&& dpi = get_dpi();

        if (this->dpi.get() != dpi)
        {
            this->dpi = dpi;

            dpi_change_event.fire(dpi.get_x(), dpi.get_y());
        }

        mouse_focus_window = has_mouse_focus() ? this : mouse_focus_window;
        keyboard_focus_window = has_keyboard_focus() ? this : keyboard_focus_window;

        // Handles any pending deletions that must be done in the shared
        // graphics context and couldn't be done in the texture destructor.

        graphics::texture::free_textures_pending_deletion();

        // We may not want to do this every frame. If it turns out that we're
        // freeing stuff too early, move this into some strategic places around
        // the code. We could do this on a timer or a memory threshold as well.

        asset::free_unused_assets();
    }