diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | Changelog | 3 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | library/tkdnd_unix.tcl | 51 | ||||
-rw-r--r-- | unix/Cursors.c | 255 | ||||
-rw-r--r-- | unix/TkDND_XDND.c | 53 | ||||
-rw-r--r-- | unix/tkSelect.h | 167 | ||||
-rw-r--r-- | unix/tkUnixSelect.c | 1 |
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 ) @@ -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: @@ -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; |