Hi Sam and SDL community
The attached patch for SDL implements drag and drop using XDND protocol on X11.
XDND protocol: http://www.newplanetsoftware.com/xdnd/
The present SDL_DROPFILE event does not trigger on X11 systems such as BSD and Linux.
The SDL_DROPFILE seems to support a single file drag and drop.
Whereas, the XDND protocol on X11, supports not only single file drag and drop, it supports multiple files, text and other types of drag and drop. Therefore, more versatile.
This patch introduces a new programming interface on drag and drop on X11. Once this new programming interface is finalised and acceptable to the SDL community, I would like to see this patch is absorbed into the SDL main tree.
A summary and an example of how to use XDND-based drag and drop on X11 are also included below.
Those who are new for XDND, please read the ?Example walk-through? section from http://www.newplanetsoftware.com/xdnd/ .
Thank you.
Kind regards
Sagara Wijetunga
About the patch----------------------
-
New set of drag and drop events have been introduced: SDL_XDNDENTER, SDL_XDNDPOSITION, SDL_XDNDLEAVE and SDL_XDNDDROP. [include/SDL_events.h]
-
Instead of activating them individually, the patch relies on the activation of the SDL_DROPFILE.
-
Corresponding data structures SDL_XdndEnter, SDL_XdndPosition, SDL_XdndLeave and SDL_XdndDrop have also been introduced to above new events. [include/SDL_events.h]
-
A new SDL_WindowFlags is also introduced: SDL_WINDOW_XDNDAWARE. This new flag creates a SDL_Window which XDnD aware.
-
Code sections may require to move to different files or to new files to suit SDL coding conventions. Also may require to update the patch to exclude compiling on non-X11 systems.
-
When retrive data using “text/uri-list”, the returned list may be separated by newline (\n).
-
This patch was developed and only tested on SDL 2.0.
How to apply the patch
cd SDL
patch -Np1 path-to-patch
Example
?SDL_Event??? event;
?SDL_Window window;
?SDL_SysWMinfo info;
?unsigned long int SDLWindowXID = 0; / X Window id of the SDL Window */
?Uint8??? currentXdndProtocolVersion = 0;
?Uint32??? currentXdndDataTypeList = NULL;
?Uint32??? currentXdndNumDataTypes = 0;? / Number of data types in currentDnDDataTypeList */
?unsigned char *currentXdndDataBuf = NULL;
?Uint32?? ??? currentXdndDataBufLen = 0;
?unsigned char *appDataBuf = NULL;
?
?int n;
?
?int curWindowPosition_x, curWindowPosition_y;
?int curWindow_w, curWindow_h;
?/* Enable SDL_DROPFILE event which is disabled by default */
?SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
?/* Create the SDL_Window with XdndAware */
?window = SDL_CreateWindow(“SDL Window”, 0, 0, width, height, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_XDNDAWARE);
?/* Initialize info structure with SDL version info */
?SDL_VERSION(&info.version);
?
? if (SDL_GetWindowWMInfo(window, &info))
??? {
??? SDLWindowXID = (unsigned long int) info.info.x11.window;
??? }
?/* Wait for events */
?for(;
?{
? SDL_WaitEvent(&event);
?
? switch(event.type)
? {
??? case SDL_XDNDENTER:??? ?
??? if (event.xDndEnter.targetWindow == SDLWindowXID)
??? {
?? ?? printf("\n SDL_XDNDENTER \n");
?? ?? printf(“event.xDndEnter.targetWindow: %lu\n”, (unsigned long int) event.xDndEnter.targetWindow);
?? ?? printf(“SDLWindowXID: %lu\n”, (unsigned long int) SDLWindowXID);
?? ?? currentXdndProtocolVersion = event.xDndEnter.protocolVersion;
?? ? ?
?? ?? if (currentXdndDataTypeList != NULL)
?? ??? SDL_free(currentXdndDataTypeList);
?? ??? ?
?? ?? currentXdndDataTypeList??? = event.xDndEnter.dataTypeList;
?? ?? currentXdndNumDataTypes??? = event.xDndEnter.numDataTypes;? /* Number of data types in currentDnDDataTypeList */??? ?
?? ?
?? ?? printf(“sourceWindow: %d\n”, event.xDndEnter.sourceWindow);
?? ?? printf(“protocolVersion: %d\n”, event.xDndEnter.protocolVersion);
?? ?? printf(“numDataTypes: %d\n”, event.xDndEnter.numDataTypes);
?? ?? if (event.xDndEnter.dataTypeList == NULL)
?? ??? printf(“dataTypeList is NULL\n”);
??? ?
?? ?? for (n=0; n < event.xDndEnter.numDataTypes; n++)
?? ??? {
?? ??? printf(“dataType: %d - %s\n”, event.xDndEnter.dataTypeList[n],
?? ??? ?SDL_XdndGetDataTypeName(event.xDndEnter.sourceDisplay, event.xDndEnter.dataTypeList[n]));
?? ??? }
??? }
??? break;
??? case SDL_XDNDPOSITION:
??? if (event.xDndPosition.targetWindow == SDLWindowXID)
??? {
?? ?? printf("\n SDL_XDNDPOSITION \n");
?? ?? printf(“sourceWindow: %d\n”, event.xDndPosition.sourceWindow);
?? ?? printf(“X: %d\n”, event.xDndPosition.x);
?? ?? printf(“Y: %d\n”, event.xDndPosition.y);
?? ?? printf(“timeStamp: %d\n”, event.xDndPosition.timeStamp);
?? ?? printf(“actionRequested: %d\n”, event.xDndPosition.actionRequested);
?? ?? /* Call SDL_XdndXConvertSelection() is required in SDL_XDNDPOSITION */
?? ?? SDL_XdndXConvertSelection(event.xDndPosition.sourceDisplay,
?? ??? ??? ??? ??? event.xDndPosition.sourceWindow,
?? ??? ??? ??? ??? SDL_XdndGetDataType(event.xDndPosition.sourceDisplay, “text/uri-list”),
?? ??? ??? ??? ??? event.xDndPosition.timeStamp);
?? ? ?
?? ?? SDL_GetWindowPosition(window, &curWindowPosition_x, &curWindowPosition_y);
?? ?? SDL_GetWindowSize(window, &curWindow_w, &curWindow_h);
?? ?? SDL_SendXdndStatus(window, event.xDndPosition.sourceDisplay, event.xDndPosition.sourceWindow,
?? ??? ??? ??? 1, curWindowPosition_x, curWindowPosition_y,
?? ??? ??? ??? curWindow_w, curWindow_h);?? ??? ?
?? ? }
??? break;
??? case SDL_XDNDLEAVE:
??? if (event.xDndLeave.targetWindow == SDLWindowXID)
??? {
?? ?? printf("\n SDL_XDNDLEAVE \n");
?? ?? printf(“sourceWindow: %d\n”, event.xDndLeave.sourceWindow);
?? ?? if (currentXdndDataBuf != NULL)
?? ??? {
?? ??? SDL_free(currentXdndDataBuf);
?? ??? currentXdndDataBuf = NULL;
?? ??? }
?? ? }
??? break;
??? case SDL_XDNDDROP:
??? if (event.xDndDrop.targetWindow == SDLWindowXID)
??? {
?? ?? printf("\n SDL_XDNDDROP \n");
?? ?? printf(“sourceWindow: %d\n”, event.xDndDrop.sourceWindow);
?? ?? printf(“timeStamp: %d\n”, event.xDndDrop.timeStamp);
?? ??? ?
?? ?? if (appDataBuf != NULL)
?? ??? {
?? ??? SDL_free(appDataBuf);
?? ??? }
?? ?? currentXdndDataBuf = SDL_XdndGetData(event.xDndDrop.sourceDisplay,
?? ??? ??? ??? ??? event.xDndDrop.sourceWindow,
?? ??? ??? ??? ??? SDL_XdndGetDataType(event.xDndDrop.sourceDisplay, “text/uri-list”),
?? ??? ??? ??? ??? event.xDndDrop.timeStamp,
?? ??? ??? ??? ??? ¤tXdndDataBufLen);
?? ?? if (currentXdndDataBuf == NULL)
?? ??? printf(“No data buffer returned!\n”);
?? ? ?
?? ?? printf(“currentXdndDataBufLen: %d\n”, currentXdndDataBufLen);
?? ? ?
?? ?? SDL_SendXdndFinished(window, event.xDndDrop.sourceDisplay, event.xDndDrop.sourceWindow,
?? ??? ??? ??? 1, currentXdndProtocolVersion);
?? ??? ??? ??? ?
?? ?? if (currentXdndDataBufLen > 0)
?? ??? {
?? ??? appDataBuf = (Uint8 ) SDL_malloc(sizeof(Uint8)(currentXdndDataBufLen+1));
?? ? ?
?? ??? if (appDataBuf != NULL)
?? ??? ? {
?? ??? ?? for (n=0; n < currentXdndDataBufLen; n++)
?? ??? ??? {
?? ??? ??? appDataBuf[n] = currentXdndDataBuf[n];
?? ??? ??? }
?? ??? ?
?? ??? ?? appDataBuf[currentXdndDataBufLen] = ‘\0’;
?? ??? ?? SDL_free(currentXdndDataBuf);
?? ??? ?? currentXdndDataBuf = NULL;
?? ??? ? ?
?? ??? ?? printf(“Data: %s\n”, appDataBuf);
?? ??? ? }
?? ??? }
?? ? }
??? break;
? }
}
==============
-------------- next part --------------
A non-text attachment was scrubbed…
Name: SDL-XDND-2013-Feb-11.patch
Type: application/octet-stream
Size: 20143 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20130211/59c1acc6/attachment-0001.obj