/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#if SDL_VIDEO_DRIVER_X11

#include <X11/cursorfont.h>
#include "SDL_x11video.h"
#include "SDL_x11mouse.h"
#include "SDL_x11xinput2.h"
#include "../../events/SDL_mouse_c.h"


/* FIXME: Find a better place to put this... */
static Cursor x11_empty_cursor = None;

static Display *
GetDisplay(void)
{
    return ((SDL_VideoData *)SDL_GetVideoDevice()->driverdata)->display;
}

static Cursor
X11_CreateEmptyCursor()
{
    if (x11_empty_cursor == None) {
        Display *display = GetDisplay();
        char data[1];
        XColor color;
        Pixmap pixmap;

        SDL_zeroa(data);
        color.red = color.green = color.blue = 0;
        pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display),
                                       data, 1, 1);
        if (pixmap) {
            x11_empty_cursor = X11_XCreatePixmapCursor(display, pixmap, pixmap,
                                                   &color, &color, 0, 0);
            X11_XFreePixmap(display, pixmap);
        }
    }
    return x11_empty_cursor;
}

static void
X11_DestroyEmptyCursor(void)
{
    if (x11_empty_cursor != None) {
        X11_XFreeCursor(GetDisplay(), x11_empty_cursor);
        x11_empty_cursor = None;
    }
}

static SDL_Cursor *
X11_CreateDefaultCursor()
{
    SDL_Cursor *cursor;

    cursor = SDL_calloc(1, sizeof(*cursor));
    if (cursor) {
        /* None is used to indicate the default cursor */
        cursor->driverdata = (void*)None;
    } else {
        SDL_OutOfMemory();
    }

    return cursor;
}

#if SDL_VIDEO_DRIVER_X11_XCURSOR
static Cursor
X11_CreateXCursorCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
    Display *display = GetDisplay();
    Cursor cursor = None;
    XcursorImage *image;

    image = X11_XcursorImageCreate(surface->w, surface->h);
    if (!image) {
        SDL_OutOfMemory();
        return None;
    }
    image->xhot = hot_x;
    image->yhot = hot_y;
    image->delay = 0;

    SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
    SDL_assert(surface->pitch == surface->w * 4);
    SDL_memcpy(image->pixels, surface->pixels, surface->h * surface->pitch);

    cursor = X11_XcursorImageLoadCursor(display, image);

    X11_XcursorImageDestroy(image);

    return cursor;
}
#endif /* SDL_VIDEO_DRIVER_X11_XCURSOR */

static Cursor
X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
    Display *display = GetDisplay();
    XColor fg, bg;
    Cursor cursor = None;
    Uint32 *ptr;
    Uint8 *data_bits, *mask_bits;
    Pixmap data_pixmap, mask_pixmap;
    int x, y;
    unsigned int rfg, gfg, bfg, rbg, gbg, bbg, fgBits, bgBits;
    unsigned int width_bytes = ((surface->w + 7) & ~7) / 8;

    data_bits = SDL_calloc(1, surface->h * width_bytes);
    if (!data_bits) {
        SDL_OutOfMemory();
        return None;
    }

    mask_bits = SDL_calloc(1, surface->h * width_bytes);
    if (!mask_bits) {
        SDL_free(data_bits);
        SDL_OutOfMemory();
        return None;
    }

    /* Code below assumes ARGB pixel format */
    SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);

    rfg = gfg = bfg = rbg = gbg = bbg = fgBits = bgBits = 0;
    for (y = 0; y < surface->h; ++y) {
        ptr = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch);
        for (x = 0; x < surface->w; ++x) {
            int alpha = (*ptr >> 24) & 0xff;
            int red   = (*ptr >> 16) & 0xff;
            int green = (*ptr >> 8) & 0xff;
            int blue  = (*ptr >> 0) & 0xff;
            if (alpha > 25) {
                mask_bits[y * width_bytes + x / 8] |= (0x01 << (x % 8));

                if ((red + green + blue) > 0x40) {
                    fgBits++;
                    rfg += red;
                    gfg += green;
                    bfg += blue;
                    data_bits[y * width_bytes + x / 8] |= (0x01 << (x % 8));
                } else {
                    bgBits++;
                    rbg += red;
                    gbg += green;
                    bbg += blue;
                }
            }
            ++ptr;
        }
    }

    if (fgBits) {
        fg.red   = rfg * 257 / fgBits;
        fg.green = gfg * 257 / fgBits;
        fg.blue  = bfg * 257 / fgBits;
    }
    else fg.red = fg.green = fg.blue = 0;

    if (bgBits) {
        bg.red   = rbg * 257 / bgBits;
        bg.green = gbg * 257 / bgBits;
        bg.blue  = bbg * 257 / bgBits;
    }
    else bg.red = bg.green = bg.blue = 0;

    data_pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display),
                                        (char*)data_bits,
                                        surface->w, surface->h);
    mask_pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display),
                                        (char*)mask_bits,
                                        surface->w, surface->h);
    cursor = X11_XCreatePixmapCursor(display, data_pixmap, mask_pixmap,
                                 &fg, &bg, hot_x, hot_y);
    X11_XFreePixmap(display, data_pixmap);
    X11_XFreePixmap(display, mask_pixmap);

    return cursor;
}

