/*
 * QEMU SDL display driver
 *
 * Copyright (c) 2003 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
/* Ported SDL 1.2 code to 2.0 by Dave Airlie. */

/* Avoid compiler warning because macro is redefined in SDL_syswm.h. */
#undef WIN32_LEAN_AND_MEAN

#include <SDL.h>

#if SDL_MAJOR_VERSION == 2
#include <SDL_syswm.h>

#include "qemu-common.h"
#include "ui/console.h"
#include "ui/input.h"
#include "sysemu/sysemu.h"

#include "sdl2-keymap.h"

static int sdl2_num_outputs;
static struct sdl2_state {
    DisplayChangeListener dcl;
    DisplaySurface *surface;
    SDL_Texture *texture;
    SDL_Window *real_window;
    SDL_Renderer *real_renderer;
    int idx;
    int last_vm_running; /* per console for caption reasons */
    int x, y;
    int hidden;
} *sdl2_console;

static SDL_Surface *guest_sprite_surface;
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */

static bool gui_saved_scaling;
static int gui_saved_width;
static int gui_saved_height;
static int gui_saved_grab;
static int gui_fullscreen;
static int gui_noframe;
static int gui_key_modifier_pressed;
static int gui_keysym;
static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
static uint8_t modifiers_state[SDL_NUM_SCANCODES];
static SDL_Cursor *sdl_cursor_normal;
static SDL_Cursor *sdl_cursor_hidden;
static int absolute_enabled;
static int guest_cursor;
static int guest_x, guest_y;
static SDL_Cursor *guest_sprite;
static int scaling_active;
static Notifier mouse_mode_notifier;

static void sdl_update_caption(struct sdl2_state *scon);

static struct sdl2_state *get_scon_from_window(uint32_t window_id)
{
    int i;
    for (i = 0; i < sdl2_num_outputs; i++) {
        if (sdl2_console[i].real_window == SDL_GetWindowFromID(window_id)) {
            return &sdl2_console[i];
        }
    }
    return NULL;
}

static void sdl_update(DisplayChangeListener *dcl,
                       int x, int y, int w, int h)
{
    struct sdl2_state *scon = container_of(dcl, struct sdl2_state, dcl);
    SDL_Rect rect;
    DisplaySurface *surf = qemu_console_surface(dcl->con);

    if (!surf) {
        return;
    }
    if (!scon->texture) {
        return;
    }

    rect.x = x;
    rect.y = y;
    rect.w = w;
    rect.h = h;

    SDL_UpdateTexture(scon->texture, NULL, surface_data(surf),
                      surface_stride(surf));
    SDL_RenderCopy(scon->real_renderer, scon->texture, &rect, &rect);
    SDL_RenderPresent(scon->real_renderer);
}

static void do_sdl_resize(struct sdl2_state *scon, int width, int height,
                          int bpp)
{
    int flags;

    if (scon->real_window && scon->real_renderer) {
        if (width && height) {
            SDL_RenderSetLogicalSize(scon->real_renderer, width, height);
            SDL_SetWindowSize(scon->real_window, width, height);
        } else {
            SDL_DestroyRenderer(scon->real_renderer);
            SDL_DestroyWindow(scon->real_window);
            scon->real_renderer = NULL;
            scon->real_window = NULL;
        }
    } else {
        if (!width || !height) {
            return;
        }
        flags = 0;
        if (gui_fullscreen) {
            flags |= SDL_WINDOW_FULLSCREEN;
        } else {
            flags |= SDL_WINDOW_RESIZABLE;
        }
        if (scon->hidden) {
            flags |= SDL_WINDOW_HIDDEN;
        }

        scon->real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED,
                                             SDL_WINDOWPOS_UNDEFINED,
                                             width, height, flags);
        scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0);
        sdl_update_caption(scon);
    }
}

