summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpetasis <petasis@f3661a36-4baa-549a-d6c7-40e0ffef350e>2009-12-09 21:00:34 (GMT)
committerpetasis <petasis@f3661a36-4baa-549a-d6c7-40e0ffef350e>2009-12-09 21:00:34 (GMT)
commitc80f725cf708460935311c056d5ada6a39a2ac1a (patch)
treebd4371cbf3eb27d1548ad69507bfc40c485c0721
parent97696624c65652b5fe47c8c30ab0056b2e591824 (diff)
downloadtkdnd-c80f725cf708460935311c056d5ada6a39a2ac1a.zip
tkdnd-c80f725cf708460935311c056d5ada6a39a2ac1a.tar.gz
tkdnd-c80f725cf708460935311c056d5ada6a39a2ac1a.tar.bz2
MAC OS X updates
-rw-r--r--library/tkdnd_macosx.tcl11
-rw-r--r--macosx/macdnd.m134
2 files changed, 120 insertions, 25 deletions
diff --git a/library/tkdnd_macosx.tcl b/library/tkdnd_macosx.tcl
index 0e7d1e2..0e007d7 100644
--- a/library/tkdnd_macosx.tcl
+++ b/library/tkdnd_macosx.tcl
@@ -60,9 +60,9 @@ namespace eval macdnd {
};# namespace macdnd
# ----------------------------------------------------------------------------
-# Command macdnd::_HandleXdndEnter
+# Command macdnd::_HandleEnter
# ----------------------------------------------------------------------------
-proc macdnd::_HandleXdndEnter { path drag_source typelist } {
+proc macdnd::_HandleEnter { path drag_source typelist } {
variable _typelist; set _typelist $typelist
variable _pressedkeys; set _pressedkeys 1
variable _action; set _action {}
@@ -73,10 +73,11 @@ proc macdnd::_HandleXdndEnter { path drag_source typelist } {
variable _drop_target; set _drop_target {}
variable _actionlist; set _actionlist \
{copy move link ask private}
- # puts "macdnd::_HandleXdndEnter: path=$path, drag_source=$drag_source,\
- # typelist=$typelist"
+ puts "macdnd::_HandleEnter: path=$path, drag_source=$drag_source,\
+ typelist=$typelist"
update
-};# macdnd::_HandleXdndEnter
+ return default
+};# macdnd::_HandleEnter
# ----------------------------------------------------------------------------
# Command macdnd::_HandleXdndPosition
diff --git a/macosx/macdnd.m b/macosx/macdnd.m
index 6869ee0..dc4cf61 100644
--- a/macosx/macdnd.m
+++ b/macosx/macdnd.m
@@ -18,11 +18,42 @@
#import <tkMacOSXInt.h>
#import <Cocoa/Cocoa.h>
+#define TkDND_TkWin(x) \
+ (Tk_NameToWindow(interp, Tcl_GetString(x), Tk_MainWindow(interp)))
+
+#define TkDND_Eval(objc) \
+ for (i=0; i<objc; ++i) Tcl_IncrRefCount(objv[i]);\
+ if (Tcl_EvalObjv(interp, objc, objv, TCL_EVAL_GLOBAL) != TCL_OK) \
+ Tk_BackgroundError(interp); \
+ for (i=0; i<objc; ++i) Tcl_DecrRefCount(objv[i]);
+
+#define TkDND_Status_Eval(objc) \
+ for (i=0; i<objc; ++i) Tcl_IncrRefCount(objv[i]);\
+ status = Tcl_EvalObjv(interp, objc, objv, TCL_EVAL_GLOBAL);\
+ if (status != TCL_OK) Tk_BackgroundError(interp); \
+ for (i=0; i<objc; ++i) Tcl_DecrRefCount(objv[i]);
+
+#ifndef Tk_Interp
+/*
+ * Tk 8.5 has a new function to return the interpreter that is associated with a
+ * window. Under 8.4 and earlier versions, simulate this function.
+ */
+#import "tkInt.h"
+Tcl_Interp * TkDND_Interp(Tk_Window tkwin) {
+ if (tkwin != NULL && ((TkWindow *)tkwin)->mainPtr != NULL) {
+ return ((TkWindow *)tkwin)->mainPtr->interp;
+ }
+ return NULL;
+}; /* Tk_Interp */
+#define Tk_Interp TkDND_Interp
+#endif /* Tk_Interp */
+
+
//Here we need to wrap Cocoa methods in Cocoa class: methods for initiating, tracking, and terminating drag from inside and outside the application.
@interface DNDView : NSView {
-
- NSPasteboard *dragpasteboard;
+ NSDragOperation sourceDragMask;
+ NSPasteboard *sourcePasteBoard;
NSMutableArray *draggedtypes;
}
@@ -46,20 +77,82 @@ TkWindow* TkMacOSXGetTkWindow(NSWindow *w) {
}
-//We are only implementing dragging destination methods here: widget is drop target. Making a Tk widget a drag source under Cocoa is more complex because mouse events are defined at the Objective-C level.
+/*
+ * We are only implementing dragging destination methods here:
+ * widget is drop target. Making a Tk widget a drag source under
+ * Cocoa is more complex because mouse events are defined at the
+ * Objective-C level.
+ */
-//standard Cocoa method for entering drop target; generate <<MacDragEnter>> event for Tk callback
+/*
+ * Standard Cocoa method for entering drop target;
+ * Calls tkdnd::macdnd::_HandleEnter
+ */
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
-
- dragpasteboard = [sender draggingPasteboard];
-
- //create Tk virtual event
- XVirtualEvent event;
- int x, y;
-
- TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
- Tk_Window tkwin = (Tk_Window) winPtr;
-
+ static char *DropActions[] = {
+ "copy", "move", "link", "ask", "private", "refuse_drop", "default",
+ (char *) NULL
+ };
+ enum dropactions {
+ ActionCopy, ActionMove, ActionLink, ActionAsk, ActionPrivate,
+ refuse_drop, ActionDefault
+ };
+
+ TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
+ Tk_Window tkwin = (Tk_Window) winPtr;
+ Tcl_Interp *interp = Tk_Interp(tkwin);
+ sourceDragMask = [sender draggingSourceOperationMask];
+ sourcePasteBoard = [sender draggingPasteboard];
+
+ Tcl_Obj* objv[4], *element, *result;
+ int i, index, status;
+
+ objv[0] = Tcl_NewStringObj("tkdnd::macdnd::_HandleEnter", -1);
+ objv[1] = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
+ objv[2] = Tcl_NewLongObj(0);
+ objv[3] = Tcl_NewListObj(0, NULL);
+ /*
+ * Search for known types...
+ */
+ if ([[sourcePasteBoard types] containsObject:NSStringPboardType]) {
+ element = Tcl_NewStringObj("NSStringPboardType", -1);
+ Tcl_ListObjAppendElement(NULL, objv[3], element);
+ }
+ if ([[sourcePasteBoard types] containsObject:NSFilenamesPboardType]) {
+ element = Tcl_NewStringObj("NSFilenamesPboardType", -1);
+ Tcl_ListObjAppendElement(NULL, objv[3], element);
+ }
+ /* Evaluate the command and get the result...*/
+ TkDND_Status_Eval(4);
+ printf("Status=%d (%d)\n", status, TCL_OK);fflush(0);
+ if (status != TCL_OK) {
+ /* An error has happened. Cancel the drop! */
+ return NSDragOperationNone;
+ }
+ /* We have a result: the returned action... */
+ result = Tcl_GetObjResult(interp); Tcl_IncrRefCount(result);
+ status = Tcl_GetIndexFromObj(interp, result, (const char **) DropActions,
+ "dropactions", 0, &index);
+ Tcl_DecrRefCount(result);
+ if (status != TCL_OK) index = refuse_drop;
+ switch ((enum dropactions) index) {
+ case ActionDefault:
+ case ActionCopy:
+ return NSDragOperationCopy;
+ case ActionMove:
+ return NSDragOperationMove;
+ case ActionAsk:
+ return NSDragOperationGeneric;
+ case ActionPrivate:
+ return NSDragOperationPrivate;
+ case ActionLink:
+ return NSDragOperationLink;
+ case refuse_drop: {
+ return NSDragOperationNone; /* Refuse drop. */
+ }
+ }
+ return NSDragOperationNone;
+#if 0
bzero(&event, sizeof(XVirtualEvent));
event.type = VirtualEvent;
event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
@@ -78,11 +171,12 @@ TkWindow* TkMacOSXGetTkWindow(NSWindow *w) {
//return valid NSDragOperations
return NSDragOperationEvery;
+#endif
}
//prepare to perform drag operation
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender {
- dragpasteboard = [sender draggingPasteboard];
+ sourcePasteBoard = [sender draggingPasteboard];
return YES;
}
@@ -91,18 +185,18 @@ TkWindow* TkMacOSXGetTkWindow(NSWindow *w) {
// NSArray types;
- dragpasteboard = [sender draggingPasteboard];
+ sourcePasteBoard = [sender draggingPasteboard];
//retrieve string data from clipboard
- NSArray *types = [dragpasteboard types];
+ NSArray *types = [sourcePasteBoard types];
NSString *pasteboardvalue = nil;
for (NSString *type in types) {
//string type
if ([type isEqualToString:NSStringPboardType]) {
- pasteboardvalue = [dragpasteboard stringForType:NSStringPboardType];
+ pasteboardvalue = [sourcePasteBoard stringForType:NSStringPboardType];
//file array, convert to string
} else if ([type isEqualToString:NSFilenamesPboardType]) {
- NSArray *files = [dragpasteboard propertyListForType:NSFilenamesPboardType];
+ NSArray *files = [sourcePasteBoard propertyListForType:NSFilenamesPboardType];
NSString *filename;
filename = [files componentsJoinedByString:@"\t"];
pasteboardvalue = filename;
@@ -143,7 +237,7 @@ TkWindow* TkMacOSXGetTkWindow(NSWindow *w) {
//drop target exited: generate <<MacDragExit>> virtual event
- (void)draggingExited:(id < NSDraggingInfo >)sender {
- dragpasteboard = [sender draggingPasteboard];
+ sourcePasteBoard = [sender draggingPasteboard];
XVirtualEvent event;
int x, y;