/*
  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 <limits.h> /* For INT_MAX */

#include "SDL_events.h"
#include "SDL_x11video.h"
#include "SDL_timer.h"


/* If you don't support UTF-8, you might use XA_STRING here */
#ifdef X_HAVE_UTF8_STRING
#define TEXT_FORMAT X11_XInternAtom(display, "UTF8_STRING", False)
#else
#define TEXT_FORMAT XA_STRING
#endif

/* Get any application owned window handle for clipboard association */
static Window
GetWindow(_THIS)
{
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;

    /* We create an unmapped window that exists just to manage the clipboard,
       since X11 selection data is tied to a specific window and dies with it.
       We create the window on demand, so apps that don't use the clipboard
       don't have to keep an unnecessary resource around. */
    if (data->clipboard_window == None) {
        Display *dpy = data->display;
        Window parent = RootWindow(dpy, DefaultScreen(dpy));
        XSetWindowAttributes xattr;
        data->clipboard_window = X11_XCreateWindow(dpy, parent, -10, -10, 1, 1, 0,
                                                   CopyFromParent, InputOnly,
                                                   CopyFromParent, 0, &xattr);
        X11_XFlush(data->display);
    }

    return data->clipboard_window;
}

/* We use our own cut-buffer for intermediate storage instead of  
   XA_CUT_BUFFER0 because their use isn't really defined for holding UTF8. */ 
Atom
X11_GetSDLCutBufferClipboardType(Display *display)
{
    return X11_XInternAtom(display, "SDL_CUTBUFFER", False);
}

int
X11_SetClipboardText(_THIS, const char *text)
{
    Display *display = ((SDL_VideoData *) _this->driverdata)->display;
    Atom format;
    Window window;
    Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0);

    /* Get the SDL window that will own the selection */
    window = GetWindow(_this);
    if (window == None) {
        return SDL_SetError("Couldn't find a window to own the selection");
    }

    /* Save the selection on the root window */
    format = TEXT_FORMAT;
    X11_XChangeProperty(display, DefaultRootWindow(display),
        X11_GetSDLCutBufferClipboardType(display), format, 8, PropModeReplace,
        (const unsigned char *)text, SDL_strlen(text));

    if (XA_CLIPBOARD != None &&
        X11_XGetSelectionOwner(display, XA_CLIPBOARD) != window) {
        X11_XSetSelectionOwner(display, XA_CLIPBOARD, window, CurrentTime);
    }

    if (X11_XGetSelectionOwner(display, XA_PRIMARY) != window) {
        X11_XSetSelectionOwner(display, XA_PRIMARY, window, CurrentTime);
    }
    return 0;
}

char *
X11_GetClipboardText(_THIS)
{
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    Display *display = videodata->display;
    Atom format;
    Window window;
    Window owner;
    Atom selection;
    Atom seln_type;
    int seln_format;
    unsigned long nbytes;
    unsigned long overflow;
    unsigned char *src;
    char *text;
    Uint32 waitStart;
    Uint32 waitElapsed;
    Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0);
    if (XA_CLIPBOARD == None) {
        SDL_SetError("Couldn't access X clipboard");
        return SDL_strdup("");
    }

    text = NULL;

    /* Get the window that holds the selection */
    window = GetWindow(_this);
    format = TEXT_FORMAT;
    owner = X11_XGetSelectionOwner(display, XA_CLIPBOARD);
    if (owner == None) {
        /* Fall back to ancient X10 cut-buffers which do not support UTF8 strings*/
        owner = DefaultRootWindow(display);
        selection = XA_CUT_BUFFER0;
        format = XA_STRING;
    } else if (owner == window) {
        owner = DefaultRootWindow(display);
        selection = X11_GetSDLCutBufferClipboardType(display);
    } else {
        /* Request that the selection owner copy the data to our window */
        owner = window;
        selection = X11_XInternAtom(display, "SDL_SELECTION", False);
        X11_XConvertSelection(display, XA_CLIPBOARD, format, selection, owner,
            CurrentTime);

        /* When using synergy on Linux and when data has been put in the clipboard
           on the remote (Windows anyway) machine then selection_waiting may never
           be set to False. Time out after a while. */
        waitStart = SDL_GetTicks();
        videodata->selection_waiting = SDL_TRUE;
        while (videodata->selection_waiting) {
            SDL_PumpEvents();
            waitElapsed = SDL_GetTicks() - waitStart;
            /* Wait one second for a clipboard response. */
            if (waitElapsed > 1000) {
                videodata->selection_waiting = SDL_FALSE;
                SDL_SetError("Clipboard timeout");
                /* We need to set the clipboard text so that next time we won't
                   timeout, otherwise we will hang on every call to this function. */
                X11_SetClipboardText(_this, "");
                return SDL_strdup("");
            }
        }
    }

    if (X11_XGetWindowProperty(display, owner, selection, 0, INT_MAX/4, False,
            format, &seln_type, &seln_format, &nbytes, &overflow, &src)
            == Success) {
        if (seln_type == format) {
            text = (char *)SDL_malloc(nbytes+1);
            if (text) {
                SDL_memcpy(text, src, nbytes);
                text[nbytes] = '\0';
            }
        }
        X11_XFree(src);
    }

    if (!text) {
        text = SDL_strdup("");
    }

    return text;
}

SDL_bool
X11_HasClipboardText(_THIS)
{
    SDL_bool result = SDL_FALSE;
    char *text = X11_GetClipboardText(_this);
    if (text) {
        result = text[0] != '\0' ? SDL_TRUE : SDL_FALSE;
        SDL_free(text);
    }
    return result;
}

#endif /* SDL_VIDEO_DRIVER_X11 */

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