By using this, we can get rid of our own homebrewn solution scrap.[c|h] and drop X11 from the build system.pull/3/head
parent
8f1b565dbe
commit
bfdb850bfb
@ -1,559 +0,0 @@
|
|||||||
/* Handle clipboard text and data in arbitrary formats */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <SDL.h>
|
|
||||||
#include <SDL_syswm.h>
|
|
||||||
#else
|
|
||||||
#include <SDL/SDL.h>
|
|
||||||
#include <SDL/SDL_syswm.h>
|
|
||||||
#endif
|
|
||||||
#include "scrap.h"
|
|
||||||
#include "rfb/rfbconfig.h"
|
|
||||||
|
|
||||||
/* Determine what type of clipboard we are using */
|
|
||||||
#if defined(__unix__) && !defined(__QNXNTO__) && defined(SDL_VIDEO_DRIVER_X11)
|
|
||||||
#define X11_SCRAP
|
|
||||||
#elif defined(__WIN32__)
|
|
||||||
#define WIN_SCRAP
|
|
||||||
#elif defined(__QNXNTO__)
|
|
||||||
#define QNX_SCRAP
|
|
||||||
#else
|
|
||||||
#warning Unknown window manager for clipboard handling
|
|
||||||
#endif /* scrap type */
|
|
||||||
|
|
||||||
/* System dependent data types */
|
|
||||||
#if defined(X11_SCRAP)
|
|
||||||
typedef Atom scrap_type;
|
|
||||||
static Atom XA_TARGETS, XA_TEXT, XA_COMPOUND_TEXT, XA_UTF8_STRING;
|
|
||||||
#elif defined(WIN_SCRAP)
|
|
||||||
typedef UINT scrap_type;
|
|
||||||
#elif defined(QNX_SCRAP)
|
|
||||||
typedef uint32_t scrap_type;
|
|
||||||
#define Ph_CL_TEXT T('T', 'E', 'X', 'T')
|
|
||||||
#else
|
|
||||||
typedef int scrap_type;
|
|
||||||
#endif /* scrap type */
|
|
||||||
|
|
||||||
/* System dependent variables */
|
|
||||||
#if defined(X11_SCRAP)
|
|
||||||
static Display *SDL_Display;
|
|
||||||
static Window SDL_Window;
|
|
||||||
static void (*Lock_Display)(void);
|
|
||||||
static void (*Unlock_Display)(void);
|
|
||||||
static Atom XA_UTF8_STRING;
|
|
||||||
#elif defined(WIN_SCRAP)
|
|
||||||
static HWND SDL_Window;
|
|
||||||
#elif defined(QNX_SCRAP)
|
|
||||||
static unsigned short InputGroup;
|
|
||||||
#endif /* scrap type */
|
|
||||||
|
|
||||||
#define FORMAT_PREFIX "SDL_scrap_0x"
|
|
||||||
|
|
||||||
static scrap_type convert_format(int type)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case T('T', 'E', 'X', 'T'):
|
|
||||||
#if defined(X11_SCRAP)
|
|
||||||
return XA_UTF8_STRING ? XA_UTF8_STRING : XA_STRING;
|
|
||||||
#elif defined(WIN_SCRAP)
|
|
||||||
return CF_TEXT;
|
|
||||||
#elif defined(QNX_SCRAP)
|
|
||||||
return Ph_CL_TEXT;
|
|
||||||
#endif /* scrap type */
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
char format[sizeof(FORMAT_PREFIX)+8+1];
|
|
||||||
|
|
||||||
sprintf(format, "%s%08lx", FORMAT_PREFIX,
|
|
||||||
(unsigned long)type);
|
|
||||||
#if defined(X11_SCRAP)
|
|
||||||
return XInternAtom(SDL_Display, format, False);
|
|
||||||
#elif defined(WIN_SCRAP)
|
|
||||||
return RegisterClipboardFormat(format);
|
|
||||||
#endif /* scrap type */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert internal data to scrap format */
|
|
||||||
static int convert_data(int type, char *dst, const char *src, int srclen)
|
|
||||||
{
|
|
||||||
int dstlen;
|
|
||||||
|
|
||||||
dstlen = 0;
|
|
||||||
switch (type) {
|
|
||||||
case T('T', 'E', 'X', 'T'):
|
|
||||||
if (dst) {
|
|
||||||
while (--srclen >= 0) {
|
|
||||||
#if defined(__unix__)
|
|
||||||
if (*src == '\r') {
|
|
||||||
*dst++ = '\n';
|
|
||||||
++dstlen;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#elif defined(__WIN32__)
|
|
||||||
if (*src == '\r') {
|
|
||||||
*dst++ = '\r';
|
|
||||||
++dstlen;
|
|
||||||
*dst++ = '\n';
|
|
||||||
++dstlen;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
*dst++ = *src;
|
|
||||||
++dstlen;
|
|
||||||
}
|
|
||||||
++src;
|
|
||||||
}
|
|
||||||
*dst = '\0';
|
|
||||||
++dstlen;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
while (--srclen >= 0) {
|
|
||||||
#if defined(__unix__)
|
|
||||||
if (*src == '\r')
|
|
||||||
++dstlen;
|
|
||||||
else
|
|
||||||
#elif defined(__WIN32__)
|
|
||||||
if (*src == '\r') {
|
|
||||||
++dstlen;
|
|
||||||
++dstlen;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
++dstlen;
|
|
||||||
}
|
|
||||||
++src;
|
|
||||||
}
|
|
||||||
++dstlen;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (dst) {
|
|
||||||
*(int *)dst = srclen;
|
|
||||||
dst += sizeof(int);
|
|
||||||
memcpy(dst, src, srclen);
|
|
||||||
}
|
|
||||||
dstlen = sizeof(int)+srclen;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return(dstlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert scrap data to internal format */
|
|
||||||
static int convert_scrap(int type, char *dst, char *src, int srclen)
|
|
||||||
{
|
|
||||||
int dstlen;
|
|
||||||
|
|
||||||
dstlen = 0;
|
|
||||||
switch (type) {
|
|
||||||
case T('T', 'E', 'X', 'T'):
|
|
||||||
{
|
|
||||||
if (srclen == 0)
|
|
||||||
srclen = strlen(src);
|
|
||||||
if (dst) {
|
|
||||||
while (--srclen >= 0) {
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
if (*src == '\r')
|
|
||||||
/* drop extraneous '\r' */;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (*src == '\n') {
|
|
||||||
*dst++ = '\r';
|
|
||||||
++dstlen;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*dst++ = *src;
|
|
||||||
++dstlen;
|
|
||||||
}
|
|
||||||
++src;
|
|
||||||
}
|
|
||||||
*dst = '\0';
|
|
||||||
++dstlen;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
while (--srclen >= 0) {
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
/* drop extraneous '\r' */;
|
|
||||||
if (*src != '\r')
|
|
||||||
#endif
|
|
||||||
++dstlen;
|
|
||||||
++src;
|
|
||||||
}
|
|
||||||
++dstlen;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
dstlen = *(int *)src;
|
|
||||||
if (dst)
|
|
||||||
memcpy(dst, src + sizeof(int),
|
|
||||||
srclen ? srclen - sizeof(int) : dstlen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return dstlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
int init_scrap(void)
|
|
||||||
{
|
|
||||||
SDL_SysWMinfo info;
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
/* Grab the window manager specific information */
|
|
||||||
retval = -1;
|
|
||||||
SDL_SetError("SDL is not running on known window manager");
|
|
||||||
|
|
||||||
SDL_VERSION(&info.version);
|
|
||||||
//FIXMEif (SDL_GetWMInfo(&info))
|
|
||||||
{
|
|
||||||
/* Save the information for later use */
|
|
||||||
#if defined(X11_SCRAP)
|
|
||||||
if (info.subsystem == SDL_SYSWM_X11) {
|
|
||||||
SDL_Display = info.info.x11.display;
|
|
||||||
SDL_Window = info.info.x11.window;
|
|
||||||
Lock_Display = info.info.x11.lock_func;
|
|
||||||
Unlock_Display = info.info.x11.unlock_func;
|
|
||||||
|
|
||||||
/* Enable the special window hook events */
|
|
||||||
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
|
|
||||||
SDL_SetEventFilter(clipboard_filter);
|
|
||||||
|
|
||||||
XA_TARGETS = XInternAtom(SDL_Display, "TARGETS", False);
|
|
||||||
XA_TEXT = XInternAtom(SDL_Display, "TEXT", False);
|
|
||||||
XA_COMPOUND_TEXT = XInternAtom(SDL_Display,
|
|
||||||
"COMPOUND_TEXT", False);
|
|
||||||
XA_UTF8_STRING = XInternAtom(SDL_Display,
|
|
||||||
"UTF8_STRING", False);
|
|
||||||
|
|
||||||
retval = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SDL_SetError("SDL is not running on X11");
|
|
||||||
#elif defined(WIN_SCRAP)
|
|
||||||
SDL_Window = info.window;
|
|
||||||
retval = 0;
|
|
||||||
#elif defined(QNX_SCRAP)
|
|
||||||
InputGroup = PhInputGroup(NULL);
|
|
||||||
retval = 0;
|
|
||||||
#endif /* scrap type */
|
|
||||||
}
|
|
||||||
return(retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
int lost_scrap(void)
|
|
||||||
{
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
#if defined(X11_SCRAP)
|
|
||||||
if (Lock_Display)
|
|
||||||
Lock_Display();
|
|
||||||
retval = (XGetSelectionOwner(SDL_Display, XA_PRIMARY) != SDL_Window);
|
|
||||||
if (Unlock_Display)
|
|
||||||
Unlock_Display();
|
|
||||||
#elif defined(WIN_SCRAP)
|
|
||||||
retval = (GetClipboardOwner() != SDL_Window);
|
|
||||||
#elif defined(QNX_SCRAP)
|
|
||||||
retval = (PhInputGroup(NULL) != InputGroup);
|
|
||||||
#endif /* scrap type */
|
|
||||||
|
|
||||||
return(retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
void put_scrap(int type, int srclen, const char *src)
|
|
||||||
{
|
|
||||||
scrap_type format;
|
|
||||||
int dstlen;
|
|
||||||
char *dst;
|
|
||||||
|
|
||||||
format = convert_format(type);
|
|
||||||
dstlen = convert_data(type, NULL, src, srclen);
|
|
||||||
|
|
||||||
#if defined(X11_SCRAP)
|
|
||||||
dst = (char *)malloc(dstlen);
|
|
||||||
if (dst != NULL) {
|
|
||||||
if (Lock_Display)
|
|
||||||
Lock_Display();
|
|
||||||
convert_data(type, dst, src, srclen);
|
|
||||||
XChangeProperty(SDL_Display, DefaultRootWindow(SDL_Display),
|
|
||||||
XA_CUT_BUFFER0, format, 8, PropModeReplace,
|
|
||||||
(unsigned char *)dst, dstlen);
|
|
||||||
free(dst);
|
|
||||||
if (lost_scrap())
|
|
||||||
XSetSelectionOwner(SDL_Display, XA_PRIMARY,
|
|
||||||
SDL_Window, CurrentTime);
|
|
||||||
if (Unlock_Display)
|
|
||||||
Unlock_Display();
|
|
||||||
}
|
|
||||||
#elif defined(WIN_SCRAP)
|
|
||||||
if (OpenClipboard(SDL_Window)) {
|
|
||||||
HANDLE hMem;
|
|
||||||
|
|
||||||
hMem = GlobalAlloc((GMEM_MOVEABLE|GMEM_DDESHARE), dstlen);
|
|
||||||
if (hMem != NULL) {
|
|
||||||
dst = (char *)GlobalLock(hMem);
|
|
||||||
convert_data(type, dst, src, srclen);
|
|
||||||
GlobalUnlock(hMem);
|
|
||||||
EmptyClipboard();
|
|
||||||
SetClipboardData(format, hMem);
|
|
||||||
}
|
|
||||||
CloseClipboard();
|
|
||||||
}
|
|
||||||
#elif defined(QNX_SCRAP)
|
|
||||||
#if (_NTO_VERSION < 620) /* before 6.2.0 releases */
|
|
||||||
#define PhClipboardHdr PhClipHeader
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
PhClipboardHdr clheader = { Ph_CLIPBOARD_TYPE_TEXT, 0, NULL };
|
|
||||||
int* cldata;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
dst = (char *)malloc(dstlen+4);
|
|
||||||
if (dst != NULL) {
|
|
||||||
cldata = (int*)dst;
|
|
||||||
*cldata = type;
|
|
||||||
convert_data(type, dst+4, src, srclen);
|
|
||||||
clheader.data = dst;
|
|
||||||
#if (_NTO_VERSION < 620) /* before 6.2.0 releases */
|
|
||||||
if (dstlen > 65535)
|
|
||||||
/* maximum photon clipboard size :(*/
|
|
||||||
clheader.length = 65535;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
clheader.length = dstlen+4;
|
|
||||||
status = PhClipboardCopy(InputGroup, 1, &clheader);
|
|
||||||
if (status == -1)
|
|
||||||
fprintf(stderr,
|
|
||||||
"Photon: copy to clipboard failed!\n");
|
|
||||||
free(dst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* scrap type */
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_scrap(int type, int *dstlen, char **dst)
|
|
||||||
{
|
|
||||||
scrap_type format;
|
|
||||||
|
|
||||||
*dstlen = 0;
|
|
||||||
format = convert_format(type);
|
|
||||||
|
|
||||||
#if defined(X11_SCRAP)
|
|
||||||
{
|
|
||||||
Window owner;
|
|
||||||
Atom selection;
|
|
||||||
Atom seln_type;
|
|
||||||
int seln_format;
|
|
||||||
unsigned long nbytes;
|
|
||||||
unsigned long overflow;
|
|
||||||
char *src;
|
|
||||||
|
|
||||||
if (Lock_Display)
|
|
||||||
Lock_Display();
|
|
||||||
owner = XGetSelectionOwner(SDL_Display, XA_PRIMARY);
|
|
||||||
if (Unlock_Display)
|
|
||||||
Unlock_Display();
|
|
||||||
if ((owner == None) || (owner == SDL_Window)) {
|
|
||||||
owner = DefaultRootWindow(SDL_Display);
|
|
||||||
selection = XA_CUT_BUFFER0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int selection_response = 0;
|
|
||||||
SDL_Event event;
|
|
||||||
|
|
||||||
owner = SDL_Window;
|
|
||||||
if (Lock_Display)
|
|
||||||
Lock_Display();
|
|
||||||
selection = XInternAtom(SDL_Display, "SDL_SELECTION",
|
|
||||||
False);
|
|
||||||
XConvertSelection(SDL_Display, XA_PRIMARY, format,
|
|
||||||
selection, owner, CurrentTime);
|
|
||||||
if (Unlock_Display)
|
|
||||||
Unlock_Display();
|
|
||||||
while (!selection_response) {
|
|
||||||
SDL_WaitEvent(&event);
|
|
||||||
if (event.type == SDL_SYSWMEVENT) {
|
|
||||||
XEvent xevent =
|
|
||||||
event.syswm.msg->event.xevent;
|
|
||||||
|
|
||||||
if ((xevent.type == SelectionNotify) &&
|
|
||||||
(xevent.xselection.requestor
|
|
||||||
== owner))
|
|
||||||
selection_response = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Lock_Display)
|
|
||||||
Lock_Display();
|
|
||||||
if (XGetWindowProperty(SDL_Display, owner, selection,
|
|
||||||
0, INT_MAX/4, False, format, &seln_type,
|
|
||||||
&seln_format, &nbytes, &overflow,
|
|
||||||
(unsigned char **)&src) == Success) {
|
|
||||||
if (seln_type == format) {
|
|
||||||
*dstlen = convert_scrap(type, NULL,
|
|
||||||
src, nbytes);
|
|
||||||
*dst = (char *)realloc(*dst, *dstlen);
|
|
||||||
if (*dst == NULL)
|
|
||||||
*dstlen = 0;
|
|
||||||
else
|
|
||||||
convert_scrap(type, *dst, src, nbytes);
|
|
||||||
}
|
|
||||||
XFree(src);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Unlock_Display)
|
|
||||||
Unlock_Display();
|
|
||||||
#elif defined(WIN_SCRAP)
|
|
||||||
if (IsClipboardFormatAvailable(format) && OpenClipboard(SDL_Window)) {
|
|
||||||
HANDLE hMem;
|
|
||||||
char *src;
|
|
||||||
|
|
||||||
hMem = GetClipboardData(format);
|
|
||||||
if (hMem != NULL) {
|
|
||||||
src = (char *)GlobalLock(hMem);
|
|
||||||
*dstlen = convert_scrap(type, NULL, src, 0);
|
|
||||||
*dst = (char *)realloc(*dst, *dstlen);
|
|
||||||
if (*dst == NULL)
|
|
||||||
*dstlen = 0;
|
|
||||||
else
|
|
||||||
convert_scrap(type, *dst, src, 0);
|
|
||||||
GlobalUnlock(hMem);
|
|
||||||
}
|
|
||||||
CloseClipboard();
|
|
||||||
}
|
|
||||||
#elif defined(QNX_SCRAP)
|
|
||||||
#if (_NTO_VERSION < 620) /* before 6.2.0 releases */
|
|
||||||
{
|
|
||||||
void* clhandle;
|
|
||||||
PhClipHeader* clheader;
|
|
||||||
int* cldata;
|
|
||||||
|
|
||||||
clhandle = PhClipboardPasteStart(InputGroup);
|
|
||||||
if (clhandle != NULL) {
|
|
||||||
clheader = PhClipboardPasteType(clhandle,
|
|
||||||
Ph_CLIPBOARD_TYPE_TEXT);
|
|
||||||
if (clheader != NULL) {
|
|
||||||
cldata = clheader->data;
|
|
||||||
if ((clheader->length>4) && (*cldata == type)) {
|
|
||||||
*dstlen = convert_scrap(type, NULL,
|
|
||||||
(char*)clheader->data+4,
|
|
||||||
clheader->length-4);
|
|
||||||
*dst = (char *)realloc(*dst, *dstlen);
|
|
||||||
if (*dst == NULL)
|
|
||||||
*dstlen = 0;
|
|
||||||
else
|
|
||||||
convert_scrap(type, *dst,
|
|
||||||
(char*)clheader->data+4,
|
|
||||||
clheader->length-4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PhClipboardPasteFinish(clhandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else /* 6.2.0 and 6.2.1 and future releases */
|
|
||||||
{
|
|
||||||
void* clhandle;
|
|
||||||
PhClipboardHdr* clheader;
|
|
||||||
int* cldata;
|
|
||||||
|
|
||||||
clheader=PhClipboardRead(InputGroup, Ph_CLIPBOARD_TYPE_TEXT);
|
|
||||||
if (clheader!=NULL) {
|
|
||||||
cldata=clheader->data;
|
|
||||||
if ((clheader->length>4) && (*cldata==type)) {
|
|
||||||
*dstlen = convert_scrap(type, NULL,
|
|
||||||
(char*)clheader->data+4,
|
|
||||||
clheader->length-4);
|
|
||||||
*dst = (char *)realloc(*dst, *dstlen);
|
|
||||||
if (*dst == NULL)
|
|
||||||
*dstlen = 0;
|
|
||||||
else
|
|
||||||
convert_scrap(type, *dst,
|
|
||||||
(char*)clheader->data+4,
|
|
||||||
clheader->length-4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* scrap type */
|
|
||||||
}
|
|
||||||
|
|
||||||
int clipboard_filter(const SDL_Event *event)
|
|
||||||
{
|
|
||||||
#if defined(X11_SCRAP)
|
|
||||||
/* Post all non-window manager specific events */
|
|
||||||
if (event->type != SDL_SYSWMEVENT)
|
|
||||||
return(1);
|
|
||||||
|
|
||||||
/* Handle window-manager specific clipboard events */
|
|
||||||
switch (event->syswm.msg->event.xevent.type) {
|
|
||||||
/* Copy the selection from XA_CUT_BUFFER0 to the requested property */
|
|
||||||
case SelectionRequest: {
|
|
||||||
XSelectionRequestEvent *req;
|
|
||||||
XEvent sevent;
|
|
||||||
int seln_format;
|
|
||||||
unsigned long nbytes;
|
|
||||||
unsigned long overflow;
|
|
||||||
unsigned char *seln_data;
|
|
||||||
|
|
||||||
req = &event->syswm.msg->event.xevent.xselectionrequest;
|
|
||||||
if (req->target == XA_TARGETS) {
|
|
||||||
Atom supported[] = {
|
|
||||||
XA_TEXT, XA_COMPOUND_TEXT, XA_UTF8_STRING,
|
|
||||||
XA_TARGETS, XA_STRING
|
|
||||||
};
|
|
||||||
XEvent response;
|
|
||||||
|
|
||||||
XChangeProperty(SDL_Display, req->requestor,
|
|
||||||
req->property, req->target, 32, PropModeReplace,
|
|
||||||
(unsigned char*)supported,
|
|
||||||
sizeof(supported) / sizeof(supported[0]));
|
|
||||||
response.xselection.property=None;
|
|
||||||
response.xselection.type= SelectionNotify;
|
|
||||||
response.xselection.display= req->display;
|
|
||||||
response.xselection.requestor= req->requestor;
|
|
||||||
response.xselection.selection=req->selection;
|
|
||||||
response.xselection.target= req->target;
|
|
||||||
response.xselection.time = req->time;
|
|
||||||
XSendEvent (SDL_Display, req->requestor,0,0,&response);
|
|
||||||
XFlush (SDL_Display);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sevent.xselection.type = SelectionNotify;
|
|
||||||
sevent.xselection.display = req->display;
|
|
||||||
sevent.xselection.selection = req->selection;
|
|
||||||
sevent.xselection.target = None;
|
|
||||||
sevent.xselection.property = req->property;
|
|
||||||
sevent.xselection.requestor = req->requestor;
|
|
||||||
sevent.xselection.time = req->time;
|
|
||||||
if (XGetWindowProperty(SDL_Display,
|
|
||||||
DefaultRootWindow(SDL_Display), XA_CUT_BUFFER0,
|
|
||||||
0, INT_MAX/4, False, req->target,
|
|
||||||
&sevent.xselection.target, &seln_format,
|
|
||||||
&nbytes, &overflow, &seln_data) == Success) {
|
|
||||||
if (sevent.xselection.target == req->target) {
|
|
||||||
if (sevent.xselection.target == XA_STRING &&
|
|
||||||
nbytes > 0 &&
|
|
||||||
seln_data[nbytes-1] == '\0')
|
|
||||||
--nbytes;
|
|
||||||
XChangeProperty(SDL_Display, req->requestor,
|
|
||||||
req->property, sevent.xselection.target,
|
|
||||||
seln_format, PropModeReplace,
|
|
||||||
seln_data, nbytes);
|
|
||||||
sevent.xselection.property = req->property;
|
|
||||||
}
|
|
||||||
XFree(seln_data);
|
|
||||||
}
|
|
||||||
XSendEvent(SDL_Display,req->requestor,False,0,&sevent);
|
|
||||||
XSync(SDL_Display, False);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Post the event for X11 clipboard reading above */
|
|
||||||
#endif /* X11_SCRAP */
|
|
||||||
return(1);
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
/* Handle clipboard text and data in arbitrary formats */
|
|
||||||
|
|
||||||
/* Miscellaneous defines */
|
|
||||||
#define T(A, B, C, D) (int)((A<<24)|(B<<16)|(C<<8)|(D<<0))
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
extern int init_scrap(void);
|
|
||||||
extern int lost_scrap(void);
|
|
||||||
extern void put_scrap(int type, int srclen, const char *src);
|
|
||||||
extern void get_scrap(int type, int *dstlen, char **dst);
|
|
||||||
extern int clipboard_filter(const SDL_Event *event);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
Loading…
Reference in new issue