Added Drag&Drop from KDE app to 16/32 bit Windoze app.

diff --git a/windows/event.c b/windows/event.c
index 4ec26dd..1ebe5b0 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -56,6 +56,9 @@
 
 #define DndEND          8
 
+#define DndURL          128   /* KDE drag&drop */
+
+
   /* X context to associate a hwnd to an X window */
 static XContext winContext = 0;
 
@@ -150,12 +153,24 @@
 {
     WND *pWnd;
     
-    if (TSXFindContext( display, event->xany.window, winContext,
-                      (char **)&pWnd ) != 0)
-        return;  /* Not for a registered window */
+    if ( TSXFindContext( display, event->xany.window, winContext,
+			 (char **)&pWnd ) != 0) {
+      if ( event->type == ClientMessage) {
+	/* query window (drag&drop event contains only drag window) */
+	Window   	root, child;
+	int      	root_x, root_y, child_x, child_y;
+	unsigned	u;
+	TSXQueryPointer( display, rootWindow, &root, &child,
+			 &root_x, &root_y, &child_x, &child_y, &u);
+	if (TSXFindContext( display, child, winContext, (char **)&pWnd ) != 0)
+	  return;
+      } else {
+	return;  /* Not for a registered window */
+      }
+    }
 
     TRACE(event, "Got event %s for hwnd %04x\n",
-                   event_names[event->type], pWnd->hwndSelf );
+	  event_names[event->type], pWnd->hwndSelf );
 
     switch(event->type)
     {
@@ -412,9 +427,6 @@
 	  WND*		pWnd;
 	  MESSAGEQUEUE* pQ;
 
-          if (TSXFindContext( display, ((XAnyEvent *)&event)->window, winContext,
-                            (char **)&pWnd ) || (event.type == NoExpose))
-              continue;
 
 	  /* Check only for those events which can be processed
 	   * internally. */
@@ -422,12 +434,17 @@
 	  if( event.type == MotionNotify ||
 	      event.type == ButtonPress || event.type == ButtonRelease ||
 	      event.type == KeyPress || event.type == KeyRelease ||
-	      event.type == SelectionRequest || event.type == SelectionClear )
+	      event.type == SelectionRequest || event.type == SelectionClear ||
+	      event.type == ClientMessage )
 	  {
 	       EVENT_ProcessEvent( &event );
                continue;
 	  }
 