static void sdl_switch(DisplayChangeListener *dcl,
                       DisplaySurface *new_surface)
{
    struct sdl2_state *scon = container_of(dcl, struct sdl2_state, dcl);
    int format = 0;
    int idx = scon->idx;
    DisplaySurface *old_surface = scon->surface;

    /* temporary hack: allows to call sdl_switch to handle scaling changes */
    if (new_surface) {
        scon->surface = new_surface;
    }

    if (!new_surface && idx > 0) {
        scon->surface = NULL;
    }

    if (new_surface == NULL) {
        do_sdl_resize(scon, 0, 0, 0);
    } else {
        do_sdl_resize(scon, surface_width(scon->surface),
                      surface_height(scon->surface), 0);
    }

    if (old_surface && scon->texture) {
        SDL_DestroyTexture(scon->texture);
        scon->texture = NULL;
    }

    if (new_surface) {
        if (!scon->texture) {
            if (surface_bits_per_pixel(scon->surface) == 16) {
                format = SDL_PIXELFORMAT_RGB565;
            } else if (surface_bits_per_pixel(scon->surface) == 32) {
                format = SDL_PIXELFORMAT_ARGB8888;
            }

            scon->texture = SDL_CreateTexture(scon->real_renderer, format,
                                              SDL_TEXTUREACCESS_STREAMING,
                                              surface_width(new_surface),
                                              surface_height(new_surface));
        }
    }
}

static void reset_keys(struct sdl2_state *scon)
{
    QemuConsole *con = scon ? scon->dcl.con : NULL;
    int i;

    for (i = 0; i < 256; i++) {
        if (modifiers_state[i]) {
            int qcode = sdl2_scancode_to_qcode[i];
            qemu_input_event_send_key_qcode(con, qcode, false);
            modifiers_state[i] = 0;
        }
    }
}

static void sdl_process_key(struct sdl2_state *scon,
                            SDL_KeyboardEvent *ev)
{
    int qcode = sdl2_scancode_to_qcode[ev->keysym.scancode];
    QemuConsole *con = scon ? scon->dcl.con : NULL;

    if (!qemu_console_is_graphic(con)) {
        if (ev->type == SDL_KEYDOWN) {
            switch (ev->keysym.scancode) {
            case SDL_SCANCODE_RETURN:
                kbd_put_keysym_console(con, '\n');
                break;
            case SDL_SCANCODE_BACKSPACE:
                kbd_put_keysym_console(con, QEMU_KEY_BACKSPACE);
                break;
            default:
                kbd_put_qcode_console(con, qcode);
                break;
            }
        }
        return;
    }

    switch (ev->keysym.scancode) {
#if 0
    case SDL_SCANCODE_NUMLOCKCLEAR:
    case SDL_SCANCODE_CAPSLOCK:
        /* SDL does not send the key up event, so we generate it */
        qemu_input_event_send_key_qcode(con, qcode, true);
        qemu_input_event_send_key_qcode(con, qcode, false);
        return;
#endif
    case SDL_SCANCODE_LCTRL:
    case SDL_SCANCODE_LSHIFT:
    case SDL_SCANCODE_LALT:
    case SDL_SCANCODE_LGUI:
    case SDL_SCANCODE_RCTRL:
    case SDL_SCANCODE_RSHIFT:
    case SDL_SCANCODE_RALT:
    case SDL_SCANCODE_RGUI:
        if (ev->type == SDL_KEYUP) {
            modifiers_state[ev->keysym.scancode] = 0;
        } else {
            modifiers_state[ev->keysym.scancode] = 1;
        }
        /* fall though */
    default:
        qemu_input_event_send_key_qcode(con, qcode,
                                        ev->type == SDL_KEYDOWN);
    }
}

