summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--Changelog3
-rwxr-xr-xconfigure2
-rw-r--r--configure.in2
-rw-r--r--library/tkdnd_unix.tcl51
-rw-r--r--unix/Cursors.c255
-rw-r--r--unix/TkDND_XDND.c53
-rw-r--r--unix/tkSelect.h167
-rw-r--r--unix/tkUnixSelect.c1
9 files changed, 357 insertions, 179 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index acfc6cb..7257d38 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -49,7 +49,7 @@ ELSE ( WIN32 )
SET ( PKG_SOURCES unix/macosx/macdnd.m )
ELSE ( APPLE )
INCLUDE_DIRECTORIES ( unix )
- SET ( PKG_SOURCES unix/TkDND_XDND.c )
+ SET ( PKG_SOURCES unix/TkDND_XDND.c unix/tkUnixSelect.c unix/Cursors.c )
MESSAGE ( STATUS "Searching for X11..." )
FIND_PACKAGE ( X11 REQUIRED )
IF ( X11_FOUND )
diff --git a/Changelog b/Changelog
index 846c27d..1d1722b 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,6 @@
+2012-06-06 Petasis George <petasis@iit.demokritos.gr>
+ * unix/Cursors.c: Ported cursors from TkDND 1.x to TkDND 2.x
+
2012-06-05 Petasis George <petasis@iit.demokritos.gr>
* library/tkdnd.tcl:
* library/tkdnd_unix.tcl:
diff --git a/configure b/configure
index 32e3013..b9069e3 100755
--- a/configure
+++ b/configure
@@ -5656,7 +5656,7 @@ fi
if test "${TEA_WINDOWINGSYSTEM}" = "x11"; then
- vars="unix/TkDND_XDND.c unix/tkUnixSelect.c"
+ vars="unix/TkDND_XDND.c unix/tkUnixSelect.c unix/Cursors.c"
for i in $vars; do
case $i in
\$*)
diff --git a/configure.in b/configure.in
index ee0b510..0cb0b2b 100644
--- a/configure.in
+++ b/configure.in
@@ -109,7 +109,7 @@ else
fi
if test "${TEA_WINDOWINGSYSTEM}" = "x11"; then
- TEA_ADD_SOURCES([unix/TkDND_XDND.c unix/tkUnixSelect.c])
+ TEA_ADD_SOURCES([unix/TkDND_XDND.c unix/tkUnixSelect.c unix/Cursors.c])
fi
if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
diff --git a/library/tkdnd_unix.tcl b/library/tkdnd_unix.tcl
index 8b94254..397c58a 100644
--- a/library/tkdnd_unix.tcl
+++ b/library/tkdnd_unix.tcl
@@ -508,10 +508,12 @@ proc xdnd::_dodragdrop { source actions types data button } {
variable _dodragdrop_data $data
variable _dodragdrop_button $button
variable _dodragdrop_time 0
- variable _dodragdrop_default_action default
+ variable _dodragdrop_default_action refuse_drop
variable _dodragdrop_waiting_status 0
variable _dodragdrop_drop_target_accepts_drop 0
variable _dodragdrop_drop_target_accepts_action refuse_drop
+ variable _dodragdrop_current_cursor $_dodragdrop_default_action
+ variable _dodragdrop_drop_occured 0
##
## If we have more than 3 types, the property XdndTypeList must be set on
@@ -544,7 +546,7 @@ proc xdnd::_dodragdrop { source actions types data button } {
set _dragging 1
## Grab the mouse pointer...
- _grab_pointer $source star
+ _grab_pointer $source $_dodragdrop_default_action
## Register our generic event handler...
# The generic event callback will report events by modifying variable
@@ -650,7 +652,9 @@ proc xdnd::_SendXdndEnter {window proxy} {
variable _dodragdrop_drop_target_proxy
variable _dodragdrop_types
variable _dodragdrop_waiting_status
+ variable _dodragdrop_drop_occured
if {$_dodragdrop_drop_target > 0} _SendXdndLeave
+ if {$_dodragdrop_drop_occured} return
set _dodragdrop_drop_target $window
set _dodragdrop_drop_target_proxy $proxy
set _dodragdrop_waiting_status 0
@@ -667,6 +671,8 @@ proc xdnd::_SendXdndPosition {rootx rooty action} {
variable _dodragdrop_drag_source
variable _dodragdrop_drop_target
if {$_dodragdrop_drop_target < 1} return
+ variable _dodragdrop_drop_occured
+ if {$_dodragdrop_drop_occured} return
variable _dodragdrop_drop_target_proxy
variable _dodragdrop_waiting_status
## Arrange a new XdndPosition, to be send periodically...
@@ -675,7 +681,7 @@ proc xdnd::_SendXdndPosition {rootx rooty action} {
set _dodragdrop_xdnd_position_heartbeat [after 200 \
[list ::tkdnd::xdnd::_SendXdndPosition $rootx $rooty $action]]
if {$_dodragdrop_waiting_status} {return}
- # puts "XdndPosition: $_dodragdrop_drop_target"
+ # puts "XdndPosition: $_dodragdrop_drop_target $rootx $rooty $action"
_send_XdndPosition $_dodragdrop_drag_source $_dodragdrop_drop_target \
$_dodragdrop_drop_target_proxy $rootx $rooty $action
set _dodragdrop_waiting_status 1
@@ -696,6 +702,10 @@ proc xdnd::_HandleXdndStatus {event} {
}
set _dodragdrop_drop_target_accepts_drop $accept
set _dodragdrop_drop_target_accepts_action $action
+ if {$_dodragdrop_drop_target < 1} return
+ variable _dodragdrop_drop_occured
+ if {$_dodragdrop_drop_occured} return
+ _update_cursor
# puts "XdndStatus: $event"
};# xdnd::_HandleXdndStatus
@@ -722,6 +732,13 @@ proc xdnd::_SendXdndLeave {} {
_send_XdndLeave $_dodragdrop_drag_source $_dodragdrop_drop_target \
$_dodragdrop_drop_target_proxy
set _dodragdrop_drop_target 0
+ variable _dodragdrop_drop_target_accepts_drop
+ variable _dodragdrop_drop_target_accepts_action
+ set _dodragdrop_drop_target_accepts_drop 0
+ set _dodragdrop_drop_target_accepts_action refuse_drop
+ variable _dodragdrop_drop_occured
+ if {$_dodragdrop_drop_occured} return
+ _update_cursor
};# xdnd::_SendXdndLeave
# ----------------------------------------------------------------------------
@@ -731,9 +748,15 @@ proc xdnd::_SendXdndDrop {} {
variable _dodragdrop_drag_source
variable _dodragdrop_drop_target
if {$_dodragdrop_drop_target < 1} return
+ variable _dodragdrop_drop_occured
+ if {$_dodragdrop_drop_occured} {return}
variable _dodragdrop_drop_target_proxy
variable _dodragdrop_drop_target_accepts_drop
variable _dodragdrop_drop_target_accepts_action
+
+ set _dodragdrop_drop_occured 1
+ _update_cursor clock
+
if {!$_dodragdrop_drop_target_accepts_drop} {
_SendXdndLeave
_HandleXdndFinished {}
@@ -745,6 +768,7 @@ proc xdnd::_SendXdndDrop {} {
$_dodragdrop_drag_source $_dodragdrop_drop_target \
$_dodragdrop_drop_target_proxy]
set _dodragdrop_drop_target 0
+ # puts "XdndDrop: $_dodragdrop_drop_target"
## Arrange a timeout for receiving XdndFinished...
after 10000 [list ::tkdnd::xdnd::_HandleXdndFinished {}]
};# xdnd::_SendXdndDrop
@@ -759,6 +783,27 @@ proc xdnd::_SendData {type s e args} {
};# xdnd::_SendData
# ----------------------------------------------------------------------------
+# Command xdnd::_update_cursor
+# ----------------------------------------------------------------------------
+proc xdnd::_update_cursor { {cursor {}}} {
+ # puts "_update_cursor $cursor"
+ variable _dodragdrop_current_cursor
+ variable _dodragdrop_drag_source
+ variable _dodragdrop_drop_target_accepts_drop
+ variable _dodragdrop_drop_target_accepts_action
+
+ if {![string length $cursor]} {
+ set cursor refuse_drop
+ if {$_dodragdrop_drop_target_accepts_drop} {
+ set cursor $_dodragdrop_drop_target_accepts_action
+ }
+ }
+ if {![string equal $cursor $_dodragdrop_current_cursor]} {
+ _set_pointer_cursor $_dodragdrop_drag_source $cursor
+ set _dodragdrop_current_cursor $cursor
+ }
+};# xdnd::_update_cursor
+# ----------------------------------------------------------------------------
# Command xdnd::_default_action
# ----------------------------------------------------------------------------
proc xdnd::_default_action {event} {
diff --git a/unix/Cursors.c b/unix/Cursors.c
new file mode 100644
index 0000000..40e8893
--- /dev/null
+++ b/unix/Cursors.c
@@ -0,0 +1,255 @@
+#include "tcl.h"
+#include "tk.h"
+#include <X11/Xlib.h>
+#include <X11/X.h>
+
+/*
+ * Define DND Cursors...
+ */
+
+/* No Drop Cursor... */
+#define noDropCursorWidth 20
+#define noDropCursorHeight 20
+#define noDropCursorX 10
+#define noDropCursorY 10
+static unsigned char noDropCurBits[] = {
+ 0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
+ 0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
+ 0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
+ 0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00};
+
+static unsigned char noDropCurMask[] = {
+ 0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
+ 0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
+ 0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
+ 0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
+
+/* Copy Cursor... */
+#define CopyCursorWidth 29
+#define CopyCursorHeight 25
+#define CopyCursorX 10
+#define CopyCursorY 10
+static unsigned char CopyCurBits[] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x02, 0x00, 0x08, 0x01,
+ 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0xe8, 0x0f,
+ 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0x08, 0x01,
+ 0x02, 0x00, 0x08, 0x00, 0x02, 0x04, 0x08, 0x00, 0x02, 0x0c, 0x08, 0x00,
+ 0x02, 0x1c, 0x08, 0x00, 0x02, 0x3c, 0x08, 0x00, 0x02, 0x7c, 0x08, 0x00,
+ 0x02, 0xfc, 0x08, 0x00, 0x02, 0xfc, 0x09, 0x00, 0x02, 0xfc, 0x0b, 0x00,
+ 0x02, 0x7c, 0x08, 0x00, 0xfe, 0x6d, 0x0f, 0x00, 0x00, 0xc4, 0x00, 0x00,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+
+static unsigned char CopyCurMask[] =
+{
+ 0xff, 0xff, 0x1f, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0x1f,
+ 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f,
+ 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f,
+ 0x07, 0x06, 0xfc, 0x1f, 0x07, 0x0e, 0xfc, 0x1f, 0x07, 0x1e, 0x1c, 0x00,
+ 0x07, 0x3e, 0x1c, 0x00, 0x07, 0x7e, 0x1c, 0x00, 0x07, 0xfe, 0x1c, 0x00,
+ 0x07, 0xfe, 0x1d, 0x00, 0x07, 0xfe, 0x1f, 0x00, 0x07, 0xfe, 0x1f, 0x00,
+ 0xff, 0xff, 0x1f, 0x00, 0xff, 0xff, 0x1e, 0x00, 0xff, 0xef, 0x1f, 0x00,
+ 0x00, 0xe6, 0x01, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00,
+ 0x00, 0x80, 0x01, 0x00};
+
+/* Move Cursor... */
+#define MoveCursorWidth 21
+#define MoveCursorHeight 25
+#define MoveCursorX 10
+#define MoveCursorY 10
+static unsigned char MoveCurBits[] =
+{
+ 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08,
+ 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08,
+ 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x04, 0x08, 0x02, 0x0c, 0x08,
+ 0x02, 0x1c, 0x08, 0x02, 0x3c, 0x08, 0x02, 0x7c, 0x08, 0x02, 0xfc, 0x08,
+ 0x02, 0xfc, 0x09, 0x02, 0xfc, 0x0b, 0x02, 0x7c, 0x08, 0xfe, 0x6d, 0x0f,
+ 0x00, 0xc4, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01,
+ 0x00, 0x00, 0x00};
+
+static unsigned char MoveCurMask[] =
+{
+ 0xff, 0xff, 0x1f, 0xff, 0xff, 0x1f, 0xff, 0xff, 0x1f, 0x07, 0x00, 0x1c,
+ 0x07, 0x00, 0x1c, 0x07, 0x00, 0x1c, 0x07, 0x00, 0x1c, 0x07, 0x00, 0x1c,
+ 0x07, 0x00, 0x1c, 0x07, 0x06, 0x1c, 0x07, 0x0e, 0x1c, 0x07, 0x1e, 0x1c,
+ 0x07, 0x3e, 0x1c, 0x07, 0x7e, 0x1c, 0x07, 0xfe, 0x1c, 0x07, 0xfe, 0x1d,
+ 0x07, 0xfe, 0x1f, 0x07, 0xfe, 0x1f, 0xff, 0xff, 0x1f, 0xff, 0xff, 0x1e,
+ 0xff, 0xef, 0x1f, 0x00, 0xe6, 0x01, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03,
+ 0x00, 0x80, 0x01};
+
+/* Link Cursor... */
+#define LinkCursorWidth 29
+#define LinkCursorHeight 25
+#define LinkCursorX 10
+#define LinkCursorY 10
+static unsigned char LinkCurBits[] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x02, 0x00, 0x08, 0x01,
+ 0x02, 0x00, 0x88, 0x00, 0x02, 0x00, 0x48, 0x00, 0x02, 0x00, 0xe8, 0x0f,
+ 0x02, 0x00, 0x48, 0x00, 0x02, 0x00, 0x88, 0x00, 0x02, 0x00, 0x08, 0x01,
+ 0x02, 0x00, 0x08, 0x00, 0x02, 0x04, 0x08, 0x00, 0x02, 0x0c, 0x08, 0x00,
+ 0x02, 0x1c, 0x08, 0x00, 0x02, 0x3c, 0x08, 0x00, 0x02, 0x7c, 0x08, 0x00,
+ 0x02, 0xfc, 0x08, 0x00, 0x02, 0xfc, 0x09, 0x00, 0x02, 0xfc, 0x0b, 0x00,
+ 0x02, 0x7c, 0x08, 0x00, 0xfe, 0x6d, 0x0f, 0x00, 0x00, 0xc4, 0x00, 0x00,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+
+static unsigned char LinkCurMask[] =
+{
+ 0xff, 0xff, 0x1f, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0x1f,
+ 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f,
+ 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f,
+ 0x07, 0x06, 0xfc, 0x1f, 0x07, 0x0e, 0xfc, 0x1f, 0x07, 0x1e, 0x1c, 0x00,
+ 0x07, 0x3e, 0x1c, 0x00, 0x07, 0x7e, 0x1c, 0x00, 0x07, 0xfe, 0x1c, 0x00,
+ 0x07, 0xfe, 0x1d, 0x00, 0x07, 0xfe, 0x1f, 0x00, 0x07, 0xfe, 0x1f, 0x00,
+ 0xff, 0xff, 0x1f, 0x00, 0xff, 0xff, 0x1e, 0x00, 0xff, 0xef, 0x1f, 0x00,
+ 0x00, 0xe6, 0x01, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00,
+ 0x00, 0x80, 0x01, 0x00};
+
+/* Ask Cursor... */
+#define AskCursorWidth 29
+#define AskCursorHeight 25
+#define AskCursorX 10
+#define AskCursorY 10
+static unsigned char AskCurBits[] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x02, 0x00, 0x88, 0x03,
+ 0x02, 0x00, 0x48, 0x04, 0x02, 0x00, 0x08, 0x04, 0x02, 0x00, 0x08, 0x02,
+ 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0x08, 0x00,
+ 0x02, 0x00, 0x08, 0x01, 0x02, 0x04, 0x08, 0x00, 0x02, 0x0c, 0x08, 0x00,
+ 0x02, 0x1c, 0x08, 0x00, 0x02, 0x3c, 0x08, 0x00, 0x02, 0x7c, 0x08, 0x00,
+ 0x02, 0xfc, 0x08, 0x00, 0x02, 0xfc, 0x09, 0x00, 0x02, 0xfc, 0x0b, 0x00,
+ 0x02, 0x7c, 0x08, 0x00, 0xfe, 0x6d, 0x0f, 0x00, 0x00, 0xc4, 0x00, 0x00,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+
+static unsigned char AskCurMask[] =
+{
+ 0xff, 0xff, 0x1f, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0x1f,
+ 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f,
+ 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f, 0x07, 0x00, 0xfc, 0x1f,
+ 0x07, 0x06, 0xfc, 0x1f, 0x07, 0x0e, 0xfc, 0x1f, 0x07, 0x1e, 0x1c, 0x00,
+ 0x07, 0x3e, 0x1c, 0x00, 0x07, 0x7e, 0x1c, 0x00, 0x07, 0xfe, 0x1c, 0x00,
+ 0x07, 0xfe, 0x1d, 0x00, 0x07, 0xfe, 0x1f, 0x00, 0x07, 0xfe, 0x1f, 0x00,
+ 0xff, 0xff, 0x1f, 0x00, 0xff, 0xff, 0x1e, 0x00, 0xff, 0xef, 0x1f, 0x00,
+ 0x00, 0xe6, 0x01, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00,
+ 0x00, 0x80, 0x01, 0x00};
+
+static Cursor noDropCursor = 0,
+ moveCursor = 0,
+ copyCursor = 0,
+ linkCursor = 0,
+ askCursor = 0;
+
+
+void TkDND_InitialiseCursors(Tcl_Interp *interp) {
+ XColor black, white;
+ Pixmap image_pixmap, mask_pixmap;
+ Tk_Window main_window;
+ Display *display;
+ Window RootWindow;
+
+ if (!interp) return;
+ main_window = Tk_MainWindow(interp);
+ Tk_MakeWindowExist(main_window);
+ display = Tk_Display(main_window);
+ RootWindow = DefaultRootWindow(display);
+
+ black.pixel = BlackPixel(display, DefaultScreen(display));
+ white.pixel = WhitePixel(display, DefaultScreen(display));
+ XQueryColor(display, DefaultColormap(display,
+ DefaultScreen(display)), &black);
+ XQueryColor(display, DefaultColormap(display,
+ DefaultScreen(display)), &white);
+ /* No Drop Cursor */
+ if (!noDropCursor) {
+ image_pixmap = XCreateBitmapFromData(display, RootWindow,
+ (char *) noDropCurBits, noDropCursorWidth, noDropCursorHeight);
+ mask_pixmap = XCreateBitmapFromData(display, RootWindow,
+ (char *) noDropCurMask, noDropCursorWidth, noDropCursorHeight);
+ noDropCursor = XCreatePixmapCursor (display, image_pixmap,
+ mask_pixmap, &black, &white, noDropCursorX, noDropCursorY);
+ XFreePixmap (display, image_pixmap);
+ XFreePixmap (display, mask_pixmap);
+ }
+ /* Copy Cursor */
+ if (!copyCursor) {
+ image_pixmap = XCreateBitmapFromData(display, RootWindow,
+ (char *) CopyCurBits, CopyCursorWidth, CopyCursorHeight);
+ mask_pixmap = XCreateBitmapFromData(display, RootWindow,
+ (char *) CopyCurMask, CopyCursorWidth, CopyCursorHeight);
+ copyCursor = XCreatePixmapCursor (display, image_pixmap,
+ mask_pixmap, &black, &white, CopyCursorX, CopyCursorY);
+ XFreePixmap (display, image_pixmap);
+ XFreePixmap (display, mask_pixmap);
+ }
+ /* Move Cursor */
+ if (!moveCursor) {
+ image_pixmap = XCreateBitmapFromData(display, RootWindow,
+ (char *) MoveCurBits, MoveCursorWidth, MoveCursorHeight);
+ mask_pixmap = XCreateBitmapFromData(display, RootWindow,
+ (char *) MoveCurMask, MoveCursorWidth, MoveCursorHeight);
+ moveCursor = XCreatePixmapCursor (display, image_pixmap,
+ mask_pixmap, &black, &white, MoveCursorX, MoveCursorY);
+ XFreePixmap (display, image_pixmap);
+ XFreePixmap (display, mask_pixmap);
+ }
+ /* Link Cursor */
+ if (!linkCursor) {
+ image_pixmap = XCreateBitmapFromData(display, RootWindow,
+ (char *) LinkCurBits, LinkCursorWidth, LinkCursorHeight);
+ mask_pixmap = XCreateBitmapFromData(display, RootWindow,
+ (char *) LinkCurMask, LinkCursorWidth, LinkCursorHeight);
+ linkCursor = XCreatePixmapCursor (display, image_pixmap,
+ mask_pixmap, &black, &white, LinkCursorX, LinkCursorY);
+ XFreePixmap (display, image_pixmap);
+ XFreePixmap (display, mask_pixmap);
+ }
+ /* Ask Cursor */
+ if (!askCursor) {
+ image_pixmap = XCreateBitmapFromData(display, RootWindow,
+ (char *) AskCurBits, AskCursorWidth, AskCursorHeight);
+ mask_pixmap = XCreateBitmapFromData(display, RootWindow,
+ (char *) AskCurMask, AskCursorWidth, AskCursorHeight);
+ askCursor = XCreatePixmapCursor (display, image_pixmap,
+ mask_pixmap, &black, &white, AskCursorX, AskCursorY);
+ XFreePixmap (display, image_pixmap);
+ XFreePixmap (display, mask_pixmap);
+ }
+ /* Register Cursors... */
+}; /* TkDND_InitialiseCursors */
+
+Tk_Cursor TkDND_GetCursor(Tcl_Interp *interp, Tcl_Obj *name) {
+ static char *DropActions[] = {
+ "copy", "move", "link", "ask", "private", "refuse_drop", "default",
+ (char *) NULL
+ };
+ enum dropactions {
+ ActionCopy, ActionMove, ActionLink, ActionAsk, ActionPrivate,
+ refuse_drop, ActionDefault
+ };
+ int status, index;
+ Tk_Cursor cursor;
+
+ status = Tcl_GetIndexFromObj(interp, name, (const char **) DropActions,
+ "dropactions", 0, &index);
+ if (status == TCL_OK) {
+ switch ((enum dropactions) index) {
+ case ActionDefault:
+ case ActionCopy: return (Tk_Cursor) copyCursor;
+ case ActionMove: return (Tk_Cursor) moveCursor;
+ case ActionLink: return (Tk_Cursor) linkCursor;
+ case ActionAsk: return (Tk_Cursor) askCursor;
+ case ActionPrivate: return (Tk_Cursor) askCursor;
+ case refuse_drop: return (Tk_Cursor) noDropCursor;
+ }
+ }
+ /* The name is not an action. Try Tk cursors... */
+ cursor = Tk_AllocCursorFromObj(interp, Tk_MainWindow(interp), name);
+ if (cursor == None) {
+ Tcl_SetResult(interp, "invalid cursor name", TCL_STATIC);
+ return (Tk_Cursor) None;
+ }
+ return cursor;
+}; /* TkDND_GetCursor */
diff --git a/unix/TkDND_XDND.c b/unix/TkDND_XDND.c
index cdf89d4..eba6c87 100644
--- a/unix/TkDND_XDND.c
+++ b/unix/TkDND_XDND.c
@@ -169,10 +169,12 @@ Tcl_Interp * TkDND_Interp(Tk_Window tkwin) {
#define XDND_FINISHED_ACCEPTED_YES(e) ((e)->xclient.data.l[1] |= (1 << 1))
#define XDND_FINISHED_ACTION(e) ((e)->xclient.data.l[2])
-extern int TkDND_GetSelection(Tcl_Interp *interp, Tk_Window tkwin, Atom selection,
+extern int TkDND_GetSelection(Tcl_Interp *interp, Tk_Window tkwin,
+ Atom selection,
Atom target, Time time,
Tk_GetSelProc *proc, ClientData clientData);
-
+extern void TkDND_InitialiseCursors(Tcl_Interp *interp);
+extern Tk_Cursor TkDND_GetCursor(Tcl_Interp *interp, Tcl_Obj *name);
/*
* Support for getting the wrapper window for our top-level...
@@ -868,9 +870,10 @@ int TkDND_GrabPointerObjCmd(ClientData clientData, Tcl_Interp *interp,
if (!path) return TCL_ERROR;
Tk_MakeWindowExist(path);
- cursor = Tk_AllocCursorFromObj(interp, path, objv[2]);
+ cursor = TkDND_GetCursor(interp, objv[2]);
if (cursor == None) {
- Tcl_SetResult(interp, "invalid cursor", TCL_STATIC);
+ Tcl_SetResult(interp, "invalid cursor name: ", TCL_STATIC);
+ Tcl_AppendResult(interp, Tcl_GetString(objv[2]));
return TCL_ERROR;
}
@@ -898,6 +901,37 @@ int TkDND_UnrabPointerObjCmd(ClientData clientData, Tcl_Interp *interp,
return TCL_OK;
}; /* TkDND_GrabPointerObjCmd */
+int TkDND_SetPointerCursorObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]) {
+ Tk_Window path;
+ Tk_Cursor cursor;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "path cursor");
+ return TCL_ERROR;
+ }
+
+ path = TkDND_TkWin(objv[1]);
+ if (!path) return TCL_ERROR;
+ Tk_MakeWindowExist(path);
+
+ cursor = TkDND_GetCursor(interp, objv[2]);
+ if (cursor == None) {
+ Tcl_SetResult(interp, "invalid cursor name: ", TCL_STATIC);
+ Tcl_AppendResult(interp, Tcl_GetString(objv[2]));
+ return TCL_ERROR;
+ }
+
+ if (XChangeActivePointerGrab(Tk_Display(path),
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | EnterWindowMask | LeaveWindowMask,
+ (Cursor) cursor, CurrentTime) != GrabSuccess) {
+ /* Tcl_SetResult(interp, "unable to update mouse pointer", TCL_STATIC);
+ return TCL_ERROR; */
+ }
+ return TCL_OK;
+}; /* TkDND_SetPointerCursorObjCmd */
+
void TkDND_AddStateInformation(Tcl_Interp *interp, Tcl_Obj *dict,
unsigned int state) {
Tcl_Obj *key, *value;
@@ -1389,7 +1423,13 @@ int DLLEXPORT Tkdnd_Init(Tcl_Interp *interp) {
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL) == NULL) {
return TCL_ERROR;
}
-
+
+ if (Tcl_CreateObjCommand(interp, "_set_pointer_cursor",
+ (Tcl_ObjCmdProc*) TkDND_SetPointerCursorObjCmd,
+ (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL) == NULL) {
+ return TCL_ERROR;
+ }
+
if (Tcl_CreateObjCommand(interp, "_register_generic_event_handler",
(Tcl_ObjCmdProc*) TkDND_RegisterGenericEventHandlerObjCmd,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL) == NULL) {
@@ -1450,6 +1490,9 @@ int DLLEXPORT Tkdnd_Init(Tcl_Interp *interp) {
return TCL_ERROR;
}
+ /* Create the cursors... */
+ TkDND_InitialiseCursors(interp);
+
/* Finally, register the XDND Handler... */
Tk_CreateClientMessageHandler(&TkDND_XDNDHandler);
diff --git a/unix/tkSelect.h b/unix/tkSelect.h
index 74326d0..e69de29 100644
--- a/unix/tkSelect.h
+++ b/unix/tkSelect.h
@@ -1,167 +0,0 @@
-/*
- * tkSelect.h --
- *
- * Declarations of types shared among the files that implement selection
- * support.
- *
- * Copyright (c) 1995 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
- */
-
-#ifndef _TKSELECT
-#define _TKSELECT
-
-/*
- * When a selection is owned by a window on a given display, one of the
- * following structures is present on a list of current selections in the
- * display structure. The structure is used to record the current owner of a
- * selection for use in later retrieval requests. There is a list of such
- * structures because a display can have multiple different selections active
- * at the same time.
- */
-
-typedef struct TkSelectionInfo {
- Atom selection; /* Selection name, e.g. XA_PRIMARY. */
- Tk_Window owner; /* Current owner of this selection. */
- int serial; /* Serial number of last XSelectionSetOwner
- * request made to server for this selection
- * (used to filter out redundant
- * SelectionClear events). */
- Time time; /* Timestamp used to acquire selection. */
- Tk_LostSelProc *clearProc; /* Procedure to call when owner loses
- * selection. */
- ClientData clearData; /* Info to pass to clearProc. */
- struct TkSelectionInfo *nextPtr;
- /* Next in list of current selections on this
- * display. NULL means end of list. */
-} TkSelectionInfo;
-
-/*
- * One of the following structures exists for each selection handler created
- * for a window by calling Tk_CreateSelHandler. The handlers are linked in a
- * list rooted in the TkWindow structure.
- */
-
-typedef struct TkSelHandler {
- Atom selection; /* Selection name, e.g. XA_PRIMARY. */
- Atom target; /* Target type for selection conversion, such
- * as TARGETS or STRING. */
- Atom format; /* Format in which selection info will be
- * returned, such as STRING or ATOM. */
- Tk_SelectionProc *proc; /* Procedure to generate selection in this
- * format. */
- ClientData clientData; /* Argument to pass to proc. */
- int size; /* Size of units returned by proc (8 for
- * STRING, 32 for almost anything else). */
- struct TkSelHandler *nextPtr;
- /* Next selection handler associated with same
- * window (NULL for end of list). */
-} TkSelHandler;
-
-/*
- * When the selection is being retrieved, one of the following structures is
- * present on a list of pending selection retrievals. The structure is used to
- * communicate between the background procedure that requests the selection
- * and the foreground event handler that processes the events in which the
- * selection is returned. There is a list of such structures so that there can
- * be multiple simultaneous selection retrievals (e.g. on different displays).
- */
-
-typedef struct TkSelRetrievalInfo {
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- TkWindow *winPtr; /* Window used as requestor for selection. */
- Atom selection; /* Selection being requested. */
- Atom property; /* Property where selection will appear. */
- Atom target; /* Desired form for selection. */
- Tk_GetSelProc *proc; /* Procedure to call to handle pieces of
- * selection. */
- ClientData clientData; /* Argument for proc. */
- int result; /* Initially -1. Set to a Tcl return value
- * once the selection has been retrieved. */
- Tcl_TimerToken timeout; /* Token for current timeout procedure. */
- int idleTime; /* Number of seconds that have gone by without
- * hearing anything from the selection
- * owner. */
- Tcl_EncodingState encState; /* Holds intermediate state during translations
- * of data that cross buffer boundaries. */
- int encFlags; /* Encoding translation state flags. */
- Tcl_DString buf; /* Buffer to hold translation data. */
- struct TkSelRetrievalInfo *nextPtr;
- /* Next in list of all pending selection
- * retrievals. NULL means end of list. */
-} TkSelRetrievalInfo;
-
-/*
- * The clipboard contains a list of buffers of various types and formats. All
- * of the buffers of a given type will be returned in sequence when the
- * CLIPBOARD selection is retrieved. All buffers of a given type on the same
- * clipboard must have the same format. The TkClipboardTarget structure is
- * used to record the information about a chain of buffers of the same type.
- */
-
-typedef struct TkClipboardBuffer {
- char *buffer; /* Null terminated data buffer. */
- long length; /* Length of string in buffer. */
- struct TkClipboardBuffer *nextPtr;
- /* Next in list of buffers. NULL means end of
- * list . */
-} TkClipboardBuffer;
-
-typedef struct TkClipboardTarget {
- Atom type; /* Type conversion supported. */
- Atom format; /* Representation used for data. */
- TkClipboardBuffer *firstBufferPtr;
- /* First in list of data buffers. */
- TkClipboardBuffer *lastBufferPtr;
- /* Last in list of clipboard buffers. Used to
- * speed up appends. */
- struct TkClipboardTarget *nextPtr;
- /* Next in list of targets on clipboard. NULL
- * means end of list. */
-} TkClipboardTarget;
-
-/*
- * It is possible for a Tk_SelectionProc to delete the handler that it
- * represents. If this happens, the code that is retrieving the selection
- * needs to know about it so it doesn't use the now-defunct handler structure.
- * One structure of the following form is created for each retrieval in
- * progress, so that the retriever can find out if its handler is deleted. All
- * of the pending retrievals (if there are more than one) are linked into a
- * list.
- */
-
-typedef struct TkSelInProgress {
- TkSelHandler *selPtr; /* Handler being executed. If this handler is
- * deleted, the field is set to NULL. */
- struct TkSelInProgress *nextPtr;
- /* Next higher nested search. */
-} TkSelInProgress;
-
-/*
- * Chunk size for retrieving selection. It's defined both in words and in
- * bytes; the word size is used to allocate buffer space that's guaranteed to
- * be word-aligned and that has an extra character for the terminating NULL.
- */
-
-#define TK_SEL_BYTES_AT_ONCE 4000
-#define TK_SEL_WORDS_AT_ONCE 1001
-
-/*
- * Declarations for procedures that are used by the selection-related files
- * but shouldn't be used anywhere else in Tk (or by Tk clients):
- */
-
-MODULE_SCOPE TkSelInProgress *TkSelGetInProgress(void);
-MODULE_SCOPE void TkSelSetInProgress(TkSelInProgress *pendingPtr);
-MODULE_SCOPE void TkSelClearSelection(Tk_Window tkwin, XEvent *eventPtr);
-MODULE_SCOPE int TkSelDefaultSelection(TkSelectionInfo *infoPtr,
- Atom target, char *buffer, int maxBytes,
- Atom *typePtr);
-#ifndef TkSelUpdateClipboard
-MODULE_SCOPE void TkSelUpdateClipboard(TkWindow *winPtr,
- TkClipboardTarget *targetPtr);
-#endif
-
-#endif /* _TKSELECT */
diff --git a/unix/tkUnixSelect.c b/unix/tkUnixSelect.c
index a56df9f..2baa0fb 100644
--- a/unix/tkUnixSelect.c
+++ b/unix/tkUnixSelect.c
@@ -127,7 +127,6 @@ int TkDND_ClipboardReadIncrementalProperty(Tk_Window tkwin,
TkDND_ProcDetail *detail) {
TkDND_ProcDetail detail2;
Tcl_DString *buffer = (Tcl_DString *) detail->clientData;
- Display *display = Tk_Display(tkwin);
detail2.interp = detail->interp;
detail2.tkwin = detail->tkwin;
detail2.property = detail->property;