diff src/video/x11/SDL_x11clipboard.c @ 4508:15d2c6f40c48

Added X11 clipboard support. As far as I know there isn't any real way to tell when the clipboard contents have changed without polling them, so I didn't implement the clipboard update event on X11.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 12 Jul 2010 00:36:55 -0700
parents
children 8e91c3947210
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/x11/SDL_x11clipboard.c	Mon Jul 12 00:36:55 2010 -0700
@@ -0,0 +1,152 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include <limits.h> /* For INT_MAX */
+
+#include "SDL_events.h"
+#include "SDL_x11video.h"
+
+
+/* Get any application owned window handle for clipboard association */
+static Window
+GetWindow(_THIS)
+{
+    SDL_VideoDisplay *display;
+    SDL_Window *window;
+
+    display = _this->displays;
+    if (display) {
+        window = display->windows;
+        if (window) {
+            return ((SDL_WindowData *) window->driverdata)->xwindow;
+        }
+    }
+    return None;
+}
+
+int
+X11_SetClipboardText(_THIS, const char *text)
+{
+    Display *display = ((SDL_VideoData *) _this->driverdata)->display;
+    Atom format;
+    Window window;
+
+    /* Get the SDL window that will own the selection */
+    window = GetWindow(_this);
+    if (window == None) {
+        SDL_SetError("Couldn't find a window to own the selection");
+        return -1;
+    }
+
+    /* If you don't support UTF-8, you might use XA_STRING here */
+    format = XInternAtom(display, "UTF8_STRING", False);
+    XChangeProperty(display, DefaultRootWindow(display),
+        XA_CUT_BUFFER0, format, 8, PropModeReplace,
+        (const unsigned char *)text, SDL_strlen(text));
+
+    if (XGetSelectionOwner(display, XA_PRIMARY) != window) {
+        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;
+
+    text = NULL;
+
+    /* Get the SDL window that will own the selection */
+    window = GetWindow(_this);
+
+    /* If you don't support UTF-8, you might use XA_STRING here */
+    format = XInternAtom(display, "UTF8_STRING", False);
+
+    owner = XGetSelectionOwner(display, XA_PRIMARY);
+    if ((owner == None) || (owner == window)) {
+        owner = DefaultRootWindow(display);
+        selection = XA_CUT_BUFFER0;
+    } else {
+        /* Request that the selection owner copy the data to our window */
+        owner = window;
+        selection = XInternAtom(display, "SDL_SELECTION", False);
+        XConvertSelection(display, XA_PRIMARY, format, selection, owner,
+            CurrentTime);
+
+        /* FIXME: Should we have a timeout here? */
+        videodata->selection_waiting = SDL_TRUE;
+        while (videodata->selection_waiting) {
+            SDL_PumpEvents();
+        }
+    }
+
+    if (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';
+            }
+        }
+        XFree(src);
+    }
+
+    if (!text) {
+        text = SDL_strdup("");
+    }
+    return text;
+}
+
+SDL_bool
+X11_HasClipboardText(_THIS)
+{
+    /* Not an easy way to tell with X11, as far as I know... */
+    char *text;
+    SDL_bool retval;
+
+    text = X11_GetClipboardText(_this);
+    if (*text) {
+        retval = SDL_TRUE;
+    } else {
+        retval = SDL_FALSE;
+    }
+    SDL_free(text);
+
+    return retval;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */