From 8b9b2102f39b843ec2a92e5e05faea07713f320d Mon Sep 17 00:00:00 2001 From: Fred Kiefer Date: Wed, 25 Apr 2007 00:12:46 +0000 Subject: [PATCH] XDnD improvements by Matt Rice. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@25071 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 8 +++++ Source/x11/XGDragView.m | 53 ++++++++++++++++-------------- Source/x11/XGServerEvent.m | 66 +++++++++++++++++++++++++++++++------- 3 files changed, 91 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index 89134bb..6559f55 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-04-24 Fred Kiefer + + * Source/x11/XGDragView.m (-sendExternalEvent:... toWindow:) Tell + xdnd about available types and selection owner. + * Source/x11/XGServerEvent.m (processEvent:): Handle case + SelectionRequest to get some simple xdnd support. + Based on a patch by Matt Rice . + 2007-04-14 Adam Fedor * Version: Bump version diff --git a/Source/x11/XGDragView.m b/Source/x11/XGDragView.m index 27d62ec..7c1855c 100644 --- a/Source/x11/XGDragView.m +++ b/Source/x11/XGDragView.m @@ -256,40 +256,45 @@ static XGDragView *sharedDragView = nil; } - (void) sendExternalEvent: (GSAppKitSubtype)subtype - action: (NSDragOperation)action - position: (NSPoint)eventLocation - timestamp: (NSTimeInterval)time - toWindow: (int)dWindowNumber + action: (NSDragOperation)action + position: (NSPoint)eventLocation + timestamp: (NSTimeInterval)time + toWindow: (int)dWindowNumber { switch (subtype) { case GSAppKitDraggingDrop: - if (targetWindowRef == dragWindev->root) - { - // FIXME There is an xdnd extension for root drop - } - xdnd_send_drop(&dnd, dWindowNumber, dragWindev->ident, CurrentTime); - break; + if (targetWindowRef == dragWindev->root) + { + // FIXME There is an xdnd extension for root drop + } + xdnd_send_drop(&dnd, dWindowNumber, dragWindev->ident, CurrentTime); + break; case GSAppKitDraggingUpdate: - xdnd_send_position(&dnd, dWindowNumber, dragWindev->ident, - GSActionForDragOperation(dragMask & operationMask), - XX(newPosition), XY(newPosition), CurrentTime); - break; - + xdnd_send_position(&dnd, dWindowNumber, dragWindev->ident, + GSActionForDragOperation(dragMask & operationMask), + XX(newPosition), XY(newPosition), CurrentTime); + break; + case GSAppKitDraggingEnter: - xdnd_send_enter(&dnd, dWindowNumber, dragWindev->ident, typelist); - xdnd_send_position(&dnd, dWindowNumber, dragWindev->ident, - GSActionForDragOperation (dragMask & operationMask), - XX(dragPosition), XY(dragPosition), CurrentTime); - break; + // FIXME: The first two lines need only be called once for every drag operation. + // They should be moved to a different method. + xdnd_set_selection_owner(&dnd, dragWindev->ident, typelist[0]); + xdnd_set_type_list(&dnd, dragWindev->ident, typelist); + + xdnd_send_enter(&dnd, dWindowNumber, dragWindev->ident, typelist); + xdnd_send_position(&dnd, dWindowNumber, dragWindev->ident, + GSActionForDragOperation (dragMask & operationMask), + XX(dragPosition), XY(dragPosition), CurrentTime); + break; case GSAppKitDraggingExit: - xdnd_send_leave(&dnd, dWindowNumber, dragWindev->ident); - break; - + xdnd_send_leave(&dnd, dWindowNumber, dragWindev->ident); + break; + default: - break; + break; } } diff --git a/Source/x11/XGServerEvent.m b/Source/x11/XGServerEvent.m index 51f4b6c..b628351 100644 --- a/Source/x11/XGServerEvent.m +++ b/Source/x11/XGServerEvent.m @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -1466,25 +1467,66 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym, // another client attempts to change the size of a window case ResizeRequest: - NSDebugLLog(@"NSEvent", @"%d ResizeRequest\n", - xEvent.xresizerequest.window); - break; + NSDebugLLog(@"NSEvent", @"%d ResizeRequest\n", + xEvent.xresizerequest.window); + break; // events dealing with the selection case SelectionClear: - NSDebugLLog(@"NSEvent", @"%d SelectionClear\n", - xEvent.xselectionclear.window); - break; + NSDebugLLog(@"NSEvent", @"%d SelectionClear\n", + xEvent.xselectionclear.window); + break; case SelectionNotify: - NSDebugLLog(@"NSEvent", @"%d SelectionNotify\n", - xEvent.xselection.requestor); - break; + NSDebugLLog(@"NSEvent", @"%d SelectionNotify\n", + xEvent.xselection.requestor); + break; case SelectionRequest: - NSDebugLLog(@"NSEvent", @"%d SelectionRequest\n", - xEvent.xselectionrequest.requestor); - break; + NSDebugLLog(@"NSEvent", @"%d SelectionRequest\n", + xEvent.xselectionrequest.requestor); + { + NSPasteboard *pb = [NSPasteboard pasteboardWithName: NSDragPboard]; + NSArray *types = [pb types]; + NSData *data = nil; + Atom xType = xEvent.xselectionrequest.target; + static Atom XG_UTF8_STRING = None; + static Atom XG_TEXT = None; + + if (XG_UTF8_STRING == None) + { + XG_UTF8_STRING = XInternAtom(dpy, "UTF8_STRING", False); + XG_TEXT = XInternAtom(dpy, "TEXT", False); + } + + if (((xType == XG_UTF8_STRING) || + (xType == XA_STRING) || + (xType == XG_TEXT)) && + [types containsObject: NSStringPboardType]) + { + NSString *s = [pb stringForType: NSStringPboardType]; + + if (xType == XG_UTF8_STRING) + { + data = [s dataUsingEncoding: NSUTF8StringEncoding]; + } + else if ((xType == XA_STRING) || (xType == XG_TEXT)) + { + data = [s dataUsingEncoding: NSISOLatin1StringEncoding]; + } + } + // FIXME: Add support for more types. See: xpbs.m + + if (data != nil) + { + DndClass dnd = xdnd(); + + // Send the data to the other process + xdnd_selection_send(&dnd, &xEvent.xselectionrequest, + (unsigned char *)[data bytes], [data length]); + } + } + break; // We shouldn't get here unless we forgot to trap an event above default: