From f383cc8289c2018d37c613d40cb27466cd3c1689 Mon Sep 17 00:00:00 2001 From: arturo Date: Wed, 10 Jul 2013 11:42:14 +0200 Subject: [PATCH 01/16] initial drag and drop support for windows and linux --- include/GLFW/glfw3.h | 30 +++++++++++ src/input.c | 17 +++++++ src/internal.h | 9 ++++ src/win32_platform.h | 1 + src/win32_window.c | 39 +++++++++++++++ src/x11_init.c | 21 ++++++++ src/x11_platform.h | 20 ++++++++ src/x11_window.c | 115 ++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 251 insertions(+), 1 deletion(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index bb97903c..42586b4d 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -772,6 +772,20 @@ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); */ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); + +/*! @brief The function signature for drop callbacks. + * + * This is the function signature for drop callbacks. + * + * @param[in] window The window that received the event. + * @param[in] string The string descriptor for the dropped object. + * + * @sa glfwSetDropCallback + * + * @ingroup input + */ +typedef void (* GLFWdropfun)(GLFWwindow*,const char*); + /*! @brief The function signature for monitor configuration callbacks. * * This is the function signature for monitor configuration callback functions. @@ -1983,6 +1997,22 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcu */ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun); +/*! @brief Sets the drop callback. + * + * This function sets the drop callback of the specified window, which is + * called when an object is dropped over the window. + * + * + * @param[in] window The window whose callback to set. + * @param[in] cbfun The new drop callback, or `NULL` to remove the currently + * set callback. + * @return The previously set callback, or `NULL` if no callback was set or an + * error occurred. + * + * @ingroup input + */ +GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); + /*! @brief Returns whether the specified joystick is present. * * This function returns whether the specified joystick is present. diff --git a/src/input.c b/src/input.c index de4ed793..684e778a 100644 --- a/src/input.c +++ b/src/input.c @@ -218,6 +218,12 @@ void _glfwInputCursorEnter(_GLFWwindow* window, int entered) window->callbacks.cursorEnter((GLFWwindow*) window, entered); } +void _glfwInputDrop(_GLFWwindow* window, const char* dropString){ + + if (window->callbacks.drop) + window->callbacks.drop((GLFWwindow*) window, dropString); +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW public API ////// @@ -425,3 +431,14 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, return previous; } +GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + GLFWdropfun previous; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + previous = window->callbacks.drop; + window->callbacks.drop = cbfun; + return previous; +} diff --git a/src/internal.h b/src/internal.h index 677b8c67..8b258527 100644 --- a/src/internal.h +++ b/src/internal.h @@ -229,6 +229,7 @@ struct _GLFWwindow GLFWscrollfun scroll; GLFWkeyfun key; GLFWcharfun character; + GLFWdropfun drop; } callbacks; // This is defined in the window API's platform.h @@ -666,6 +667,14 @@ void _glfwInputMonitorChange(void); */ void _glfwInputError(int error, const char* format, ...); +/*! @brief Notifies dropped object over window. + * @param[in] window The window that received the event. + * @param[in] dropString The string descriptor of the dropped object + * description. + * @ingroup event + */ +void _glfwInputDrop(_GLFWwindow* window, const char* dropString); + //======================================================================== // Utility functions diff --git a/src/win32_platform.h b/src/win32_platform.h index 20a3faed..73f0319f 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -167,6 +167,7 @@ typedef struct _GLFWlibraryWin32 ATOM classAtom; DWORD foregroundLockTimeout; char* clipboardString; + char* dropString; // Timer data struct { diff --git a/src/win32_window.c b/src/win32_window.c index c01529d3..c5f4faf9 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -715,6 +715,45 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // TODO: Restore vsync if compositing was disabled break; } + case WM_DROPFILES: + + // DragQueryFile() takes a LPWSTR for the name so we need a TCHAR string + TCHAR szName[MAX_PATH]; + + // Here we cast the wParam as a HDROP handle to pass into the next functions + HDROP hDrop = (HDROP)wParam; + + POINT pt; + DragQueryPoint(hDrop, &pt); + //printf("%i %i \n", pt.x, pt.y); + + _glfwInputMouseMotion(window,pt.x,pt.y); + + + // This functions has a couple functionalities. If you pass in 0xFFFFFFFF in + // the second parameter then it returns the count of how many filers were drag + // and dropped. Otherwise, the function fills in the szName string array with + // the current file being queried. + int count = DragQueryFile(hDrop, 0xFFFFFFFF, szName, MAX_PATH); + + wchar_t * s; + // Here we go through all the files that were drag and dropped then display them + for(int i = 0; i < count; i++) + { + // Grab the name of the file associated with index "i" in the list of files dropped. + // Be sure you know that the name is attached to the FULL path of the file. + DragQueryFile(hDrop, i, szName, MAX_PATH); + + wcscat(s, (const wchar_t*)szName); + wcscat(s, (const wchar_t*)"\n"); + } + free(_glfw.win32.dropString); + char * str = _glfwCreateUTF8FromWideString(s); + + _glfwInputDrop(window,_glfw.win32.dropString); + + DragFinish(hDrop); + break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); diff --git a/src/x11_init.c b/src/x11_init.c index d73a504c..eed9f5a2 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -540,6 +540,27 @@ static GLboolean initExtensions(void) _glfw.x11.SAVE_TARGETS = XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); + // Find or create drag and drop atoms + + //Atoms for Xdnd + _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False); + _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False); + _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False); + _glfw.x11.XdndTypeList = XInternAtom(_glfw.x11.display, "XdndTypeList", False); + _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False); + _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False); + _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", False); + _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False); + _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False); + _glfw.x11.XdndProxy = XInternAtom(_glfw.x11.display, "XdndProxy", False); + _glfw.x11.XA_TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); + _glfw.x11.xdnd.string = NULL; + _glfw.x11.xdnd.type1 = NULL; + _glfw.x11.xdnd.type2 = NULL; + _glfw.x11.xdnd.type3 = NULL; + + + return GL_TRUE; } diff --git a/src/x11_platform.h b/src/x11_platform.h index 1ac323dc..71a0febc 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -123,6 +123,26 @@ typedef struct _GLFWlibraryX11 Atom NET_ACTIVE_WINDOW; Atom MOTIF_WM_HINTS; + // Atoms for Xdnd + Atom XdndEnter; + Atom XdndPosition; + Atom XdndStatus; + Atom XdndTypeList; + Atom XdndActionCopy; + Atom XdndDrop; + Atom XdndLeave; + Atom XdndFinished; + Atom XdndSelection; + Atom XdndProxy; + Atom XA_TARGETS; + struct{ + Window sourceWindow; + char* string; + char* type1; + char* type2; + char* type3; + } xdnd; + // Selection atoms Atom TARGETS; Atom MULTIPLE; diff --git a/src/x11_window.c b/src/x11_window.c index 72c79ab1..73cc8609 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -286,6 +286,15 @@ static GLboolean createWindow(_GLFWwindow* window, XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); } + // Enable Xdnd + { + //Announce XDND support + XMapWindow(_glfw.x11.display, window->x11.handle); + Atom XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False); + Atom version=5; + XChangeProperty(_glfw.x11.display, window->x11.handle, XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&version, 1); + } + _glfwPlatformSetWindowTitle(window, wndconfig->title); XRRSelectInput(_glfw.x11.display, window->x11.handle, @@ -494,6 +503,7 @@ static void leaveFullscreenMode(_GLFWwindow* window) } } + // Process the specified X event // static void processEvent(XEvent *event) @@ -689,10 +699,113 @@ static void processEvent(XEvent *event) False, SubstructureNotifyMask | SubstructureRedirectMask, event); + + } + else if(event->xclient.message_type == _glfw.x11.XdndEnter) + { + // Xdnd Enter: the drag&drop event has started in the window, + // we could be getting the type and possible conversions here + // but since we use always string conversion we don't need + // it + } + else if(event->xclient.message_type == _glfw.x11.XdndDrop) + { + // Xdnd Drop: The drag&drop event has finished dropping on + // the window, ask to convert the selection + + _glfw.x11.xdnd.sourceWindow = event->xclient.data.l[0]; + + const Atom formats[] = { _glfw.x11.UTF8_STRING, + _glfw.x11.COMPOUND_STRING, + XA_STRING }; + const int formatCount = sizeof(formats) / sizeof(formats[0]); + int i; + + for(i=0;ix11.handle, CurrentTime); + } + + } + else if(event->xclient.message_type == _glfw.x11.XdndLeave) + { + + } + else if(event->xclient.message_type == _glfw.x11.XdndPosition) + { + // Xdnd Position: get coordinates of the mouse inside the window + // and update the mouse position + int absX = (event->xclient.data.l[2]>>16) & 0xFFFF; + int absY = (event->xclient.data.l[2]) & 0xFFFF; + int x; + int y; + + _glfwPlatformGetWindowPos(window,&x,&y); + + _glfwInputCursorMotion(window,absX-x,absY-y); + + // Xdnd: reply with an XDND status message + XClientMessageEvent m; + memset(&m, sizeof(m), 0); + m.type = ClientMessage; + m.display = event->xclient.display; + m.window = event->xclient.data.l[0]; + m.message_type = _glfw.x11.XdndStatus; + m.format=32; + m.data.l[0] = window->x11.handle; + 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); + XFlush(_glfw.x11.display); + } break; } + case SelectionNotify: + { + + if(event->xselection.property != None) + { + // Xdnd: got a selection notification from the conversion + // we asked for, get the data and finish the d&d event + char* data; + _glfwGetWindowProperty(event->xselection.requestor, + event->xselection.property, + event->xselection.target, + (unsigned char**) &data); + + free(_glfw.x11.xdnd.string); + _glfw.x11.xdnd.string = strdup(data); + + XClientMessageEvent m; + memset(&m, sizeof(m), 0); + 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] = 1; + m.data.l[2] = _glfw.x11.XdndActionCopy; //We only ever copy. + + // Reply that all is well. + XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, False, NoEventMask, (XEvent*)&m); + + XSync(_glfw.x11.display, False); + + XFree(data); + + _glfwInputDrop(window,_glfw.x11.xdnd.string); + } + break; + } case MapNotify: { @@ -883,7 +996,7 @@ unsigned long _glfwGetWindowProperty(Window window, &bytesAfter, value); - if (actualType != type) + if (type != AnyPropertyType && actualType != type) return 0; return itemCount; From ae9bb3e9b9b0cebb8fb21eda004679b4752d5fe7 Mon Sep 17 00:00:00 2001 From: arturo Date: Wed, 10 Jul 2013 12:47:30 +0200 Subject: [PATCH 02/16] win32_window: fix case scope --- src/win32_window.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index c5f4faf9..05009bcb 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -715,7 +715,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // TODO: Restore vsync if compositing was disabled break; } - case WM_DROPFILES: + case WM_DROPFILES:{ // DragQueryFile() takes a LPWSTR for the name so we need a TCHAR string TCHAR szName[MAX_PATH]; @@ -753,7 +753,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, _glfwInputDrop(window,_glfw.win32.dropString); DragFinish(hDrop); - break; + } + break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); From bfdddec67c70a18f7fe4ce4a4cd26198d62f2080 Mon Sep 17 00:00:00 2001 From: arturo Date: Wed, 10 Jul 2013 12:57:05 +0200 Subject: [PATCH 03/16] win32_window.c: trying to fix includes --- src/win32_window.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index 05009bcb..41abb4f2 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -33,6 +33,7 @@ #include #include #include +#include #define _GLFW_KEY_INVALID -2 @@ -715,7 +716,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // TODO: Restore vsync if compositing was disabled break; } - case WM_DROPFILES:{ + case WM_DROPFILES: + { // DragQueryFile() takes a LPWSTR for the name so we need a TCHAR string TCHAR szName[MAX_PATH]; @@ -753,8 +755,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, _glfwInputDrop(window,_glfw.win32.dropString); DragFinish(hDrop); + break; } - break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); From af115856d4900547b5afd3720fc669e137f1e244 Mon Sep 17 00:00:00 2001 From: arturoc Date: Wed, 10 Jul 2013 13:58:23 +0200 Subject: [PATCH 04/16] win32_window.c: fix string allocations --- src/win32_window.c | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index 41abb4f2..2db4c498 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #define _GLFW_KEY_INVALID -2 @@ -719,41 +719,32 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_DROPFILES: { - // DragQueryFile() takes a LPWSTR for the name so we need a TCHAR string TCHAR szName[MAX_PATH]; - - // Here we cast the wParam as a HDROP handle to pass into the next functions HDROP hDrop = (HDROP)wParam; - POINT pt; DragQueryPoint(hDrop, &pt); - //printf("%i %i \n", pt.x, pt.y); - _glfwInputMouseMotion(window,pt.x,pt.y); + // Move the mouse to the position of the drop + _glfwInputCursorMotion(window,pt.x,pt.y); - - // This functions has a couple functionalities. If you pass in 0xFFFFFFFF in - // the second parameter then it returns the count of how many filers were drag - // and dropped. Otherwise, the function fills in the szName string array with - // the current file being queried. + // Retrieve the names of the dropped objects int count = DragQueryFile(hDrop, 0xFFFFFFFF, szName, MAX_PATH); - - wchar_t * s; - // Here we go through all the files that were drag and dropped then display them - for(int i = 0; i < count; i++) + char s[MAX_PATH*count]; + memset(s,0,sizeof(s)); + int i; + for(i = 0; i < count; i++) { - // Grab the name of the file associated with index "i" in the list of files dropped. - // Be sure you know that the name is attached to the FULL path of the file. DragQueryFile(hDrop, i, szName, MAX_PATH); - - wcscat(s, (const wchar_t*)szName); - wcscat(s, (const wchar_t*)"\n"); + char* utf8str = _glfwCreateUTF8FromWideString((const wchar_t*)szName) + strcat(s, utf8str); + strcat(s, "\n"); + free(utf8str); } free(_glfw.win32.dropString); - char * str = _glfwCreateUTF8FromWideString(s); - + _glfw.win32.dropString = strdup(s); + free(s); + _glfwInputDrop(window,_glfw.win32.dropString); - DragFinish(hDrop); break; } @@ -875,6 +866,8 @@ static int createWindow(_GLFWwindow* window, window); // Pass object to WM_CREATE free(wideTitle); + + DragAcceptFiles(window->win32.handle, TRUE); if (!window->win32.handle) { From cc9730d8a64966975bad0acfa26f1d8a1a97991c Mon Sep 17 00:00:00 2001 From: arturo Date: Wed, 10 Jul 2013 15:55:55 +0200 Subject: [PATCH 05/16] x11_window: use XTranslateCoordiantes to get correct coordiantes for XdndPosition --- src/x11_window.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index 73cc8609..247d2c18 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -740,12 +740,14 @@ static void processEvent(XEvent *event) // and update the mouse position int absX = (event->xclient.data.l[2]>>16) & 0xFFFF; int absY = (event->xclient.data.l[2]) & 0xFFFF; - int x; - int y; - _glfwPlatformGetWindowPos(window,&x,&y); + Window child; + int x, y; - _glfwInputCursorMotion(window,absX-x,absY-y); + XTranslateCoordinates(_glfw.x11.display, _glfw.x11.root, window->x11.handle, + absX, absY, &x, &y, &child); + + _glfwInputCursorMotion(window,x,y); // Xdnd: reply with an XDND status message XClientMessageEvent m; @@ -1093,14 +1095,21 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) { Window child; int x, y; + int left; + int top; - XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root, + + XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root, 0, 0, &x, &y, &child); + XTranslateCoordinates(_glfw.x11.display, window->x11.handle, child, + 0, 0, &left, &top, &child); + + if (xpos) *xpos = x; if (ypos) - *ypos = y; + *ypos = y-top; } void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) From a978ed87b6dc026e2b13c44e602a62cc848dac50 Mon Sep 17 00:00:00 2001 From: arturo Date: Wed, 10 Jul 2013 16:37:01 +0200 Subject: [PATCH 06/16] cocoa_window.m: d&d implementation from theo, not working yet --- src/cocoa_window.m | 120 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 6209d1eb..e09b7c07 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -619,6 +619,126 @@ static int translateKey(unsigned int key) [self addCursorRect:[self bounds] cursor:_glfw.ns.cursor]; } +- (NSDragOperation)draggingEntered:(id )sender +{ + if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) + == NSDragOperationGeneric) { + + return NSDragOperationGeneric; + + } // end if + + // not a drag we can use + return NSDragOperationNone; + +} // end draggingEntered + +- (BOOL)prepareForDragOperation:(id )sender { + return YES; +} // end prepareForDragOperation + + + + +- (BOOL)performDragOperation:(id )sender { + + //int i; + int count; + NSPasteboard *zPasteboard = [sender draggingPasteboard]; + NSArray *files = [zPasteboard propertyListForType:NSFilenamesPboardType]; + + // define the images types we accept + // NSPasteboardTypeTIFF: (used to be NSTIFFPboardType). + // NSFilenamesPboardType:An array of NSString filenames + + //memset(fileNames, 0, 100*1000); + + int dragX = [sender draggingLocation].x; + int dragY = [sender draggingLocation].y; + + count = 0; + int howManyFiles = 0; + if ([files count]) { + NSEnumerator *filenameEnum = [files objectEnumerator]; + NSString *name; + while (name = [filenameEnum nextObject]) { + if (count < 100){ + if (strlen([name UTF8String]) < MAXPATHLEN){ + strcpy(fileNames[count], [name UTF8String]); + howManyFiles = count + 1; + //memcpy(fileNames[0], "hello", 5); + count++; + } + } + + } + } + + //memset(fileNames[0], 0, 100); + + + if(_dragEventFunc) { + (*_dragEventFunc)(fileNames, howManyFiles, dragX, dragY); + } + + + + + + //NSLog(@"Got a drag!"); + return YES; + /* + NSArray *zImageTypesAry = [NSArray arrayWithObjects:NSPasteboardTypeTIFF, + NSFilenamesPboardType, nil]; + + NSString *zDesiredType = [zPasteboard availableTypeFromArray:zImageTypesAry]; + + if ([zDesiredType isEqualToString:NSPasteboardTypeTIFF]) { + NSData *zPasteboardData = [zPasteboard dataForType:zDesiredType]; + if (zPasteboardData == nil) { + NSLog(@"Error: MyNSView performDragOperation zPasteboardData == nil"); + return NO; + } // end if + + self.nsImageObj = [[NSImage alloc] initWithData:zPasteboardData]; + [self setNeedsDisplay:YES]; + return YES; + + } //end if + + + if ([zDesiredType isEqualToString:NSFilenamesPboardType]) { + // the pasteboard contains a list of file names + //Take the first one + NSArray *zFileNamesAry = [zPasteboard propertyListForType:@"NSFilenamesPboardType"]; + NSString *zPath = [zFileNamesAry objectAtIndex:0]; + //NSImage *zNewImage = [[NSImage alloc] initWithContentsOfFile:zPath]; + + //if (zNewImage == nil) { + // NSLog(@"Error: MyNSView performDragOperation zNewImage == nil"); + // return NO; + // }// end if + // + // self.nsImageObj = zNewImage; + // [self setNeedsDisplay:YES]; + // + + NSLog(@"Got a drag!"); + return YES; + + }// end if + */ + //this can't happen ??? + //NSLog(@"Error MyNSView performDragOperation"); + //return NO; + +} // end performDragOperation + + +- (void)concludeDragOperation:(id )sender { + //[self setNeedsDisplay:YES]; +} // end concludeDragOperation + @end From 7aed0ad35ca231b645bd7a8cff0101d65bb06376 Mon Sep 17 00:00:00 2001 From: arturo Date: Wed, 10 Jul 2013 18:13:22 +0200 Subject: [PATCH 07/16] cocoa_window.m: fix d&d, mouse is dissapearing when drop received --- src/cocoa_window.m | 73 +++++++++------------------------------------- 1 file changed, 13 insertions(+), 60 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index e09b7c07..29ae743d 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -422,6 +422,10 @@ static int translateKey(unsigned int key) trackingArea = nil; [self updateTrackingAreas]; + + + [self registerForDraggedTypes:[NSArray arrayWithObjects:NSTIFFPboardType, + NSFilenamesPboardType, nil]]; } return self; @@ -634,6 +638,7 @@ static int translateKey(unsigned int key) } // end draggingEntered - (BOOL)prepareForDragOperation:(id )sender { + [self setNeedsDisplay:YES]; return YES; } // end prepareForDragOperation @@ -651,22 +656,21 @@ static int translateKey(unsigned int key) // NSPasteboardTypeTIFF: (used to be NSTIFFPboardType). // NSFilenamesPboardType:An array of NSString filenames - //memset(fileNames, 0, 100*1000); + char fileNames[100*1000]; + memset(fileNames, 0, 100*1000); int dragX = [sender draggingLocation].x; int dragY = [sender draggingLocation].y; count = 0; - int howManyFiles = 0; if ([files count]) { NSEnumerator *filenameEnum = [files objectEnumerator]; NSString *name; while (name = [filenameEnum nextObject]) { if (count < 100){ if (strlen([name UTF8String]) < MAXPATHLEN){ - strcpy(fileNames[count], [name UTF8String]); - howManyFiles = count + 1; - //memcpy(fileNames[0], "hello", 5); + strcat(fileNames, [name UTF8String]); + strcat(fileNames, "\n"); count++; } } @@ -674,69 +678,18 @@ static int translateKey(unsigned int key) } } - //memset(fileNames[0], 0, 100); - - - if(_dragEventFunc) { - (*_dragEventFunc)(fileNames, howManyFiles, dragX, dragY); - } - - - - + int height; + _glfwPlatformGetWindowSize(window, NULL, &height); + _glfwInputCursorMotion(window, dragX, height-dragY); + _glfwInputDrop(window, fileNames); //NSLog(@"Got a drag!"); return YES; - /* - NSArray *zImageTypesAry = [NSArray arrayWithObjects:NSPasteboardTypeTIFF, - NSFilenamesPboardType, nil]; - - NSString *zDesiredType = [zPasteboard availableTypeFromArray:zImageTypesAry]; - - if ([zDesiredType isEqualToString:NSPasteboardTypeTIFF]) { - NSData *zPasteboardData = [zPasteboard dataForType:zDesiredType]; - if (zPasteboardData == nil) { - NSLog(@"Error: MyNSView performDragOperation zPasteboardData == nil"); - return NO; - } // end if - - self.nsImageObj = [[NSImage alloc] initWithData:zPasteboardData]; - [self setNeedsDisplay:YES]; - return YES; - - } //end if - - - if ([zDesiredType isEqualToString:NSFilenamesPboardType]) { - // the pasteboard contains a list of file names - //Take the first one - NSArray *zFileNamesAry = [zPasteboard propertyListForType:@"NSFilenamesPboardType"]; - NSString *zPath = [zFileNamesAry objectAtIndex:0]; - //NSImage *zNewImage = [[NSImage alloc] initWithContentsOfFile:zPath]; - - //if (zNewImage == nil) { - // NSLog(@"Error: MyNSView performDragOperation zNewImage == nil"); - // return NO; - // }// end if - // - // self.nsImageObj = zNewImage; - // [self setNeedsDisplay:YES]; - // - - NSLog(@"Got a drag!"); - return YES; - - }// end if - */ - //this can't happen ??? - //NSLog(@"Error MyNSView performDragOperation"); - //return NO; } // end performDragOperation - (void)concludeDragOperation:(id )sender { - //[self setNeedsDisplay:YES]; } // end concludeDragOperation @end From 9e9e75f3314426b47bc77cbaa0cdac75565a74e1 Mon Sep 17 00:00:00 2001 From: arturo Date: Thu, 11 Jul 2013 22:50:46 +0200 Subject: [PATCH 08/16] cocoa_window: fix mouse dissapearing after drop and on resize --- src/cocoa_window.m | 75 ++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 29ae743d..3925b107 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -390,6 +390,8 @@ static int translateKey(unsigned int key) @interface GLFWContentView : NSView { _GLFWwindow* window; + char * fileNamesForDrag; + int fileNamesSize; NSTrackingArea* trackingArea; } @@ -420,11 +422,14 @@ static int translateKey(unsigned int key) { window = initWindow; trackingArea = nil; - + + fileNamesForDrag = (char*)malloc(1024); + fileNamesSize = 1024; + [self updateTrackingAreas]; - [self registerForDraggedTypes:[NSArray arrayWithObjects:NSTIFFPboardType, + [self registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, nil]]; } @@ -434,6 +439,7 @@ static int translateKey(unsigned int key) -(void)dealloc { [trackingArea release]; + free(fileNamesForDrag); [super dealloc]; } @@ -617,80 +623,71 @@ static int translateKey(unsigned int key) _glfwInputScroll(window, deltaX, deltaY); } -- (void)resetCursorRects + +// arturoc: this makes the cursor dissapear when the window is +// resized or received a drag operation +/*- (void)resetCursorRects { [self discardCursorRects]; [self addCursorRect:[self bounds] cursor:_glfw.ns.cursor]; -} +}*/ - (NSDragOperation)draggingEntered:(id )sender { if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric) { - + + [self setNeedsDisplay:YES]; + return NSDragOperationGeneric; - } // end if - - // not a drag we can use + } + return NSDragOperationNone; - -} // end draggingEntered +} - (BOOL)prepareForDragOperation:(id )sender { [self setNeedsDisplay:YES]; return YES; -} // end prepareForDragOperation - - - +} - (BOOL)performDragOperation:(id )sender { - - //int i; - int count; NSPasteboard *zPasteboard = [sender draggingPasteboard]; NSArray *files = [zPasteboard propertyListForType:NSFilenamesPboardType]; - - // define the images types we accept - // NSPasteboardTypeTIFF: (used to be NSTIFFPboardType). - // NSFilenamesPboardType:An array of NSString filenames - char fileNames[100*1000]; - memset(fileNames, 0, 100*1000); + // set the first char to 0 so strcat + // starts to add from the beginning + fileNamesForDrag[0] = 0; int dragX = [sender draggingLocation].x; int dragY = [sender draggingLocation].y; - count = 0; + int dragSize = 1; if ([files count]) { NSEnumerator *filenameEnum = [files objectEnumerator]; NSString *name; while (name = [filenameEnum nextObject]) { - if (count < 100){ - if (strlen([name UTF8String]) < MAXPATHLEN){ - strcat(fileNames, [name UTF8String]); - strcat(fileNames, "\n"); - count++; - } - } - + dragSize += [name length]+1; + if (dragSize > fileNamesSize){ + fileNamesSize *= 2; + fileNamesForDrag = realloc(fileNamesForDrag, fileNamesSize); + } + strcat(fileNamesForDrag, [name UTF8String]); + strcat(fileNamesForDrag, "\n"); } } int height; _glfwPlatformGetWindowSize(window, NULL, &height); _glfwInputCursorMotion(window, dragX, height-dragY); - _glfwInputDrop(window, fileNames); - - //NSLog(@"Got a drag!"); + _glfwInputDrop(window, fileNamesForDrag); + return YES; - -} // end performDragOperation - +} - (void)concludeDragOperation:(id )sender { -} // end concludeDragOperation + [self setNeedsDisplay:YES]; +} @end From 0322154670e7537dda10e7b87fb29af76cc8382c Mon Sep 17 00:00:00 2001 From: arturo Date: Fri, 12 Jul 2013 01:29:25 +0200 Subject: [PATCH 09/16] x11: fix d&d type conversions + remove \r in paths --- src/x11_init.c | 3 --- src/x11_platform.h | 3 --- src/x11_window.c | 58 ++++++++++++++++++++++++++++++---------------- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index eed9f5a2..cd3f5bfd 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -546,14 +546,11 @@ static GLboolean initExtensions(void) _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False); _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False); _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False); - _glfw.x11.XdndTypeList = XInternAtom(_glfw.x11.display, "XdndTypeList", False); _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False); _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False); _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", False); _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False); _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False); - _glfw.x11.XdndProxy = XInternAtom(_glfw.x11.display, "XdndProxy", False); - _glfw.x11.XA_TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); _glfw.x11.xdnd.string = NULL; _glfw.x11.xdnd.type1 = NULL; _glfw.x11.xdnd.type2 = NULL; diff --git a/src/x11_platform.h b/src/x11_platform.h index 71a0febc..70a9d5d1 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -127,14 +127,11 @@ typedef struct _GLFWlibraryX11 Atom XdndEnter; Atom XdndPosition; Atom XdndStatus; - Atom XdndTypeList; Atom XdndActionCopy; Atom XdndDrop; Atom XdndLeave; Atom XdndFinished; Atom XdndSelection; - Atom XdndProxy; - Atom XA_TARGETS; struct{ Window sourceWindow; char* string; diff --git a/src/x11_window.c b/src/x11_window.c index 247d2c18..c2aa7b69 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -701,6 +701,11 @@ static void processEvent(XEvent *event) event); } + +#define xdndEnter_sourceWindow(evt) ( (evt)->data.l[0]) +#define xdndEnter_version(evt) ( (evt)->data.l[1] >> 24) +#define xdndEnter_hasThreeTypes(evt) (((evt)->xclient.data.l[1] & 0x1UL) == 0) +#define xdndEnter_typeAt(evt, idx) ( (evt)->xclient.data.l[2 + (idx)]) else if(event->xclient.message_type == _glfw.x11.XdndEnter) { // Xdnd Enter: the drag&drop event has started in the window, @@ -714,20 +719,11 @@ static void processEvent(XEvent *event) // the window, ask to convert the selection _glfw.x11.xdnd.sourceWindow = event->xclient.data.l[0]; - - const Atom formats[] = { _glfw.x11.UTF8_STRING, - _glfw.x11.COMPOUND_STRING, - XA_STRING }; - const int formatCount = sizeof(formats) / sizeof(formats[0]); - int i; - - for(i=0;ix11.handle, CurrentTime); - } + XConvertSelection(_glfw.x11.display, + _glfw.x11.XdndSelection, + _glfw.x11.UTF8_STRING, + _glfw.x11.XdndSelection, + window->x11.handle, CurrentTime); } else if(event->xclient.message_type == _glfw.x11.XdndLeave) @@ -765,7 +761,6 @@ static void processEvent(XEvent *event) XSendEvent(_glfw.x11.display, event->xclient.data.l[0], False, NoEventMask, (XEvent*)&m); XFlush(_glfw.x11.display); - } break; @@ -778,13 +773,36 @@ static void processEvent(XEvent *event) // Xdnd: got a selection notification from the conversion // we asked for, get the data and finish the d&d event char* data; - _glfwGetWindowProperty(event->xselection.requestor, + 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); - free(_glfw.x11.xdnd.string); - _glfw.x11.xdnd.string = strdup(data); + 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'); + while(current) + { + int charsToCopy = current - from; + memcpy(to, from, (size_t)charsToCopy); + to += charsToCopy; + + from = current+1; + current = strchr(from, '\r'); + } + + size_t remaining = strlen(from); + + memcpy(to, from, remaining); + to += remaining; + *to = 0; + } XClientMessageEvent m; memset(&m, sizeof(m), 0); @@ -794,7 +812,7 @@ static void processEvent(XEvent *event) m.message_type = _glfw.x11.XdndFinished; m.format=32; m.data.l[0] = window->x11.handle; - m.data.l[1] = 1; + m.data.l[1] = result; m.data.l[2] = _glfw.x11.XdndActionCopy; //We only ever copy. // Reply that all is well. @@ -804,7 +822,7 @@ static void processEvent(XEvent *event) XFree(data); - _glfwInputDrop(window,_glfw.x11.xdnd.string); + if(result) _glfwInputDrop(window,_glfw.x11.xdnd.string); } break; } From f821439de618797fa36310733b9fd43e4afad7cb Mon Sep 17 00:00:00 2001 From: arturo Date: Fri, 12 Jul 2013 01:30:32 +0200 Subject: [PATCH 10/16] x11_window: remove debug code --- src/x11_window.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index c2aa7b69..4e30476e 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -701,11 +701,6 @@ static void processEvent(XEvent *event) event); } - -#define xdndEnter_sourceWindow(evt) ( (evt)->data.l[0]) -#define xdndEnter_version(evt) ( (evt)->data.l[1] >> 24) -#define xdndEnter_hasThreeTypes(evt) (((evt)->xclient.data.l[1] & 0x1UL) == 0) -#define xdndEnter_typeAt(evt, idx) ( (evt)->xclient.data.l[2 + (idx)]) else if(event->xclient.message_type == _glfw.x11.XdndEnter) { // Xdnd Enter: the drag&drop event has started in the window, From 931097811c8e33ec0c42bd8b4f57ae0a35ae3fed Mon Sep 17 00:00:00 2001 From: arturoc Date: Fri, 12 Jul 2013 15:36:12 +0200 Subject: [PATCH 11/16] win32_window.c: don't memset the whole buffer --- src/win32_window.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index 2db4c498..1d1dc0d0 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -730,12 +730,12 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // Retrieve the names of the dropped objects int count = DragQueryFile(hDrop, 0xFFFFFFFF, szName, MAX_PATH); char s[MAX_PATH*count]; - memset(s,0,sizeof(s)); + s[0] = 0; int i; for(i = 0; i < count; i++) { DragQueryFile(hDrop, i, szName, MAX_PATH); - char* utf8str = _glfwCreateUTF8FromWideString((const wchar_t*)szName) + char* utf8str = _glfwCreateUTF8FromWideString((const wchar_t*)szName); strcat(s, utf8str); strcat(s, "\n"); free(utf8str); From 11cb59cc35c74be99824f82c47ae18cd79167e7f Mon Sep 17 00:00:00 2001 From: arturoc Date: Fri, 12 Jul 2013 17:34:02 +0200 Subject: [PATCH 12/16] fixes for vs --- src/win32_init.c | 5 ++++- src/win32_platform.h | 1 + src/win32_window.c | 30 ++++++++++++++++-------------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/win32_init.c b/src/win32_init.c index d7abeca6..eb69f36f 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -92,7 +92,7 @@ static GLboolean initLibraries(void) _glfw.win32.dwmapi.DwmIsCompositionEnabled = (DWMISCOMPOSITIONENABLED_T) GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); } - + return GL_TRUE; } @@ -208,6 +208,9 @@ int _glfwPlatformInit(void) if (!_glfwInitContextAPI()) return GL_FALSE; + + _glfw.win32.dropString = (char*)malloc(1000); + _glfw.win32.dropStringSize = 1000; _glfwInitTimer(); _glfwInitJoysticks(); diff --git a/src/win32_platform.h b/src/win32_platform.h index 73f0319f..70c5527c 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -168,6 +168,7 @@ typedef struct _GLFWlibraryWin32 DWORD foregroundLockTimeout; char* clipboardString; char* dropString; + int dropStringSize; // Timer data struct { diff --git a/src/win32_window.c b/src/win32_window.c index 1d1dc0d0..7b205298 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -718,31 +719,32 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, } case WM_DROPFILES: { - TCHAR szName[MAX_PATH]; HDROP hDrop = (HDROP)wParam; POINT pt; + int numFiles = DragQueryFile(hDrop, 0xFFFFFFFF, szName, MAX_PATH); + int currentSize = 1; + int i; + char* utf8str; DragQueryPoint(hDrop, &pt); // Move the mouse to the position of the drop _glfwInputCursorMotion(window,pt.x,pt.y); - - // Retrieve the names of the dropped objects - int count = DragQueryFile(hDrop, 0xFFFFFFFF, szName, MAX_PATH); - char s[MAX_PATH*count]; - s[0] = 0; - int i; - for(i = 0; i < count; i++) + + memset(_glfw.win32.dropString, 0, _glfw.win32.dropStringSize); + for(i = 0; i < numFiles; i++) { DragQueryFile(hDrop, i, szName, MAX_PATH); - char* utf8str = _glfwCreateUTF8FromWideString((const wchar_t*)szName); - strcat(s, utf8str); - strcat(s, "\n"); + 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); } - free(_glfw.win32.dropString); - _glfw.win32.dropString = strdup(s); - free(s); _glfwInputDrop(window,_glfw.win32.dropString); DragFinish(hDrop); From ca54d3bdabd30c25aedcc4d37782ce778ef99e4b Mon Sep 17 00:00:00 2001 From: arturo Date: Tue, 23 Jul 2013 22:15:46 +0200 Subject: [PATCH 13/16] x11_window: don't map the window when announcing Xdnd --- src/x11_window.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/x11_window.c b/src/x11_window.c index 4e30476e..a26834fd 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -289,7 +289,6 @@ static GLboolean createWindow(_GLFWwindow* window, // Enable Xdnd { //Announce XDND support - XMapWindow(_glfw.x11.display, window->x11.handle); Atom XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False); Atom version=5; XChangeProperty(_glfw.x11.display, window->x11.handle, XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&version, 1); From 4d3926baed38bdc9882ed177abc0fda5094848f2 Mon Sep 17 00:00:00 2001 From: arturo Date: Wed, 24 Jul 2013 14:53:32 +0200 Subject: [PATCH 14/16] fix Xdnd using Atom for passing version, was crashing on openbox --- src/x11_init.c | 23 ++++++++++------------- src/x11_platform.h | 1 + src/x11_window.c | 14 ++++++++------ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index cd3f5bfd..430a5174 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -35,6 +35,7 @@ #include #include #include +#include // Translate an X11 key code to a GLFW key code. @@ -397,7 +398,6 @@ static void detectEWMH(void) (unsigned char**) &supportedAtoms); // See which of the atoms we support that are supported by the WM - _glfw.x11.NET_WM_STATE = getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE"); _glfw.x11.NET_WM_STATE_FULLSCREEN = @@ -543,18 +543,15 @@ static GLboolean initExtensions(void) // Find or create drag and drop atoms //Atoms for Xdnd - _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False); - _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False); - _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False); - _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False); - _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False); - _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", False); - _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False); - _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False); - _glfw.x11.xdnd.string = NULL; - _glfw.x11.xdnd.type1 = NULL; - _glfw.x11.xdnd.type2 = NULL; - _glfw.x11.xdnd.type3 = NULL; + _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True); + _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True); + _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True); + _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", True); + _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", True); + _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", True); + _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", True); + _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True); + _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True); diff --git a/src/x11_platform.h b/src/x11_platform.h index 70a9d5d1..1e4f66c9 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -124,6 +124,7 @@ typedef struct _GLFWlibraryX11 Atom MOTIF_WM_HINTS; // Atoms for Xdnd + Atom XdndAware; Atom XdndEnter; Atom XdndPosition; Atom XdndStatus; diff --git a/src/x11_window.c b/src/x11_window.c index a26834fd..9258ccb7 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -287,11 +287,11 @@ static GLboolean createWindow(_GLFWwindow* window, } // Enable Xdnd + if(_glfw.x11.XdndAware!=None) { //Announce XDND support - Atom XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False); - Atom version=5; - XChangeProperty(_glfw.x11.display, window->x11.handle, XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&version, 1); + unsigned long version=5; + XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&version, 1); } _glfwPlatformSetWindowTitle(window, wndconfig->title); @@ -711,7 +711,6 @@ static void processEvent(XEvent *event) { // Xdnd Drop: The drag&drop event has finished dropping on // the window, ask to convert the selection - _glfw.x11.xdnd.sourceWindow = event->xclient.data.l[0]; XConvertSelection(_glfw.x11.display, _glfw.x11.XdndSelection, @@ -761,7 +760,6 @@ static void processEvent(XEvent *event) } case SelectionNotify: { - if(event->xselection.property != None) { // Xdnd: got a selection notification from the conversion @@ -816,7 +814,11 @@ static void processEvent(XEvent *event) XFree(data); - if(result) _glfwInputDrop(window,_glfw.x11.xdnd.string); + if(result) + { + _glfwInputDrop(window,_glfw.x11.xdnd.string); + + } } break; } From db5101323d64efc40914f8dc6a33a8cd1a35b0f0 Mon Sep 17 00:00:00 2001 From: arturo Date: Wed, 24 Jul 2013 20:03:31 +0200 Subject: [PATCH 15/16] x11_window: getPosition, check child!=NULL to avoid crashes --- src/x11_window.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index 9258ccb7..99d015e1 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -290,7 +290,7 @@ static GLboolean createWindow(_GLFWwindow* window, if(_glfw.x11.XdndAware!=None) { //Announce XDND support - unsigned long version=5; + Atom version=5; XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&version, 1); } @@ -1109,15 +1109,18 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) { Window child; int x, y; - int left; - int top; + int left=0; + int top=0; XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root, 0, 0, &x, &y, &child); - XTranslateCoordinates(_glfw.x11.display, window->x11.handle, child, + if(child) + { + XTranslateCoordinates(_glfw.x11.display, window->x11.handle, child, 0, 0, &left, &top, &child); + } if (xpos) From dbe4dab355511e4d72656806f00441b8c6c15f31 Mon Sep 17 00:00:00 2001 From: arturo Date: Wed, 4 Dec 2013 14:15:18 +0100 Subject: [PATCH 16/16] fix header --- src/cocoa_window.m | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index b776d328..d85e60ea 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1,8 +1,5 @@ //======================================================================== -// GLFW - An OpenGL library -// Platform: Cocoa/NSOpenGL -// API Version: 3.0 -// WWW: http://www.glfw.org/ +// GLFW 3.0 OS X - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2009-2010 Camilla Berglund //