Added SDL_DROPTEXT event, for dragging and dropping string data.
authorRyan C. Gordon <icculus@icculus.org>
Tue, 05 Jan 2016 02:26:45 -0500
changeset 1002008b9e569e1ce
parent 10019 36f7e8084508
child 10021 3beca914a2ad
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.
include/SDL_events.h
src/events/SDL_dropevents.c
src/events/SDL_dropevents_c.h
src/video/x11/SDL_x11events.c
test/testdropfile.c
     1.1 --- a/include/SDL_events.h	Mon Jan 04 23:52:40 2016 -0500
     1.2 +++ b/include/SDL_events.h	Tue Jan 05 02:26:45 2016 -0500
     1.3 @@ -136,6 +136,7 @@
     1.4  
     1.5      /* Drag and drop events */
     1.6      SDL_DROPFILE        = 0x1000, /**< The system requests a file open */
     1.7 +    SDL_DROPTEXT,                 /**< text/plain drag-and-drop event */
     1.8  
     1.9      /* Audio hotplug events */
    1.10      SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */
     2.1 --- a/src/events/SDL_dropevents.c	Mon Jan 04 23:52:40 2016 -0500
     2.2 +++ b/src/events/SDL_dropevents.c	Tue Jan 05 02:26:45 2016 -0500
     2.3 @@ -27,20 +27,33 @@
     2.4  #include "SDL_dropevents_c.h"
     2.5  
     2.6  
     2.7 -int
     2.8 -SDL_SendDropFile(const char *file)
     2.9 +static int
    2.10 +SDL_SendDrop(const SDL_EventType evtype, const char *data)
    2.11  {
    2.12      int posted;
    2.13  
    2.14      /* Post the event, if desired */
    2.15      posted = 0;
    2.16 -    if (SDL_GetEventState(SDL_DROPFILE) == SDL_ENABLE) {
    2.17 +    if (SDL_GetEventState(evtype) == SDL_ENABLE) {
    2.18          SDL_Event event;
    2.19 -        event.type = SDL_DROPFILE;
    2.20 -        event.drop.file = SDL_strdup(file);
    2.21 +        SDL_zero(event);
    2.22 +        event.type = evtype;
    2.23 +        event.drop.file = SDL_strdup(data);
    2.24          posted = (SDL_PushEvent(&event) > 0);
    2.25      }
    2.26 -    return (posted);
    2.27 +    return posted;
    2.28 +}
    2.29 +
    2.30 +int
    2.31 +SDL_SendDropFile(const char *file)
    2.32 +{
    2.33 +    return SDL_SendDrop(SDL_DROPFILE, file);
    2.34 +}
    2.35 +
    2.36 +int
    2.37 +SDL_SendDropText(const char *text)
    2.38 +{
    2.39 +    return SDL_SendDrop(SDL_DROPTEXT, text);
    2.40  }
    2.41  
    2.42  /* vi: set ts=4 sw=4 expandtab: */
     3.1 --- a/src/events/SDL_dropevents_c.h	Mon Jan 04 23:52:40 2016 -0500
     3.2 +++ b/src/events/SDL_dropevents_c.h	Tue Jan 05 02:26:45 2016 -0500
     3.3 @@ -24,6 +24,7 @@
     3.4  #define _SDL_dropevents_c_h
     3.5  
     3.6  extern int SDL_SendDropFile(const char *file);
     3.7 +extern int SDL_SendDropText(const char *text);
     3.8  
     3.9  #endif /* _SDL_dropevents_c_h */
    3.10  
     4.1 --- a/src/video/x11/SDL_x11events.c	Mon Jan 04 23:52:40 2016 -0500
     4.2 +++ b/src/video/x11/SDL_x11events.c	Tue Jan 05 02:26:45 2016 -0500
     4.3 @@ -117,7 +117,9 @@
     4.4      int i;
     4.5      for (i=0; i < list_count && request == None; i++) {
     4.6          name = X11_XGetAtomName(disp, list[i]);
     4.7 -        if (strcmp("text/uri-list", name)==0) request = list[i];
     4.8 +        if ((SDL_strcmp("text/uri-list", name) == 0) || (SDL_strcmp("text/plain", name) == 0)) {
     4.9 +             request = list[i];
    4.10 +        }
    4.11          X11_XFree(name);
    4.12      }
    4.13      return request;
    4.14 @@ -1223,37 +1225,19 @@
    4.15                  X11_ReadProperty(&p, display, data->xwindow, videodata->PRIMARY);
    4.16  
    4.17                  if (p.format == 8) {
    4.18 -                    SDL_bool expect_lf = SDL_FALSE;
    4.19 -                    char *start = NULL;
    4.20 -                    char *scan = (char*)p.data;
    4.21 -                    char *fn;
    4.22 -                    char *uri;
    4.23 -                    int length = 0;
    4.24 -                    while (p.count--) {
    4.25 -                        if (!expect_lf) {
    4.26 -                            if (*scan == 0x0D) {
    4.27 -                                expect_lf = SDL_TRUE;
    4.28 +                    /* !!! FIXME: don't use strtok here. It's not reentrant and not in SDL_stdinc. */
    4.29 +                    char* name = X11_XGetAtomName(display, target);
    4.30 +                    char *token = strtok((char *) p.data, "\r\n");
    4.31 +                    while (token != NULL) {
    4.32 +                        if (SDL_strcmp("text/plain", name)==0) {
    4.33 +                            SDL_SendDropText(token);
    4.34 +                        } else if (SDL_strcmp("text/uri-list", name)==0) {
    4.35 +                            char *fn = X11_URIToLocal(token);
    4.36 +                            if (fn) {
    4.37 +                                SDL_SendDropFile(fn);
    4.38                              }
    4.39 -                            if (start == NULL) {
    4.40 -                                start = scan;
    4.41 -                                length = 0;
    4.42 -                            }
    4.43 -                            length++;
    4.44 -                        } else {
    4.45 -                            if (*scan == 0x0A && length > 0) {
    4.46 -                                uri = SDL_malloc(length--);
    4.47 -                                SDL_memcpy(uri, start, length);
    4.48 -                                uri[length] = '\0';
    4.49 -                                fn = X11_URIToLocal(uri);
    4.50 -                                if (fn) {
    4.51 -                                    SDL_SendDropFile(fn);
    4.52 -                                }
    4.53 -                                SDL_free(uri);
    4.54 -                            }
    4.55 -                            expect_lf = SDL_FALSE;
    4.56 -                            start = NULL;
    4.57                          }
    4.58 -                        scan++;
    4.59 +                        token = strtok(NULL, "\r\n");
    4.60                      }
    4.61                  }
    4.62  
     5.1 --- a/test/testdropfile.c	Mon Jan 04 23:52:40 2016 -0500
     5.2 +++ b/test/testdropfile.c	Tue Jan 05 02:26:45 2016 -0500
     5.3 @@ -77,9 +77,10 @@
     5.4          while (SDL_PollEvent(&event)) {
     5.5              SDLTest_CommonEvent(state, &event, &done);
     5.6  
     5.7 -            if (event.type == SDL_DROPFILE) {
     5.8 +            if ((event.type == SDL_DROPFILE) || (event.type == SDL_DROPTEXT)) {
     5.9 +                const char *typestr = (event.type == SDL_DROPFILE) ? "File" : "Text";
    5.10                  char *dropped_filedir = event.drop.file;
    5.11 -                SDL_Log("File dropped on window: %s", dropped_filedir);
    5.12 +                SDL_Log("%s dropped on window: %s", typestr, dropped_filedir);
    5.13                  SDL_free(dropped_filedir);
    5.14              }
    5.15          }