diff --git a/src/cocoa_window.m b/src/cocoa_window.m index eca98995..4b14ef4a 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -445,13 +445,11 @@ static int translateKey(unsigned int key) { window = initWindow; trackingArea = nil; - - fileNamesForDrag = (char*)malloc(1024); + + fileNamesForDrag = malloc(1024); fileNamesSize = 1024; - + [self updateTrackingAreas]; - - [self registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, nil]]; } @@ -667,69 +665,75 @@ static int translateKey(unsigned int key) _glfwInputScroll(window, deltaX, deltaY); } - -// arturoc: this makes the cursor dissapear when the window is -// resized or received a drag operation -/*- (void)resetCursorRects +- (void)resetCursorRects { + // This makes the cursor dissapear when the window is + // resized or received a drag operation [self discardCursorRects]; [self addCursorRect:[self bounds] cursor:_glfw.ns.cursor]; -}*/ +} - (NSDragOperation)draggingEntered:(id )sender { - if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) - == NSDragOperationGeneric) { - - [self setNeedsDisplay:YES]; - + if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) + == NSDragOperationGeneric) + { + [self setNeedsDisplay:YES]; return NSDragOperationGeneric; - } - - return NSDragOperationNone; + + return NSDragOperationNone; } -- (BOOL)prepareForDragOperation:(id )sender { +- (BOOL)prepareForDragOperation:(id )sender +{ [self setNeedsDisplay:YES]; return YES; } -- (BOOL)performDragOperation:(id )sender { - NSPasteboard *zPasteboard = [sender draggingPasteboard]; - NSArray *files = [zPasteboard propertyListForType:NSFilenamesPboardType]; - +- (BOOL)performDragOperation:(id )sender +{ + NSPasteboard* pasteboard = [sender draggingPasteboard]; + NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType]; + // set the first char to 0 so strcat // starts to add from the beginning - fileNamesForDrag[0] = 0; + fileNamesForDrag[0] = 0; - int dragX = [sender draggingLocation].x; - int dragY = [sender draggingLocation].y; - - int dragSize = 1; - if ([files count]) { - NSEnumerator *filenameEnum = [files objectEnumerator]; - NSString *name; - while (name = [filenameEnum nextObject]) { - dragSize += [name length]+1; - if (dragSize > fileNamesSize){ + const int dragX = [sender draggingLocation].x; + const int dragY = [sender draggingLocation].y; + int dragSize = 1; + + if ([files count]) + { + NSEnumerator* filenameEnum = [files objectEnumerator]; + NSString* name; + + while (name = [filenameEnum nextObject]) + { + 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); + _glfwPlatformGetWindowSize(window, NULL, &height); + _glfwInputCursorMotion(window, dragX, height - dragY); _glfwInputDrop(window, fileNamesForDrag); - - return YES; + + return YES; } -- (void)concludeDragOperation:(id )sender { +- (void)concludeDragOperation:(id )sender +{ [self setNeedsDisplay:YES]; } diff --git a/src/input.c b/src/input.c index b7e090c6..2fd23a12 100644 --- a/src/input.c +++ b/src/input.c @@ -211,8 +211,8 @@ void _glfwInputCursorEnter(_GLFWwindow* window, int 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) window->callbacks.drop((GLFWwindow*) window, dropString); } @@ -403,11 +403,8 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, 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; + _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun); + return cbfun; } + diff --git a/src/win32_init.c b/src/win32_init.c index d7ed7938..2063000e 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -98,7 +98,7 @@ static GLboolean initLibraries(void) _glfw.win32.dwmapi.DwmIsCompositionEnabled = (DWMISCOMPOSITIONENABLED_T) GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); } - + return GL_TRUE; } @@ -214,8 +214,8 @@ int _glfwPlatformInit(void) if (!_glfwInitContextAPI()) return GL_FALSE; - - _glfw.win32.dropString = (char*)malloc(1000); + + _glfw.win32.dropString = malloc(1000); _glfw.win32.dropStringSize = 1000; _glfwInitTimer(); diff --git a/src/win32_window.c b/src/win32_window.c index 08108ed0..4cd69bc5 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -749,38 +749,43 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // TODO: Restore vsync if compositing was disabled break; } + 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); + WCHAR szName[MAX_PATH]; + HDROP hDrop = (HDROP) wParam; + POINT pt; + const int numFiles = DragQueryFile(hDrop, 0xffffffff, szName, MAX_PATH); + int i, currentSize = 1; + char* utf8str; - // Move the mouse to the position of the drop - _glfwInputCursorMotion(window,pt.x,pt.y); - - 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); - DragFinish(hDrop); - break; + // Move the mouse to the position of the drop + DragQueryPoint(hDrop, &pt); + _glfwInputCursorMotion(window, pt.x, pt.y); + + memset(_glfw.win32.dropString, 0, _glfw.win32.dropStringSize); + + for (i = 0; i < numFiles; i++) + { + 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; } } @@ -900,8 +905,8 @@ static int createWindow(_GLFWwindow* window, window); // Pass object to WM_CREATE free(wideTitle); - - DragAcceptFiles(window->win32.handle, TRUE); + + DragAcceptFiles(window->win32.handle, TRUE); if (!window->win32.handle) { diff --git a/src/x11_init.c b/src/x11_init.c index 22097afb..5571e08a 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -540,8 +540,6 @@ static GLboolean initExtensions(void) XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); // Find or create drag and drop atoms - - //Atoms for Xdnd _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); @@ -552,8 +550,6 @@ static GLboolean initExtensions(void) _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True); _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True); - - return GL_TRUE; } diff --git a/src/x11_platform.h b/src/x11_platform.h index 72db890e..95682cf0 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -121,20 +121,21 @@ typedef struct _GLFWlibraryX11 // Atoms for Xdnd Atom XdndAware; - Atom XdndEnter; - Atom XdndPosition; - Atom XdndStatus; - Atom XdndActionCopy; - Atom XdndDrop; - Atom XdndLeave; - Atom XdndFinished; - Atom XdndSelection; - struct{ - Window sourceWindow; - char* string; - char* type1; - char* type2; - char* type3; + Atom XdndEnter; + Atom XdndPosition; + Atom XdndStatus; + Atom XdndActionCopy; + Atom XdndDrop; + Atom XdndLeave; + Atom XdndFinished; + Atom XdndSelection; + + struct { + Window sourceWindow; + char* string; + char* type1; + char* type2; + char* type3; } xdnd; // Selection atoms diff --git a/src/x11_window.c b/src/x11_window.c index 78082cd0..0d749beb 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -306,12 +306,14 @@ static GLboolean createWindow(_GLFWwindow* window, XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); } - // Enable Xdnd - if(_glfw.x11.XdndAware!=None) + if (_glfw.x11.XdndAware) { - //Announce XDND support - Atom version=5; - XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&version, 1); + // Announce support for XDND version 5 and below + + 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); @@ -714,126 +716,123 @@ static void processEvent(XEvent *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, - // we could be getting the type and possible conversions here - // but since we use always string conversion we don't need - // it + // 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) + 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]; - XConvertSelection(_glfw.x11.display, - _glfw.x11.XdndSelection, - _glfw.x11.UTF8_STRING, - _glfw.x11.XdndSelection, - window->x11.handle, CurrentTime); - + // 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, + _glfw.x11.UTF8_STRING, + _glfw.x11.XdndSelection, + 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 - // 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; + // Xdnd Position: get coordinates of the mouse inside the window + // and update the mouse position + const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF; + const int absY = (event->xclient.data.l[2]) & 0xFFFF; + int x, 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 - 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 + reply.type = ClientMessage; + reply.xclient.window = event->xclient.data.l[0]; + reply.xclient.message_type = _glfw.x11.XdndStatus; + reply.xclient.format = 32; + reply.xclient.data.l[0] = window->x11.handle; + reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle + reply.xclient.data.l[2] = 0; // Specify an empty rectangle + reply.xclient.data.l[3] = 0; + reply.xclient.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); + XSendEvent(_glfw.x11.display, window->x11.handle, + False, NoEventMask, &reply); + 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; - 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 (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; - 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; + free(_glfw.x11.xdnd.string); + _glfw.x11.xdnd.string = NULL; - from = current+1; - current = strchr(from, '\r'); - } + const int result = _glfwGetWindowProperty(event->xselection.requestor, + 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); - to += remaining; - *to = 0; - } + while (current) + { + const int charsToCopy = current - from; + memcpy(to, from, (size_t) charsToCopy); + to += charsToCopy; - 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] = result; - m.data.l[2] = _glfw.x11.XdndActionCopy; //We only ever copy. + from = current + 1; + current = strchr(from, '\r'); + } - // Reply that all is well. - XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, False, NoEventMask, (XEvent*)&m); + const size_t remaining = strlen(from); - 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) - { - _glfwInputDrop(window,_glfw.x11.xdnd.string); + // Reply that all is well + XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, + False, NoEventMask, &reply); + XSync(_glfw.x11.display, False); + XFree(data); - } - } - break; - } + if (result) + _glfwInputDrop(window, _glfw.x11.xdnd.string); + } + + break; + } case MapNotify: {