static void sdl_update_caption(struct sdl2_state *scon)
{
    char win_title[1024];
    char icon_title[1024];
    const char *status = "";

    if (!runstate_is_running()) {
        status = " [Stopped]";
    } else if (gui_grab) {
        if (alt_grab) {
            status = " - Press Ctrl-Alt-Shift to exit mouse grab";
        } else if (ctrl_grab) {
            status = " - Press Right-Ctrl to exit mouse grab";
        } else {
            status = " - Press Ctrl-Alt to exit mouse grab";
        }
    }

    if (qemu_name) {
        snprintf(win_title, sizeof(win_title), "QEMU (%s-%d)%s", qemu_name,
                 scon->idx, status);
        snprintf(icon_title, sizeof(icon_title), "QEMU (%s)", qemu_name);
    } else {
        snprintf(win_title, sizeof(win_title), "QEMU%s", status);
        snprintf(icon_title, sizeof(icon_title), "QEMU");
    }

    if (scon->real_window) {
        SDL_SetWindowTitle(scon->real_window, win_title);
    }
}

static void sdl_hide_cursor(void)
{
    if (!cursor_hide) {
        return;
    }

    if (qemu_input_is_absolute()) {
        SDL_ShowCursor(1);
        SDL_SetCursor(sdl_cursor_hidden);
    } else {
        SDL_SetRelativeMouseMode(SDL_TRUE);
    }
}

static void sdl_show_cursor(void)
{
    if (!cursor_hide) {
        return;
    }

    if (!qemu_input_is_absolute()) {
        SDL_SetRelativeMouseMode(SDL_FALSE);
        SDL_ShowCursor(1);
        if (guest_cursor &&
            (gui_grab || qemu_input_is_absolute() || absolute_enabled)) {
            SDL_SetCursor(guest_sprite);
        } else {
            SDL_SetCursor(sdl_cursor_normal);
        }
    }
}

static void sdl_grab_start(struct sdl2_state *scon)
{
    QemuConsole *con = scon ? scon->dcl.con : NULL;

    if (!con || !qemu_console_is_graphic(con)) {
        return;
    }
    /*
     * If the application is not active, do not try to enter grab state. This
     * prevents 'SDL_WM_GrabInput(SDL_GRAB_ON)' from blocking all the
     * application (SDL bug).
     */
    if (!(SDL_GetWindowFlags(scon->real_window) & SDL_WINDOW_INPUT_FOCUS)) {
        return;
    }
    if (guest_cursor) {
        SDL_SetCursor(guest_sprite);
        if (!qemu_input_is_absolute() && !absolute_enabled) {
            SDL_WarpMouseInWindow(scon->real_window, guest_x, guest_y);
        }
    } else {
        sdl_hide_cursor();
    }
    SDL_SetWindowGrab(scon->real_window, SDL_TRUE);
    gui_grab = 1;
    sdl_update_caption(scon);
}

static void sdl_grab_end(struct sdl2_state *scon)
{
    SDL_SetWindowGrab(scon->real_window, SDL_FALSE);
    gui_grab = 0;
    sdl_show_cursor();
    sdl_update_caption(scon);
}

static void absolute_mouse_grab(struct sdl2_state *scon)
{
    int mouse_x, mouse_y;
    int scr_w, scr_h;
    SDL_GetMouseState(&mouse_x, &mouse_y);
    SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);
    if (mouse_x > 0 && mouse_x < scr_w - 1 &&
        mouse_y > 0 && mouse_y < scr_h - 1) {
        sdl_grab_start(scon);
    }
}

static void sdl_mouse_mode_change(Notifier *notify, void *data)
{
    if (qemu_input_is_absolute()) {
        if (!absolute_enabled) {
            absolute_enabled = 1;
            absolute_mouse_grab(&sdl2_console[0]);
        }
    } else if (absolute_enabled) {
        if (!gui_fullscreen) {
            sdl_grab_end(&sdl2_console[0]);
        }
        absolute_enabled = 0;
    }
}

