Commit 3f2fde2a authored by Cole Robinson's avatar Cole Robinson Committed by Gerd Hoffmann
Browse files

sdl2: Support mouse wheel



In SDL2, wheel movement is its own event, not a button event. Wire
it up similar to gtk.c

Signed-off-by: default avatarCole Robinson <crobinso@redhat.com>
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent 8b15d9f1
Loading
Loading
Loading
Loading
+26 −18
Original line number Diff line number Diff line
@@ -359,16 +359,12 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data)
}

static void sdl_send_mouse_event(struct sdl2_state *scon, int dx, int dy,
                                 int dz, int x, int y, int state)
                                 int x, int y, int state)
{
    static uint32_t bmap[INPUT_BUTTON_MAX] = {
        [INPUT_BUTTON_LEFT]       = SDL_BUTTON(SDL_BUTTON_LEFT),
        [INPUT_BUTTON_MIDDLE]     = SDL_BUTTON(SDL_BUTTON_MIDDLE),
        [INPUT_BUTTON_RIGHT]      = SDL_BUTTON(SDL_BUTTON_RIGHT),
#if 0
        [INPUT_BUTTON_WHEEL_UP]   = SDL_BUTTON(SDL_BUTTON_WHEELUP),
        [INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN),
#endif
    };
    static uint32_t prev_state;

@@ -566,7 +562,7 @@ static void handle_mousemotion(SDL_Event *ev)
        }
    }
    if (gui_grab || qemu_input_is_absolute() || absolute_enabled) {
        sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel, 0,
        sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel,
                             ev->motion.x, ev->motion.y, ev->motion.state);
    }
}
@@ -576,7 +572,6 @@ static void handle_mousebutton(SDL_Event *ev)
    int buttonstate = SDL_GetMouseState(NULL, NULL);
    SDL_MouseButtonEvent *bev;
    struct sdl2_state *scon = get_scon_from_window(ev->key.windowID);
    int dz;

    bev = &ev->button;
    if (!gui_grab && !qemu_input_is_absolute()) {
@@ -585,23 +580,33 @@ static void handle_mousebutton(SDL_Event *ev)
            sdl_grab_start(scon);
        }
    } else {
        dz = 0;
        if (ev->type == SDL_MOUSEBUTTONDOWN) {
            buttonstate |= SDL_BUTTON(bev->button);
        } else {
            buttonstate &= ~SDL_BUTTON(bev->button);
        }
#ifdef SDL_BUTTON_WHEELUP
        if (bev->button == SDL_BUTTON_WHEELUP &&
            ev->type == SDL_MOUSEBUTTONDOWN) {
            dz = -1;
        } else if (bev->button == SDL_BUTTON_WHEELDOWN &&
                   ev->type == SDL_MOUSEBUTTONDOWN) {
            dz = 1;
        sdl_send_mouse_event(scon, 0, 0, bev->x, bev->y, buttonstate);
    }
#endif
        sdl_send_mouse_event(scon, 0, 0, dz, bev->x, bev->y, buttonstate);
}

static void handle_mousewheel(SDL_Event *ev)
{
    struct sdl2_state *scon = get_scon_from_window(ev->key.windowID);
    SDL_MouseWheelEvent *wev = &ev->wheel;
    InputButton btn;

    if (wev->y > 0) {
        btn = INPUT_BUTTON_WHEEL_UP;
    } else if (wev->y < 0) {
        btn = INPUT_BUTTON_WHEEL_DOWN;
    } else {
        return;
    }

    qemu_input_queue_btn(scon->dcl.con, btn, true);
    qemu_input_event_sync();
    qemu_input_queue_btn(scon->dcl.con, btn, false);
    qemu_input_event_sync();
}

static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev)
@@ -685,6 +690,9 @@ static void sdl_refresh(DisplayChangeListener *dcl)
        case SDL_MOUSEBUTTONUP:
            handle_mousebutton(ev);
            break;
        case SDL_MOUSEWHEEL:
            handle_mousewheel(ev);
            break;
        case SDL_WINDOWEVENT:
            handle_windowevent(dcl, ev);
            break;