mirror of
https://github.com/glfw/glfw.git
synced 2024-11-23 10:35:10 +00:00
Cleanup.
This commit is contained in:
parent
89d0723ba3
commit
8ae063bb1b
@ -446,12 +446,10 @@ static int translateKey(unsigned int key)
|
|||||||
window = initWindow;
|
window = initWindow;
|
||||||
trackingArea = nil;
|
trackingArea = nil;
|
||||||
|
|
||||||
fileNamesForDrag = (char*)malloc(1024);
|
fileNamesForDrag = malloc(1024);
|
||||||
fileNamesSize = 1024;
|
fileNamesSize = 1024;
|
||||||
|
|
||||||
[self updateTrackingAreas];
|
[self updateTrackingAreas];
|
||||||
|
|
||||||
|
|
||||||
[self registerForDraggedTypes:[NSArray arrayWithObjects:
|
[self registerForDraggedTypes:[NSArray arrayWithObjects:
|
||||||
NSFilenamesPboardType, nil]];
|
NSFilenamesPboardType, nil]];
|
||||||
}
|
}
|
||||||
@ -667,69 +665,75 @@ static int translateKey(unsigned int key)
|
|||||||
_glfwInputScroll(window, deltaX, deltaY);
|
_glfwInputScroll(window, deltaX, deltaY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)resetCursorRects
|
||||||
// arturoc: this makes the cursor dissapear when the window is
|
|
||||||
// resized or received a drag operation
|
|
||||||
/*- (void)resetCursorRects
|
|
||||||
{
|
{
|
||||||
|
// This makes the cursor dissapear when the window is
|
||||||
|
// resized or received a drag operation
|
||||||
[self discardCursorRects];
|
[self discardCursorRects];
|
||||||
[self addCursorRect:[self bounds] cursor:_glfw.ns.cursor];
|
[self addCursorRect:[self bounds] cursor:_glfw.ns.cursor];
|
||||||
}*/
|
}
|
||||||
|
|
||||||
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
|
if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
|
||||||
== NSDragOperationGeneric) {
|
== NSDragOperationGeneric)
|
||||||
|
{
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
|
|
||||||
return NSDragOperationGeneric;
|
return NSDragOperationGeneric;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NSDragOperationNone;
|
return NSDragOperationNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender {
|
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
|
||||||
|
{
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
|
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||||
NSPasteboard *zPasteboard = [sender draggingPasteboard];
|
{
|
||||||
NSArray *files = [zPasteboard propertyListForType:NSFilenamesPboardType];
|
NSPasteboard* pasteboard = [sender draggingPasteboard];
|
||||||
|
NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||||
|
|
||||||
// set the first char to 0 so strcat
|
// set the first char to 0 so strcat
|
||||||
// starts to add from the beginning
|
// starts to add from the beginning
|
||||||
fileNamesForDrag[0] = 0;
|
fileNamesForDrag[0] = 0;
|
||||||
|
|
||||||
int dragX = [sender draggingLocation].x;
|
const int dragX = [sender draggingLocation].x;
|
||||||
int dragY = [sender draggingLocation].y;
|
const int dragY = [sender draggingLocation].y;
|
||||||
|
int dragSize = 1;
|
||||||
|
|
||||||
int dragSize = 1;
|
if ([files count])
|
||||||
if ([files count]) {
|
{
|
||||||
NSEnumerator *filenameEnum = [files objectEnumerator];
|
NSEnumerator* filenameEnum = [files objectEnumerator];
|
||||||
NSString *name;
|
NSString* name;
|
||||||
while (name = [filenameEnum nextObject]) {
|
|
||||||
dragSize += [name length]+1;
|
while (name = [filenameEnum nextObject])
|
||||||
if (dragSize > fileNamesSize){
|
{
|
||||||
|
dragSize += [name length] + 1;
|
||||||
|
|
||||||
|
if (dragSize > fileNamesSize)
|
||||||
|
{
|
||||||
fileNamesSize *= 2;
|
fileNamesSize *= 2;
|
||||||
fileNamesForDrag = realloc(fileNamesForDrag, fileNamesSize);
|
fileNamesForDrag = realloc(fileNamesForDrag, fileNamesSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat(fileNamesForDrag, [name UTF8String]);
|
strcat(fileNamesForDrag, [name UTF8String]);
|
||||||
strcat(fileNamesForDrag, "\n");
|
strcat(fileNamesForDrag, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int height;
|
int height;
|
||||||
_glfwPlatformGetWindowSize(window, NULL, &height);
|
_glfwPlatformGetWindowSize(window, NULL, &height);
|
||||||
_glfwInputCursorMotion(window, dragX, height-dragY);
|
_glfwInputCursorMotion(window, dragX, height - dragY);
|
||||||
_glfwInputDrop(window, fileNamesForDrag);
|
_glfwInputDrop(window, fileNamesForDrag);
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender {
|
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
|
||||||
|
{
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
src/input.c
13
src/input.c
@ -211,8 +211,8 @@ void _glfwInputCursorEnter(_GLFWwindow* window, int entered)
|
|||||||
window->callbacks.cursorEnter((GLFWwindow*) window, entered);
|
window->callbacks.cursorEnter((GLFWwindow*) window, entered);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwInputDrop(_GLFWwindow* window, const char* dropString){
|
void _glfwInputDrop(_GLFWwindow* window, const char* dropString)
|
||||||
|
{
|
||||||
if (window->callbacks.drop)
|
if (window->callbacks.drop)
|
||||||
window->callbacks.drop((GLFWwindow*) window, dropString);
|
window->callbacks.drop((GLFWwindow*) window, dropString);
|
||||||
}
|
}
|
||||||
@ -403,11 +403,8 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
|
|||||||
GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
|
GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
GLFWdropfun previous;
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
_GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun);
|
||||||
previous = window->callbacks.drop;
|
return cbfun;
|
||||||
window->callbacks.drop = cbfun;
|
|
||||||
return previous;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ int _glfwPlatformInit(void)
|
|||||||
if (!_glfwInitContextAPI())
|
if (!_glfwInitContextAPI())
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
|
|
||||||
_glfw.win32.dropString = (char*)malloc(1000);
|
_glfw.win32.dropString = malloc(1000);
|
||||||
_glfw.win32.dropStringSize = 1000;
|
_glfw.win32.dropStringSize = 1000;
|
||||||
|
|
||||||
_glfwInitTimer();
|
_glfwInitTimer();
|
||||||
|
@ -749,38 +749,43 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
// TODO: Restore vsync if compositing was disabled
|
// TODO: Restore vsync if compositing was disabled
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_DROPFILES:
|
case WM_DROPFILES:
|
||||||
{
|
{
|
||||||
TCHAR szName[MAX_PATH];
|
WCHAR szName[MAX_PATH];
|
||||||
HDROP hDrop = (HDROP)wParam;
|
HDROP hDrop = (HDROP) wParam;
|
||||||
POINT pt;
|
POINT pt;
|
||||||
int numFiles = DragQueryFile(hDrop, 0xFFFFFFFF, szName, MAX_PATH);
|
const int numFiles = DragQueryFile(hDrop, 0xffffffff, szName, MAX_PATH);
|
||||||
int currentSize = 1;
|
int i, currentSize = 1;
|
||||||
int i;
|
char* utf8str;
|
||||||
char* utf8str;
|
|
||||||
DragQueryPoint(hDrop, &pt);
|
|
||||||
|
|
||||||
// Move the mouse to the position of the drop
|
// Move the mouse to the position of the drop
|
||||||
_glfwInputCursorMotion(window,pt.x,pt.y);
|
DragQueryPoint(hDrop, &pt);
|
||||||
|
_glfwInputCursorMotion(window, pt.x, pt.y);
|
||||||
|
|
||||||
memset(_glfw.win32.dropString, 0, _glfw.win32.dropStringSize);
|
memset(_glfw.win32.dropString, 0, _glfw.win32.dropStringSize);
|
||||||
for(i = 0; i < numFiles; i++)
|
|
||||||
{
|
|
||||||
DragQueryFile(hDrop, i, szName, MAX_PATH);
|
|
||||||
utf8str = _glfwCreateUTF8FromWideString((const wchar_t*)szName);
|
|
||||||
currentSize += strlen(utf8str);
|
|
||||||
if(_glfw.win32.dropStringSize < currentSize){
|
|
||||||
_glfw.win32.dropStringSize *= 2;
|
|
||||||
_glfw.win32.dropString = (char*)realloc(_glfw.win32.dropString,_glfw.win32.dropStringSize);
|
|
||||||
}
|
|
||||||
strcat(_glfw.win32.dropString, utf8str);
|
|
||||||
strcat(_glfw.win32.dropString, "\n");
|
|
||||||
free(utf8str);
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputDrop(window,_glfw.win32.dropString);
|
for (i = 0; i < numFiles; i++)
|
||||||
DragFinish(hDrop);
|
{
|
||||||
break;
|
DragQueryFile(hDrop, i, szName, MAX_PATH);
|
||||||
|
utf8str = _glfwCreateUTF8FromWideString((const WCHAR*) szName);
|
||||||
|
currentSize += strlen(utf8str);
|
||||||
|
|
||||||
|
if (_glfw.win32.dropStringSize < currentSize)
|
||||||
|
{
|
||||||
|
_glfw.win32.dropStringSize *= 2;
|
||||||
|
_glfw.win32.dropString = realloc(_glfw.win32.dropString,
|
||||||
|
_glfw.win32.dropStringSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(_glfw.win32.dropString, utf8str);
|
||||||
|
strcat(_glfw.win32.dropString, "\n");
|
||||||
|
free(utf8str);
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwInputDrop(window,_glfw.win32.dropString);
|
||||||
|
DragFinish(hDrop);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -901,7 +906,7 @@ static int createWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
free(wideTitle);
|
free(wideTitle);
|
||||||
|
|
||||||
DragAcceptFiles(window->win32.handle, TRUE);
|
DragAcceptFiles(window->win32.handle, TRUE);
|
||||||
|
|
||||||
if (!window->win32.handle)
|
if (!window->win32.handle)
|
||||||
{
|
{
|
||||||
|
@ -540,8 +540,6 @@ static GLboolean initExtensions(void)
|
|||||||
XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False);
|
XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False);
|
||||||
|
|
||||||
// Find or create drag and drop atoms
|
// Find or create drag and drop atoms
|
||||||
|
|
||||||
//Atoms for Xdnd
|
|
||||||
_glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True);
|
_glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True);
|
||||||
_glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True);
|
_glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True);
|
||||||
_glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True);
|
_glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True);
|
||||||
@ -552,8 +550,6 @@ static GLboolean initExtensions(void)
|
|||||||
_glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True);
|
_glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True);
|
||||||
_glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True);
|
_glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,20 +121,21 @@ typedef struct _GLFWlibraryX11
|
|||||||
|
|
||||||
// Atoms for Xdnd
|
// Atoms for Xdnd
|
||||||
Atom XdndAware;
|
Atom XdndAware;
|
||||||
Atom XdndEnter;
|
Atom XdndEnter;
|
||||||
Atom XdndPosition;
|
Atom XdndPosition;
|
||||||
Atom XdndStatus;
|
Atom XdndStatus;
|
||||||
Atom XdndActionCopy;
|
Atom XdndActionCopy;
|
||||||
Atom XdndDrop;
|
Atom XdndDrop;
|
||||||
Atom XdndLeave;
|
Atom XdndLeave;
|
||||||
Atom XdndFinished;
|
Atom XdndFinished;
|
||||||
Atom XdndSelection;
|
Atom XdndSelection;
|
||||||
struct{
|
|
||||||
Window sourceWindow;
|
struct {
|
||||||
char* string;
|
Window sourceWindow;
|
||||||
char* type1;
|
char* string;
|
||||||
char* type2;
|
char* type1;
|
||||||
char* type3;
|
char* type2;
|
||||||
|
char* type3;
|
||||||
} xdnd;
|
} xdnd;
|
||||||
|
|
||||||
// Selection atoms
|
// Selection atoms
|
||||||
|
197
src/x11_window.c
197
src/x11_window.c
@ -306,12 +306,14 @@ static GLboolean createWindow(_GLFWwindow* window,
|
|||||||
XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1);
|
XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable Xdnd
|
if (_glfw.x11.XdndAware)
|
||||||
if(_glfw.x11.XdndAware!=None)
|
|
||||||
{
|
{
|
||||||
//Announce XDND support
|
// Announce support for XDND version 5 and below
|
||||||
Atom version=5;
|
|
||||||
XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&version, 1);
|
const Atom version = 5;
|
||||||
|
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||||
|
_glfw.x11.XdndAware, XA_ATOM, 32,
|
||||||
|
PropModeReplace, (unsigned char*) &version, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwPlatformSetWindowTitle(window, wndconfig->title);
|
_glfwPlatformSetWindowTitle(window, wndconfig->title);
|
||||||
@ -714,126 +716,123 @@ static void processEvent(XEvent *event)
|
|||||||
event);
|
event);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(event->xclient.message_type == _glfw.x11.XdndEnter)
|
else if (event->xclient.message_type == _glfw.x11.XdndEnter)
|
||||||
{
|
{
|
||||||
// Xdnd Enter: the drag&drop event has started in the window,
|
// Xdnd Enter: the drag&drop event has started in the window, we
|
||||||
// we could be getting the type and possible conversions here
|
// could be getting the type and possible conversions here but
|
||||||
// but since we use always string conversion we don't need
|
// since we use always string conversion we don't need it
|
||||||
// it
|
|
||||||
}
|
}
|
||||||
else if(event->xclient.message_type == _glfw.x11.XdndDrop)
|
else if (event->xclient.message_type == _glfw.x11.XdndDrop)
|
||||||
{
|
{
|
||||||
// Xdnd Drop: The drag&drop event has finished dropping on
|
// Xdnd Drop: The drag&drop event has finished dropping on
|
||||||
// the window, ask to convert the selection
|
// the window, ask to convert the selection
|
||||||
_glfw.x11.xdnd.sourceWindow = event->xclient.data.l[0];
|
_glfw.x11.xdnd.sourceWindow = event->xclient.data.l[0];
|
||||||
XConvertSelection(_glfw.x11.display,
|
XConvertSelection(_glfw.x11.display,
|
||||||
_glfw.x11.XdndSelection,
|
_glfw.x11.XdndSelection,
|
||||||
_glfw.x11.UTF8_STRING,
|
_glfw.x11.UTF8_STRING,
|
||||||
_glfw.x11.XdndSelection,
|
_glfw.x11.XdndSelection,
|
||||||
window->x11.handle, CurrentTime);
|
window->x11.handle, CurrentTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(event->xclient.message_type == _glfw.x11.XdndLeave)
|
else if (event->xclient.message_type == _glfw.x11.XdndLeave)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(event->xclient.message_type == _glfw.x11.XdndPosition)
|
else if (event->xclient.message_type == _glfw.x11.XdndPosition)
|
||||||
{
|
{
|
||||||
// Xdnd Position: get coordinates of the mouse inside the window
|
// Xdnd Position: get coordinates of the mouse inside the window
|
||||||
// and update the mouse position
|
// and update the mouse position
|
||||||
int absX = (event->xclient.data.l[2]>>16) & 0xFFFF;
|
const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF;
|
||||||
int absY = (event->xclient.data.l[2]) & 0xFFFF;
|
const int absY = (event->xclient.data.l[2]) & 0xFFFF;
|
||||||
int x;
|
int x, y;
|
||||||
int y;
|
|
||||||
|
|
||||||
_glfwPlatformGetWindowPos(window,&x,&y);
|
_glfwPlatformGetWindowPos(window, &x, &y);
|
||||||
|
_glfwInputCursorMotion(window, absX - x, absY - y);
|
||||||
|
|
||||||
_glfwInputCursorMotion(window,absX-x,absY-y);
|
// Xdnd: reply with an XDND status message
|
||||||
|
XEvent reply;
|
||||||
|
memset(&reply, sizeof(reply), 0);
|
||||||
|
|
||||||
// Xdnd: reply with an XDND status message
|
reply.type = ClientMessage;
|
||||||
XClientMessageEvent m;
|
reply.xclient.window = event->xclient.data.l[0];
|
||||||
memset(&m, sizeof(m), 0);
|
reply.xclient.message_type = _glfw.x11.XdndStatus;
|
||||||
m.type = ClientMessage;
|
reply.xclient.format = 32;
|
||||||
m.display = event->xclient.display;
|
reply.xclient.data.l[0] = window->x11.handle;
|
||||||
m.window = event->xclient.data.l[0];
|
reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle
|
||||||
m.message_type = _glfw.x11.XdndStatus;
|
reply.xclient.data.l[2] = 0; // Specify an empty rectangle
|
||||||
m.format=32;
|
reply.xclient.data.l[3] = 0;
|
||||||
m.data.l[0] = window->x11.handle;
|
reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy; // We only accept copying
|
||||||
m.data.l[1] = 1; // Always accept the dnd with no rectangle
|
|
||||||
m.data.l[2] = 0; // Specify an empty rectangle
|
|
||||||
m.data.l[3] = 0;
|
|
||||||
m.data.l[4] = _glfw.x11.XdndActionCopy; // We only accept copying
|
|
||||||
|
|
||||||
XSendEvent(_glfw.x11.display, event->xclient.data.l[0], False, NoEventMask, (XEvent*)&m);
|
XSendEvent(_glfw.x11.display, window->x11.handle,
|
||||||
XFlush(_glfw.x11.display);
|
False, NoEventMask, &reply);
|
||||||
|
XFlush(_glfw.x11.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SelectionNotify:
|
case SelectionNotify:
|
||||||
{
|
{
|
||||||
if(event->xselection.property != None)
|
if (event->xselection.property != None)
|
||||||
{
|
{
|
||||||
// Xdnd: got a selection notification from the conversion
|
// Xdnd: got a selection notification from the conversion
|
||||||
// we asked for, get the data and finish the d&d event
|
// we asked for, get the data and finish the d&d event
|
||||||
char* data;
|
char* data;
|
||||||
free(_glfw.x11.xdnd.string);
|
|
||||||
_glfw.x11.xdnd.string = NULL;
|
|
||||||
int result = _glfwGetWindowProperty(event->xselection.requestor,
|
|
||||||
event->xselection.property,
|
|
||||||
event->xselection.target,
|
|
||||||
(unsigned char**) &data);
|
|
||||||
|
|
||||||
if(result){
|
free(_glfw.x11.xdnd.string);
|
||||||
// nautilus seems to add a \r at the end of the paths
|
_glfw.x11.xdnd.string = NULL;
|
||||||
// remove it so paths can be directly used
|
|
||||||
_glfw.x11.xdnd.string = malloc(strlen(data));
|
|
||||||
char *to = _glfw.x11.xdnd.string;
|
|
||||||
const char *from = data;
|
|
||||||
const char *current = strchr(from, '\r');
|
|
||||||
while(current)
|
|
||||||
{
|
|
||||||
int charsToCopy = current - from;
|
|
||||||
memcpy(to, from, (size_t)charsToCopy);
|
|
||||||
to += charsToCopy;
|
|
||||||
|
|
||||||
from = current+1;
|
const int result = _glfwGetWindowProperty(event->xselection.requestor,
|
||||||
current = strchr(from, '\r');
|
event->xselection.property,
|
||||||
}
|
event->xselection.target,
|
||||||
|
(unsigned char**) &data);
|
||||||
|
|
||||||
size_t remaining = strlen(from);
|
if (result)
|
||||||
|
{
|
||||||
|
// Nautilus seems to add a \r at the end of the paths
|
||||||
|
// remove it so paths can be directly used
|
||||||
|
_glfw.x11.xdnd.string = malloc(strlen(data));
|
||||||
|
char *to = _glfw.x11.xdnd.string;
|
||||||
|
const char *from = data;
|
||||||
|
const char *current = strchr(from, '\r');
|
||||||
|
|
||||||
memcpy(to, from, remaining);
|
while (current)
|
||||||
to += remaining;
|
{
|
||||||
*to = 0;
|
const int charsToCopy = current - from;
|
||||||
}
|
memcpy(to, from, (size_t) charsToCopy);
|
||||||
|
to += charsToCopy;
|
||||||
|
|
||||||
XClientMessageEvent m;
|
from = current + 1;
|
||||||
memset(&m, sizeof(m), 0);
|
current = strchr(from, '\r');
|
||||||
m.type = ClientMessage;
|
}
|
||||||
m.display = _glfw.x11.display;
|
|
||||||
m.window = _glfw.x11.xdnd.sourceWindow;
|
|
||||||
m.message_type = _glfw.x11.XdndFinished;
|
|
||||||
m.format=32;
|
|
||||||
m.data.l[0] = window->x11.handle;
|
|
||||||
m.data.l[1] = result;
|
|
||||||
m.data.l[2] = _glfw.x11.XdndActionCopy; //We only ever copy.
|
|
||||||
|
|
||||||
// Reply that all is well.
|
const size_t remaining = strlen(from);
|
||||||
XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, False, NoEventMask, (XEvent*)&m);
|
|
||||||
|
|
||||||
XSync(_glfw.x11.display, False);
|
memcpy(to, from, remaining);
|
||||||
|
to += remaining;
|
||||||
|
*to = 0;
|
||||||
|
}
|
||||||
|
|
||||||
XFree(data);
|
XEvent reply;
|
||||||
|
memset(&reply, sizeof(reply), 0);
|
||||||
|
reply.type = ClientMessage;
|
||||||
|
reply.xclient.window = _glfw.x11.xdnd.sourceWindow;
|
||||||
|
reply.xclient.message_type = _glfw.x11.XdndFinished;
|
||||||
|
reply.xclient.format = 32;
|
||||||
|
reply.xclient.data.l[0] = window->x11.handle;
|
||||||
|
reply.xclient.data.l[1] = result;
|
||||||
|
reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy; // We only ever copy
|
||||||
|
|
||||||
if(result)
|
// Reply that all is well
|
||||||
{
|
XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow,
|
||||||
_glfwInputDrop(window,_glfw.x11.xdnd.string);
|
False, NoEventMask, &reply);
|
||||||
|
XSync(_glfw.x11.display, False);
|
||||||
|
XFree(data);
|
||||||
|
|
||||||
}
|
if (result)
|
||||||
}
|
_glfwInputDrop(window, _glfw.x11.xdnd.string);
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MapNotify:
|
case MapNotify:
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user