static void sdl_send_mouse_event(struct sdl2_state *scon, int dx, int dy,
                                 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),
    };
    static uint32_t prev_state;

    if (prev_state != state) {
        qemu_input_update_buttons(scon->dcl.con, bmap, prev_state, state);
        prev_state = state;
    }

    if (qemu_input_is_absolute()) {
        int scr_w, scr_h;
        int max_w = 0, max_h = 0;
        int off_x = 0, off_y = 0;
        int cur_off_x = 0, cur_off_y = 0;
        int i;

        for (i = 0; i < sdl2_num_outputs; i++) {
            struct sdl2_state *thiscon = &sdl2_console[i];
            if (thiscon->real_window && thiscon->surface) {
                SDL_GetWindowSize(thiscon->real_window, &scr_w, &scr_h);
                cur_off_x = thiscon->x;
                cur_off_y = thiscon->y;
                if (scr_w + cur_off_x > max_w) {
                    max_w = scr_w + cur_off_x;
                }
                if (scr_h + cur_off_y > max_h) {
                    max_h = scr_h + cur_off_y;
                }
                if (i == scon->idx) {
                    off_x = cur_off_x;
                    off_y = cur_off_y;
                }
            }
        }
        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, off_x + x, max_w);
        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, off_y + y, max_h);
    } else {
        if (guest_cursor) {
            x -= guest_x;
            y -= guest_y;
            guest_x += x;
            guest_y += y;
            dx = x;
            dy = y;
        }
        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_X, dx);
        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_Y, dy);
    }
    qemu_input_event_sync();
}

static void sdl_scale(struct sdl2_state *scon, int width, int height)
{
    int bpp = 0;
    do_sdl_resize(scon, width, height, bpp);
    scaling_active = 1;
}

static void toggle_full_screen(struct sdl2_state *scon)
{
    int width = surface_width(scon->surface);
    int height = surface_height(scon->surface);
    int bpp = surface_bits_per_pixel(scon->surface);

    gui_fullscreen = !gui_fullscreen;
    if (gui_fullscreen) {
        SDL_GetWindowSize(scon->real_window,
                          &gui_saved_width, &gui_saved_height);
        gui_saved_scaling = scaling_active;

        do_sdl_resize(scon, width, height, bpp);
        scaling_active = 0;

        gui_saved_grab = gui_grab;
        sdl_grab_start(scon);
    } else {
        if (gui_saved_scaling) {
            sdl_scale(scon, gui_saved_width, gui_saved_height);
        } else {
            do_sdl_resize(scon, width, height, 0);
        }
        if (!gui_saved_grab) {
            sdl_grab_end(scon);
        }
    }
    graphic_hw_invalidate(scon->dcl.con);
    graphic_hw_update(scon->dcl.con);
}

static void handle_keydown(SDL_Event *ev)
{
    int mod_state, win;
    struct sdl2_state *scon = get_scon_from_window(ev->key.windowID);

    if (alt_grab) {
        mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
            (gui_grab_code | KMOD_LSHIFT);
    } else if (ctrl_grab) {
        mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL;
    } else {
        mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code;
    }
    gui_key_modifier_pressed = mod_state;

    if (gui_key_modifier_pressed) {
        switch (ev->key.keysym.scancode) {
        case SDL_SCANCODE_2:
        case SDL_SCANCODE_3:
        case SDL_SCANCODE_4:
        case SDL_SCANCODE_5:
        case SDL_SCANCODE_6:
        case SDL_SCANCODE_7:
        case SDL_SCANCODE_8:
        case SDL_SCANCODE_9:
            win = ev->key.keysym.scancode - SDL_SCANCODE_1;
            if (win < sdl2_num_outputs) {
                sdl2_console[win].hidden = !sdl2_console[win].hidden;
                if (sdl2_console[win].real_window) {
                    if (sdl2_console[win].hidden) {
                        SDL_HideWindow(sdl2_console[win].real_window);
                    } else {
                        SDL_ShowWindow(sdl2_console[win].real_window);
                    }
                }
                gui_keysym = 1;
            }
            break;
        case SDL_SCANCODE_F:
            toggle_full_screen(scon);
            gui_keysym = 1;
            break;
        case SDL_SCANCODE_U:
            if (scaling_active) {
                scaling_active = 0;
                sdl_switch(&scon->dcl, NULL);
                graphic_hw_invalidate(scon->dcl.con);
                graphic_hw_update(scon->dcl.con);
            }
            gui_keysym = 1;
            break;
        case SDL_SCANCODE_KP_PLUS:
        case SDL_SCANCODE_KP_MINUS:
            if (!gui_fullscreen) {
                int scr_w, scr_h;
                int width, height;
                SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);

                width = MAX(scr_w + (ev->key.keysym.scancode ==
                                     SDL_SCANCODE_KP_PLUS ? 50 : -50),
                            160);
                height = (surface_height(scon->surface) * width) /
                    surface_width(scon->surface);

                sdl_scale(scon, width, height);
                graphic_hw_invalidate(NULL);
                graphic_hw_update(NULL);
                gui_keysym = 1;
            }
        default:
            break;
        }
    }
    if (!gui_keysym) {
        sdl_process_key(scon, &ev->key);
    }
}

