mirror of
				https://github.com/glfw/glfw.git
				synced 2025-11-04 06:15:07 +00:00 
			
		
		
		
	Cleanup.
This commit is contained in:
		
							parent
							
								
									89d0723ba3
								
							
						
					
					
						commit
						8ae063bb1b
					
				@ -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 <NSDraggingInfo>)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 <NSDraggingInfo>)sender {
 | 
			
		||||
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
 | 
			
		||||
{
 | 
			
		||||
    [self setNeedsDisplay:YES];
 | 
			
		||||
    return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
 | 
			
		||||
	NSPasteboard *zPasteboard = [sender draggingPasteboard];
 | 
			
		||||
	NSArray *files = [zPasteboard propertyListForType:NSFilenamesPboardType];
 | 
			
		||||
	
 | 
			
		||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)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 <NSDraggingInfo>)sender {
 | 
			
		||||
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
 | 
			
		||||
{
 | 
			
		||||
    [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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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:
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user