static SDL_Cursor *
X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
    SDL_Cursor *cursor;

    cursor = SDL_calloc(1, sizeof(*cursor));
    if (cursor) {
        Cursor x11_cursor = None;

#if SDL_VIDEO_DRIVER_X11_XCURSOR
        if (SDL_X11_HAVE_XCURSOR) {
            x11_cursor = X11_CreateXCursorCursor(surface, hot_x, hot_y);
        }
#endif
        if (x11_cursor == None) {
            x11_cursor = X11_CreatePixmapCursor(surface, hot_x, hot_y);
        }
        cursor->driverdata = (void*)x11_cursor;
    } else {
        SDL_OutOfMemory();
    }

    return cursor;
}

static SDL_Cursor *
X11_CreateSystemCursor(SDL_SystemCursor id)
{
    SDL_Cursor *cursor;
    unsigned int shape;

    switch(id)
    {
    default:
        SDL_assert(0);
        return NULL;
    /* X Font Cursors reference: */
    /*   http://tronche.com/gui/x/xlib/appendix/b/ */
    case SDL_SYSTEM_CURSOR_ARROW:     shape = XC_left_ptr; break;
    case SDL_SYSTEM_CURSOR_IBEAM:     shape = XC_xterm; break;
    case SDL_SYSTEM_CURSOR_WAIT:      shape = XC_watch; break;
    case SDL_SYSTEM_CURSOR_CROSSHAIR: shape = XC_tcross; break;
    case SDL_SYSTEM_CURSOR_WAITARROW: shape = XC_watch; break;
    case SDL_SYSTEM_CURSOR_SIZENWSE:  shape = XC_fleur; break;
    case SDL_SYSTEM_CURSOR_SIZENESW:  shape = XC_fleur; break;
    case SDL_SYSTEM_CURSOR_SIZEWE:    shape = XC_sb_h_double_arrow; break;
    case SDL_SYSTEM_CURSOR_SIZENS:    shape = XC_sb_v_double_arrow; break;
    case SDL_SYSTEM_CURSOR_SIZEALL:   shape = XC_fleur; break;
    case SDL_SYSTEM_CURSOR_NO:        shape = XC_pirate; break;
    case SDL_SYSTEM_CURSOR_HAND:      shape = XC_hand2; break;
    }

    cursor = SDL_calloc(1, sizeof(*cursor));
    if (cursor) {
        Cursor x11_cursor;

        x11_cursor = X11_XCreateFontCursor(GetDisplay(), shape);

        cursor->driverdata = (void*)x11_cursor;
    } else {
        SDL_OutOfMemory();
    }

    return cursor;
}

static void
X11_FreeCursor(SDL_Cursor * cursor)
{
    Cursor x11_cursor = (Cursor)cursor->driverdata;

    if (x11_cursor != None) {
        X11_XFreeCursor(GetDisplay(), x11_cursor);
    }
    SDL_free(cursor);
}

static int
X11_ShowCursor(SDL_Cursor * cursor)
{
    Cursor x11_cursor = 0;

    if (cursor) {
        x11_cursor = (Cursor)cursor->driverdata;
    } else {
        x11_cursor = X11_CreateEmptyCursor();
    }

    /* FIXME: Is there a better way than this? */
    {
        SDL_VideoDevice *video = SDL_GetVideoDevice();
        Display *display = GetDisplay();
        SDL_Window *window;
        SDL_WindowData *data;

        for (window = video->windows; window; window = window->next) {
            data = (SDL_WindowData *)window->driverdata;
            if (x11_cursor != None) {
                X11_XDefineCursor(display, data->xwindow, x11_cursor);
            } else {
                X11_XUndefineCursor(display, data->xwindow);
            }
        }
        X11_XFlush(display);
    }
    return 0;
}

