1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDropTarget class
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "dnd.h"
15 #include "wx/window.h"
17 #include "wx/gdicmn.h"
21 #include "gdk/gdkprivate.h"
25 // ----------------------------------------------------------------------------
27 // ----------------------------------------------------------------------------
29 extern bool g_blockEventsOnDrag
;
31 #ifdef NEW_GTK_DND_CODE
33 #include "gtk/gtkdnd.h"
34 #include "gtk/gtkselection.h"
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 static void target_drag_leave( GtkWidget
*WXUNUSED(widget
),
41 GdkDragContext
*WXUNUSED(context
),
42 guint
WXUNUSED(time
) )
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 static gboolean
target_drag_motion( GtkWidget
*WXUNUSED(widget
),
52 GdkDragContext
*context
,
57 printf( "motion.\n" );
58 gdk_drag_status( context
, context
->suggested_action
, time
);
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 static gboolean
target_drag_drop( GtkWidget
*widget
,
67 GdkDragContext
*context
,
72 printf( "drop at: %d,%d.\n", x
, y
);
76 gtk_drag_get_data( widget
,
78 GPOINTER_TO_INT (context
->targets
->data
),
84 // ----------------------------------------------------------------------------
85 // "drag_data_received"
86 // ----------------------------------------------------------------------------
88 static void target_drag_data_received( GtkWidget
*WXUNUSED(widget
),
89 GdkDragContext
*context
,
92 GtkSelectionData
*data
,
96 printf( "data receive at: %d,%d.\n", x
, y
);
98 if ((data
->length
>= 0) && (data
->format
== 8))
100 wxString str
= (const char*)data
->data
;
101 printf( "Received %s\n.", WXSTRINGCAST str
);
102 gtk_drag_finish( context
, TRUE
, FALSE
, time
);
106 gtk_drag_finish (context
, FALSE
, FALSE
, time
);
109 // ----------------------------------------------------------------------------
111 // ----------------------------------------------------------------------------
113 wxDropTarget::wxDropTarget()
117 wxDropTarget::~wxDropTarget()
121 void wxDropTarget::UnregisterWidget( GtkWidget
*widget
)
123 wxCHECK_RET( widget
!= NULL
, "unregister widget is NULL" );
125 gtk_drag_dest_set( widget
,
127 (GtkTargetEntry
*) NULL
,
131 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
132 GTK_SIGNAL_FUNC(target_drag_leave
), (gpointer
) this );
134 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
135 GTK_SIGNAL_FUNC(target_drag_motion
), (gpointer
) this );
137 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
138 GTK_SIGNAL_FUNC(target_drag_drop
), (gpointer
) this );
140 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
141 GTK_SIGNAL_FUNC(target_drag_data_received
), (gpointer
) this );
144 void wxDropTarget::RegisterWidget( GtkWidget
*widget
)
146 wxCHECK_RET( widget
!= NULL
, "register widget is NULL" );
148 GtkTargetEntry format
;
153 for ( size_t i
= 0; i
< GetFormatCount(); i
++ )
155 wxDataFormat df
= GetFormat( i
);
159 format
.target
= "text/plain";
163 format
.target
= "file:ALL";
171 wxASSERT_MSG( valid
!= 0, "No valid DnD format supported." );
173 gtk_drag_dest_set( widget
,
174 GTK_DEST_DEFAULT_ALL
,
177 (GdkDragAction
)(GDK_ACTION_COPY
| GDK_ACTION_MOVE
) );
179 gtk_signal_connect( GTK_OBJECT(widget
), "drag_leave",
180 GTK_SIGNAL_FUNC(target_drag_leave
), (gpointer
) this );
182 gtk_signal_connect( GTK_OBJECT(widget
), "drag_motion",
183 GTK_SIGNAL_FUNC(target_drag_motion
), (gpointer
) this );
185 gtk_signal_connect( GTK_OBJECT(widget
), "drag_drop",
186 GTK_SIGNAL_FUNC(target_drag_drop
), (gpointer
) this );
188 gtk_signal_connect( GTK_OBJECT(widget
), "drag_data_received",
189 GTK_SIGNAL_FUNC(target_drag_data_received
), (gpointer
) this );
192 // ----------------------------------------------------------------------------
194 // ----------------------------------------------------------------------------
196 bool wxTextDropTarget::OnDrop( long x
, long y
, const void *data
, size_t WXUNUSED(size
) )
198 OnDropText( x
, y
, (const char*)data
);
202 bool wxTextDropTarget::OnDropText( long x
, long y
, const char *psz
)
204 printf( "Got dropped text: %s.\n", psz
);
205 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
209 size_t wxTextDropTarget::GetFormatCount() const
214 wxDataFormat
wxTextDropTarget::GetFormat(size_t WXUNUSED(n
)) const
219 // ----------------------------------------------------------------------------
221 // ----------------------------------------------------------------------------
223 bool wxFileDropTarget::OnDropFiles( long x
, long y
, size_t nFiles
, const char * const aszFiles
[] )
225 printf( "Got %d dropped files.\n", (int)nFiles
);
226 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
227 for (size_t i
= 0; i
< nFiles
; i
++)
229 printf( aszFiles
[i
] );
235 bool wxFileDropTarget::OnDrop(long x
, long y
, const void *data
, size_t size
)
238 char *text
= (char*) data
;
239 for (size_t i
= 0; i
< size
; i
++)
240 if (text
[i
] == 0) number
++;
242 if (number
== 0) return TRUE
;
244 char **files
= new char*[number
];
247 for (size_t i
= 0; i
< number
; i
++)
250 int len
= strlen( text
);
254 bool ret
= OnDropFiles( x
, y
, 1, files
);
261 size_t wxFileDropTarget::GetFormatCount() const
266 wxDataFormat
wxFileDropTarget::GetFormat(size_t WXUNUSED(n
)) const
268 return wxDF_FILENAME
;
271 //-------------------------------------------------------------------------
273 //-------------------------------------------------------------------------
275 wxDropSource::wxDropSource( wxWindow
*win
)
277 g_blockEventsOnDrag
= TRUE
;
280 m_widget
= win
->m_widget
;
281 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
283 m_data
= (wxDataObject
*) NULL
;
284 m_retValue
= wxDragCancel
;
286 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
287 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
290 wxDropSource::wxDropSource( wxDataObject
&data
, wxWindow
*win
)
292 g_blockEventsOnDrag
= TRUE
;
295 m_widget
= win
->m_widget
;
296 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
297 m_retValue
= wxDragCancel
;
301 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
302 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
305 void wxDropSource::SetData( wxDataObject
&data
)
310 wxDropSource::~wxDropSource(void)
312 // if (m_data) delete m_data;
314 g_blockEventsOnDrag
= FALSE
;
317 wxDragResult
wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove
) )
319 wxASSERT_MSG( m_data
, "wxDragSource: no data" );
321 if (!m_data
) return (wxDragResult
) wxDragNone
;
322 if (m_data
->GetDataSize() == 0) return (wxDragResult
) wxDragNone
;
330 g_blockEventsOnDrag
= FALSE
;
335 void wxDropSource::RegisterWindow(void)
341 wxDataFormat df
= m_data
->GetPreferredFormat();
346 formats
+= "text/plain";
349 formats
+= "file:ALL";
355 char *str
= WXSTRINGCAST formats
;
360 void wxDropSource::UnregisterWindow(void)
362 if (!m_widget
) return;
370 GtkWidget
*shape_create_icon (char **data
,
378 static char * gv_xpm
[] = {
390 " .XXXXXXXXXXXXXX. ",
391 " .XXX..XXXX..XXX. ",
392 " ....XX....XX....XX. ",
393 " .XXX.XXX..XXXX..XXX.... ",
394 " .XXXXXXXXXXXXXXXXXXX.XXX. ",
395 " .XXXXXXXXXXXXXXXXXXXXXXXX. ",
396 " .XXXXXXXXXXXXXXXXXXXXXXXX. ",
397 " ..XXXXXXXXXXXXXXXXXXXXXX. ",
398 " .XXXXXXXXXXXXXXXXXX... ",
399 " ..XXXXXXXXXXXXXXXX. ",
400 " .XXXXXXXXXXXXXXXX. ",
401 " .XXXXXXXXXXXXXXXX. ",
402 " .XXXXXXXXXXXXXXXXX. ",
403 " .XXXXXXXXXXXXXXXXX. ",
404 " .XXXXXXXXXXXXXXXXXX. ",
405 " .XXXXXXXXXXXXXXXXXXX. ",
406 " .XXXXXXXXXXXXXXXXXXXXX. ",
407 " .XXXXXXXXXXXXXX.XXXXXXX. ",
408 " .XXXXXXX.XXXXXXX.XXXXXXX. ",
409 " .XXXXXXXX.XXXXXXX.XXXXXXX. ",
410 " .XXXXXXX...XXXXX...XXXXX. ",
411 " .XXXXXXX. ..... ..... ",
419 static char * page_xpm
[] = {
420 /* width height ncolors chars_per_pixel */
429 " ................... ",
430 " .XXXXXXXXXXXXXXXXX.. ",
431 " .XXXXXXXXXXXXXXXXX.o. ",
432 " .XXXXXXXXXXXXXXXXX.oo. ",
433 " .XXXXXXXXXXXXXXXXX.ooo. ",
434 " .XXXXXXXXXXXXXXXXX.oooo. ",
435 " .XXXXXXXXXXXXXXXXX....... ",
436 " .XXXXXOOOOOOOOOOXXXooooo. ",
437 " .XXXXXXXXXXXXXXXXXXooooo. ",
438 " .XXXXXOOOOOOOOOOXXXXXXXX. ",
439 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
440 " .XXXXXXXOOOOOOOOOXXXXXXX. ",
441 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
442 " .XXXXXXOOOOOOOOOOXXXXXXX. ",
443 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
444 " .XXXXXOOOOOOOOOOXXXXXXXX. ",
445 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
446 " .XXXXXXXOOOOOOOOOXXXXXXX. ",
447 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
448 " .XXXXXXOOOOOOOOOOXXXXXXX. ",
449 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
450 " .XXXXXOOOOOOOOOOXXXXXXXX. ",
451 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
452 " .XXXXXXOOOOOOOOOOXXXXXXX. ",
453 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
454 " .XXXXXOOOOOOOXXXXXXXXXXX. ",
455 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
456 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
457 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
458 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
459 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
460 " ......................... "};
463 //-----------------------------------------------------------------------------
464 // "drop_data_available_event"
465 //-----------------------------------------------------------------------------
467 static void gtk_target_callback( GtkWidget
*widget
,
468 GdkEventDropDataAvailable
*event
,
469 wxDropTarget
*target
)
475 gdk_window_get_pointer( widget
->window
, &x
, &y
, (GdkModifierType
*) NULL
);
477 // printf( "Drop data is of type %s.\n", event->data_type );
479 target
->OnDrop( x
, y
, (const void*)event
->data
, (size_t)event
->data_numbytes
);
483 g_free (event->data);
484 g_free (event->data_type);
488 // ----------------------------------------------------------------------------
490 // ----------------------------------------------------------------------------
492 wxDropTarget::wxDropTarget()
496 wxDropTarget::~wxDropTarget()
500 void wxDropTarget::UnregisterWidget( GtkWidget
*widget
)
504 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
505 GTK_SIGNAL_FUNC(gtk_target_callback
), (gpointer
) this );
507 gtk_widget_dnd_drop_set( widget
, FALSE
, (gchar
**) NULL
, 0, FALSE
);
510 void wxDropTarget::RegisterWidget( GtkWidget
*widget
)
515 for ( size_t i
= 0; i
< GetFormatCount(); i
++ )
517 wxDataFormat df
= GetFormat( i
);
521 if (i
> 0) formats
+= ";";
522 formats
+= "text/plain";
526 if (i
> 0) formats
+= ";";
527 formats
+= "file:ALL";
535 char *str
= WXSTRINGCAST formats
;
537 gtk_widget_dnd_drop_set( widget
, TRUE
, &str
, valid
, FALSE
);
539 gtk_signal_connect( GTK_OBJECT(widget
), "drop_data_available_event",
540 GTK_SIGNAL_FUNC(gtk_target_callback
), (gpointer
) this );
543 // ----------------------------------------------------------------------------
545 // ----------------------------------------------------------------------------
547 bool wxTextDropTarget::OnDrop( long x
, long y
, const void *data
, size_t WXUNUSED(size
) )
549 OnDropText( x
, y
, (const char*)data
);
553 bool wxTextDropTarget::OnDropText( long x
, long y
, const char *psz
)
555 printf( "Got dropped text: %s.\n", psz
);
556 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
560 size_t wxTextDropTarget::GetFormatCount() const
565 wxDataFormat
wxTextDropTarget::GetFormat(size_t WXUNUSED(n
)) const
570 // ----------------------------------------------------------------------------
572 // ----------------------------------------------------------------------------
574 bool wxFileDropTarget::OnDropFiles( long x
, long y
, size_t nFiles
, const char * const aszFiles
[] )
576 printf( "Got %d dropped files.\n", (int)nFiles
);
577 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
578 for (size_t i
= 0; i
< nFiles
; i
++)
580 printf( aszFiles
[i
] );
586 bool wxFileDropTarget::OnDrop(long x
, long y
, const void *data
, size_t size
)
589 char *text
= (char*) data
;
590 for (size_t i
= 0; i
< size
; i
++)
591 if (text
[i
] == 0) number
++;
593 if (number
== 0) return TRUE
;
595 char **files
= new char*[number
];
598 for (size_t i
= 0; i
< number
; i
++)
601 int len
= strlen( text
);
605 bool ret
= OnDropFiles( x
, y
, 1, files
);
612 size_t wxFileDropTarget::GetFormatCount() const
617 wxDataFormat
wxFileDropTarget::GetFormat(size_t WXUNUSED(n
)) const
619 return wxDF_FILENAME
;
622 //-------------------------------------------------------------------------
624 //-------------------------------------------------------------------------
627 shape_motion (GtkWidget
*widget
,
628 GdkEventMotion */
*event*/
);
630 //-----------------------------------------------------------------------------
633 void gtk_drag_callback( GtkWidget
*widget
, GdkEvent
*event
, wxDropSource
*source
)
635 wxDataObject
*data
= source
->m_data
;
637 switch (data
->GetFormat())
641 wxTextDataObject
*text_object
= (wxTextDataObject
*) data
;
643 wxString text
= text_object
->GetText();
645 char *s
= WXSTRINGCAST text
;
647 gtk_widget_dnd_data_set( widget
,
650 (int) text
.Length()+1 );
657 wxFileDataObject
*file_object
= (wxFileDataObject
*) data
;
659 wxString text
= file_object
->GetFiles();
661 char *s
= WXSTRINGCAST text
;
663 gtk_widget_dnd_data_set( widget
,
666 (int) text
.Length()+1 );
677 source
->m_retValue
= wxDragCopy
;
680 wxDropSource::wxDropSource( wxWindow
*win
)
682 g_blockEventsOnDrag
= TRUE
;
685 m_widget
= win
->m_widget
;
686 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
688 m_data
= (wxDataObject
*) NULL
;
689 m_retValue
= wxDragCancel
;
691 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
692 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
695 wxDropSource::wxDropSource( wxDataObject
&data
, wxWindow
*win
)
697 g_blockEventsOnDrag
= TRUE
;
700 m_widget
= win
->m_widget
;
701 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
702 m_retValue
= wxDragCancel
;
706 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
707 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
710 void wxDropSource::SetData( wxDataObject
&data
)
715 wxDropSource::~wxDropSource(void)
717 // if (m_data) delete m_data;
719 g_blockEventsOnDrag
= FALSE
;
722 wxDragResult
wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove
) )
724 if (gdk_dnd
.dnd_grabbed
) return (wxDragResult
) wxDragNone
;
725 if (gdk_dnd
.drag_really
) return (wxDragResult
) wxDragNone
;
727 wxASSERT_MSG( m_data
, "wxDragSource: no data" );
729 if (!m_data
) return (wxDragResult
) wxDragNone
;
731 static GtkWidget
*drag_icon
= NULL
;
732 static GtkWidget
*drop_icon
= NULL
;
734 GdkPoint hotspot_1
= {0,-5 };
738 drag_icon
= shape_create_icon ( gv_xpm
,
739 440, 140, 0,0, GTK_WINDOW_POPUP
);
741 gtk_signal_connect (GTK_OBJECT (drag_icon
), "destroy",
742 GTK_SIGNAL_FUNC(gtk_widget_destroyed
),
745 gtk_widget_hide (drag_icon
);
748 GdkPoint hotspot_2
= {-5,-5};
752 drop_icon
= shape_create_icon ( page_xpm
,
753 440, 140, 0,0, GTK_WINDOW_POPUP
);
755 gtk_signal_connect (GTK_OBJECT (drop_icon
), "destroy",
756 GTK_SIGNAL_FUNC(gtk_widget_destroyed
),
759 gtk_widget_hide (drop_icon
);
763 gdk_dnd_set_drag_shape( drag_icon
->window
,
769 GdkWindowPrivate
*wp
= (GdkWindowPrivate
*) m_widget
->window
;
773 gdk_dnd
.drag_perhaps
= TRUE
;
775 gdk_dnd
.dnd_drag_start
.x
= 5;
776 gdk_dnd
.dnd_drag_start
.y
= 5;
777 gdk_dnd
.real_sw
= wp
;
779 if (gdk_dnd
.drag_startwindows
)
781 g_free( gdk_dnd
.drag_startwindows
);
782 gdk_dnd
.drag_startwindows
= (GdkWindow
**) NULL
;
784 gdk_dnd
.drag_numwindows
= gdk_dnd
.drag_really
= 0;
786 XWindowAttributes dnd_winattr
;
787 XGetWindowAttributes( gdk_display
, wp
->xwindow
, &dnd_winattr
);
788 wp
->dnd_drag_savedeventmask
= dnd_winattr
.your_event_mask
;
790 gdk_dnd_drag_addwindow( m_widget
->window
);
792 GdkEventDragBegin ev
;
793 ev
.type
= GDK_DRAG_BEGIN
;
794 ev
.window
= m_widget
->window
;
796 ev
.u
.flags
.protocol_version
= DND_PROTOCOL_VERSION
;
798 gdk_event_put( (GdkEvent
*)&ev
);
800 XGrabPointer( gdk_display
, wp
->xwindow
, False
,
801 ButtonMotionMask
| ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
,
802 GrabModeAsync
, GrabModeAsync
, gdk_root_window
, None
, CurrentTime
);
804 gdk_dnd_set_drag_cursors( m_defaultCursor
.GetCursor(), m_goaheadCursor
.GetCursor() );
806 gdk_dnd
.dnd_grabbed
= TRUE
;
807 gdk_dnd
.drag_really
= 1;
811 wxGetMousePosition( &x
, &y
);
813 gdk_dnd_display_drag_cursor( x
, y
, FALSE
, TRUE
);
816 shape_motion( drag_icon, (GdkEventMotion *)NULL );
817 shape_motion( drop_icon, (GdkEventMotion *)NULL );
820 while (gdk_dnd
.drag_really
|| gdk_dnd
.drag_perhaps
) wxYield();
824 g_blockEventsOnDrag
= FALSE
;
829 void wxDropSource::RegisterWindow(void)
835 wxDataFormat df
= m_data
->GetFormat();
840 formats
+= "text/plain";
843 formats
+= "file:ALL";
849 char *str
= WXSTRINGCAST formats
;
851 gtk_widget_dnd_drag_set( m_widget
, TRUE
, &str
, 1 );
853 gtk_signal_connect( GTK_OBJECT(m_widget
), "drag_request_event",
854 GTK_SIGNAL_FUNC(gtk_drag_callback
), (gpointer
)this );
857 void wxDropSource::UnregisterWindow(void)
859 if (!m_widget
) return;
861 gtk_widget_dnd_drag_set( m_widget
, FALSE
, (gchar
**) NULL
, 0 );
863 gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget
), (gpointer
)this );
870 static GdkWindow
*root_win
= NULL
;
872 typedef struct _cursoroffset
{gint x
,y
;} CursorOffset
;
875 shape_pressed (GtkWidget
*widget
, GdkEventButton
*event
)
879 /* ignore double and triple click */
880 if (event
->type
!= GDK_BUTTON_PRESS
)
883 p
= (CursorOffset
*)gtk_object_get_user_data (GTK_OBJECT(widget
));
884 p
->x
= (int) event
->x
;
885 p
->y
= (int) event
->y
;
887 gtk_grab_add (widget
);
888 gdk_pointer_grab (widget
->window
, TRUE
,
890 (GDK_BUTTON_RELEASE_MASK
|
891 GDK_BUTTON_MOTION_MASK
|
892 GDK_POINTER_MOTION_HINT_MASK
),
898 shape_released (GtkWidget
*widget
)
900 gtk_grab_remove (widget
);
901 gdk_pointer_ungrab (0);
905 shape_motion (GtkWidget
*widget
,
906 GdkEventMotion */
*event*/
)
910 GdkModifierType mask
;
912 p
= (CursorOffset
*)gtk_object_get_user_data (GTK_OBJECT (widget
));
915 * Can't use event->x / event->y here
916 * because I need absolute coordinates.
918 gdk_window_get_pointer (root_win
, &xp
, &yp
, &mask
);
919 gtk_widget_set_uposition (widget
, xp
- p
->x
, yp
- p
->y
);
923 shape_create_icon (char **data
,
933 CursorOffset
* icon_pos
;
935 GdkBitmap
*gdk_pixmap_mask
;
936 GdkPixmap
*gdk_pixmap
;
939 style
= gtk_widget_get_default_style ();
940 gc
= style
->black_gc
;
943 * GDK_WINDOW_TOPLEVEL works also, giving you a title border
945 window
= gtk_window_new ((GtkWindowType
)window_type
);
947 fixed
= gtk_fixed_new ();
948 gtk_widget_set_usize (fixed
, 100,100);
949 gtk_container_add (GTK_CONTAINER (window
), fixed
);
950 gtk_widget_show (fixed
);
952 gtk_widget_set_events (window
,
953 gtk_widget_get_events (window
) |
954 GDK_BUTTON_MOTION_MASK
|
955 GDK_POINTER_MOTION_HINT_MASK
|
956 GDK_BUTTON_PRESS_MASK
);
958 gtk_widget_realize (window
);
960 gdk_pixmap
= gdk_pixmap_create_from_xpm_d (window
->window
, &gdk_pixmap_mask
,
961 &style
->bg
[GTK_STATE_NORMAL
],
964 pixmap
= gtk_pixmap_new (gdk_pixmap
, gdk_pixmap_mask
);
965 gtk_fixed_put (GTK_FIXED (fixed
), pixmap
, px
,py
);
966 gtk_widget_show (pixmap
);
968 gtk_widget_shape_combine_mask (window
, gdk_pixmap_mask
, px
,py
);
971 gtk_signal_connect (GTK_OBJECT (window
), "button_press_event",
972 GTK_SIGNAL_FUNC (shape_pressed
),NULL
);
973 gtk_signal_connect (GTK_OBJECT (window
), "button_release_event",
974 GTK_SIGNAL_FUNC (shape_released
),NULL
);
975 gtk_signal_connect (GTK_OBJECT (window
), "motion_notify_event",
976 GTK_SIGNAL_FUNC (shape_motion
),NULL
);
978 icon_pos
= g_new (CursorOffset
, 1);
979 gtk_object_set_user_data(GTK_OBJECT(window
), icon_pos
);
981 gtk_widget_set_uposition (window
, x
, y
);
982 gtk_widget_show (window
);