Mercurial > sdl-ios-xcode
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: */