static void
WarpMouseInternal(Window xwindow, const int x, const int y)
{
    SDL_VideoData *videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata;
    Display *display = videodata->display;
    X11_XWarpPointer(display, None, xwindow, 0, 0, 0, 0, x, y);
    X11_XSync(display, False);
    videodata->global_mouse_changed = SDL_TRUE;
}

static void
X11_WarpMouse(SDL_Window * window, int x, int y)
{
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    WarpMouseInternal(data->xwindow, x, y);
}

static int
X11_WarpMouseGlobal(int x, int y)
{
    WarpMouseInternal(DefaultRootWindow(GetDisplay()), x, y);
    return 0;
}

static int
X11_SetRelativeMouseMode(SDL_bool enabled)
{
#if SDL_VIDEO_DRIVER_X11_XINPUT2
    if(X11_Xinput2IsInitialized())
        return 0;
#else
    SDL_Unsupported();
#endif
    return -1;
}

static int
X11_CaptureMouse(SDL_Window *window)
{
    Display *display = GetDisplay();

    if (window) {
        SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
        const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
        const int rc = X11_XGrabPointer(display, data->xwindow, False,
                                        mask, GrabModeAsync, GrabModeAsync,
                                        None, None, CurrentTime);
        if (rc != GrabSuccess) {
            return SDL_SetError("X server refused mouse capture");
        }
    } else {
        X11_XUngrabPointer(display, CurrentTime);
    }

    X11_XSync(display, False);

    return 0;
}

static Uint32
X11_GetGlobalMouseState(int *x, int *y)
{
    SDL_VideoData *videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata;
    Display *display = GetDisplay();
    const int num_screens = SDL_GetNumVideoDisplays();
    int i;

    /* !!! FIXME: should we XSync() here first? */

#if !SDL_VIDEO_DRIVER_X11_XINPUT2
    videodata->global_mouse_changed = SDL_TRUE;
#endif

    /* check if we have this cached since XInput last saw the mouse move. */
    /* !!! FIXME: can we just calculate this from XInput's events? */
    if (videodata->global_mouse_changed) {
        for (i = 0; i < num_screens; i++) {
            SDL_DisplayData *data = (SDL_DisplayData *) SDL_GetDisplayDriverData(i);
            if (data != NULL) {
                Window root, child;
                int rootx, rooty, winx, winy;
                unsigned int mask;
                if (X11_XQueryPointer(display, RootWindow(display, data->screen), &root, &child, &rootx, &rooty, &winx, &winy, &mask)) {
                    XWindowAttributes root_attrs;
                    Uint32 buttons = 0;
                    buttons |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0;
                    buttons |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0;
                    buttons |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0;
                    /* SDL_DisplayData->x,y point to screen origin, and adding them to mouse coordinates relative to root window doesn't do the right thing
                     * (observed on dual monitor setup with primary display being the rightmost one - mouse was offset to the right).
                     *
                     * Adding root position to root-relative coordinates seems to be a better way to get absolute position. */
                    X11_XGetWindowAttributes(display, root, &root_attrs);
                    videodata->global_mouse_position.x = root_attrs.x + rootx;
                    videodata->global_mouse_position.y = root_attrs.y + rooty;
                    videodata->global_mouse_buttons = buttons;
                    videodata->global_mouse_changed = SDL_FALSE;
                    break;
                }
            }
        }
    }

    SDL_assert(!videodata->global_mouse_changed);  /* The pointer wasn't on any X11 screen?! */

    *x = videodata->global_mouse_position.x;
    *y = videodata->global_mouse_position.y;
    return videodata->global_mouse_buttons;
}


void
X11_InitMouse(_THIS)
{
    SDL_Mouse *mouse = SDL_GetMouse();

    mouse->CreateCursor = X11_CreateCursor;
    mouse->CreateSystemCursor = X11_CreateSystemCursor;
    mouse->ShowCursor = X11_ShowCursor;
    mouse->FreeCursor = X11_FreeCursor;
    mouse->WarpMouse = X11_WarpMouse;
    mouse->WarpMouseGlobal = X11_WarpMouseGlobal;
    mouse->SetRelativeMouseMode = X11_SetRelativeMouseMode;
    mouse->CaptureMouse = X11_CaptureMouse;
    mouse->GetGlobalMouseState = X11_GetGlobalMouseState;

    SDL_SetDefaultCursor(X11_CreateDefaultCursor());
}

void
X11_QuitMouse(_THIS)
{
    X11_DestroyEmptyCursor();
}

#endif /* SDL_VIDEO_DRIVER_X11 */

/* vi: set ts=4 sw=4 expandtab: */