static void handle_keyup(SDL_Event *ev)
{
    int mod_state;
    struct sdl2_state *scon = get_scon_from_window(ev->key.windowID);

    if (!alt_grab) {
        mod_state = (ev->key.keysym.mod & gui_grab_code);
    } else {
        mod_state = (ev->key.keysym.mod & (gui_grab_code | KMOD_LSHIFT));
    }
    if (!mod_state && gui_key_modifier_pressed) {
        gui_key_modifier_pressed = 0;
        if (gui_keysym == 0) {
            /* exit/enter grab if pressing Ctrl-Alt */
            if (!gui_grab) {
                sdl_grab_start(scon);
            } else if (!gui_fullscreen) {
                sdl_grab_end(scon);
            }
            /* SDL does not send back all the modifiers key, so we must
             * correct it. */
            reset_keys(scon);
            return;
        }
        gui_keysym = 0;
    }
    if (!gui_keysym) {
        sdl_process_key(scon, &ev->key);
    }
}

static void handle_textinput(SDL_Event *ev)
{
    struct sdl2_state *scon = get_scon_from_window(ev->key.windowID);
    QemuConsole *con = scon ? scon->dcl.con : NULL;

    if (qemu_console_is_graphic(con)) {
        return;
    }
    kbd_put_string_console(con, ev->text.text, strlen(ev->text.text));
}

