Added SDL_DROPTEXT event, for dragging and dropping string data.

This patch is based on work in Unreal Engine 4's fork of SDL,
compliments of Epic Games.
Ryan C. Gordon 2016-01-05 02:26:45 -05:00
parent c3114975db
commit f9b7379341
5 changed files with 38 additions and 38 deletions

View File

@ -136,6 +136,7 @@ typedef enum
/* Drag and drop events */ /* Drag and drop events */
SDL_DROPFILE = 0x1000, /**< The system requests a file open */ SDL_DROPFILE = 0x1000, /**< The system requests a file open */
SDL_DROPTEXT, /**< text/plain drag-and-drop event */
/* Audio hotplug events */ /* Audio hotplug events */
SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */ SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */

View File

@ -27,20 +27,33 @@
#include "SDL_dropevents_c.h" #include "SDL_dropevents_c.h"
int static int
SDL_SendDropFile(const char *file) SDL_SendDrop(const SDL_EventType evtype, const char *data)
{ {
int posted; int posted;
/* Post the event, if desired */ /* Post the event, if desired */
posted = 0; posted = 0;
if (SDL_GetEventState(SDL_DROPFILE) == SDL_ENABLE) { if (SDL_GetEventState(evtype) == SDL_ENABLE) {
SDL_Event event; SDL_Event event;
event.type = SDL_DROPFILE; SDL_zero(event);
event.drop.file = SDL_strdup(file); event.type = evtype;
event.drop.file = SDL_strdup(data);
posted = (SDL_PushEvent(&event) > 0); posted = (SDL_PushEvent(&event) > 0);
} }
return (posted); return posted;
}
int
SDL_SendDropFile(const char *file)
{
return SDL_SendDrop(SDL_DROPFILE, file);
}
int
SDL_SendDropText(const char *text)
{
return SDL_SendDrop(SDL_DROPTEXT, text);
} }
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -24,6 +24,7 @@
#define _SDL_dropevents_c_h #define _SDL_dropevents_c_h
extern int SDL_SendDropFile(const char *file); extern int SDL_SendDropFile(const char *file);
extern int SDL_SendDropText(const char *text);
#endif /* _SDL_dropevents_c_h */ #endif /* _SDL_dropevents_c_h */

View File

@ -117,7 +117,9 @@ static Atom X11_PickTarget(Display *disp, Atom list[], int list_count)
int i; int i;
for (i=0; i < list_count && request == None; i++) { for (i=0; i < list_count && request == None; i++) {
name = X11_XGetAtomName(disp, list[i]); name = X11_XGetAtomName(disp, list[i]);
if (strcmp("text/uri-list", name)==0) request = list[i]; if ((SDL_strcmp("text/uri-list", name) == 0) || (SDL_strcmp("text/plain", name) == 0)) {
request = list[i];
}
X11_XFree(name); X11_XFree(name);
} }
return request; return request;
@ -1223,37 +1225,19 @@ X11_DispatchEvent(_THIS)
X11_ReadProperty(&p, display, data->xwindow, videodata->PRIMARY); X11_ReadProperty(&p, display, data->xwindow, videodata->PRIMARY);
if (p.format == 8) { if (p.format == 8) {
SDL_bool expect_lf = SDL_FALSE; /* !!! FIXME: don't use strtok here. It's not reentrant and not in SDL_stdinc. */
char *start = NULL; char* name = X11_XGetAtomName(display, target);
char *scan = (char*)p.data; char *token = strtok((char *) p.data, "\r\n");
char *fn; while (token != NULL) {
char *uri; if (SDL_strcmp("text/plain", name)==0) {
int length = 0; SDL_SendDropText(token);
while (p.count--) { } else if (SDL_strcmp("text/uri-list", name)==0) {
if (!expect_lf) { char *fn = X11_URIToLocal(token);
if (*scan == 0x0D) {
expect_lf = SDL_TRUE;
}
if (start == NULL) {
start = scan;
length = 0;
}
length++;
} else {
if (*scan == 0x0A && length > 0) {
uri = SDL_malloc(length--);
SDL_memcpy(uri, start, length);
uri[length] = '\0';
fn = X11_URIToLocal(uri);
if (fn) { if (fn) {
SDL_SendDropFile(fn); SDL_SendDropFile(fn);
} }
SDL_free(uri);
} }
expect_lf = SDL_FALSE; token = strtok(NULL, "\r\n");
start = NULL;
}
scan++;
} }
} }

View File

@ -77,9 +77,10 @@ main(int argc, char *argv[])
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
SDLTest_CommonEvent(state, &event, &done); SDLTest_CommonEvent(state, &event, &done);
if (event.type == SDL_DROPFILE) { if ((event.type == SDL_DROPFILE) || (event.type == SDL_DROPTEXT)) {
const char *typestr = (event.type == SDL_DROPFILE) ? "File" : "Text";
char *dropped_filedir = event.drop.file; char *dropped_filedir = event.drop.file;
SDL_Log("File dropped on window: %s", dropped_filedir); SDL_Log("%s dropped on window: %s", typestr, dropped_filedir);
SDL_free(dropped_filedir); SDL_free(dropped_filedir);
} }
} }