+          if (TSXFindContext( display, ((XAnyEvent *)&event)->window, winContext,
+                            (char **)&pWnd ) || (event.type == NoExpose))
+              continue;
+
 	  if( pWnd )
           {
             if( (pQ = (MESSAGEQUEUE*)GlobalLock16(pWnd->hmemTaskQ)) )
@@ -1003,124 +1020,299 @@
 
 
 /**********************************************************************
+ *           EVENT_DropFromOffix
+ *
+ * don't know if it still works (last Changlog is from 96/11/04)
+ */
+static void EVENT_DropFromOffiX( WND *pWnd, XClientMessageEvent *event )
+{
+  unsigned long		data_length;
+  unsigned long		aux_long;
+  unsigned char*	p_data = NULL;
+  union {
+    Atom		atom_aux;
+    POINT32	pt_aux;
+    int		i;
+  }		u;
+  int			x, y;
+  BOOL16	        bAccept;
+  HGLOBAL16		hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, sizeof(DRAGINFO));
+  LPDRAGINFO            lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
+  SEGPTR		spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
+  Window		w_aux_root, w_aux_child;
+  WND*			pDropWnd;
+  
+  if( !lpDragInfo || !spDragInfo ) return;
+  
+  TSXQueryPointer( display, pWnd->window, &w_aux_root, &w_aux_child, 
+		   &x, &y, &u.pt_aux.x, &u.pt_aux.y, (unsigned int*)&aux_long);
+  
+  lpDragInfo->hScope = pWnd->hwndSelf;
+  lpDragInfo->pt.x = (INT16)x; lpDragInfo->pt.y = (INT16)y;
+  
+  /* find out drop point and drop window */
+  if( x < 0 || y < 0 ||
+      x > (pWnd->rectWindow.right - pWnd->rectWindow.left) ||
+      y > (pWnd->rectWindow.bottom - pWnd->rectWindow.top) )
+    {   bAccept = pWnd->dwExStyle & WS_EX_ACCEPTFILES; x = y = 0; }
+  else
+    {
+      bAccept = DRAG_QueryUpdate( pWnd->hwndSelf, spDragInfo, TRUE );
+      x = lpDragInfo->pt.x; y = lpDragInfo->pt.y;
+    }
+  pDropWnd = WIN_FindWndPtr( lpDragInfo->hScope );
+  GlobalFree16( hDragInfo );
+  
+  if( bAccept )
+    {
+      TSXGetWindowProperty( display, DefaultRootWindow(display),
+			    dndSelection, 0, 65535, FALSE,
+			    AnyPropertyType, &u.atom_aux, &u.pt_aux.y,
+			    &data_length, &aux_long, &p_data);
+      
+      if( !aux_long && p_data)	/* don't bother if > 64K */
+	{
+	  char *p = (char*) p_data;
+	  char *p_drop;
+	  
+	  aux_long = 0; 
+	  while( *p )	/* calculate buffer size */
+	    {
+	      p_drop = p;
+	      if((u.i = *p) != -1 ) 
+		u.i = DRIVE_FindDriveRoot( (const char **)&p_drop );
+	      if( u.i == -1 ) *p = -1;	/* mark as "bad" */
+	      else
+		{
+		  INT32 len = GetShortPathName32A( p, NULL, 0 );
+		  if (len) aux_long += len + 1;
+		  else *p = -1;
+		}
+	      p += strlen(p) + 1;
+	    }
+	  if( aux_long && aux_long < 65535 )
+	    {
+	      HDROP16                 hDrop;
+	      LPDROPFILESTRUCT16        lpDrop;
+	      
+	      aux_long += sizeof(DROPFILESTRUCT16) + 1; 
+	      hDrop = (HDROP16)GlobalAlloc16( GMEM_SHARE, aux_long );
+	      lpDrop = (LPDROPFILESTRUCT16) GlobalLock16( hDrop );
+	      
+	      if( lpDrop )
+		{
+		  lpDrop->wSize = sizeof(DROPFILESTRUCT16);
+		  lpDrop->ptMousePos.x = (INT16)x;
+		  lpDrop->ptMousePos.y = (INT16)y;
+		  lpDrop->fInNonClientArea = (BOOL16) 
+		    ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left)  ||
+		      y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top)    ||
+		      x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
+		      y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
+		  p_drop = ((char*)lpDrop) + sizeof(DROPFILESTRUCT16);
+		  p = p_data;
+		  while(*p)
+		    {
+		      if( *p != -1 )	/* use only "good" entries */
+			{
+                          GetShortPathName32A( p, p_drop, 65535 );
+                          p_drop += strlen( p_drop ) + 1;
+			}
+		      p += strlen(p) + 1;
+		    }
+		  *p_drop = '\0';
+		  PostMessage16( pWnd->hwndSelf, WM_DROPFILES,
+				 (WPARAM16)hDrop, 0L );
+		}
+	    }
+	}
+      if( p_data ) TSXFree(p_data);  
+      
+    } /* WS_EX_ACCEPTFILES */
+}
+
+/**********************************************************************
+ *           EVENT_DropURLs
+ *
+ * drop items are separated by \n 
+ * each item is prefixed by its mime type
+ *
+ * event->data.l[3], event->data.l[4] contains drop x,y position
+ */
+static void EVENT_DropURLs( WND *pWnd, XClientMessageEvent *event )
+{
+  WND           *pDropWnd;
+  unsigned long	data_length;
+  unsigned long	aux_long, drop_len = 0;
+  unsigned char	*p_data = NULL; /* property data */
+  char		*p_drop = NULL;
+  char          *p, *next;
+  int		x, y, drop32 = FALSE ;
+  union {
+    Atom	atom_aux;
+    POINT32	pt_aux;
+    int         i;
+    Window      w_aux;
+  }		u; /* unused */
+  union {
+    HDROP16     h16;
+    HDROP32     h32;
+  } hDrop;
+
+  drop32 = pWnd->flags & WIN_ISWIN32;
+
+  if (!(pWnd->dwExStyle & WS_EX_ACCEPTFILES))
+    return;
+
+  TSXGetWindowProperty( display, DefaultRootWindow(display),
+			dndSelection, 0, 65535, FALSE,
+			AnyPropertyType, &u.atom_aux, &u.i,
+			&data_length, &aux_long, &p_data);
+  if (aux_long)
+    WARN(event,"property too large, truncated!\n");
+  TRACE(event,"urls=%s\n", p_data);
+
+  if( !aux_long && p_data) {	/* don't bother if > 64K */
+    /* calculate length */
+    p = p_data;
+    next = strchr(p, '\n');
+    while (p) {
+      if (next) *next=0;
+      if (strncmp(p,"file:",5) == 0 ) {
+	INT32 len = GetShortPathName32A( p+5, NULL, 0 );
+	if (len) drop_len += len + 1;
+      }
+      if (next) { 
+	*next = '\n'; 
+	p = next + 1;
+	next = strchr(p, '\n');
+      } else {
+	p = NULL;
+      }
+    }
+    
+    if( drop_len && drop_len < 65535 ) {
+      TSXQueryPointer( display, rootWindow, &u.w_aux, &u.w_aux, 
+		       &x, &y, &u.i, &u.i, &u.i);
+      pDropWnd = WIN_FindWndPtr( pWnd->hwndSelf );
+      
+      if (drop32) {
+	LPDROPFILESTRUCT32        lpDrop;
+	drop_len += sizeof(DROPFILESTRUCT32) + 1; 
+	hDrop.h32 = (HDROP32)GlobalAlloc32( GMEM_SHARE, drop_len );
+	lpDrop = (LPDROPFILESTRUCT32) GlobalLock32( hDrop.h32 );
+	
+	if( lpDrop ) {
+	  lpDrop->lSize = sizeof(DROPFILESTRUCT32);
+	  lpDrop->ptMousePos.x = (INT32)x;
+	  lpDrop->ptMousePos.y = (INT32)y;
+	  lpDrop->fInNonClientArea = (BOOL32) 
+	    ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left)  ||
+	      y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top)    ||
+	      x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
+	      y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
+	  lpDrop->fWideChar = FALSE;
+	  p_drop = ((char*)lpDrop) + sizeof(DROPFILESTRUCT32);
+	}
+      } else {
+	LPDROPFILESTRUCT16        lpDrop;
+	drop_len += sizeof(DROPFILESTRUCT16) + 1; 
+	hDrop.h16 = (HDROP16)GlobalAlloc16( GMEM_SHARE, drop_len );
+	lpDrop = (LPDROPFILESTRUCT16) GlobalLock16( hDrop.h16 );
+	
+	if( lpDrop ) {
+	  lpDrop->wSize = sizeof(DROPFILESTRUCT16);
+	  lpDrop->ptMousePos.x = (INT16)x;
+	  lpDrop->ptMousePos.y = (INT16)y;
+	  lpDrop->fInNonClientArea = (BOOL16) 
+	    ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left)  ||
+	      y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top)    ||
+	      x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
+	      y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
+	  p_drop = ((char*)lpDrop) + sizeof(DROPFILESTRUCT16);
+	}
+      }
+      
+      /* create message content */
+      if (p_drop) {
+	p = p_data;
+	next = strchr(p, '\n');
+	while (p) {
+	  if (next) *next=0;
+	  if (strncmp(p,"file:",5) == 0 ) {
+	    INT32 len = GetShortPathName32A( p+5, p_drop, 65535 );
+	    if (len) {
+	      TRACE(event, "drop file %s as %s\n", p+5, p_drop);
+	      p_drop += len+1;
+	    } else {
+	      WARN(event, "can't convert file %s to dos name \n", p+5);
+	    }
+	  } else {
+	    WARN(event, "unknown mime type %s\n", p);
+	  }
+	  if (next) { 
+	    *next = '\n'; 
+	    p = next + 1;
+	    next = strchr(p, '\n');
+	  } else {
+	    p = NULL;
+	  }
+	  *p_drop = '\0';
+	}
+
+	if (drop32) {
+	  /* can not use PostMessage32A because it is currently based on 
+	   * PostMessage16 and WPARAM32 would be truncated to WPARAM16
+	   */
+	  GlobalUnlock32(hDrop.h32);
+	  SendMessage32A( pWnd->hwndSelf, WM_DROPFILES,
+			  (WPARAM32)hDrop.h32, 0L );
+	} else {
+	  GlobalUnlock16(hDrop.h16);
+	  PostMessage16( pWnd->hwndSelf, WM_DROPFILES,
+			 (WPARAM16)hDrop.h16, 0L );
+	}
+      }
+    }
+    if( p_data ) TSXFree(p_data);  
+  }
+}
+
+/**********************************************************************
  *           EVENT_ClientMessage
  */
 static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event )
 {
-    if (event->message_type != None && event->format == 32)
-    {
-       if ((event->message_type == wmProtocols) && 
-           (((Atom) event->data.l[0]) == wmDeleteWindow))
-	  SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, 0 );
-       else if ( event->message_type == dndProtocol &&
+    if (event->message_type != None && event->format == 32) {
+      if ((event->message_type == wmProtocols) && 
+	  (((Atom) event->data.l[0]) == wmDeleteWindow))
+	SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, 0 );
+      else if ( event->message_type == dndProtocol &&
 		(event->data.l[0] == DndFile || event->data.l[0] == DndFiles) )
-       {
-	  unsigned long		data_length;
-	  unsigned long		aux_long;
-	  unsigned char*	p_data = NULL;
-	  union {
-		   Atom		atom_aux;
-		   POINT32	pt_aux;
-		   int		i;
-		}		u;
-	  int			x, y;
-          BOOL16	        bAccept;
-	  HGLOBAL16		hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, sizeof(DRAGINFO));
-	  LPDRAGINFO            lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
-	  SEGPTR		spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
-	  Window		w_aux_root, w_aux_child;
-	  WND*			pDropWnd;
-	  
-          if( !lpDragInfo || !spDragInfo ) return;
-
-	  TSXQueryPointer( display, pWnd->window, &w_aux_root, &w_aux_child, 
-		 &x, &y, &u.pt_aux.x, &u.pt_aux.y, (unsigned int*)&aux_long);
-
-          lpDragInfo->hScope = pWnd->hwndSelf;
-          lpDragInfo->pt.x = (INT16)x; lpDragInfo->pt.y = (INT16)y;
-
-	  /* find out drop point and drop window */
-	  if( x < 0 || y < 0 ||
-	      x > (pWnd->rectWindow.right - pWnd->rectWindow.left) ||
-	      y > (pWnd->rectWindow.bottom - pWnd->rectWindow.top) )
-	  {   bAccept = pWnd->dwExStyle & WS_EX_ACCEPTFILES; x = y = 0; }
-	  else
-	  {
-	      bAccept = DRAG_QueryUpdate( pWnd->hwndSelf, spDragInfo, TRUE );
-	      x = lpDragInfo->pt.x; y = lpDragInfo->pt.y;
-	  }
-	  pDropWnd = WIN_FindWndPtr( lpDragInfo->hScope );
-	  GlobalFree16( hDragInfo );
-
-	  if( bAccept )
-	  {
-	      TSXGetWindowProperty( display, DefaultRootWindow(display),
+	EVENT_DropFromOffiX(pWnd, event);
+      else if ( event->message_type == dndProtocol &&
+		event->data.l[0] == DndURL )
+	EVENT_DropURLs(pWnd, event);
+      else {
+#if 0
+	/* enable this if you want to see the message */
+	unsigned char* p_data = NULL;
+	union {
+	  unsigned long	l;
+	  int            	i;
+	  Atom		atom;
+	} u; /* unused */
+	TSXGetWindowProperty( display, DefaultRootWindow(display),
 			      dndSelection, 0, 65535, FALSE,
-                              AnyPropertyType, &u.atom_aux, &u.pt_aux.y,
-		             &data_length, &aux_long, &p_data);
-
-	      if( !aux_long && p_data)	/* don't bother if > 64K */
-	      {
-		char *p = (char*) p_data;
-		char *p_drop;
-
-		aux_long = 0; 
-		while( *p )	/* calculate buffer size */
-		{
-		  p_drop = p;
-		  if((u.i = *p) != -1 ) 
-		      u.i = DRIVE_FindDriveRoot( (const char **)&p_drop );
-		  if( u.i == -1 ) *p = -1;	/* mark as "bad" */
-		  else
-		  {
-                      INT32 len = GetShortPathName32A( p, NULL, 0 );
-                      if (len) aux_long += len + 1;
-		      else *p = -1;
-		  }
-		  p += strlen(p) + 1;
-		}
-		if( aux_long && aux_long < 65535 )
-		{
-		  HDROP16                 hDrop;
-		  LPDROPFILESTRUCT        lpDrop;
-
-		  aux_long += sizeof(DROPFILESTRUCT) + 1; 
-		  hDrop = (HDROP16)GlobalAlloc16( GMEM_SHARE, aux_long );
-		  lpDrop = (LPDROPFILESTRUCT) GlobalLock16( hDrop );
-
-		  if( lpDrop )
-		  {
-		    lpDrop->wSize = sizeof(DROPFILESTRUCT);
-		    lpDrop->ptMousePos.x = (INT16)x;
-		    lpDrop->ptMousePos.y = (INT16)y;
-		    lpDrop->fInNonClientArea = (BOOL16) 
-			( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left)  ||
-			  y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top)    ||
-			  x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
-			  y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
-		    p_drop = ((char*)lpDrop) + sizeof(DROPFILESTRUCT);
-		    p = p_data;
-		    while(*p)
-		    {
-		      if( *p != -1 )	/* use only "good" entries */
-		      {
-                          GetShortPathName32A( p, p_drop, 65535 );
-                          p_drop += strlen( p_drop ) + 1;
-		      }
-		      p += strlen(p) + 1;
-		    }
-		    *p_drop = '\0';
-		    PostMessage16( pWnd->hwndSelf, WM_DROPFILES,
-                                   (WPARAM16)hDrop, 0L );
-		  }
-	        }
-	      }
-	      if( p_data ) TSXFree(p_data);  
-
-	  } /* WS_EX_ACCEPTFILES */
-       } /* dndProtocol */
-       else
-	  TRACE(event, "unrecognized ClientMessage\n" );
+			      AnyPropertyType, &u.atom, &u.i,
+			      &u.l, &u.l, &p_data);
+	TRACE(event, "message_type=%ld, data=%ld,%ld,%ld,%ld,%ld, msg=%s\n",
+	      event->message_type, event->data.l[0], event->data.l[1], 
+	      event->data.l[2], event->data.l[3], event->data.l[4],
+	      p_data);
+#endif
+	TRACE(event, "unrecognized ClientMessage\n" );
+      }
     }
 }