static void handle_mousemotion(SDL_Event *ev)
{
    int max_x, max_y;
    struct sdl2_state *scon = get_scon_from_window(ev->key.windowID);

    if (qemu_input_is_absolute() || absolute_enabled) {
        int scr_w, scr_h;
        SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);
        max_x = scr_w - 1;
        max_y = scr_h - 1;
        if (gui_grab && (ev->motion.x == 0 || ev->motion.y == 0 ||
                         ev->motion.x == max_x || ev->motion.y == max_y)) {
            sdl_grab_end(scon);
        }
        if (!gui_grab &&
            (ev->motion.x > 0 && ev->motion.x < max_x &&
             ev->motion.y > 0 && ev->motion.y < max_y)) {
            sdl_grab_start(scon);
        }
    }
    if (gui_grab || qemu_input_is_absolute() || absolute_enabled) {
        sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel,
                             ev->motion.x, ev->motion.y, ev->motion.state);
    }
}

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);

    bev = &ev->button;
    if (!gui_grab && !qemu_input_is_absolute()) {
        if (ev->type == SDL_MOUSEBUTTONUP && bev->button == SDL_BUTTON_LEFT) {
            /* start grabbing all events */
            sdl_grab_start(scon);
        }
    } else {
        if (ev->type == SDL_MOUSEBUTTONDOWN) {
            buttonstate |= SDL_BUTTON(bev->button);
        } else {
            buttonstate &= ~SDL_BUTTON(bev->button);
        }
        sdl_send_mouse_event(scon, 0, 0, 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)
{
    int w, h;
    struct sdl2_state *scon = get_scon_from_window(ev->key.windowID);

    switch (ev->window.event) {
    case SDL_WINDOWEVENT_RESIZED:
        sdl_scale(scon, ev->window.data1, ev->window.data2);
        {
            QemuUIInfo info;
            memset(&info, 0, sizeof(info));
            info.width = ev->window.data1;
            info.height = ev->window.data2;
            dpy_set_ui_info(scon->dcl.con, &info);
        }
        graphic_hw_invalidate(scon->dcl.con);
        graphic_hw_update(scon->dcl.con);
        break;
    case SDL_WINDOWEVENT_EXPOSED:
        SDL_GetWindowSize(SDL_GetWindowFromID(ev->window.windowID), &w, &h);
        sdl_update(dcl, 0, 0, w, h);
        break;
    case SDL_WINDOWEVENT_FOCUS_GAINED:
    case SDL_WINDOWEVENT_ENTER:
        if (!gui_grab && (qemu_input_is_absolute() || absolute_enabled)) {
            absolute_mouse_grab(scon);
        }
        break;
    case SDL_WINDOWEVENT_FOCUS_LOST:
        if (gui_grab && !gui_fullscreen) {
            sdl_grab_end(scon);
        }
        break;
    case SDL_WINDOWEVENT_RESTORED:
        update_displaychangelistener(dcl, GUI_REFRESH_INTERVAL_DEFAULT);
        break;
    case SDL_WINDOWEVENT_MINIMIZED:
        update_displaychangelistener(dcl, 500);
        break;
    case SDL_WINDOWEVENT_CLOSE:
        if (!no_quit) {
            no_shutdown = 0;
            qemu_system_shutdown_request();
        }
        break;
    }
}

static void sdl_refresh(DisplayChangeListener *dcl)
{
    struct sdl2_state *scon = container_of(dcl, struct sdl2_state, dcl);
    SDL_Event ev1, *ev = &ev1;

    if (scon->last_vm_running != runstate_is_running()) {
        scon->last_vm_running = runstate_is_running();
        sdl_update_caption(scon);
    }

    graphic_hw_update(dcl->con);

    while (SDL_PollEvent(ev)) {
        switch (ev->type) {
        case SDL_KEYDOWN:
            handle_keydown(ev);
            break;
        case SDL_KEYUP:
            handle_keyup(ev);
            break;
        case SDL_TEXTINPUT:
            handle_textinput(ev);
            break;
        case SDL_QUIT:
            if (!no_quit) {
                no_shutdown = 0;
                qemu_system_shutdown_request();
            }
            break;
        case SDL_MOUSEMOTION:
            handle_mousemotion(ev);
            break;
        case SDL_MOUSEBUTTONDOWN:
        case SDL_MOUSEBUTTONUP:
            handle_mousebutton(ev);
            break;
        case SDL_MOUSEWHEEL:
            handle_mousewheel(ev);
            break;
        case SDL_WINDOWEVENT:
            handle_windowevent(dcl, ev);
            break;
        default:
            break;
        }
    }
}

static void sdl_mouse_warp(DisplayChangeListener *dcl,
                           int x, int y, int on)
{
    struct sdl2_state *scon = container_of(dcl, struct sdl2_state, dcl);
    if (on) {
        if (!guest_cursor) {
            sdl_show_cursor();
        }
        if (gui_grab || qemu_input_is_absolute() || absolute_enabled) {
            SDL_SetCursor(guest_sprite);
            if (!qemu_input_is_absolute() && !absolute_enabled) {
                SDL_WarpMouseInWindow(scon->real_window, x, y);
            }
        }
    } else if (gui_grab) {
        sdl_hide_cursor();
    }
    guest_cursor = on;
    guest_x = x, guest_y = y;
}

static void sdl_mouse_define(DisplayChangeListener *dcl,
                             QEMUCursor *c)
{

    if (guest_sprite) {
        SDL_FreeCursor(guest_sprite);
    }

    if (guest_sprite_surface) {
        SDL_FreeSurface(guest_sprite_surface);
    }

    guest_sprite_surface =
        SDL_CreateRGBSurfaceFrom(c->data, c->width, c->height, 32, c->width * 4,
                                 0xff0000, 0x00ff00, 0xff, 0xff000000);

    if (!guest_sprite_surface) {
        fprintf(stderr, "Failed to make rgb surface from %p\n", c);
        return;
    }
    guest_sprite = SDL_CreateColorCursor(guest_sprite_surface,
                                         c->hot_x, c->hot_y);
    if (!guest_sprite) {
        fprintf(stderr, "Failed to make color cursor from %p\n", c);
        return;
    }
    if (guest_cursor &&
        (gui_grab || qemu_input_is_absolute() || absolute_enabled)) {
        SDL_SetCursor(guest_sprite);
    }
}

static void sdl_cleanup(void)
{
    if (guest_sprite) {
        SDL_FreeCursor(guest_sprite);
    }
    SDL_QuitSubSystem(SDL_INIT_VIDEO);
}

static const DisplayChangeListenerOps dcl_ops = {
    .dpy_name          = "sdl",
    .dpy_gfx_update    = sdl_update,
    .dpy_gfx_switch    = sdl_switch,
    .dpy_refresh       = sdl_refresh,
    .dpy_mouse_set     = sdl_mouse_warp,
    .dpy_cursor_define = sdl_mouse_define,
};

bool sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
{
    int flags;
    uint8_t data = 0;
    char *filename;
    int i;

    if (no_frame) {
        gui_noframe = 1;
    }

#ifdef __linux__
    /* on Linux, SDL may use fbcon|directfb|svgalib when run without
     * accessible $DISPLAY to open X11 window.  This is often the case
     * when qemu is run using sudo.  But in this case, and when actually
     * run in X11 environment, SDL fights with X11 for the video card,
     * making current display unavailable, often until reboot.
     * So make x11 the default SDL video driver if this variable is unset.
     * This is a bit hackish but saves us from bigger problem.
     * Maybe it's a good idea to fix this in SDL instead.
     */
    setenv("SDL_VIDEODRIVER", "x11", 0);
#endif

    flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
    if (SDL_Init(flags)) {
        fprintf(stderr, "Could not initialize SDL(%s) - exiting\n",
                SDL_GetError());
        return false;
    }

    for (i = 0;; i++) {
        QemuConsole *con = qemu_console_lookup_by_index(i);
        if (!con) {
            break;
        }
    }
    sdl2_num_outputs = i;
    sdl2_console = g_new0(struct sdl2_state, sdl2_num_outputs);
    for (i = 0; i < sdl2_num_outputs; i++) {
        QemuConsole *con = qemu_console_lookup_by_index(i);
        if (!qemu_console_is_graphic(con)) {
            sdl2_console[i].hidden = true;
        }
        sdl2_console[i].dcl.ops = &dcl_ops;
        sdl2_console[i].dcl.con = con;
        register_displaychangelistener(&sdl2_console[i].dcl);
        sdl2_console[i].idx = i;
    }

    /* Load a 32x32x4 image. White pixels are transparent. */
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu-icon.bmp");
    if (filename) {
        SDL_Surface *image = SDL_LoadBMP(filename);
        if (image) {
            uint32_t colorkey = SDL_MapRGB(image->format, 255, 255, 255);
            SDL_SetColorKey(image, SDL_TRUE, colorkey);
            SDL_SetWindowIcon(sdl2_console[0].real_window, image);
        }
        g_free(filename);
    }

    if (full_screen) {
        gui_fullscreen = 1;
        sdl_grab_start(0);
    }

    mouse_mode_notifier.notify = sdl_mouse_mode_change;
    qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier);

    gui_grab = 0;

    sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
    sdl_cursor_normal = SDL_GetCursor();

    atexit(sdl_cleanup);

    return true;
}
#endif
