Add Drag and drop position, for x11, wayland and MACOSX
This commit is contained in:
@@ -27,9 +27,11 @@
|
||||
|
||||
#include "../video/SDL_sysvideo.h" /* for SDL_Window internals. */
|
||||
|
||||
static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data)
|
||||
static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data, float x, float y)
|
||||
{
|
||||
static SDL_bool app_is_dropping = SDL_FALSE;
|
||||
static float last_drop_x = 0;
|
||||
static float last_drop_y = 0;
|
||||
int posted = 0;
|
||||
|
||||
/* Post the event, if desired */
|
||||
@@ -58,6 +60,13 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
|
||||
event.common.timestamp = 0;
|
||||
event.drop.file = data ? SDL_strdup(data) : NULL;
|
||||
event.drop.windowID = window ? window->id : 0;
|
||||
|
||||
if (evtype == SDL_EVENT_DROP_POSITION) {
|
||||
last_drop_x = x;
|
||||
last_drop_y = y;
|
||||
}
|
||||
event.drop.x = last_drop_x;
|
||||
event.drop.y = last_drop_y;
|
||||
posted = (SDL_PushEvent(&event) > 0);
|
||||
|
||||
if (posted && (evtype == SDL_EVENT_DROP_COMPLETE)) {
|
||||
@@ -66,6 +75,9 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
|
||||
} else {
|
||||
app_is_dropping = SDL_FALSE;
|
||||
}
|
||||
|
||||
last_drop_x = 0;
|
||||
last_drop_y = 0;
|
||||
}
|
||||
}
|
||||
return posted;
|
||||
@@ -73,15 +85,21 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
|
||||
|
||||
int SDL_SendDropFile(SDL_Window *window, const char *file)
|
||||
{
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_FILE, file);
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_FILE, file, 0, 0);
|
||||
}
|
||||
|
||||
int SDL_SendDropPosition(SDL_Window *window, const char *file, float x, float y)
|
||||
{
|
||||
/* Don't send 'file' since this is an malloc per position, which may be forgotten to be freed */
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_POSITION, NULL, x, y);
|
||||
}
|
||||
|
||||
int SDL_SendDropText(SDL_Window *window, const char *text)
|
||||
{
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_TEXT, text);
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_TEXT, text, 0, 0);
|
||||
}
|
||||
|
||||
int SDL_SendDropComplete(SDL_Window *window)
|
||||
{
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_COMPLETE, NULL);
|
||||
return SDL_SendDrop(window, SDL_EVENT_DROP_COMPLETE, NULL, 0, 0);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define SDL_dropevents_c_h_
|
||||
|
||||
extern int SDL_SendDropFile(SDL_Window *window, const char *file);
|
||||
extern int SDL_SendDropPosition(SDL_Window *window, const char *file, float x, float y);
|
||||
extern int SDL_SendDropText(SDL_Window *window, const char *text);
|
||||
extern int SDL_SendDropComplete(SDL_Window *window);
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
|
||||
/* Handle drag-and-drop of files onto the SDL window. */
|
||||
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender;
|
||||
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender;
|
||||
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender;
|
||||
- (BOOL)wantsPeriodicDraggingUpdates;
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem;
|
||||
@@ -158,6 +159,21 @@
|
||||
return NSDragOperationNone; /* no idea what to do with this, reject it. */
|
||||
}
|
||||
|
||||
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
|
||||
{
|
||||
if (([sender draggingSourceOperationMask] & NSDragOperationGeneric) == NSDragOperationGeneric) {
|
||||
SDL_Window *sdlwindow = [self findSDLWindow];
|
||||
NSPoint point = [sender draggingLocation];
|
||||
float x, y;
|
||||
x = point.x;
|
||||
y = (sdlwindow->h - point.y);
|
||||
SDL_SendDropPosition(sdlwindow, NULL, x, y); /* FIXME, should we get the filename */
|
||||
return NSDragOperationGeneric;
|
||||
}
|
||||
|
||||
return NSDragOperationNone; /* no idea what to do with this, reject it. */
|
||||
}
|
||||
|
||||
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
@@ -96,6 +96,8 @@ struct SDL_WaylandTouchPointList
|
||||
|
||||
static struct SDL_WaylandTouchPointList touch_points = { NULL, NULL };
|
||||
|
||||
static char *Wayland_URIToLocal(char *uri);
|
||||
|
||||
static void touch_add(SDL_TouchID id, float x, float y, struct wl_surface *surface)
|
||||
{
|
||||
struct SDL_WaylandTouchPoint *tp = SDL_malloc(sizeof(struct SDL_WaylandTouchPoint));
|
||||
@@ -1845,6 +1847,30 @@ static void data_device_handle_leave(void *data, struct wl_data_device *wl_data_
|
||||
static void data_device_handle_motion(void *data, struct wl_data_device *wl_data_device,
|
||||
uint32_t time, wl_fixed_t x, wl_fixed_t y)
|
||||
{
|
||||
SDL_WaylandDataDevice *data_device = data;
|
||||
|
||||
if (data_device->drag_offer != NULL) {
|
||||
/* TODO: SDL Support more mime types */
|
||||
size_t length;
|
||||
void *buffer = Wayland_data_offer_receive(data_device->drag_offer,
|
||||
&length, FILE_MIME, SDL_TRUE);
|
||||
if (buffer) {
|
||||
char *saveptr = NULL;
|
||||
char *token = SDL_strtokr((char *)buffer, "\r\n", &saveptr);
|
||||
while (token != NULL) {
|
||||
char *fn = Wayland_URIToLocal(token);
|
||||
if (fn) {
|
||||
double dx;
|
||||
double dy;
|
||||
dx = wl_fixed_to_double(x);
|
||||
dy = wl_fixed_to_double(y);
|
||||
SDL_SendDropPosition(data_device->dnd_window, fn, (float)dx, (float)dy);
|
||||
}
|
||||
token = SDL_strtokr(NULL, "\r\n", &saveptr);
|
||||
}
|
||||
SDL_free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Decodes URI escape sequences in string buf of len bytes
|
||||
|
||||
@@ -1222,6 +1222,18 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
|
||||
}
|
||||
printf("Action requested by user is : %s\n", X11_XGetAtomName(display, act));
|
||||
#endif
|
||||
{
|
||||
/* Drag and Drop position */
|
||||
int root_x, root_y, window_x, window_y;
|
||||
Window ChildReturn;
|
||||
root_x = xevent->xclient.data.l[2] >> 16;
|
||||
root_y = xevent->xclient.data.l[2] & 0xffff;
|
||||
/* Translate from root to current window position */
|
||||
X11_XTranslateCoordinates(display, DefaultRootWindow(display), data->xwindow,
|
||||
root_x, root_y, &window_x, &window_y, &ChildReturn);
|
||||
|
||||
SDL_SendDropPosition(data->window, NULL, (float)window_x, (float)window_y); /* FIXME, can we get the filename ? */
|
||||
}
|
||||
|
||||
/* reply with status */
|
||||
SDL_memset(&m, 0, sizeof(XClientMessageEvent));
|
||||
|
||||
Reference in New Issue
Block a user