|  |  |  | @ -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,14 +716,13 @@ 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
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -731,107 +732,105 @@ static void processEvent(XEvent *event) | 
			
		
	
		
			
				
					|  |  |  |  |                                   _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; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             	_glfwPlatformGetWindowPos(window,&x,&y); | 
			
		
	
		
			
				
					|  |  |  |  |                 const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF; | 
			
		
	
		
			
				
					|  |  |  |  |                 const int absY = (event->xclient.data.l[2]) & 0xFFFF; | 
			
		
	
		
			
				
					|  |  |  |  |                 int x, y; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             	_glfwInputCursorMotion(window,absX-x,absY-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); | 
			
		
	
		
			
				
					|  |  |  |  |                 XEvent reply; | 
			
		
	
		
			
				
					|  |  |  |  |                 memset(&reply, sizeof(reply), 0); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 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, window->x11.handle, | 
			
		
	
		
			
				
					|  |  |  |  |                            False, NoEventMask, &reply); | 
			
		
	
		
			
				
					|  |  |  |  |                 XFlush(_glfw.x11.display); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             break; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         case SelectionNotify: | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  | 			if(event->xselection.property != None) | 
			
		
	
		
			
				
					|  |  |  |  |             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, | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 const int result = _glfwGetWindowProperty(event->xselection.requestor, | 
			
		
	
		
			
				
					|  |  |  |  |                                                           event->xselection.property, | 
			
		
	
		
			
				
					|  |  |  |  |                                                           event->xselection.target, | 
			
		
	
		
			
				
					|  |  |  |  |                                                           (unsigned char**) &data); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				if(result){ | 
			
		
	
		
			
				
					|  |  |  |  | 					// nautilus seems to add a \r at the end of the paths
 | 
			
		
	
		
			
				
					|  |  |  |  |                 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) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     while (current) | 
			
		
	
		
			
				
					|  |  |  |  |                     { | 
			
		
	
		
			
				
					|  |  |  |  | 						int charsToCopy = current - from; | 
			
		
	
		
			
				
					|  |  |  |  | 						memcpy(to, from, (size_t)charsToCopy); | 
			
		
	
		
			
				
					|  |  |  |  |                         const int charsToCopy = current - from; | 
			
		
	
		
			
				
					|  |  |  |  |                         memcpy(to, from, (size_t) charsToCopy); | 
			
		
	
		
			
				
					|  |  |  |  |                         to += charsToCopy; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 						from = current+1; | 
			
		
	
		
			
				
					|  |  |  |  |                         from = current + 1; | 
			
		
	
		
			
				
					|  |  |  |  |                         current = strchr(from, '\r'); | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					size_t remaining = strlen(from); | 
			
		
	
		
			
				
					|  |  |  |  |                     const size_t remaining = strlen(from); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     memcpy(to, from, remaining); | 
			
		
	
		
			
				
					|  |  |  |  |                     to += remaining; | 
			
		
	
		
			
				
					|  |  |  |  |                     *to = 0; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				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.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				// Reply that all is well.
 | 
			
		
	
		
			
				
					|  |  |  |  | 				XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, False, NoEventMask, (XEvent*)&m); | 
			
		
	
		
			
				
					|  |  |  |  |                 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
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 // Reply that all is well
 | 
			
		
	
		
			
				
					|  |  |  |  |                 XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, | 
			
		
	
		
			
				
					|  |  |  |  |                            False, NoEventMask, &reply); | 
			
		
	
		
			
				
					|  |  |  |  |                 XSync(_glfw.x11.display, False); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 XFree(data); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				if(result) | 
			
		
	
		
			
				
					|  |  |  |  | 				{ | 
			
		
	
		
			
				
					|  |  |  |  | 					_glfwInputDrop(window,_glfw.x11.xdnd.string); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				} | 
			
		
	
		
			
				
					|  |  |  |  |                 if (result) | 
			
		
	
		
			
				
					|  |  |  |  |                     _glfwInputDrop(window, _glfw.x11.xdnd.string); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             break; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |