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"
20 #include "gdk/gdkprivate.h"
24 // ----------------------------------------------------------------------------
26 // ----------------------------------------------------------------------------
28 extern bool g_blockEventsOnDrag
;
30 #ifdef NEW_GTK_DND_CODE
32 #include "gtk/gtkdnd.h"
33 #include "gtk/gtkselection.h"
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 static void target_drag_leave( GtkWidget
*WXUNUSED(widget
),
40 GdkDragContext
*WXUNUSED(context
),
41 guint
WXUNUSED(time
) )
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 static gboolean
target_drag_motion( GtkWidget
*WXUNUSED(widget
),
51 GdkDragContext
*context
,
56 printf( "motion.\n" );
57 gdk_drag_status( context
, context
->suggested_action
, time
);
61 // ----------------------------------------------------------------------------
63 // ----------------------------------------------------------------------------
65 static gboolean
target_drag_drop( GtkWidget
*widget
,
66 GdkDragContext
*context
,
71 printf( "drop at: %d,%d.\n", x
, y
);
75 gtk_drag_get_data( widget
,
77 GPOINTER_TO_INT (context
->targets
->data
),
83 // ----------------------------------------------------------------------------
84 // "drag_data_received"
85 // ----------------------------------------------------------------------------
87 static void target_drag_data_received( GtkWidget
*WXUNUSED(widget
),
88 GdkDragContext
*context
,
91 GtkSelectionData
*data
,
95 printf( "data receive at: %d,%d.\n", x
, y
);
97 if ((data
->length
>= 0) && (data
->format
== 8))
99 wxString str
= (const char*)data
->data
;
100 printf( "Received %s\n.", WXSTRINGCAST str
);
101 gtk_drag_finish( context
, TRUE
, FALSE
, time
);
105 gtk_drag_finish (context
, FALSE
, FALSE
, time
);
108 // ----------------------------------------------------------------------------
110 // ----------------------------------------------------------------------------
112 wxDropTarget::wxDropTarget()
116 wxDropTarget::~wxDropTarget()
120 void wxDropTarget::UnregisterWidget( GtkWidget
*widget
)
122 wxCHECK_RET( widget
!= NULL
, "unregister widget is NULL" );
124 gtk_drag_dest_set( widget
,
126 (GtkTargetEntry
*) NULL
,
130 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
131 GTK_SIGNAL_FUNC(target_drag_leave
), (gpointer
) this );
133 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
134 GTK_SIGNAL_FUNC(target_drag_motion
), (gpointer
) this );
136 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
137 GTK_SIGNAL_FUNC(target_drag_drop
), (gpointer
) this );
139 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
140 GTK_SIGNAL_FUNC(target_drag_data_received
), (gpointer
) this );
143 void wxDropTarget::RegisterWidget( GtkWidget
*widget
)
145 wxCHECK_RET( widget
!= NULL
, "register widget is NULL" );
147 GtkTargetEntry format
;
152 for ( size_t i
= 0; i
< GetFormatCount(); i
++ )
154 wxDataFormat df
= GetFormat( i
);
158 format
.target
= "text/plain";
162 format
.target
= "file:ALL";
170 wxASSERT_MSG( valid
!= 0, "No valid DnD format supported." );
172 gtk_drag_dest_set( widget
,
173 GTK_DEST_DEFAULT_ALL
,
176 (GdkDragAction
)(GDK_ACTION_COPY
| GDK_ACTION_MOVE
) );
178 gtk_signal_connect( GTK_OBJECT(widget
), "drag_leave",
179 GTK_SIGNAL_FUNC(target_drag_leave
), (gpointer
) this );
181 gtk_signal_connect( GTK_OBJECT(widget
), "drag_motion",
182 GTK_SIGNAL_FUNC(target_drag_motion
), (gpointer
) this );
184 gtk_signal_connect( GTK_OBJECT(widget
), "drag_drop",
185 GTK_SIGNAL_FUNC(target_drag_drop
), (gpointer
) this );
187 gtk_signal_connect( GTK_OBJECT(widget
), "drag_data_received",
188 GTK_SIGNAL_FUNC(target_drag_data_received
), (gpointer
) this );
191 // ----------------------------------------------------------------------------
193 // ----------------------------------------------------------------------------
195 bool wxTextDropTarget::OnDrop( long x
, long y
, const void *data
, size_t WXUNUSED(size
) )
197 OnDropText( x
, y
, (const char*)data
);
201 bool wxTextDropTarget::OnDropText( long x
, long y
, const char *psz
)
203 printf( "Got dropped text: %s.\n", psz
);
204 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
208 size_t wxTextDropTarget::GetFormatCount() const
213 wxDataFormat
wxTextDropTarget::GetFormat(size_t WXUNUSED(n
)) const
218 // ----------------------------------------------------------------------------
220 // ----------------------------------------------------------------------------
222 bool wxFileDropTarget::OnDropFiles( long x
, long y
, size_t nFiles
, const char * const aszFiles
[] )
224 printf( "Got %d dropped files.\n", (int)nFiles
);
225 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
226 for (size_t i
= 0; i
< nFiles
; i
++)
228 printf( aszFiles
[i
] );
234 bool wxFileDropTarget::OnDrop(long x
, long y
, const void *data
, size_t size
)
237 char *text
= (char*) data
;
238 for (size_t i
= 0; i
< size
; i
++)
239 if (text
[i
] == 0) number
++;
241 if (number
== 0) return TRUE
;
243 char **files
= new char*[number
];
246 for (size_t i
= 0; i
< number
; i
++)
249 int len
= strlen( text
);
253 bool ret
= OnDropFiles( x
, y
, 1, files
);
260 size_t wxFileDropTarget::GetFormatCount() const
265 wxDataFormat
wxFileDropTarget::GetFormat(size_t WXUNUSED(n
)) const
267 return wxDF_FILENAME
;
270 //-------------------------------------------------------------------------
272 //-------------------------------------------------------------------------
274 wxDropSource::wxDropSource( wxWindow
*win
)
276 g_blockEventsOnDrag
= TRUE
;
279 m_widget
= win
->m_widget
;
280 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
282 m_data
= (wxDataObject
*) NULL
;
283 m_retValue
= wxDragCancel
;
285 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
286 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
289 wxDropSource::wxDropSource( wxDataObject
&data
, wxWindow
*win
)
291 g_blockEventsOnDrag
= TRUE
;
294 m_widget
= win
->m_widget
;
295 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
296 m_retValue
= wxDragCancel
;
300 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
301 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
304 void wxDropSource::SetData( wxDataObject
&data
)
309 wxDropSource::~wxDropSource(void)
311 // if (m_data) delete m_data;
313 g_blockEventsOnDrag
= FALSE
;
316 wxDragResult
wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove
) )
318 wxASSERT_MSG( m_data
, "wxDragSource: no data" );
320 if (!m_data
) return (wxDragResult
) wxDragNone
;
321 if (m_data
->GetDataSize() == 0) return (wxDragResult
) wxDragNone
;
329 g_blockEventsOnDrag
= FALSE
;
334 void wxDropSource::RegisterWindow(void)
340 wxDataFormat df
= m_data
->GetPreferredFormat();
345 formats
+= "text/plain";
348 formats
+= "file:ALL";
354 char *str
= WXSTRINGCAST formats
;
359 void wxDropSource::UnregisterWindow(void)
361 if (!m_widget
) return;
369 GtkWidget
*shape_create_icon (char **data
,
377 static char * gv_xpm
[] = {
389 " .XXXXXXXXXXXXXX. ",
390 " .XXX..XXXX..XXX. ",
391 " ....XX....XX....XX. ",
392 " .XXX.XXX..XXXX..XXX.... ",
393 " .XXXXXXXXXXXXXXXXXXX.XXX. ",
394 " .XXXXXXXXXXXXXXXXXXXXXXXX. ",
395 " .XXXXXXXXXXXXXXXXXXXXXXXX. ",
396 " ..XXXXXXXXXXXXXXXXXXXXXX. ",
397 " .XXXXXXXXXXXXXXXXXX... ",
398 " ..XXXXXXXXXXXXXXXX. ",
399 " .XXXXXXXXXXXXXXXX. ",
400 " .XXXXXXXXXXXXXXXX. ",
401 " .XXXXXXXXXXXXXXXXX. ",
402 " .XXXXXXXXXXXXXXXXX. ",
403 " .XXXXXXXXXXXXXXXXXX. ",
404 " .XXXXXXXXXXXXXXXXXXX. ",
405 " .XXXXXXXXXXXXXXXXXXXXX. ",
406 " .XXXXXXXXXXXXXX.XXXXXXX. ",
407 " .XXXXXXX.XXXXXXX.XXXXXXX. ",
408 " .XXXXXXXX.XXXXXXX.XXXXXXX. ",
409 " .XXXXXXX...XXXXX...XXXXX. ",
410 " .XXXXXXX. ..... ..... ",
418 static char * page_xpm
[] = {
419 /* width height ncolors chars_per_pixel */
428 " ................... ",
429 " .XXXXXXXXXXXXXXXXX.. ",
430 " .XXXXXXXXXXXXXXXXX.o. ",
431 " .XXXXXXXXXXXXXXXXX.oo. ",
432 " .XXXXXXXXXXXXXXXXX.ooo. ",
433 " .XXXXXXXXXXXXXXXXX.oooo. ",
434 " .XXXXXXXXXXXXXXXXX....... ",
435 " .XXXXXOOOOOOOOOOXXXooooo. ",
436 " .XXXXXXXXXXXXXXXXXXooooo. ",
437 " .XXXXXOOOOOOOOOOXXXXXXXX. ",
438 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
439 " .XXXXXXXOOOOOOOOOXXXXXXX. ",
440 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
441 " .XXXXXXOOOOOOOOOOXXXXXXX. ",
442 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
443 " .XXXXXOOOOOOOOOOXXXXXXXX. ",
444 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
445 " .XXXXXXXOOOOOOOOOXXXXXXX. ",
446 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
447 " .XXXXXXOOOOOOOOOOXXXXXXX. ",
448 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
449 " .XXXXXOOOOOOOOOOXXXXXXXX. ",
450 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
451 " .XXXXXXOOOOOOOOOOXXXXXXX. ",
452 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
453 " .XXXXXOOOOOOOXXXXXXXXXXX. ",
454 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
455 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
456 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
457 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
458 " .XXXXXXXXXXXXXXXXXXXXXXX. ",
459 " ......................... "};
462 //-----------------------------------------------------------------------------
463 // "drop_data_available_event"
464 //-----------------------------------------------------------------------------
466 static void gtk_target_callback( GtkWidget
*widget
,
467 GdkEventDropDataAvailable
*event
,
468 wxDropTarget
*target
)
474 gdk_window_get_pointer( widget
->window
, &x
, &y
, (GdkModifierType
*) NULL
);
476 // printf( "Drop data is of type %s.\n", event->data_type );
478 target
->OnDrop( x
, y
, (const void*)event
->data
, (size_t)event
->data_numbytes
);
482 g_free (event->data);
483 g_free (event->data_type);
487 // ----------------------------------------------------------------------------
489 // ----------------------------------------------------------------------------
491 wxDropTarget::wxDropTarget()
495 wxDropTarget::~wxDropTarget()
499 void wxDropTarget::UnregisterWidget( GtkWidget
*widget
)
503 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
504 GTK_SIGNAL_FUNC(gtk_target_callback
), (gpointer
) this );
506 gtk_widget_dnd_drop_set( widget
, FALSE
, (gchar
**) NULL
, 0, FALSE
);
509 void wxDropTarget::RegisterWidget( GtkWidget
*widget
)
514 for ( size_t i
= 0; i
< GetFormatCount(); i
++ )
516 wxDataFormat df
= GetFormat( i
);
520 if (i
> 0) formats
+= ";";
521 formats
+= "text/plain";
525 if (i
> 0) formats
+= ";";
526 formats
+= "file:ALL";
534 char *str
= WXSTRINGCAST formats
;
536 gtk_widget_dnd_drop_set( widget
, TRUE
, &str
, valid
, FALSE
);
538 gtk_signal_connect( GTK_OBJECT(widget
), "drop_data_available_event",
539 GTK_SIGNAL_FUNC(gtk_target_callback
), (gpointer
) this );
542 // ----------------------------------------------------------------------------
544 // ----------------------------------------------------------------------------
546 bool wxTextDropTarget::OnDrop( long x
, long y
, const void *data
, size_t WXUNUSED(size
) )
548 OnDropText( x
, y
, (const char*)data
);
552 bool wxTextDropTarget::OnDropText( long x
, long y
, const char *psz
)
554 printf( "Got dropped text: %s.\n", psz
);
555 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
559 size_t wxTextDropTarget::GetFormatCount() const
564 wxDataFormat
wxTextDropTarget::GetFormat(size_t WXUNUSED(n
)) const
569 // ----------------------------------------------------------------------------
571 // ----------------------------------------------------------------------------
573 bool wxFileDropTarget::OnDropFiles( long x
, long y
, size_t nFiles
, const char * const aszFiles
[] )
575 printf( "Got %d dropped files.\n", (int)nFiles
);
576 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
577 for (size_t i
= 0; i
< nFiles
; i
++)
579 printf( aszFiles
[i
] );
585 bool wxFileDropTarget::OnDrop(long x
, long y
, const void *data
, size_t size
)
588 char *text
= (char*) data
;
589 for (size_t i
= 0; i
< size
; i
++)
590 if (text
[i
] == 0) number
++;
592 if (number
== 0) return TRUE
;
594 char **files
= new char*[number
];
597 for (size_t i
= 0; i
< number
; i
++)
600 int len
= strlen( text
);
604 bool ret
= OnDropFiles( x
, y
, 1, files
);
611 size_t wxFileDropTarget::GetFormatCount() const
616 wxDataFormat
wxFileDropTarget::GetFormat(size_t WXUNUSED(n
)) const
618 return wxDF_FILENAME
;
621 //-------------------------------------------------------------------------
623 //-------------------------------------------------------------------------
625 //-----------------------------------------------------------------------------
628 void gtk_drag_callback( GtkWidget
*widget
, GdkEvent
*event
, wxDropSource
*source
)
630 wxDataObject
*data
= source
->m_data
;
632 size_t size
= data
->GetDataSize();
633 char *ptr
= new char[size
];
634 data
->GetDataHere( ptr
);
636 gtk_widget_dnd_data_set( widget
, event
, ptr
, size
);
640 source
->m_retValue
= wxDragCopy
;
643 wxDropSource::wxDropSource( wxWindow
*win
)
645 g_blockEventsOnDrag
= TRUE
;
648 m_widget
= win
->m_widget
;
649 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
651 m_data
= (wxDataObject
*) NULL
;
652 m_retValue
= wxDragCancel
;
654 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
655 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
658 wxDropSource::wxDropSource( wxDataObject
&data
, wxWindow
*win
)
660 g_blockEventsOnDrag
= TRUE
;
663 m_widget
= win
->m_widget
;
664 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
665 m_retValue
= wxDragCancel
;
669 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
670 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
673 void wxDropSource::SetData( wxDataObject
&data
)
678 wxDropSource::~wxDropSource(void)
680 // if (m_data) delete m_data;
682 g_blockEventsOnDrag
= FALSE
;
685 wxDragResult
wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove
) )
687 if (gdk_dnd
.dnd_grabbed
) return (wxDragResult
) wxDragNone
;
688 if (gdk_dnd
.drag_really
) return (wxDragResult
) wxDragNone
;
690 wxASSERT_MSG( m_data
, "wxDragSource: no data" );
692 if (!m_data
) return (wxDragResult
) wxDragNone
;
693 if (m_data
->GetDataSize() == 0) return (wxDragResult
) wxDragNone
;
695 static GtkWidget
*drag_icon
= NULL
;
696 static GtkWidget
*drop_icon
= NULL
;
698 GdkPoint hotspot_1
= {0,-5 };
702 drag_icon
= shape_create_icon ( gv_xpm
,
703 440, 140, 0,0, GTK_WINDOW_POPUP
);
705 gtk_signal_connect (GTK_OBJECT (drag_icon
), "destroy",
706 GTK_SIGNAL_FUNC(gtk_widget_destroyed
),
709 gtk_widget_hide (drag_icon
);
712 GdkPoint hotspot_2
= {-5,-5};
716 drop_icon
= shape_create_icon ( page_xpm
,
717 440, 140, 0,0, GTK_WINDOW_POPUP
);
719 gtk_signal_connect (GTK_OBJECT (drop_icon
), "destroy",
720 GTK_SIGNAL_FUNC(gtk_widget_destroyed
),
723 gtk_widget_hide (drop_icon
);
726 gdk_dnd_set_drag_shape(drag_icon
->window
,
732 GdkWindowPrivate
*wp
= (GdkWindowPrivate
*) m_widget
->window
;
736 gdk_dnd
.drag_perhaps
= TRUE
;
738 gdk_dnd
.dnd_drag_start
.x
= 5;
739 gdk_dnd
.dnd_drag_start
.y
= 5;
740 gdk_dnd
.real_sw
= wp
;
742 if (gdk_dnd
.drag_startwindows
)
744 g_free( gdk_dnd
.drag_startwindows
);
745 gdk_dnd
.drag_startwindows
= (GdkWindow
**) NULL
;
747 gdk_dnd
.drag_numwindows
= gdk_dnd
.drag_really
= 0;
749 XWindowAttributes dnd_winattr
;
750 XGetWindowAttributes( gdk_display
, wp
->xwindow
, &dnd_winattr
);
751 wp
->dnd_drag_savedeventmask
= dnd_winattr
.your_event_mask
;
753 gdk_dnd_drag_addwindow( m_widget
->window
);
755 GdkEventDragBegin ev
;
756 ev
.type
= GDK_DRAG_BEGIN
;
757 ev
.window
= m_widget
->window
;
759 ev
.u
.flags
.protocol_version
= DND_PROTOCOL_VERSION
;
761 gdk_event_put( (GdkEvent
*)&ev
);
763 XGrabPointer( gdk_display
, wp
->xwindow
, False
,
764 ButtonMotionMask
| ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
,
765 GrabModeAsync
, GrabModeAsync
, gdk_root_window
, None
, CurrentTime
);
767 gdk_dnd_set_drag_cursors( m_defaultCursor
.GetCursor(), m_goaheadCursor
.GetCursor() );
769 gdk_dnd
.dnd_grabbed
= TRUE
;
770 gdk_dnd
.drag_really
= 1;
774 gdk_window_get_pointer( m_widget
->window
, &x
, &y
, (GdkModifierType
*) NULL
);
776 gdk_dnd_display_drag_cursor( x
, y
, FALSE
, TRUE
);
778 while (gdk_dnd
.drag_really
|| gdk_dnd
.drag_perhaps
) wxYield();
782 g_blockEventsOnDrag
= FALSE
;
787 void wxDropSource::RegisterWindow(void)
793 wxDataFormat df
= m_data
->GetPreferredFormat();
798 formats
+= "text/plain";
801 formats
+= "file:ALL";
807 char *str
= WXSTRINGCAST formats
;
809 gtk_widget_dnd_drag_set( m_widget
, TRUE
, &str
, 1 );
811 gtk_signal_connect( GTK_OBJECT(m_widget
), "drag_request_event",
812 GTK_SIGNAL_FUNC(gtk_drag_callback
), (gpointer
)this );
815 void wxDropSource::UnregisterWindow(void)
817 if (!m_widget
) return;
819 gtk_widget_dnd_drag_set( m_widget
, FALSE
, (gchar
**) NULL
, 0 );
821 gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget
), (gpointer
)this );
828 static GdkWindow
*root_win
= NULL
;
830 typedef struct _cursoroffset
{gint x
,y
;} CursorOffset
;
833 shape_pressed (GtkWidget
*widget
, GdkEventButton
*event
)
837 /* ignore double and triple click */
838 if (event
->type
!= GDK_BUTTON_PRESS
)
841 p
= gtk_object_get_user_data (GTK_OBJECT(widget
));
842 p
->x
= (int) event
->x
;
843 p
->y
= (int) event
->y
;
845 gtk_grab_add (widget
);
846 gdk_pointer_grab (widget
->window
, TRUE
,
847 GDK_BUTTON_RELEASE_MASK
|
848 GDK_BUTTON_MOTION_MASK
|
849 GDK_POINTER_MOTION_HINT_MASK
,
855 shape_released (GtkWidget
*widget
)
857 gtk_grab_remove (widget
);
858 gdk_pointer_ungrab (0);
862 shape_motion (GtkWidget
*widget
,
863 GdkEventMotion
*event
)
867 GdkModifierType mask
;
869 p
= gtk_object_get_user_data (GTK_OBJECT (widget
));
872 * Can't use event->x / event->y here
873 * because I need absolute coordinates.
875 gdk_window_get_pointer (root_win
, &xp
, &yp
, &mask
);
876 gtk_widget_set_uposition (widget
, xp
- p
->x
, yp
- p
->y
);
880 shape_create_icon (char **data
,
890 CursorOffset
* icon_pos
;
892 GdkBitmap
*gdk_pixmap_mask
;
893 GdkPixmap
*gdk_pixmap
;
896 style
= gtk_widget_get_default_style ();
897 gc
= style
->black_gc
;
900 * GDK_WINDOW_TOPLEVEL works also, giving you a title border
902 window
= gtk_window_new (window_type
);
904 fixed
= gtk_fixed_new ();
905 gtk_widget_set_usize (fixed
, 100,100);
906 gtk_container_add (GTK_CONTAINER (window
), fixed
);
907 gtk_widget_show (fixed
);
909 gtk_widget_set_events (window
,
910 gtk_widget_get_events (window
) |
911 GDK_BUTTON_MOTION_MASK
|
912 GDK_POINTER_MOTION_HINT_MASK
|
913 GDK_BUTTON_PRESS_MASK
);
915 gtk_widget_realize (window
);
917 gdk_pixmap
= gdk_pixmap_create_from_xpm_d (window
->window
, &gdk_pixmap_mask
,
918 &style
->bg
[GTK_STATE_NORMAL
],
921 pixmap
= gtk_pixmap_new (gdk_pixmap
, gdk_pixmap_mask
);
922 gtk_fixed_put (GTK_FIXED (fixed
), pixmap
, px
,py
);
923 gtk_widget_show (pixmap
);
925 gtk_widget_shape_combine_mask (window
, gdk_pixmap_mask
, px
,py
);
928 gtk_signal_connect (GTK_OBJECT (window
), "button_press_event",
929 GTK_SIGNAL_FUNC (shape_pressed
),NULL
);
930 gtk_signal_connect (GTK_OBJECT (window
), "button_release_event",
931 GTK_SIGNAL_FUNC (shape_released
),NULL
);
932 gtk_signal_connect (GTK_OBJECT (window
), "motion_notify_event",
933 GTK_SIGNAL_FUNC (shape_motion
),NULL
);
935 icon_pos
= g_new (CursorOffset
, 1);
936 gtk_object_set_user_data(GTK_OBJECT(window
), icon_pos
);
938 gtk_widget_set_uposition (window
, x
, y
);
939 gtk_widget_show (window
);