Added a modular client-message-filter mechanism, that is used for the DND

Sun Oct 18 18:16:39 1998  Owen Taylor  <otaylor@gtk.org>

	* gdk/gdk.c gdkprivate.h: Added a modular client-message-filter
	mechanism, that is used for the DND messages.

	  Removed all the old DND code.

	* gdk/gdkcolormap.c gdk/gdkcolormap.h: Add a function to
	get the visual of a given colormap.

	* gtk/gtkcolorsel.c: Conversion to new DND, drag
	a color-swatch.

	* gdk/gdk.h gdk/gdkdnd.c: The low-level
	X oriented portions of drag and drop protocols.
	Sending and receiving client messages, and navigating
	window trees.

	* gdk/gdkimage.c: added a gdk_flush() when destroying
	SHM images to hopefully make it more likely that
        X will gracefully handle the segment being destroyed.

	* gdk/gdkprivate.h gtk/gtkdebug.h: Add new
	DND debugging flags.

	* gtk/gtkeditable.[ch]: Updates for the selection handling
	changes.

	* gtk/gtkselection.[ch]: Added GtkTargetList, a
	refcounted data structure for keeping track of lists
	of GdkAtom + information. Removed selection_handler_add
	in favor of a "drag_data_get" signal.

	* gtk/gtkdnd.[ch] gtk/gtk.h: New files - highlevel (event loop
	dependent) parts of the DND protocols, display of drag icons,
	drag-under highlighting, and the "default handlers".

	* gtk/gtkinvisible.[ch]: New widget - InputOnly offscreen
	windows that are used for reliable pointer grabs and
	selection handling in the DND code.

	* gtk/testdnd.c: New test program for new DND. (Old
	DND tests in testgtk still need to be converted.)

	* gtk/testselection.c: Use the new selection API.

	* docs/dnd_internals: Start at describing how
	all the new code works inside.

	* docs/Changes-1.2.txt: New file describing source-incompatible
	changes in GTK+-1.2.

Sat Oct 17 22:50:34 1998  Owen Taylor  <otaylor@gtk.org>

	* gdk/gdkwindow.c (gdk_window_remove_filter): Free
	the right list node.

	* gdk/gdkwindow.c (gdk_window_init): Add gdk_root_parent
	to the XID table so we can receive events on it.

Wed Oct 14 12:57:40 1998  Owen Taylor  <otaylor@redhat.com>

	* gdk/gdk.c gdk/gdk.h (gdk_event_get_time): New function
	to get the timestamp from a generic event.

Fri Oct  9 13:16:04 1998  Owen Taylor  <otaylor@redhat.com>

	* gtk/gtkwidget.c (gtk_widget_add_events): Added function
	that safely adds additional events to a widget's event
	mask, even if the widget has previously been realized.
	(We can do this, but not remove events from the event
	 mask).

Fri Oct  2 17:35:35 1998  Owen Taylor  <otaylor@redhat.com>

	* gdk/gdkproperty.c (gdk_property_get): Allow type == 0,
	for AnyPropertyType.

Fri Oct  2 10:32:21 1998  Owen Taylor  <otaylor@redhat.com>

	* gdk/gdkproperty.c (gdk_atom_intern): Add client-local
	hashing.

Thu Sep 24 20:33:54 1998  Owen Taylor  <otaylor@redhat.com>

	* gdk/gdk.c (gdk_event_send_clientmessage_toall): serial
	isn't a timestamp.

Thu Sep 17 14:23:03 1998  Owen Taylor  <otaylor@redhat.com>

	* gdk/gdk.c (gdk_event_translate): Removed printing
	of unknown window lookup warnings. (Made it
	a GDK_NOTE) - they happen in many circumstances.
This commit is contained in:
Owen Taylor 1998-10-18 22:51:24 +00:00 committed by Owen Taylor
parent 7dbb5755a4
commit f7bcb45607
47 changed files with 10781 additions and 3004 deletions

111
ChangeLog
View File

@ -1,3 +1,114 @@
Sun Oct 18 18:16:39 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdk.c gdkprivate.h: Added a modular client-message-filter
mechanism, that is used for the DND messages.
Removed all the old DND code.
* gdk/gdkcolormap.c gdk/gdkcolormap.h: Add a function to
get the visual of a given colormap.
* gtk/gtkcolorsel.c: Conversion to new DND, drag
a color-swatch.
* gdk/gdk.h gdk/gdkdnd.c: The low-level
X oriented portions of drag and drop protocols.
Sending and receiving client messages, and navigating
window trees.
* gdk/gdkimage.c: added a gdk_flush() when destroying
SHM images to hopefully make it more likely that
X will gracefully handle the segment being destroyed.
* gdk/gdkprivate.h gtk/gtkdebug.h: Add new
DND debugging flags.
* gtk/gtkeditable.[ch]: Updates for the selection handling
changes.
* gtk/gtkselection.[ch]: Added GtkTargetList, a
refcounted data structure for keeping track of lists
of GdkAtom + information. Removed selection_handler_add
in favor of a "drag_data_get" signal.
* gtk/gtkdnd.[ch] gtk/gtk.h: New files - highlevel (event loop
dependent) parts of the DND protocols, display of drag icons,
drag-under highlighting, and the "default handlers".
* gtk/gtkinvisible.[ch]: New widget - InputOnly offscreen
windows that are used for reliable pointer grabs and
selection handling in the DND code.
* gtk/testdnd.c: New test program for new DND. (Old
DND tests in testgtk still need to be converted.)
* gtk/testselection.c: Use the new selection API.
* docs/dnd_internals: Start at describing how
all the new code works inside.
* docs/Changes-1.2.txt: New file describing source-incompatible
changes in GTK+-1.2.
Sat Oct 17 22:50:34 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdkwindow.c (gdk_window_remove_filter): Free
the right list node.
* gdk/gdkwindow.c (gdk_window_init): Add gdk_root_parent
to the XID table so we can receive events on it.
Wed Oct 14 12:57:40 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c gdk/gdk.h (gdk_event_get_time): New function
to get the timestamp from a generic event.
Fri Oct 9 13:16:04 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_add_events): Added function
that safely adds additional events to a widget's event
mask, even if the widget has previously been realized.
(We can do this, but not remove events from the event
mask).
Fri Oct 2 17:35:35 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_property_get): Allow type == 0,
for AnyPropertyType.
Fri Oct 2 10:32:21 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_atom_intern): Add client-local
hashing.
Thu Sep 24 20:33:54 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_send_clientmessage_toall): serial
isn't a timestamp.
Thu Sep 17 14:23:03 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_translate): Removed printing
of unknown window lookup warnings. (Made it
a GDK_NOTE) - they happen in many circumstances.
Tue Sep 8 12:38:43 1998 Owen Taylor <otaylor@redhat.com>
* Call XFilterEvent() on events we get for unknown
windows, since it may be the window Xlib uses to
communicate with the IM.
(From Yung-Ching Hsiao <yhsiao@cae.wisc.edu>)
Tue Sep 1 10:53:52 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkprogress.c (gtk_progress_finalize): Unref
the adjustment.
Thu Aug 27 12:03:14 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtksignal.c (gtk_signal_newv): Improve warning
message for return_value + GTK_RUN_FIRST.
1998-10-18 Martin Baulig <martin@home-of-linux.org>
* gtk/gtktext.c (gtk_text_set_line_wrap): new function to toggle

View File

@ -1,3 +1,114 @@
Sun Oct 18 18:16:39 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdk.c gdkprivate.h: Added a modular client-message-filter
mechanism, that is used for the DND messages.
Removed all the old DND code.
* gdk/gdkcolormap.c gdk/gdkcolormap.h: Add a function to
get the visual of a given colormap.
* gtk/gtkcolorsel.c: Conversion to new DND, drag
a color-swatch.
* gdk/gdk.h gdk/gdkdnd.c: The low-level
X oriented portions of drag and drop protocols.
Sending and receiving client messages, and navigating
window trees.
* gdk/gdkimage.c: added a gdk_flush() when destroying
SHM images to hopefully make it more likely that
X will gracefully handle the segment being destroyed.
* gdk/gdkprivate.h gtk/gtkdebug.h: Add new
DND debugging flags.
* gtk/gtkeditable.[ch]: Updates for the selection handling
changes.
* gtk/gtkselection.[ch]: Added GtkTargetList, a
refcounted data structure for keeping track of lists
of GdkAtom + information. Removed selection_handler_add
in favor of a "drag_data_get" signal.
* gtk/gtkdnd.[ch] gtk/gtk.h: New files - highlevel (event loop
dependent) parts of the DND protocols, display of drag icons,
drag-under highlighting, and the "default handlers".
* gtk/gtkinvisible.[ch]: New widget - InputOnly offscreen
windows that are used for reliable pointer grabs and
selection handling in the DND code.
* gtk/testdnd.c: New test program for new DND. (Old
DND tests in testgtk still need to be converted.)
* gtk/testselection.c: Use the new selection API.
* docs/dnd_internals: Start at describing how
all the new code works inside.
* docs/Changes-1.2.txt: New file describing source-incompatible
changes in GTK+-1.2.
Sat Oct 17 22:50:34 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdkwindow.c (gdk_window_remove_filter): Free
the right list node.
* gdk/gdkwindow.c (gdk_window_init): Add gdk_root_parent
to the XID table so we can receive events on it.
Wed Oct 14 12:57:40 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c gdk/gdk.h (gdk_event_get_time): New function
to get the timestamp from a generic event.
Fri Oct 9 13:16:04 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_add_events): Added function
that safely adds additional events to a widget's event
mask, even if the widget has previously been realized.
(We can do this, but not remove events from the event
mask).
Fri Oct 2 17:35:35 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_property_get): Allow type == 0,
for AnyPropertyType.
Fri Oct 2 10:32:21 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_atom_intern): Add client-local
hashing.
Thu Sep 24 20:33:54 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_send_clientmessage_toall): serial
isn't a timestamp.
Thu Sep 17 14:23:03 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_translate): Removed printing
of unknown window lookup warnings. (Made it
a GDK_NOTE) - they happen in many circumstances.
Tue Sep 8 12:38:43 1998 Owen Taylor <otaylor@redhat.com>
* Call XFilterEvent() on events we get for unknown
windows, since it may be the window Xlib uses to
communicate with the IM.
(From Yung-Ching Hsiao <yhsiao@cae.wisc.edu>)
Tue Sep 1 10:53:52 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkprogress.c (gtk_progress_finalize): Unref
the adjustment.
Thu Aug 27 12:03:14 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtksignal.c (gtk_signal_newv): Improve warning
message for return_value + GTK_RUN_FIRST.
1998-10-18 Martin Baulig <martin@home-of-linux.org>
* gtk/gtktext.c (gtk_text_set_line_wrap): new function to toggle

View File

@ -1,3 +1,114 @@
Sun Oct 18 18:16:39 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdk.c gdkprivate.h: Added a modular client-message-filter
mechanism, that is used for the DND messages.
Removed all the old DND code.
* gdk/gdkcolormap.c gdk/gdkcolormap.h: Add a function to
get the visual of a given colormap.
* gtk/gtkcolorsel.c: Conversion to new DND, drag
a color-swatch.
* gdk/gdk.h gdk/gdkdnd.c: The low-level
X oriented portions of drag and drop protocols.
Sending and receiving client messages, and navigating
window trees.
* gdk/gdkimage.c: added a gdk_flush() when destroying
SHM images to hopefully make it more likely that
X will gracefully handle the segment being destroyed.
* gdk/gdkprivate.h gtk/gtkdebug.h: Add new
DND debugging flags.
* gtk/gtkeditable.[ch]: Updates for the selection handling
changes.
* gtk/gtkselection.[ch]: Added GtkTargetList, a
refcounted data structure for keeping track of lists
of GdkAtom + information. Removed selection_handler_add
in favor of a "drag_data_get" signal.
* gtk/gtkdnd.[ch] gtk/gtk.h: New files - highlevel (event loop
dependent) parts of the DND protocols, display of drag icons,
drag-under highlighting, and the "default handlers".
* gtk/gtkinvisible.[ch]: New widget - InputOnly offscreen
windows that are used for reliable pointer grabs and
selection handling in the DND code.
* gtk/testdnd.c: New test program for new DND. (Old
DND tests in testgtk still need to be converted.)
* gtk/testselection.c: Use the new selection API.
* docs/dnd_internals: Start at describing how
all the new code works inside.
* docs/Changes-1.2.txt: New file describing source-incompatible
changes in GTK+-1.2.
Sat Oct 17 22:50:34 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdkwindow.c (gdk_window_remove_filter): Free
the right list node.
* gdk/gdkwindow.c (gdk_window_init): Add gdk_root_parent
to the XID table so we can receive events on it.
Wed Oct 14 12:57:40 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c gdk/gdk.h (gdk_event_get_time): New function
to get the timestamp from a generic event.
Fri Oct 9 13:16:04 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_add_events): Added function
that safely adds additional events to a widget's event
mask, even if the widget has previously been realized.
(We can do this, but not remove events from the event
mask).
Fri Oct 2 17:35:35 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_property_get): Allow type == 0,
for AnyPropertyType.
Fri Oct 2 10:32:21 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_atom_intern): Add client-local
hashing.
Thu Sep 24 20:33:54 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_send_clientmessage_toall): serial
isn't a timestamp.
Thu Sep 17 14:23:03 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_translate): Removed printing
of unknown window lookup warnings. (Made it
a GDK_NOTE) - they happen in many circumstances.
Tue Sep 8 12:38:43 1998 Owen Taylor <otaylor@redhat.com>
* Call XFilterEvent() on events we get for unknown
windows, since it may be the window Xlib uses to
communicate with the IM.
(From Yung-Ching Hsiao <yhsiao@cae.wisc.edu>)
Tue Sep 1 10:53:52 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkprogress.c (gtk_progress_finalize): Unref
the adjustment.
Thu Aug 27 12:03:14 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtksignal.c (gtk_signal_newv): Improve warning
message for return_value + GTK_RUN_FIRST.
1998-10-18 Martin Baulig <martin@home-of-linux.org>
* gtk/gtktext.c (gtk_text_set_line_wrap): new function to toggle

View File

@ -1,3 +1,114 @@
Sun Oct 18 18:16:39 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdk.c gdkprivate.h: Added a modular client-message-filter
mechanism, that is used for the DND messages.
Removed all the old DND code.
* gdk/gdkcolormap.c gdk/gdkcolormap.h: Add a function to
get the visual of a given colormap.
* gtk/gtkcolorsel.c: Conversion to new DND, drag
a color-swatch.
* gdk/gdk.h gdk/gdkdnd.c: The low-level
X oriented portions of drag and drop protocols.
Sending and receiving client messages, and navigating
window trees.
* gdk/gdkimage.c: added a gdk_flush() when destroying
SHM images to hopefully make it more likely that
X will gracefully handle the segment being destroyed.
* gdk/gdkprivate.h gtk/gtkdebug.h: Add new
DND debugging flags.
* gtk/gtkeditable.[ch]: Updates for the selection handling
changes.
* gtk/gtkselection.[ch]: Added GtkTargetList, a
refcounted data structure for keeping track of lists
of GdkAtom + information. Removed selection_handler_add
in favor of a "drag_data_get" signal.
* gtk/gtkdnd.[ch] gtk/gtk.h: New files - highlevel (event loop
dependent) parts of the DND protocols, display of drag icons,
drag-under highlighting, and the "default handlers".
* gtk/gtkinvisible.[ch]: New widget - InputOnly offscreen
windows that are used for reliable pointer grabs and
selection handling in the DND code.
* gtk/testdnd.c: New test program for new DND. (Old
DND tests in testgtk still need to be converted.)
* gtk/testselection.c: Use the new selection API.
* docs/dnd_internals: Start at describing how
all the new code works inside.
* docs/Changes-1.2.txt: New file describing source-incompatible
changes in GTK+-1.2.
Sat Oct 17 22:50:34 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdkwindow.c (gdk_window_remove_filter): Free
the right list node.
* gdk/gdkwindow.c (gdk_window_init): Add gdk_root_parent
to the XID table so we can receive events on it.
Wed Oct 14 12:57:40 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c gdk/gdk.h (gdk_event_get_time): New function
to get the timestamp from a generic event.
Fri Oct 9 13:16:04 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_add_events): Added function
that safely adds additional events to a widget's event
mask, even if the widget has previously been realized.
(We can do this, but not remove events from the event
mask).
Fri Oct 2 17:35:35 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_property_get): Allow type == 0,
for AnyPropertyType.
Fri Oct 2 10:32:21 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_atom_intern): Add client-local
hashing.
Thu Sep 24 20:33:54 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_send_clientmessage_toall): serial
isn't a timestamp.
Thu Sep 17 14:23:03 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_translate): Removed printing
of unknown window lookup warnings. (Made it
a GDK_NOTE) - they happen in many circumstances.
Tue Sep 8 12:38:43 1998 Owen Taylor <otaylor@redhat.com>
* Call XFilterEvent() on events we get for unknown
windows, since it may be the window Xlib uses to
communicate with the IM.
(From Yung-Ching Hsiao <yhsiao@cae.wisc.edu>)
Tue Sep 1 10:53:52 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkprogress.c (gtk_progress_finalize): Unref
the adjustment.
Thu Aug 27 12:03:14 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtksignal.c (gtk_signal_newv): Improve warning
message for return_value + GTK_RUN_FIRST.
1998-10-18 Martin Baulig <martin@home-of-linux.org>
* gtk/gtktext.c (gtk_text_set_line_wrap): new function to toggle

View File

@ -1,3 +1,114 @@
Sun Oct 18 18:16:39 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdk.c gdkprivate.h: Added a modular client-message-filter
mechanism, that is used for the DND messages.
Removed all the old DND code.
* gdk/gdkcolormap.c gdk/gdkcolormap.h: Add a function to
get the visual of a given colormap.
* gtk/gtkcolorsel.c: Conversion to new DND, drag
a color-swatch.
* gdk/gdk.h gdk/gdkdnd.c: The low-level
X oriented portions of drag and drop protocols.
Sending and receiving client messages, and navigating
window trees.
* gdk/gdkimage.c: added a gdk_flush() when destroying
SHM images to hopefully make it more likely that
X will gracefully handle the segment being destroyed.
* gdk/gdkprivate.h gtk/gtkdebug.h: Add new
DND debugging flags.
* gtk/gtkeditable.[ch]: Updates for the selection handling
changes.
* gtk/gtkselection.[ch]: Added GtkTargetList, a
refcounted data structure for keeping track of lists
of GdkAtom + information. Removed selection_handler_add
in favor of a "drag_data_get" signal.
* gtk/gtkdnd.[ch] gtk/gtk.h: New files - highlevel (event loop
dependent) parts of the DND protocols, display of drag icons,
drag-under highlighting, and the "default handlers".
* gtk/gtkinvisible.[ch]: New widget - InputOnly offscreen
windows that are used for reliable pointer grabs and
selection handling in the DND code.
* gtk/testdnd.c: New test program for new DND. (Old
DND tests in testgtk still need to be converted.)
* gtk/testselection.c: Use the new selection API.
* docs/dnd_internals: Start at describing how
all the new code works inside.
* docs/Changes-1.2.txt: New file describing source-incompatible
changes in GTK+-1.2.
Sat Oct 17 22:50:34 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdkwindow.c (gdk_window_remove_filter): Free
the right list node.
* gdk/gdkwindow.c (gdk_window_init): Add gdk_root_parent
to the XID table so we can receive events on it.
Wed Oct 14 12:57:40 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c gdk/gdk.h (gdk_event_get_time): New function
to get the timestamp from a generic event.
Fri Oct 9 13:16:04 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_add_events): Added function
that safely adds additional events to a widget's event
mask, even if the widget has previously been realized.
(We can do this, but not remove events from the event
mask).
Fri Oct 2 17:35:35 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_property_get): Allow type == 0,
for AnyPropertyType.
Fri Oct 2 10:32:21 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_atom_intern): Add client-local
hashing.
Thu Sep 24 20:33:54 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_send_clientmessage_toall): serial
isn't a timestamp.
Thu Sep 17 14:23:03 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_translate): Removed printing
of unknown window lookup warnings. (Made it
a GDK_NOTE) - they happen in many circumstances.
Tue Sep 8 12:38:43 1998 Owen Taylor <otaylor@redhat.com>
* Call XFilterEvent() on events we get for unknown
windows, since it may be the window Xlib uses to
communicate with the IM.
(From Yung-Ching Hsiao <yhsiao@cae.wisc.edu>)
Tue Sep 1 10:53:52 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkprogress.c (gtk_progress_finalize): Unref
the adjustment.
Thu Aug 27 12:03:14 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtksignal.c (gtk_signal_newv): Improve warning
message for return_value + GTK_RUN_FIRST.
1998-10-18 Martin Baulig <martin@home-of-linux.org>
* gtk/gtktext.c (gtk_text_set_line_wrap): new function to toggle

View File

@ -1,3 +1,114 @@
Sun Oct 18 18:16:39 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdk.c gdkprivate.h: Added a modular client-message-filter
mechanism, that is used for the DND messages.
Removed all the old DND code.
* gdk/gdkcolormap.c gdk/gdkcolormap.h: Add a function to
get the visual of a given colormap.
* gtk/gtkcolorsel.c: Conversion to new DND, drag
a color-swatch.
* gdk/gdk.h gdk/gdkdnd.c: The low-level
X oriented portions of drag and drop protocols.
Sending and receiving client messages, and navigating
window trees.
* gdk/gdkimage.c: added a gdk_flush() when destroying
SHM images to hopefully make it more likely that
X will gracefully handle the segment being destroyed.
* gdk/gdkprivate.h gtk/gtkdebug.h: Add new
DND debugging flags.
* gtk/gtkeditable.[ch]: Updates for the selection handling
changes.
* gtk/gtkselection.[ch]: Added GtkTargetList, a
refcounted data structure for keeping track of lists
of GdkAtom + information. Removed selection_handler_add
in favor of a "drag_data_get" signal.
* gtk/gtkdnd.[ch] gtk/gtk.h: New files - highlevel (event loop
dependent) parts of the DND protocols, display of drag icons,
drag-under highlighting, and the "default handlers".
* gtk/gtkinvisible.[ch]: New widget - InputOnly offscreen
windows that are used for reliable pointer grabs and
selection handling in the DND code.
* gtk/testdnd.c: New test program for new DND. (Old
DND tests in testgtk still need to be converted.)
* gtk/testselection.c: Use the new selection API.
* docs/dnd_internals: Start at describing how
all the new code works inside.
* docs/Changes-1.2.txt: New file describing source-incompatible
changes in GTK+-1.2.
Sat Oct 17 22:50:34 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdkwindow.c (gdk_window_remove_filter): Free
the right list node.
* gdk/gdkwindow.c (gdk_window_init): Add gdk_root_parent
to the XID table so we can receive events on it.
Wed Oct 14 12:57:40 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c gdk/gdk.h (gdk_event_get_time): New function
to get the timestamp from a generic event.
Fri Oct 9 13:16:04 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_add_events): Added function
that safely adds additional events to a widget's event
mask, even if the widget has previously been realized.
(We can do this, but not remove events from the event
mask).
Fri Oct 2 17:35:35 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_property_get): Allow type == 0,
for AnyPropertyType.
Fri Oct 2 10:32:21 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_atom_intern): Add client-local
hashing.
Thu Sep 24 20:33:54 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_send_clientmessage_toall): serial
isn't a timestamp.
Thu Sep 17 14:23:03 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_translate): Removed printing
of unknown window lookup warnings. (Made it
a GDK_NOTE) - they happen in many circumstances.
Tue Sep 8 12:38:43 1998 Owen Taylor <otaylor@redhat.com>
* Call XFilterEvent() on events we get for unknown
windows, since it may be the window Xlib uses to
communicate with the IM.
(From Yung-Ching Hsiao <yhsiao@cae.wisc.edu>)
Tue Sep 1 10:53:52 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkprogress.c (gtk_progress_finalize): Unref
the adjustment.
Thu Aug 27 12:03:14 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtksignal.c (gtk_signal_newv): Improve warning
message for return_value + GTK_RUN_FIRST.
1998-10-18 Martin Baulig <martin@home-of-linux.org>
* gtk/gtktext.c (gtk_text_set_line_wrap): new function to toggle

View File

@ -1,3 +1,114 @@
Sun Oct 18 18:16:39 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdk.c gdkprivate.h: Added a modular client-message-filter
mechanism, that is used for the DND messages.
Removed all the old DND code.
* gdk/gdkcolormap.c gdk/gdkcolormap.h: Add a function to
get the visual of a given colormap.
* gtk/gtkcolorsel.c: Conversion to new DND, drag
a color-swatch.
* gdk/gdk.h gdk/gdkdnd.c: The low-level
X oriented portions of drag and drop protocols.
Sending and receiving client messages, and navigating
window trees.
* gdk/gdkimage.c: added a gdk_flush() when destroying
SHM images to hopefully make it more likely that
X will gracefully handle the segment being destroyed.
* gdk/gdkprivate.h gtk/gtkdebug.h: Add new
DND debugging flags.
* gtk/gtkeditable.[ch]: Updates for the selection handling
changes.
* gtk/gtkselection.[ch]: Added GtkTargetList, a
refcounted data structure for keeping track of lists
of GdkAtom + information. Removed selection_handler_add
in favor of a "drag_data_get" signal.
* gtk/gtkdnd.[ch] gtk/gtk.h: New files - highlevel (event loop
dependent) parts of the DND protocols, display of drag icons,
drag-under highlighting, and the "default handlers".
* gtk/gtkinvisible.[ch]: New widget - InputOnly offscreen
windows that are used for reliable pointer grabs and
selection handling in the DND code.
* gtk/testdnd.c: New test program for new DND. (Old
DND tests in testgtk still need to be converted.)
* gtk/testselection.c: Use the new selection API.
* docs/dnd_internals: Start at describing how
all the new code works inside.
* docs/Changes-1.2.txt: New file describing source-incompatible
changes in GTK+-1.2.
Sat Oct 17 22:50:34 1998 Owen Taylor <otaylor@gtk.org>
* gdk/gdkwindow.c (gdk_window_remove_filter): Free
the right list node.
* gdk/gdkwindow.c (gdk_window_init): Add gdk_root_parent
to the XID table so we can receive events on it.
Wed Oct 14 12:57:40 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c gdk/gdk.h (gdk_event_get_time): New function
to get the timestamp from a generic event.
Fri Oct 9 13:16:04 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_add_events): Added function
that safely adds additional events to a widget's event
mask, even if the widget has previously been realized.
(We can do this, but not remove events from the event
mask).
Fri Oct 2 17:35:35 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_property_get): Allow type == 0,
for AnyPropertyType.
Fri Oct 2 10:32:21 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdkproperty.c (gdk_atom_intern): Add client-local
hashing.
Thu Sep 24 20:33:54 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_send_clientmessage_toall): serial
isn't a timestamp.
Thu Sep 17 14:23:03 1998 Owen Taylor <otaylor@redhat.com>
* gdk/gdk.c (gdk_event_translate): Removed printing
of unknown window lookup warnings. (Made it
a GDK_NOTE) - they happen in many circumstances.
Tue Sep 8 12:38:43 1998 Owen Taylor <otaylor@redhat.com>
* Call XFilterEvent() on events we get for unknown
windows, since it may be the window Xlib uses to
communicate with the IM.
(From Yung-Ching Hsiao <yhsiao@cae.wisc.edu>)
Tue Sep 1 10:53:52 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkprogress.c (gtk_progress_finalize): Unref
the adjustment.
Thu Aug 27 12:03:14 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtksignal.c (gtk_signal_newv): Improve warning
message for return_value + GTK_RUN_FIRST.
1998-10-18 Martin Baulig <martin@home-of-linux.org>
* gtk/gtktext.c (gtk_text_set_line_wrap): new function to toggle

18
TODO
View File

@ -297,3 +297,21 @@ Calendar Widget:
- The keyboard support has to be finished.
DND
===
- Use a cursor instead of an ICON when over Motif windows,
to get rid of the current junk that Motif leaves because
of it's XCopyArea stupidity for doing highlighting.
- Add a GTK_DRAG_VERIFY target flag and a "drag_data_verify"
signal so that apps can easily check if a, say,
text/uri-list URL looks OK during the drop.
- Check more for memory leaks.
- Drag and drop for Entry and Text widgets.
- Send synthetic motion events on structure changes so
drag_enter/leave get sent properly. (See the popup
in testdnd)

49
docs/Changes-1.2.txt Normal file
View File

@ -0,0 +1,49 @@
Incompatible Changes from GTK+-1.0 to GTK+-1.2:
* GtkAcceleratorTable has been replaced with GtkAccelGroup
* GtkMenuFactory has been replaced with GtkItemFactory, although
a version of GtkMenuFactory is provided to ease compatibility.
* GtkButton has been changed to derive from GtkBin.
To access a button's child, use GTK_BIN (button)->child, instead
of the old GTK_BUTTON (button)->child.
* The selection API has been slightly modified:
gtk_selection_add_handler() and gtk_selection_add_handler_full()
have been removed. To supply the selection, one now register
the targets one is interested in with:
void gtk_selection_add_target (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,
guint info);
or:
void gtk_selection_add_targets (GtkWidget *widget,
GdkAtom selection,
GtkTargetEntry *targets,
guint ntargets);
When a request for a selection is received, the new "selection_get"
signal will be called:
void "selection_get" (GtkWidget *widget,
GtkSelectionData *selection_data,
guint info,
guint time);
A "time" parameter has also been added to the "selection_received"
signal.
void "selection_received" (GtkWidget *widget,
GtkSelectionData *selection_data,
guint time);
* The old drag and drop API has been completely removed and replaced.
See the reference documentation for details on the new API.

210
docs/dnd_internals.txt Normal file
View File

@ -0,0 +1,210 @@
This document describes some of the internals of the DND handling
code.
Organization
============
The DND code is split between a lowlevel part - gdkdnd.c and a
highlevel part - gtkdnd.c. To put it simply, gdkdnd.c contain the
portions of DND code that are easiest to do in raw X, while gtkdnd.c
contains the portions of DND that are easiest to do with an event loop
and high level selection handling.
Except for a few details of selection handling, most of the
dependencies on the DND protocol are confined to gdkdnd.c.
There are two or three supported protocols - Motif DND,
Xdnd and a pseudo-protocol ROOTWIN, which is used for drops
on root windows that aren't really accepting drops.
gdkdnd.c divides into 4 pieces:
1) Utility functions (finding client windows)
2) Motif specific code (the biggest chunk)
3) Xdnd specific code
4) The public interfaces
The code in gtkdnd.c roughly consists of three parts
1) General utility functions
2) Destination side code
3) Source side code.
Both on the source and dest side, there is some division
between the low level layers and the default handlers,
though they are rather mixed in many cases.
Structures and Memory Management
================================
Information about source sites and drop sites is stored
in the structures GtkSourceSite and GtkDestSite.
Information about in-progress drags and drops is stored
in the structures GtkSourceInfo and GtkDestInfo.
The GtkSourceInfo structure is created when the drag
begins, and persists until the drag either completes
or times out. A pointer to it is stored in
dataset-data for the GdkDragContext, however there
is no ownership. If the SourceInfo is destroyed
before the context, the field is simply cleared.
A GtkDestInfo is attached to each GdkDragContext
that is received for an incoming drag. In contrast
to the SourceInfo the DestInfo is "owned" by the
context, and when the context is destroyed, destroyed.
The GDK API
===========
It is expect that the GDK DND API will never be
used by anything other than the DND code in GTK+.
/* Drag and Drop */
GdkDragContext * gdk_drag_context_new (void);
void gdk_drag_context_ref (GdkDragContext *context);
void gdk_drag_context_unref (GdkDragContext *context);
These create and refcount GdkDragContexts in a
straightforward manner.
/* Destination side */
void gdk_drag_status (GdkDragContext *context,
GdkDragAction action,
guint32 time);
void gdk_drop_reply (GdkDragContext *context,
gboolean ok,
guint32 time);
void gdk_drop_finish (GdkDragContext *context,
gboolean success,
guint32 time);
GdkAtom gdk_drag_get_selection (GdkDragContext *context);
/* Source side */
GdkDragContext * gdk_drag_begin (GdkWindow *window,
GList *targets,
GdkDragAction actions);
gboolean gdk_drag_get_protocol (guint32 xid,
GdkDragProtocol *protocol);
void gdk_drag_find_window (GdkDragContext *context,
GdkWindow *drag_window,
gint x_root,
gint y_root,
GdkWindow **dest_window,
GdkDragProtocol *protocol);
gboolean gdk_drag_motion (GdkDragContext *context,
GdkWindow *dest_window,
GdkDragProtocol protocol,
gint x_root,
gint y_root,
GdkDragAction action,
guint32 time);
void gdk_drag_drop (GdkDragContext *context,
guint32 time);
void gdk_drag_abort (GdkDragContext *context,
guint32 time);
GdkAtom gdk_drag_get_selection (GdkDragContext *context);
Retrieves the selection that will be used to communicate
the data for the drag context (valid on both source
and dest sides)
Cursors and window heirarchies
==============================
The DND code, when possible (and it isn't possible over
Motif window) uses a shaped window as a drag icon.
Because the cursor may fall inside this window during the
drag, we actually have to figure out which window
the cursor is in _ourselves_ so we can ignore the
drag icon properly. (Oh for OutputOnly windows!)
To avoid obscene amounts of server traffic (which are only
slighly observerable locally, but would really kill a
session over a slow link), the code in GDK does
XGetWindowAttributes for every child of the root window at
the beginning of the drag, then selects with
SubstructureNotifyMask on the root window, so that
it can update this list.
It probably would be easier to just reread the entire
list when one of these events occurs, instead of
incrementally updating, but updating the list in
sync was sort of fun code, so I did it that way ;-)
There is also a problem of trying to follow the
mouse cursor as well as possible. Currently, the
code uses PointerMotionHint, and an XQueryPointer
on MotionNotify events. This results in pretty
good syncing, but may result in somewhat poor
accuracy for drops. (Because the coordinates of
the drop are the coordinates when the server receives
the button press, which might actually be before
the XQueryPointer for the previous MotionNotify
event is done.)
Probably better is doing MotionNotify compression
and discarding MotionNotify events when there
are more on the queue before the next ButtonPress/Release.
Proxying
========
A perhaps rather unusual feature of GTK's DND is proxying. A
dest site can be specified as a proxy drop site for another
window. This is most needed for the plug-socket code - the
socket needs to pass on drags to the plug since the original
source only sees toplevel windows. However, it can also be
used as a user visible proxy - i.e., dragging to buttons on
the taskbar.
Internally, when the outer drag enters a proxy dest site, a
new source drag is created, with SourceInfo and
GdkDragContext. From the GDK side, it looks much like a
normal source drag; on the GTK+ side, most of the code is
disjoint. The need to pass in a specific target window
is the reason why the GDK DND API splits
gdk_drag_find_window() and gdk_drag_motion().
For proxy drags, the GtkDestInfo and GtkSourceInfo for the
drag point at each other.
Because the abstraction of the drag protocol is at the GDK
level, a proxy drag from Motif to Xdnd or vice versa happens
pretty much automatically during the drag, though the
drop can get complicated. For Xdnd <-> Motif,
Motif <-> Xdnd, or Motif <-> Motif drags, it is necessary to
for the Proxy to retrieve the data and pass it on to
the true destination, since either the selection names
differ or (Motif<->Motif), the proxy needs to know
about the XmDRAG_SUCCESS/FAILURE selection targets.
Further Reading:
================
Xdnd:
The spec is at:
http://www.cco.caltech.edu/~jafl/xdnd/
Motif:
The Motif DND protocol is best described in the
Hungry Programmers _Inside Lesstif_ book, available
from:
http://www.igpm.rwth-aachen.de/~albrecht/hungry.html
Harald Albrecht and Mitch Miers have done a far
better job at documenting the DND protocol then
anything the OpenGroup has produced.
Owen Taylor
otaylor@redhat.com
Oct 18, 1998

1056
gdk/gdk.c

File diff suppressed because it is too large Load Diff

125
gdk/gdk.h
View File

@ -40,8 +40,9 @@ GdkEvent *gdk_event_get (void);
GdkEvent *gdk_event_get_graphics_expose (GdkWindow *window);
void gdk_event_put (GdkEvent *event);
GdkEvent *gdk_event_copy (GdkEvent *event);
void gdk_event_free (GdkEvent *event);
GdkEvent *gdk_event_copy (GdkEvent *event);
void gdk_event_free (GdkEvent *event);
guint32 gdk_event_get_time (GdkEvent *event);
void gdk_set_show_events (gint show_events);
void gdk_set_use_xshm (gint use_xshm);
@ -196,51 +197,61 @@ void gdk_window_shape_combine_mask (GdkWindow *window,
gint offset_x,
gint offset_y);
/*
* Drag & Drop
* Algorithm (drop source):
* A window being dragged will be sent a GDK_DRAG_BEGIN message.
* It will then do gdk_dnd_drag_addwindow() for any other windows that are to be
* dragged.
* When we get a DROP_ENTER incoming, we send it on to the window in question.
* That window needs to use gdk_dnd_drop_enter_reply() to indicate the state of
* things (it must call that even if it's not going to accept the drop)
*
* These two turn on/off drag or drop, and if enabling it also
* sets the list of types supported. The list of types passed in
* should be in order of decreasing preference.
/*
* The following function adds a global filter for all client
* messages of type message_type
*/
void gdk_window_dnd_drag_set (GdkWindow *window,
guint8 drag_enable,
gchar **typelist,
guint numtypes);
void gdk_add_client_message_filter (GdkAtom message_type,
GdkFilterFunc func,
gpointer data);
/*
*XXX todo: add a GDK_DROP_ENTER which can look at actual data
*/
void gdk_window_dnd_drop_set (GdkWindow *window,
guint8 drop_enable,
gchar **typelist,
guint numtypes,
guint8 destructive_op);
/* Drag and Drop */
/*
* This is used by the GDK_DRAG_BEGIN handler. An example of usage would be a
* file manager where multiple icons were selected and the drag began.
* The icon that the drag actually began on would gdk_dnd_drag_addwindow
* for all the other icons that were being dragged...
*/
void gdk_dnd_drag_addwindow (GdkWindow *window);
void gdk_window_dnd_data_set (GdkWindow *window,
GdkEvent *event,
gpointer data,
gulong data_numbytes);
void gdk_dnd_set_drag_cursors(GdkCursor *default_cursor,
GdkCursor *goahead_cursor);
void gdk_dnd_set_drag_shape(GdkWindow *default_pixmapwin,
GdkPoint *default_hotspot,
GdkWindow *goahead_pixmapwin,
GdkPoint *goahead_hotspot);
GdkDragContext * gdk_drag_context_new (void);
void gdk_drag_context_ref (GdkDragContext *context);
void gdk_drag_context_unref (GdkDragContext *context);
/* Destination side */
void gdk_drag_status (GdkDragContext *context,
GdkDragAction action,
guint32 time);
void gdk_drop_reply (GdkDragContext *context,
gboolean ok,
guint32 time);
void gdk_drop_finish (GdkDragContext *context,
gboolean success,
guint32 time);
GdkAtom gdk_drag_get_selection (GdkDragContext *context);
/* Source side */
GdkDragContext * gdk_drag_begin (GdkWindow *window,
GList *targets,
GdkDragAction actions);
gboolean gdk_drag_get_protocol (guint32 xid,
GdkDragProtocol *protocol);
void gdk_drag_find_window (GdkDragContext *context,
GdkWindow *drag_window,
gint x_root,
gint y_root,
GdkWindow **dest_window,
GdkDragProtocol *protocol);
gboolean gdk_drag_motion (GdkDragContext *context,
GdkWindow *dest_window,
GdkDragProtocol protocol,
gint x_root,
gint y_root,
GdkDragAction action,
guint32 time);
void gdk_drag_drop (GdkDragContext *context,
guint32 time);
void gdk_drag_abort (GdkDragContext *context,
guint32 time);
GdkAtom gdk_drag_get_selection (GdkDragContext *context);
/* GdkWindow */
void gdk_window_set_hints (GdkWindow *window,
gint x,
@ -309,6 +320,8 @@ void gdk_window_set_functions (GdkWindow *window,
GdkWMFunction functions);
GList * gdk_window_get_toplevels (void);
void gdk_window_register_dnd (GdkWindow *window);
void gdk_drawable_set_data (GdkDrawable *drawable,
const gchar *key,
gpointer data,
@ -477,14 +490,24 @@ gboolean gdk_colormap_alloc_color (GdkColormap *colormap,
void gdk_colormap_free_colors (GdkColormap *colormap,
GdkColor *colors,
gint ncolors);
void gdk_colors_store (GdkColormap *colormap,
GdkColor *colors,
gint ncolors);
GdkVisual *gdk_colormap_get_visual (GdkColormap *colormap);
GdkColor *gdk_color_copy (GdkColor *color);
void gdk_color_free (GdkColor *color);
gint gdk_color_parse (const gchar *spec,
GdkColor *color);
guint gdk_color_hash (const GdkColor *colora,
const GdkColor *colorb);
gint gdk_color_equal (const GdkColor *colora,
const GdkColor *colorb);
/* The following functions are deprecated */
void gdk_colors_store (GdkColormap *colormap,
GdkColor *colors,
gint ncolors);
gint gdk_colors_alloc (GdkColormap *colormap,
gint contiguous,
gulong *planes,
@ -499,16 +522,10 @@ gint gdk_color_white (GdkColormap *colormap,
GdkColor *color);
gint gdk_color_black (GdkColormap *colormap,
GdkColor *color);
gint gdk_color_parse (const gchar *spec,
GdkColor *color);
gint gdk_color_alloc (GdkColormap *colormap,
GdkColor *color);
gint gdk_color_change (GdkColormap *colormap,
GdkColor *color);
guint gdk_color_hash (const GdkColor *colora,
const GdkColor *colorb);
gint gdk_color_equal (const GdkColor *colora,
const GdkColor *colorb);
/* Fonts

View File

@ -179,6 +179,18 @@ gdk_colormap_unref (GdkColormap *cmap)
gdk_colormap_real_destroy (cmap);
}
GdkVisual *
gdk_colormap_get_visual (GdkColormap *colormap)
{
GdkColormapPrivate *private;
g_return_val_if_fail (colormap != NULL, NULL);
private = (GdkColormapPrivate *)colormap;
return private->visual;
}
#define MIN_SYNC_TIME 2
void

File diff suppressed because it is too large Load Diff

View File

@ -409,6 +409,8 @@ gdk_image_destroy (GdkImage *image)
case GDK_IMAGE_SHARED:
#ifdef USE_SHM
gdk_flush();
XShmDetach (private->xdisplay, private->x_shm_info);
XDestroyImage (private->ximage);

View File

@ -46,6 +46,7 @@ typedef struct _GdkVisualPrivate GdkVisualPrivate;
typedef struct _GdkFontPrivate GdkFontPrivate;
typedef struct _GdkCursorPrivate GdkCursorPrivate;
typedef struct _GdkEventFilter GdkEventFilter;
typedef struct _GdkClientFilter GdkClientFilter;
typedef struct _GdkColorContextPrivate GdkColorContextPrivate;
typedef struct _GdkRegionPrivate GdkRegionPrivate;
@ -193,6 +194,12 @@ struct _GdkEventFilter {
gpointer data;
};
struct _GdkClientFilter {
GdkAtom type;
GdkFilterFunc function;
gpointer data;
};
#ifdef USE_XIM
struct _GdkICPrivate
@ -228,6 +235,7 @@ typedef enum {
void gdk_window_init (void);
void gdk_visual_init (void);
void gdk_dnd_init (void);
void gdk_image_init (void);
void gdk_image_exit (void);

View File

@ -22,12 +22,21 @@
#include "gdk.h"
#include "gdkprivate.h"
GdkAtom
gdk_atom_intern (const gchar *atom_name,
gint only_if_exists)
{
return XInternAtom (gdk_display, atom_name, only_if_exists);
GdkAtom retval;
static GHashTable *atom_hash = NULL;
if (!atom_hash)
atom_hash = g_hash_table_new (g_str_hash, g_str_equal);
retval = GPOINTER_TO_UINT (g_hash_table_lookup (atom_hash, atom_name));
if (!retval)
retval = XInternAtom (gdk_display, atom_name, only_if_exists);
return retval;
}
gchar *
@ -35,14 +44,16 @@ gdk_atom_name (GdkAtom atom)
{
gchar *t;
gchar *name;
gint old_error_warnings;
/* If this atom doesn't exist, we'll die with an X error unless
we take precautions */
old_error_warnings = gdk_error_warnings;
gdk_error_warnings = 0;
gdk_error_code = 0;
t = XGetAtomName (gdk_display, atom);
gdk_error_warnings = 1;
gdk_error_warnings = old_error_warnings;
if (gdk_error_code == -1)
{
@ -115,7 +126,7 @@ gdk_property_get (GdkWindow *window,
if (actual_format_type)
*actual_format_type = ret_format;
if (ret_prop_type != type)
if ((type != AnyPropertyType) && (ret_prop_type != type))
{
gchar *rn, *pn;

View File

@ -60,6 +60,7 @@ typedef struct _GdkFont GdkFont;
typedef struct _GdkCursor GdkCursor;
typedef struct _GdkColorContextDither GdkColorContextDither;
typedef struct _GdkColorContext GdkColorContext;
typedef struct _GdkDragContext GdkDragContext;
typedef struct _GdkEventAny GdkEventAny;
typedef struct _GdkEventExpose GdkEventExpose;
@ -74,14 +75,12 @@ typedef struct _GdkEventConfigure GdkEventConfigure;
typedef struct _GdkEventProperty GdkEventProperty;
typedef struct _GdkEventSelection GdkEventSelection;
typedef struct _GdkEventProximity GdkEventProximity;
typedef struct _GdkEventOther GdkEventOther;
typedef struct _GdkEventDragBegin GdkEventDragBegin;
typedef struct _GdkEventDragRequest GdkEventDragRequest;
typedef struct _GdkEventDropEnter GdkEventDropEnter;
typedef struct _GdkEventDropDataAvailable GdkEventDropDataAvailable;
typedef struct _GdkEventDropLeave GdkEventDropLeave;
typedef struct _GdkEventClient GdkEventClient;
typedef struct _GdkEventDND GdkEventDND;
typedef union _GdkEvent GdkEvent;
typedef struct _GdkDeviceKey GdkDeviceKey;
typedef struct _GdkDeviceInfo GdkDeviceInfo;
typedef struct _GdkTimeCoord GdkTimeCoord;
@ -380,15 +379,15 @@ typedef enum
GDK_SELECTION_NOTIFY = 19,
GDK_PROXIMITY_IN = 20,
GDK_PROXIMITY_OUT = 21,
GDK_DRAG_BEGIN = 22,
GDK_DRAG_REQUEST = 23,
GDK_DROP_ENTER = 24,
GDK_DROP_LEAVE = 25,
GDK_DROP_DATA_AVAIL = 26,
GDK_CLIENT_EVENT = 27,
GDK_VISIBILITY_NOTIFY = 28,
GDK_NO_EXPOSE = 29,
GDK_OTHER_EVENT = 9999 /* Deprecated, use filters instead */
GDK_DRAG_ENTER = 22,
GDK_DRAG_LEAVE = 23,
GDK_DRAG_MOTION = 24,
GDK_DRAG_STATUS = 25,
GDK_DROP_START = 26,
GDK_DROP_FINISHED = 27,
GDK_CLIENT_EVENT = 28,
GDK_VISIBILITY_NOTIFY = 29,
GDK_NO_EXPOSE = 30,
} GdkEventType;
/* Event masks. (Used to select what types of events a window
@ -539,24 +538,6 @@ typedef enum
GDK_PROP_MODE_APPEND
} GdkPropMode;
/* These definitions are for version 1 of the OffiX D&D protocol,
taken from <OffiX/DragAndDropTypes.h> */
typedef enum
{
GDK_DNDTYPE_NOTDND = -1,
GDK_DNDTYPE_UNKNOWN = 0,
GDK_DNDTYPE_RAWDATA = 1,
GDK_DNDTYPE_FILE = 2,
GDK_DNDTYPE_FILES = 3,
GDK_DNDTYPE_TEXT = 4,
GDK_DNDTYPE_DIR = 5,
GDK_DNDTYPE_LINK = 6,
GDK_DNDTYPE_EXE = 7,
GDK_DNDTYPE_URL = 8,
GDK_DNDTYPE_MIME = 9,
GDK_DNDTYPE_END = 10
} GdkDndType;
/* Enums for XInput support */
typedef enum
@ -697,6 +678,22 @@ typedef enum
GDK_OVERLAP_RECTANGLE_PART
} GdkOverlapType;
typedef enum {
GDK_ACTION_DEFAULT = 1 << 0,
GDK_ACTION_COPY = 1 << 1,
GDK_ACTION_MOVE = 1 << 2,
GDK_ACTION_LINK = 1 << 3,
GDK_ACTION_PRIVATE = 1 << 4,
GDK_ACTION_ASK = 1 << 5
} GdkDragAction;
typedef enum {
GDK_DRAG_PROTO_MOTIF,
GDK_DRAG_PROTO_XDND,
GDK_DRAG_PROTO_ROOTWIN /* A root window with nobody claiming
* drags */
} GdkDragProtocol;
/* The color type.
* A color consists of red, green and blue values in the
* range 0-65535 and a pixel value. The pixel value is highly
@ -938,6 +935,25 @@ struct _GdkTimeCoord
gdouble ytilt;
};
/* Structure that holds information about a drag in progress.
* this is used on both source and destination sides.
*/
struct _GdkDragContext {
GdkDragProtocol protocol;
gboolean is_source;
GdkWindow *source_window;
GdkWindow *dest_window;
GList *targets;
GdkDragAction actions;
GdkDragAction suggested_action;
GdkDragAction action;
guint32 start_time;
};
/* Event filtering */
typedef void GdkXEvent; /* Can be cast to XEvent */
@ -1096,100 +1112,6 @@ struct _GdkEventProximity
guint32 deviceid;
};
struct _GdkEventDragRequest
{
GdkEventType type;
GdkWindow *window;
gint8 send_event;
guint32 requestor;
union {
struct {
guint protocol_version:4;
guint sendreply:1;
guint willaccept:1;
guint delete_data:1; /* Do *not* delete if link is sent, only
if data is sent */
guint senddata:1;
guint reserved:22;
} flags;
glong allflags;
} u;
guint8 isdrop; /* This gdk event can be generated by a couple of
X events - this lets the app know whether the
drop really occurred or we just set the data */
GdkPoint drop_coords;
gchar *data_type;
guint32 timestamp;
};
struct _GdkEventDragBegin
{
GdkEventType type;
GdkWindow *window;
gint8 send_event;
union {
struct {
guint protocol_version:4;
guint reserved:28;
} flags;
glong allflags;
} u;
};
struct _GdkEventDropEnter
{
GdkEventType type;
GdkWindow *window;
gint8 send_event;
guint32 requestor;
union {
struct {
guint protocol_version:4;
guint sendreply:1;
guint extended_typelist:1;
guint reserved:26;
} flags;
glong allflags;
} u;
};
struct _GdkEventDropLeave
{
GdkEventType type;
GdkWindow *window;
gint8 send_event;
guint32 requestor;
union {
struct {
guint protocol_version:4;
guint reserved:28;
} flags;
glong allflags;
} u;
};
struct _GdkEventDropDataAvailable
{
GdkEventType type;
GdkWindow *window;
gint8 send_event;
guint32 requestor;
union {
struct {
guint protocol_version:4;
guint isdrop:1;
guint reserved:25;
} flags;
glong allflags;
} u;
gchar *data_type; /* MIME type */
gulong data_numbytes;
gpointer data;
guint32 timestamp;
GdkPoint coords;
};
struct _GdkEventClient
{
GdkEventType type;
@ -1204,12 +1126,16 @@ struct _GdkEventClient
} data;
};
struct _GdkEventOther
{
/* Event types for DND */
struct _GdkEventDND {
GdkEventType type;
GdkWindow *window;
gint8 send_event;
GdkXEvent *xevent;
GdkDragContext *context;
guint32 time;
gshort x_root, y_root;
};
union _GdkEvent
@ -1228,13 +1154,8 @@ union _GdkEvent
GdkEventProperty property;
GdkEventSelection selection;
GdkEventProximity proximity;
GdkEventDragBegin dragbegin;
GdkEventDragRequest dragrequest;
GdkEventDropEnter dropenter;
GdkEventDropLeave dropleave;
GdkEventDropDataAvailable dropdataavailable;
GdkEventClient client;
GdkEventOther other;
GdkEventDND dnd;
};
struct _GdkRegion

View File

@ -216,6 +216,9 @@ gdk_window_init (void)
gdk_root_parent.height = height;
gdk_root_parent.children = NULL;
gdk_root_parent.colormap = NULL;
gdk_root_parent.ref_count = 1;
gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
}
GdkWindow*
@ -703,11 +706,15 @@ gdk_window_unref (GdkWindow *window)
if (private->ref_count == 0)
{
if (!private->destroyed)
g_warning ("losing last reference to undestroyed window\n");
{
if (private->window_type == GDK_WINDOW_FOREIGN)
gdk_xid_table_remove (private->xwindow);
else
g_warning ("losing last reference to undestroyed window\n");
}
g_dataset_destroy (window);
g_free (window);
}
}
void
@ -1681,188 +1688,6 @@ gdk_window_shape_combine_mask (GdkWindow *window,
#endif /* HAVE_SHAPE_EXT */
}
void
gdk_dnd_drag_addwindow (GdkWindow *window)
{
GdkWindowPrivate *window_private;
g_return_if_fail (window != NULL);
window_private = (GdkWindowPrivate *) window;
if (window_private->destroyed)
return;
if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
{
gdk_dnd.drag_numwindows++;
gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
gdk_dnd.drag_numwindows
* sizeof(GdkWindow *));
gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
window_private->dnd_drag_accepted = 0;
}
else
g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
}
void
gdk_window_dnd_drag_set (GdkWindow *window,
guint8 drag_enable,
gchar **typelist,
guint numtypes)
{
GdkWindowPrivate *window_private;
int i, wasset = 0;
g_return_if_fail (window != NULL);
window_private = (GdkWindowPrivate *) window;
if (window_private->destroyed)
return;
window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
if (drag_enable)
{
g_return_if_fail(typelist != NULL);
if (window_private->dnd_drag_data_numtypesavail > 3)
wasset = 1;
window_private->dnd_drag_data_numtypesavail = numtypes;
window_private->dnd_drag_data_typesavail =
g_realloc (window_private->dnd_drag_data_typesavail,
(numtypes + 1) * sizeof (GdkAtom));
for (i = 0; i < numtypes; i++)
{
/* Allow blanket use of ALL to get anything... */
if (strcmp (typelist[i], "ALL"))
window_private->dnd_drag_data_typesavail[i] =
gdk_atom_intern (typelist[i], FALSE);
else
window_private->dnd_drag_data_typesavail[i] = None;
}
/*
* set our extended type list if we need to
*/
if (numtypes > 3)
gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
(guchar *)(window_private->dnd_drag_data_typesavail
+ (sizeof(GdkAtom) * 3)),
(numtypes - 3) * sizeof(GdkAtom));
else if (wasset)
gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
}
else
{
g_free (window_private->dnd_drag_data_typesavail);
window_private->dnd_drag_data_typesavail = NULL;
window_private->dnd_drag_data_numtypesavail = 0;
}
}
void
gdk_window_dnd_drop_set (GdkWindow *window,
guint8 drop_enable,
gchar **typelist,
guint numtypes,
guint8 destructive_op)
{
GdkWindowPrivate *window_private;
int i;
g_return_if_fail (window != NULL);
window_private = (GdkWindowPrivate *) window;
if (window_private->destroyed)
return;
window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
if (drop_enable)
{
g_return_if_fail(typelist != NULL);
window_private->dnd_drop_data_numtypesavail = numtypes;
window_private->dnd_drop_data_typesavail =
g_realloc (window_private->dnd_drop_data_typesavail,
(numtypes + 1) * sizeof (GdkAtom));
for (i = 0; i < numtypes; i++)
window_private->dnd_drop_data_typesavail[i] =
gdk_atom_intern (typelist[i], FALSE);
window_private->dnd_drop_destructive_op = destructive_op;
}
}
/*
* This is used to reply to a GDK_DRAG_REQUEST event
* (which may be generated by XdeRequest or a confirmed drop...
*/
void
gdk_window_dnd_data_set (GdkWindow *window,
GdkEvent *event,
gpointer data,
gulong data_numbytes)
{
GdkWindowPrivate *window_private;
XEvent sev;
GdkEventDropDataAvailable tmp_ev;
gchar *tmp;
g_return_if_fail (window != NULL);
g_return_if_fail (event != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (data_numbytes > 0);
g_return_if_fail (event->type == GDK_DRAG_REQUEST);
window_private = (GdkWindowPrivate *) window;
g_return_if_fail (window_private->dnd_drag_accepted != 0);
if (window_private->destroyed)
return;
/* We set the property on our window... */
gdk_property_change (window, window_private->dnd_drag_data_type,
XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
data_numbytes);
tmp = gdk_atom_name(window_private->dnd_drag_data_type);
#ifdef DEBUG_DND
g_message("DnD type %s on window %ld\n", tmp, window_private->xwindow);
#endif
g_free(tmp);
/*
* Then we send the event to tell the receiving window that the
* drop has happened
*/
tmp_ev.u.allflags = 0;
tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
sev.xclient.type = ClientMessage;
sev.xclient.format = 32;
sev.xclient.window = event->dragrequest.requestor;
sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
sev.xclient.data.l[0] = window_private->xwindow;
sev.xclient.data.l[1] = tmp_ev.u.allflags;
sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
if (event->dragrequest.isdrop)
sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
(event->dragrequest.drop_coords.y << 16);
else
sev.xclient.data.l[3] = 0;
sev.xclient.data.l[4] = event->dragrequest.timestamp;
if (!gdk_send_xevent (event->dragrequest.requestor, False,
StructureNotifyMask, &sev))
GDK_NOTE (DND, g_message("Sending XdeDataAvailable to %#x failed\n",
event->dragrequest.requestor));
}
void
gdk_window_add_filter (GdkWindow *window,
GdkFilterFunc function,
@ -1905,7 +1730,7 @@ gdk_window_remove_filter (GdkWindow *window,
gpointer data)
{
GdkWindowPrivate *private;
GList *tmp_list;
GList *tmp_list, *node;
GdkEventFilter *filter;
private = (GdkWindowPrivate*) window;
@ -1918,15 +1743,16 @@ gdk_window_remove_filter (GdkWindow *window,
while (tmp_list)
{
filter = (GdkEventFilter *)tmp_list->data;
node = tmp_list;
tmp_list = tmp_list->next;
if ((filter->function == function) && (filter->data == data))
{
if(private)
private->filters = g_list_remove_link (private->filters, tmp_list);
private->filters = g_list_remove_link (private->filters, node);
else
gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
g_list_free_1 (tmp_list);
g_list_free_1 (node);
g_free (filter);
return;

View File

@ -179,6 +179,18 @@ gdk_colormap_unref (GdkColormap *cmap)
gdk_colormap_real_destroy (cmap);
}
GdkVisual *
gdk_colormap_get_visual (GdkColormap *colormap)
{
GdkColormapPrivate *private;
g_return_val_if_fail (colormap != NULL, NULL);
private = (GdkColormapPrivate *)colormap;
return private->visual;
}
#define MIN_SYNC_TIME 2
void

File diff suppressed because it is too large Load Diff

View File

@ -409,6 +409,8 @@ gdk_image_destroy (GdkImage *image)
case GDK_IMAGE_SHARED:
#ifdef USE_SHM
gdk_flush();
XShmDetach (private->xdisplay, private->x_shm_info);
XDestroyImage (private->ximage);

File diff suppressed because it is too large Load Diff

View File

@ -22,12 +22,21 @@
#include "gdk.h"
#include "gdkprivate.h"
GdkAtom
gdk_atom_intern (const gchar *atom_name,
gint only_if_exists)
{
return XInternAtom (gdk_display, atom_name, only_if_exists);
GdkAtom retval;
static GHashTable *atom_hash = NULL;
if (!atom_hash)
atom_hash = g_hash_table_new (g_str_hash, g_str_equal);
retval = GPOINTER_TO_UINT (g_hash_table_lookup (atom_hash, atom_name));
if (!retval)
retval = XInternAtom (gdk_display, atom_name, only_if_exists);
return retval;
}
gchar *
@ -35,14 +44,16 @@ gdk_atom_name (GdkAtom atom)
{
gchar *t;
gchar *name;
gint old_error_warnings;
/* If this atom doesn't exist, we'll die with an X error unless
we take precautions */
old_error_warnings = gdk_error_warnings;
gdk_error_warnings = 0;
gdk_error_code = 0;
t = XGetAtomName (gdk_display, atom);
gdk_error_warnings = 1;
gdk_error_warnings = old_error_warnings;
if (gdk_error_code == -1)
{
@ -115,7 +126,7 @@ gdk_property_get (GdkWindow *window,
if (actual_format_type)
*actual_format_type = ret_format;
if (ret_prop_type != type)
if ((type != AnyPropertyType) && (ret_prop_type != type))
{
gchar *rn, *pn;

View File

@ -216,6 +216,9 @@ gdk_window_init (void)
gdk_root_parent.height = height;
gdk_root_parent.children = NULL;
gdk_root_parent.colormap = NULL;
gdk_root_parent.ref_count = 1;
gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
}
GdkWindow*
@ -703,11 +706,15 @@ gdk_window_unref (GdkWindow *window)
if (private->ref_count == 0)
{
if (!private->destroyed)
g_warning ("losing last reference to undestroyed window\n");
{
if (private->window_type == GDK_WINDOW_FOREIGN)
gdk_xid_table_remove (private->xwindow);
else
g_warning ("losing last reference to undestroyed window\n");
}
g_dataset_destroy (window);
g_free (window);
}
}
void
@ -1681,188 +1688,6 @@ gdk_window_shape_combine_mask (GdkWindow *window,
#endif /* HAVE_SHAPE_EXT */
}
void
gdk_dnd_drag_addwindow (GdkWindow *window)
{
GdkWindowPrivate *window_private;
g_return_if_fail (window != NULL);
window_private = (GdkWindowPrivate *) window;
if (window_private->destroyed)
return;
if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
{
gdk_dnd.drag_numwindows++;
gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
gdk_dnd.drag_numwindows
* sizeof(GdkWindow *));
gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
window_private->dnd_drag_accepted = 0;
}
else
g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
}
void
gdk_window_dnd_drag_set (GdkWindow *window,
guint8 drag_enable,
gchar **typelist,
guint numtypes)
{
GdkWindowPrivate *window_private;
int i, wasset = 0;
g_return_if_fail (window != NULL);
window_private = (GdkWindowPrivate *) window;
if (window_private->destroyed)
return;
window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
if (drag_enable)
{
g_return_if_fail(typelist != NULL);
if (window_private->dnd_drag_data_numtypesavail > 3)
wasset = 1;
window_private->dnd_drag_data_numtypesavail = numtypes;
window_private->dnd_drag_data_typesavail =
g_realloc (window_private->dnd_drag_data_typesavail,
(numtypes + 1) * sizeof (GdkAtom));
for (i = 0; i < numtypes; i++)
{
/* Allow blanket use of ALL to get anything... */
if (strcmp (typelist[i], "ALL"))
window_private->dnd_drag_data_typesavail[i] =
gdk_atom_intern (typelist[i], FALSE);
else
window_private->dnd_drag_data_typesavail[i] = None;
}
/*
* set our extended type list if we need to
*/
if (numtypes > 3)
gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
(guchar *)(window_private->dnd_drag_data_typesavail
+ (sizeof(GdkAtom) * 3)),
(numtypes - 3) * sizeof(GdkAtom));
else if (wasset)
gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
}
else
{
g_free (window_private->dnd_drag_data_typesavail);
window_private->dnd_drag_data_typesavail = NULL;
window_private->dnd_drag_data_numtypesavail = 0;
}
}
void
gdk_window_dnd_drop_set (GdkWindow *window,
guint8 drop_enable,
gchar **typelist,
guint numtypes,
guint8 destructive_op)
{
GdkWindowPrivate *window_private;
int i;
g_return_if_fail (window != NULL);
window_private = (GdkWindowPrivate *) window;
if (window_private->destroyed)
return;
window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
if (drop_enable)
{
g_return_if_fail(typelist != NULL);
window_private->dnd_drop_data_numtypesavail = numtypes;
window_private->dnd_drop_data_typesavail =
g_realloc (window_private->dnd_drop_data_typesavail,
(numtypes + 1) * sizeof (GdkAtom));
for (i = 0; i < numtypes; i++)
window_private->dnd_drop_data_typesavail[i] =
gdk_atom_intern (typelist[i], FALSE);
window_private->dnd_drop_destructive_op = destructive_op;
}
}
/*
* This is used to reply to a GDK_DRAG_REQUEST event
* (which may be generated by XdeRequest or a confirmed drop...
*/
void
gdk_window_dnd_data_set (GdkWindow *window,
GdkEvent *event,
gpointer data,
gulong data_numbytes)
{
GdkWindowPrivate *window_private;
XEvent sev;
GdkEventDropDataAvailable tmp_ev;
gchar *tmp;
g_return_if_fail (window != NULL);
g_return_if_fail (event != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (data_numbytes > 0);
g_return_if_fail (event->type == GDK_DRAG_REQUEST);
window_private = (GdkWindowPrivate *) window;
g_return_if_fail (window_private->dnd_drag_accepted != 0);
if (window_private->destroyed)
return;
/* We set the property on our window... */
gdk_property_change (window, window_private->dnd_drag_data_type,
XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
data_numbytes);
tmp = gdk_atom_name(window_private->dnd_drag_data_type);
#ifdef DEBUG_DND
g_message("DnD type %s on window %ld\n", tmp, window_private->xwindow);
#endif
g_free(tmp);
/*
* Then we send the event to tell the receiving window that the
* drop has happened
*/
tmp_ev.u.allflags = 0;
tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
sev.xclient.type = ClientMessage;
sev.xclient.format = 32;
sev.xclient.window = event->dragrequest.requestor;
sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
sev.xclient.data.l[0] = window_private->xwindow;
sev.xclient.data.l[1] = tmp_ev.u.allflags;
sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
if (event->dragrequest.isdrop)
sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
(event->dragrequest.drop_coords.y << 16);
else
sev.xclient.data.l[3] = 0;
sev.xclient.data.l[4] = event->dragrequest.timestamp;
if (!gdk_send_xevent (event->dragrequest.requestor, False,
StructureNotifyMask, &sev))
GDK_NOTE (DND, g_message("Sending XdeDataAvailable to %#x failed\n",
event->dragrequest.requestor));
}
void
gdk_window_add_filter (GdkWindow *window,
GdkFilterFunc function,
@ -1905,7 +1730,7 @@ gdk_window_remove_filter (GdkWindow *window,
gpointer data)
{
GdkWindowPrivate *private;
GList *tmp_list;
GList *tmp_list, *node;
GdkEventFilter *filter;
private = (GdkWindowPrivate*) window;
@ -1918,15 +1743,16 @@ gdk_window_remove_filter (GdkWindow *window,
while (tmp_list)
{
filter = (GdkEventFilter *)tmp_list->data;
node = tmp_list;
tmp_list = tmp_list->next;
if ((filter->function == function) && (filter->data == data))
{
if(private)
private->filters = g_list_remove_link (private->filters, tmp_list);
private->filters = g_list_remove_link (private->filters, node);
else
gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
g_list_free_1 (tmp_list);
g_list_free_1 (node);
g_free (filter);
return;

View File

@ -29,6 +29,7 @@ libgtk_la_SOURCES = \
gtkcurve.c \
gtkdata.c \
gtkdialog.c \
gtkdnd.c \
gtkdrawingarea.c \
gtkeditable.c \
gtkentry.c \
@ -49,6 +50,7 @@ libgtk_la_SOURCES = \
gtkhseparator.c \
gtkimage.c \
gtkinputdialog.c \
gtkinvisible.c \
gtkitem.c \
gtkitemfactory.c \
gtklabel.c \
@ -135,6 +137,7 @@ source_headers = \
gtkdata.h \
gtkdebug.h \
gtkdialog.h \
gtkdnd.h \
gtkdrawingarea.h \
gtkeditable.h \
gtkentry.h \
@ -156,6 +159,7 @@ source_headers = \
gtkhseparator.h \
gtkimage.h \
gtkinputdialog.h \
gtkinvisible.h \
gtkitem.h \
gtkitemfactory.h \
gtklabel.h \
@ -306,7 +310,9 @@ EXTRA_DIST = \
INCLUDES = -I$(top_srcdir) @GLIB_CFLAGS@ @x_cflags@
noinst_PROGRAMS = testgtk testinput testselection testthreads testrgb simple
noinst_PROGRAMS = testgtk testinput testselection testthreads testrgb testdnd simple
# FIXME, we currently rely on linking against libglib-1.1
DEPS = \
libgtk.la \
@ -325,6 +331,7 @@ testinput_DEPENDENCIES = $(DEPS)
testthreads_DEPENDENCIES = $(DEPS)
testselection_DEPENDENCIES = $(DEPS)
testrgb_DEPENDENCIES = $(DEPS)
testdnd_DEPENDENCIES = $(DEPS)
simple_DEPENDENCIES = $(DEPS)
testgtk_LDADD = $(LDADDS)
@ -332,6 +339,7 @@ testinput_LDADD = $(LDADDS)
testthreads_LDADD = $(LDADDS)
testselection_LDADD = $(LDADDS)
testrgb_LDADD = $(LDADDS)
testdnd_LDADD = $(LDADDS)
simple_LDADD = $(LDADDS)
.PHONY: files test test-debug

View File

@ -42,6 +42,9 @@
gdk_window_ref
gdk_window_unref)
(define-boxed GdkDragContext
gdk_drag_context_ref
gdk_drag_context_unref)
(define-boxed GdkEvent
gdk_event_copy
gdk_event_free

View File

@ -44,6 +44,7 @@
#include <gtk/gtkcurve.h>
#include <gtk/gtkdata.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkdnd.h>
#include <gtk/gtkdrawingarea.h>
#include <gtk/gtkeditable.h>
#include <gtk/gtkentry.h>

View File

@ -22,6 +22,8 @@
#include <gdk/gdk.h>
#include "gtkcolorsel.h"
#include "gtkhbbox.h"
#include "gtkdnd.h"
#include "gtkselection.h"
/*
* If you change the way the color values are stored,
@ -144,12 +146,23 @@ static gint gtk_color_selection_wheel_events (GtkWidget *area,
static gint gtk_color_selection_wheel_timeout (GtkColorSelection *colorsel);
static void gtk_color_selection_sample_resize (GtkWidget *widget,
gpointer data);
static void gtk_color_selection_drop_handle (GtkWidget *widget,
GdkEvent *event,
GtkWidget *theclorsel);
static void gtk_color_selection_drag_handle (GtkWidget *widget,
GdkEvent *event,
GtkWidget *thecolorsel);
static void gtk_color_selection_drag_begin (GtkWidget *widget,
GdkDragContext *context,
gpointer data);
static void gtk_color_selection_drop_handle (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint time,
gpointer data);
static void gtk_color_selection_drag_handle (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint time,
gpointer data);
static void gtk_color_selection_draw_wheel_marker (GtkColorSelection *colorsel);
static void gtk_color_selection_draw_wheel_frame (GtkColorSelection *colorsel);
static void gtk_color_selection_draw_value_marker (GtkColorSelection *colorsel);
@ -502,7 +515,10 @@ static void
gtk_color_selection_realize (GtkWidget *widget)
{
GtkColorSelection *colorsel;
gchar *type_accept_list[] = {"application/x-color"};
GtkTargetEntry targets[] = {
{ "application/x-color", 0 }
};
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_COLOR_SELECTION (widget));
@ -512,18 +528,30 @@ gtk_color_selection_realize (GtkWidget *widget)
if (GTK_WIDGET_CLASS (color_selection_parent_class)->realize)
(*GTK_WIDGET_CLASS (color_selection_parent_class)->realize) (widget);
gtk_widget_dnd_drag_set (colorsel->sample_area,
1, type_accept_list, 1);
gtk_widget_dnd_drop_set (colorsel->sample_area,
1, type_accept_list, 1, 0);
gtk_signal_connect_after (GTK_OBJECT (colorsel->sample_area),
"drop_data_available_event",
GTK_SIGNAL_FUNC (gtk_color_selection_drop_handle),
colorsel);
gtk_signal_connect_after (GTK_OBJECT (colorsel->sample_area),
"drag_request_event",
GTK_SIGNAL_FUNC (gtk_color_selection_drag_handle),
colorsel);
gtk_drag_dest_set (colorsel->sample_area,
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
targets, 1,
GDK_ACTION_COPY);
gtk_drag_source_set (colorsel->sample_area,
GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
targets, 1,
GDK_ACTION_COPY | GDK_ACTION_MOVE);
gtk_signal_connect (GTK_OBJECT (colorsel->sample_area),
"drag_begin",
GTK_SIGNAL_FUNC (gtk_color_selection_drag_begin),
colorsel);
gtk_signal_connect (GTK_OBJECT (colorsel->sample_area),
"drag_data_get",
GTK_SIGNAL_FUNC (gtk_color_selection_drag_handle),
colorsel);
gtk_signal_connect (GTK_OBJECT (colorsel->sample_area),
"drag_data_received",
GTK_SIGNAL_FUNC (gtk_color_selection_drop_handle),
colorsel);
}
static void
@ -824,39 +852,97 @@ gtk_color_selection_sample_resize (GtkWidget *widget,
}
static void
gtk_color_selection_drop_handle (GtkWidget *widget, GdkEvent *event,
GtkWidget *thecolorsel)
gtk_color_selection_drag_begin (GtkWidget *widget,
GdkDragContext *context,
gpointer data)
{
/* This is currently a gdouble array of the format (I think):
use_opacity
GtkColorSelection *colorsel = data;
GtkWidget *window;
gdouble colors[4];
GdkColor bg;
window = gtk_window_new(GTK_WINDOW_POPUP);
gtk_widget_set_usize (window, 48, 32);
gtk_widget_realize (window);
gtk_color_selection_get_color (colorsel, colors);
bg.red = 0xffff * colors[0];
bg.green = 0xffff * colors[1];
bg.blue = 0xffff * colors[2];
gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
gdk_window_set_background (window->window, &bg);
gtk_drag_set_icon_widget (context, window, -2, -2);
}
static void
gtk_color_selection_drop_handle (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint time,
gpointer data)
{
GtkColorSelection *colorsel = data;
guint16 *vals;
gdouble colors[4];
/* This is currently a guint16 array of the format:
R
G
B
opacity
*/
gdouble *v = event->dropdataavailable.data;
gtk_color_selection_set_opacity(GTK_COLOR_SELECTION(thecolorsel),
(v[0]==1.0)?TRUE:FALSE);
gtk_color_selection_set_color(GTK_COLOR_SELECTION(thecolorsel),
v + 1);
g_free(event->dropdataavailable.data);
g_free(event->dropdataavailable.data_type);
if (selection_data->length < 0)
return;
if ((selection_data->format != 16) ||
(selection_data->length != 8))
{
g_warning ("Received invalid color data\n");
return;
}
vals = (guint16 *)selection_data->data;
colors[0] = (gdouble)vals[0] / 0xffff;
colors[1] = (gdouble)vals[1] / 0xffff;
colors[2] = (gdouble)vals[2] / 0xffff;
colors[3] = (gdouble)vals[3] / 0xffff;
gtk_color_selection_set_color(colorsel, colors);
}
static void
gtk_color_selection_drag_handle (GtkWidget *widget, GdkEvent *event,
GtkWidget *thecolorsel)
gtk_color_selection_drag_handle (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint time,
gpointer data)
{
gdouble sendvals[(BLUE - RED + 1) + 3];
GtkColorSelection *colorsel = data;
guint16 vals[4];
gdouble colors[4];
sendvals[0] = (GTK_COLOR_SELECTION(thecolorsel)->use_opacity)?1.0:0.0;
gtk_color_selection_get_color(GTK_COLOR_SELECTION(thecolorsel),
sendvals + 1);
gtk_color_selection_get_color(colorsel, colors);
gtk_widget_dnd_data_set(widget,
event,
(gpointer)sendvals,
sizeof(sendvals));
vals[0] = colors[0] * 0xffff;
vals[1] = colors[1] * 0xffff;
vals[2] = colors[2] * 0xffff;
vals[3] = colorsel->use_opacity ? colors[3] * 0xffff : 0xffff;
g_print ("%x %x\n", vals[0], vals[4]);
g_print ("%g\n", colorsel->values[OPACITY]);
g_print ("%d\n", colorsel->use_opacity);
gtk_selection_data_set (selection_data,
gdk_atom_intern ("application/x-color", FALSE),
16, (guchar *)vals, 8);
}
static void
@ -984,6 +1070,13 @@ gtk_color_selection_value_events (GtkWidget *area,
gtk_color_selection_color_changed (colorsel);
break;
case GDK_MOTION_NOTIFY:
/* Even though we select BUTTON_MOTION_MASK, we seem to need
* to occasionally get events without buttons pressed.
*/
if (!(event->motion.state &
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))
return FALSE;
y = event->motion.y;
if (event->motion.is_hint || (event->motion.window != area->window))
@ -1074,6 +1167,13 @@ gtk_color_selection_wheel_events (GtkWidget *area,
gtk_color_selection_color_changed (colorsel);
break;
case GDK_MOTION_NOTIFY:
/* Even though we select BUTTON_MOTION_MASK, we seem to need
* to occasionally get events without buttons pressed.
*/
if (!(event->motion.state &
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))
return FALSE;
x = event->motion.x;
y = event->motion.y;

View File

@ -26,7 +26,8 @@ extern "C" {
typedef enum {
GTK_DEBUG_OBJECTS = 1 << 0,
GTK_DEBUG_MISC = 1 << 1,
GTK_DEBUG_SIGNALS = 1 << 2
GTK_DEBUG_SIGNALS = 1 << 2,
GTK_DEBUG_DND = 1 << 3
} GtkDebugFlag;
#ifdef G_ENABLE_DEBUG

2343
gtk/gtkdnd.c Normal file

File diff suppressed because it is too large Load Diff

129
gtk/gtkdnd.h Normal file
View File

@ -0,0 +1,129 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_DND_H__
#define __GTK_DND_H__
#include <gdk/gdk.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtkselection.h>
#ifdef __cplusplus
extern "C" {
#pragma }
#endif /* __cplusplus */
typedef enum {
GTK_DEST_DEFAULT_MOTION = 1 << 0, /* respond to "drag_motion" */
GTK_DEST_DEFAULT_HIGHLIGHT = 1 << 1, /* auto-highlight */
GTK_DEST_DEFAULT_DROP = 1 << 2, /* respond to "drag_drop" */
GTK_DEST_DEFAULT_ALL = 0x07
} GtkDestDefaults;
/* Destination side */
void gtk_drag_get_data (GtkWidget *widget,
GdkDragContext *context,
GdkAtom target,
guint32 time);
void gtk_drag_finish (GdkDragContext *context,
gboolean success,
gboolean delete,
guint32 time);
void gtk_drag_highlight (GtkWidget *widget);
void gtk_drag_unhighlight (GtkWidget *widget);
void gtk_drag_dest_set (GtkWidget *widget,
GtkDestDefaults flags,
GtkTargetEntry *targets,
gint n_targets,
GdkDragAction actions);
void gtk_drag_dest_set_proxy (GtkWidget *widget,
GdkWindow *proxy_window,
GdkDragProtocol protocol,
gboolean use_coordinates);
/* There probably should be functions for setting the targets
* as a GtkTargetList
*/
void gtk_drag_dest_unset (GtkWidget *widget);
/* Source side */
void gtk_drag_source_set (GtkWidget *widget,
GdkModifierType start_button_mask,
GtkTargetEntry *targets,
gint n_targets,
GdkDragAction actions);
void gtk_drag_source_set_icon (GtkWidget *widget,
GdkColormap *colormap,
GdkPixmap *pixmap,
GdkBitmap *mask);
/* There probably should be functions for setting the targets
* as a GtkTargetList
*/
GdkDragContext *gtk_drag_begin (GtkWidget *widget,
GtkTargetList *targets,
GdkDragAction actions,
gint button,
GdkEvent *event);
/* Set the image being dragged around
*/
void gtk_drag_set_icon_widget (GdkDragContext *context,
GtkWidget *widget,
gint hot_x,
gint hot_y);
void gtk_drag_set_icon_pixmap (GdkDragContext *context,
GdkColormap *colormap,
GdkPixmap *pixmap,
GdkBitmap *mask,
gint hot_x,
gint hot_y);
void gtk_drag_set_icon_default (GdkDragContext *context);
void gtk_drag_set_default_icon (GdkColormap *colormap,
GdkPixmap *pixmap,
GdkBitmap *mask,
gint hot_x,
gint hot_y);
/* Internal functions */
void gtk_drag_source_handle_event (GtkWidget *widget,
GdkEvent *event);
void gtk_drag_dest_handle_event (GtkWidget *toplevel,
GdkEvent *event);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GTK_DND_H__ */

View File

@ -58,7 +58,14 @@ enum {
ARG_TEXT_POSITION,
ARG_EDITABLE
};
/* values for selection info */
enum {
TARGET_STRING,
TARGET_TEXT,
TARGET_COMPOUND_TEXT,
};
static void gtk_editable_class_init (GtkEditableClass *klass);
static void gtk_editable_init (GtkEditable *editable);
@ -71,11 +78,13 @@ static void gtk_editable_get_arg (GtkObject *object,
static void gtk_editable_finalize (GtkObject *object);
static gint gtk_editable_selection_clear (GtkWidget *widget,
GdkEventSelection *event);
static void gtk_editable_selection_handler (GtkWidget *widget,
GtkSelectionData *selection_data,
gpointer data);
static void gtk_editable_selection_get (GtkWidget *widget,
GtkSelectionData *selection_data,
guint info,
guint time);
static void gtk_editable_selection_received (GtkWidget *widget,
GtkSelectionData *selection_data);
GtkSelectionData *selection_data,
guint time);
static void gtk_editable_set_selection (GtkEditable *editable,
gint start,
@ -90,8 +99,7 @@ static void gtk_editable_real_set_editable (GtkEditable *editable,
static GtkWidgetClass *parent_class = NULL;
static guint editable_signals[LAST_SIGNAL] = { 0 };
static GdkAtom ctext_atom = GDK_NONE;
static GdkAtom text_atom = GDK_NONE;
static GdkAtom clipboard_atom = GDK_NONE;
GtkType
@ -287,6 +295,7 @@ gtk_editable_class_init (GtkEditableClass *class)
widget_class->selection_clear_event = gtk_editable_selection_clear;
widget_class->selection_received = gtk_editable_selection_received;
widget_class->selection_get = gtk_editable_selection_get;
class->insert_text = NULL;
class->delete_text = NULL;
@ -362,6 +371,13 @@ gtk_editable_get_arg (GtkObject *object,
static void
gtk_editable_init (GtkEditable *editable)
{
static GtkTargetEntry targets[] = {
{ "STRING", TARGET_STRING },
{ "TEXT", TARGET_TEXT },
{ "COMPOUND_TEXT", TARGET_COMPOUND_TEXT }
};
static gint n_targets = sizeof(targets) / sizeof(targets[0]);
GTK_WIDGET_SET_FLAGS (editable, GTK_CAN_FOCUS);
editable->selection_start_pos = 0;
@ -377,36 +393,10 @@ gtk_editable_init (GtkEditable *editable)
if (!clipboard_atom)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
gtk_selection_add_handler (GTK_WIDGET(editable), GDK_SELECTION_PRIMARY,
GDK_TARGET_STRING, gtk_editable_selection_handler,
NULL);
gtk_selection_add_handler (GTK_WIDGET(editable), clipboard_atom,
GDK_TARGET_STRING, gtk_editable_selection_handler,
NULL);
if (!text_atom)
text_atom = gdk_atom_intern ("TEXT", FALSE);
gtk_selection_add_handler (GTK_WIDGET(editable), GDK_SELECTION_PRIMARY,
text_atom,
gtk_editable_selection_handler,
NULL);
gtk_selection_add_handler (GTK_WIDGET(editable), clipboard_atom,
text_atom,
gtk_editable_selection_handler,
NULL);
if (!ctext_atom)
ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
gtk_selection_add_handler (GTK_WIDGET(editable), GDK_SELECTION_PRIMARY,
ctext_atom,
gtk_editable_selection_handler,
NULL);
gtk_selection_add_handler (GTK_WIDGET(editable), clipboard_atom,
ctext_atom,
gtk_editable_selection_handler,
NULL);
gtk_selection_add_targets (GTK_WIDGET (editable), GDK_SELECTION_PRIMARY,
targets, n_targets);
gtk_selection_add_targets (GTK_WIDGET (editable), clipboard_atom,
targets, n_targets);
}
static void
@ -580,9 +570,10 @@ gtk_editable_selection_clear (GtkWidget *widget,
}
static void
gtk_editable_selection_handler (GtkWidget *widget,
GtkSelectionData *selection_data,
gpointer data)
gtk_editable_selection_get (GtkWidget *widget,
GtkSelectionData *selection_data,
guint info,
guint time)
{
GtkEditable *editable;
gint selection_start_pos;
@ -614,14 +605,13 @@ gtk_editable_selection_handler (GtkWidget *widget,
length = strlen (editable->clipboard_text);
}
if (selection_data->target == GDK_SELECTION_TYPE_STRING)
if (info == TARGET_STRING)
{
gtk_selection_data_set (selection_data,
GDK_SELECTION_TYPE_STRING,
8*sizeof(gchar), (guchar *)str, length);
}
else if (selection_data->target == text_atom ||
selection_data->target == ctext_atom)
else if ((info == TARGET_TEXT) || (info == TARGET_COMPOUND_TEXT))
{
guchar *text;
gchar c;
@ -643,7 +633,8 @@ gtk_editable_selection_handler (GtkWidget *widget,
static void
gtk_editable_selection_received (GtkWidget *widget,
GtkSelectionData *selection_data)
GtkSelectionData *selection_data,
guint time)
{
GtkEditable *editable;
gint reselect;
@ -658,7 +649,8 @@ gtk_editable_selection_received (GtkWidget *widget,
if (selection_data->type == GDK_TARGET_STRING)
type = STRING;
else if (selection_data->type == ctext_atom)
else if ((selection_data->type == gdk_atom_intern ("COMPOUND_TEXT", FALSE)) ||
(selection_data->type == gdk_atom_intern ("TEXT", FALSE)))
type = CTEXT;
else
type = INVALID;
@ -668,7 +660,7 @@ gtk_editable_selection_received (GtkWidget *widget,
/* avoid infinite loop */
if (selection_data->target != GDK_TARGET_STRING)
gtk_selection_convert (widget, selection_data->selection,
GDK_TARGET_STRING, GDK_CURRENT_TIME);
GDK_TARGET_STRING, time);
return;
}
@ -934,7 +926,8 @@ gtk_editable_real_paste_clipboard (GtkEditable *editable)
time = gtk_editable_get_event_time (editable);
if (editable->editable)
gtk_selection_convert (GTK_WIDGET(editable),
clipboard_atom, ctext_atom, time);
clipboard_atom,
gdk_atom_intern ("COMPOUND_TEXT", FALSE), time);
}
void

View File

@ -22,6 +22,7 @@
#include <string.h>
#include <gmodule.h>
#include "gtkbutton.h"
#include "gtkdnd.h"
#include "gtkfeatures.h"
#include "gtkhscrollbar.h"
#include "gtkhseparator.h"
@ -224,7 +225,8 @@ guint gtk_debug_flags = 0; /* Global GTK debug flag */
static GDebugKey gtk_debug_keys[] = {
{"objects", GTK_DEBUG_OBJECTS},
{"misc", GTK_DEBUG_MISC},
{"signals", GTK_DEBUG_SIGNALS}
{"signals", GTK_DEBUG_SIGNALS},
{"dnd", GTK_DEBUG_DND}
};
static const guint gtk_ndebug_keys = sizeof (gtk_debug_keys) / sizeof (GDebugKey);
@ -764,6 +766,9 @@ gtk_main_iteration_do (gboolean blocking)
* 1) these events have no meaning for the grabbing widget
* and 2) redirecting these events to the grabbing widget
* could cause the display to be messed up.
*
* Drag events are also not redirected, since it isn't
* clear what the semantics of that would be.
*/
switch (event->type)
{
@ -797,11 +802,6 @@ gtk_main_iteration_do (gboolean blocking)
case GDK_SELECTION_REQUEST:
case GDK_SELECTION_NOTIFY:
case GDK_CLIENT_EVENT:
case GDK_DRAG_BEGIN:
case GDK_DRAG_REQUEST:
case GDK_DROP_ENTER:
case GDK_DROP_LEAVE:
case GDK_DROP_DATA_AVAIL:
case GDK_VISIBILITY_NOTIFY:
gtk_widget_event (event_widget, event);
break;
@ -821,7 +821,6 @@ gtk_main_iteration_do (gboolean blocking)
case GDK_BUTTON_RELEASE:
case GDK_PROXIMITY_IN:
case GDK_PROXIMITY_OUT:
case GDK_OTHER_EVENT:
gtk_propagate_event (grab_widget, event);
break;
@ -843,6 +842,17 @@ gtk_main_iteration_do (gboolean blocking)
else if (GTK_WIDGET_IS_SENSITIVE (grab_widget))
gtk_widget_event (grab_widget, event);
break;
case GDK_DRAG_STATUS:
case GDK_DROP_FINISHED:
gtk_drag_source_handle_event (event_widget, event);
break;
case GDK_DRAG_ENTER:
case GDK_DRAG_LEAVE:
case GDK_DRAG_MOTION:
case GDK_DROP_START:
gtk_drag_dest_handle_event (event_widget, event);
break;
}
tmp_list = current_events;

View File

@ -1,6 +1,8 @@
BOOL:NONE
BOOL:POINTER
BOOL:POINTER,POINTER,INT,INT
BOOL:POINTER,INT,INT
BOOL:POINTER,INT,INT,UINT
BOOL:POINTER,STRING,STRING,POINTER
ENUM:ENUM
INT:POINTER
@ -24,6 +26,8 @@ NONE:POINTER,POINTER,POINTER
NONE:POINTER,STRING,STRING
NONE:POINTER,UINT
NONE:POINTER,UINT,ENUM
NONE:POINTER,POINTER,UINT,UINT
NONE:POINTER,UINT,UINT
NONE:POINTER,UINT,UINT
NONE:STRING
NONE:STRING,INT,POINTER

View File

@ -1,6 +1,8 @@
BOOL:NONE
BOOL:POINTER
BOOL:POINTER,POINTER,INT,INT
BOOL:POINTER,INT,INT
BOOL:POINTER,INT,INT,UINT
BOOL:POINTER,STRING,STRING,POINTER
ENUM:ENUM
INT:POINTER
@ -24,6 +26,8 @@ NONE:POINTER,POINTER,POINTER
NONE:POINTER,STRING,STRING
NONE:POINTER,UINT
NONE:POINTER,UINT,ENUM
NONE:POINTER,POINTER,UINT,UINT
NONE:POINTER,UINT,UINT
NONE:POINTER,UINT,UINT
NONE:STRING
NONE:STRING,INT,POINTER

View File

@ -58,6 +58,10 @@ struct _GtkMenu
GtkMenuPositionFunc position_func;
gpointer position_func_data;
/* Do _not_ touch these widgets directly. We hide the reference
* count from the toplevel to the menu, so it must be restored
* before operating on these widgets
*/
GtkWidget *toplevel;
GtkWidget *tearoff_window;

View File

@ -70,7 +70,6 @@ typedef struct _GtkSelectionInfo GtkSelectionInfo;
typedef struct _GtkIncrConversion GtkIncrConversion;
typedef struct _GtkIncrInfo GtkIncrInfo;
typedef struct _GtkRetrievalInfo GtkRetrievalInfo;
typedef struct _GtkSelectionHandler GtkSelectionHandler;
struct _GtkSelectionInfo
{
@ -117,16 +116,7 @@ struct _GtkRetrievalInfo
guchar *buffer; /* Buffer in which to accumulate results */
gint offset; /* Current offset in buffer, -1 indicates
not yet started */
};
struct _GtkSelectionHandler
{
GdkAtom selection; /* selection thats handled */
GdkAtom target; /* target thats handled */
GtkSelectionFunction function; /* callback function */
GtkCallbackMarshal marshal; /* Marshalling function */
gpointer data; /* callback data */
GtkDestroyNotify destroy; /* called when callback is removed */
guint32 notify_time; /* Timestamp from SelectionNotify */
};
/* Local Functions */
@ -135,9 +125,11 @@ static gint gtk_selection_incr_timeout (GtkIncrInfo *info);
static gint gtk_selection_retrieval_timeout (GtkRetrievalInfo *info);
static void gtk_selection_retrieval_report (GtkRetrievalInfo *info,
GdkAtom type, gint format,
guchar *buffer, gint length);
guchar *buffer, gint length,
guint32 time);
static void gtk_selection_invoke_handler (GtkWidget *widget,
GtkSelectionData *data);
GtkSelectionData *data,
guint time);
static void gtk_selection_default_handler (GtkWidget *widget,
GtkSelectionData *data);
@ -150,6 +142,136 @@ static GList *current_selections = NULL;
static GdkAtom gtk_selection_atoms[LAST_ATOM];
static const char *gtk_selection_handler_key = "gtk-selection-handlers";
/****************
* Target Lists *
****************/
/*
* Target lists
*/
GtkTargetList *
gtk_target_list_new (GtkTargetEntry *targets,
guint ntargets)
{
GtkTargetList *result = g_new (GtkTargetList, 1);
result->list = NULL;
result->ref_count = 1;
if (targets)
gtk_target_list_add_table (result, targets, ntargets);
return result;
}
void
gtk_target_list_ref (GtkTargetList *list)
{
list->ref_count++;
}
void
gtk_target_list_unref (GtkTargetList *list)
{
list->ref_count--;
if (list->ref_count == 0)
{
GList *tmp_list = list->list;
while (tmp_list)
{
GtkTargetEntry *entry = tmp_list->data;
g_free (entry);
tmp_list = tmp_list->next;
}
}
}
void
gtk_target_list_add (GtkTargetList *list,
GdkAtom target,
guint flags,
guint info)
{
GtkTargetPair *pair;
g_return_if_fail (list != NULL);
pair = g_new (GtkTargetPair, 1);
pair->target = target;
pair->flags = flags;
pair->info = info;
list->list = g_list_append (list->list, pair);
}
void
gtk_target_list_add_table (GtkTargetList *list,
GtkTargetEntry *targets,
guint ntargets)
{
gint i;
for (i=ntargets-1; i >= 0; i--)
{
GtkTargetPair *pair = g_new (GtkTargetPair, 1);
pair->target = gdk_atom_intern (targets[i].target, FALSE);
pair->flags = targets[i].flags;
pair->info = targets[i].info;
list->list = g_list_prepend (list->list, pair);
}
}
void
gtk_target_list_remove (GtkTargetList *list,
GdkAtom target)
{
GList *tmp_list;
g_return_if_fail (list != NULL);
tmp_list = list->list;
while (tmp_list)
{
GtkTargetPair *pair = tmp_list->data;
if (pair->target == target)
{
g_free (pair);
list->list = g_list_remove (list->list, tmp_list);
g_list_free_1 (tmp_list);
return;
}
tmp_list = tmp_list->next;
}
}
gboolean
gtk_target_list_find (GtkTargetList *list,
GdkAtom target,
guint *info)
{
GList *tmp_list = list->list;
while (tmp_list)
{
GtkTargetPair *pair = tmp_list->data;
if (pair->target == target)
{
*info = pair->info;
return TRUE;
}
tmp_list = tmp_list->next;
}
return FALSE;
}
/*************************************************************
* gtk_selection_owner_set:
* Claim ownership of a selection.
@ -252,95 +374,105 @@ gtk_selection_owner_set (GtkWidget *widget,
}
/*************************************************************
* gtk_selection_add_handler_full:
* Add a handler for a specified selection/target pair
* gtk_selection_add_target
* Add specified target to list of supported targets
*
* arguments:
* widget: The widget the handler applies to
* widget: The widget for which this target applies
* selection:
* target:
* format: Format in which this handler will return data
* function: Callback function (can be NULL)
* marshal: Callback marshal function
* data: User data for callback
* destroy: Called when handler removed
* info: guint to pass to to the selection_get signal
*
* results:
*************************************************************/
void
gtk_selection_add_handler (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,
GtkSelectionFunction function,
gpointer data)
typedef struct _GtkSelectionTargetList GtkSelectionTargetList;
struct _GtkSelectionTargetList {
GdkAtom selection;
GtkTargetList *list;
};
static GtkTargetList *
gtk_selection_target_list_get (GtkWidget *widget,
GdkAtom selection)
{
gtk_selection_add_handler_full (widget, selection, target, function,
NULL, data, NULL);
GtkSelectionTargetList *sellist;
GList *tmp_list;
GList *lists;
lists = gtk_object_get_data (GTK_OBJECT (widget), gtk_selection_handler_key);
tmp_list = lists;
while (tmp_list)
{
sellist = tmp_list->data;
if (sellist->selection == selection)
return sellist->list;
tmp_list = tmp_list->next;
}
sellist = g_new (GtkSelectionTargetList, 1);
sellist->selection = selection;
sellist->list = gtk_target_list_new (NULL, 0);
lists = g_list_prepend (lists, sellist);
gtk_object_set_data (GTK_OBJECT (widget), gtk_selection_handler_key, lists);
return sellist->list;
}
static void
gtk_selection_target_list_remove (GtkWidget *widget)
{
GtkSelectionTargetList *sellist;
GList *tmp_list;
GList *lists;
lists = gtk_object_get_data (GTK_OBJECT (widget), gtk_selection_handler_key);
tmp_list = lists;
while (tmp_list)
{
sellist = tmp_list->data;
gtk_target_list_unref (sellist->list);
g_free (sellist);
tmp_list = tmp_list->next;
}
g_list_free (lists);
gtk_object_set_data (GTK_OBJECT (widget), gtk_selection_handler_key, NULL);
}
void
gtk_selection_add_handler_full (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,
GtkSelectionFunction function,
GtkCallbackMarshal marshal,
gpointer data,
GtkDestroyNotify destroy)
gtk_selection_add_target (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,
guint info)
{
GList *selection_handlers;
GList *tmp_list;
GtkSelectionHandler *handler;
GtkTargetList *list;
g_return_if_fail (widget != NULL);
list = gtk_selection_target_list_get (widget, selection);
gtk_target_list_add (list, target, 0, info);
}
void
gtk_selection_add_targets (GtkWidget *widget,
GdkAtom selection,
GtkTargetEntry *targets,
guint ntargets)
{
GtkTargetList *list;
g_return_if_fail (widget != NULL);
if (initialize)
gtk_selection_init ();
g_return_if_fail (targets != NULL);
selection_handlers = gtk_object_get_data (GTK_OBJECT (widget),
gtk_selection_handler_key);
/* Reuse old handler structure, if present */
tmp_list = selection_handlers;
while (tmp_list)
{
handler = (GtkSelectionHandler *)tmp_list->data;
if ((handler->selection == selection) && (handler->target == target))
{
if (handler->destroy)
(*handler->destroy)(handler->data);
if (function)
{
handler->function = function;
handler->marshal = marshal;
handler->data = data;
handler->destroy = destroy;
}
else
{
selection_handlers = g_list_remove_link (selection_handlers,
tmp_list);
g_list_free (tmp_list);
g_free (handler);
}
return;
}
tmp_list = tmp_list->next;
}
if (tmp_list == NULL && function)
{
handler = g_new (GtkSelectionHandler, 1);
handler->selection = selection;
handler->target = target;
handler->function = function;
handler->marshal = marshal;
handler->data = data;
handler->destroy = destroy;
selection_handlers = g_list_append (selection_handlers, handler);
}
gtk_object_set_data (GTK_OBJECT (widget), gtk_selection_handler_key,
selection_handlers);
list = gtk_selection_target_list_get (widget, selection);
gtk_target_list_add_table (list, targets, ntargets);
}
/*************************************************************
@ -360,8 +492,6 @@ gtk_selection_remove_all (GtkWidget *widget)
GList *tmp_list;
GList *next;
GtkSelectionInfo *selection_info;
GList *selection_handlers;
GtkSelectionHandler *handler;
/* Remove pending requests/incrs for this widget */
@ -413,28 +543,9 @@ gtk_selection_remove_all (GtkWidget *widget)
tmp_list = next;
}
/* Now remove all handlers */
selection_handlers = gtk_object_get_data (GTK_OBJECT (widget),
gtk_selection_handler_key);
gtk_object_remove_data (GTK_OBJECT (widget), gtk_selection_handler_key);
tmp_list = selection_handlers;
while (tmp_list)
{
next = tmp_list->next;
handler = (GtkSelectionHandler *)tmp_list->data;
if (handler->destroy)
(*handler->destroy)(handler->data);
g_free (handler);
tmp_list = next;
}
g_list_free (selection_handlers);
/* Remove all selection lists */
gtk_selection_target_list_remove (widget);
}
/*************************************************************
@ -516,13 +627,15 @@ gtk_selection_convert (GtkWidget *widget,
if (owner_widget != NULL)
{
gtk_selection_invoke_handler (owner_widget,
&selection_data);
&selection_data,
time);
gtk_selection_retrieval_report (info,
selection_data.type,
selection_data.format,
selection_data.data,
selection_data.length);
selection_data.length,
time);
g_free (selection_data.data);
@ -666,6 +779,9 @@ gtk_selection_request (GtkWidget *widget,
guchar *mult_atoms;
int i;
if (initialize)
gtk_selection_init ();
/* Check if we own selection */
tmp_list = current_selections;
@ -704,10 +820,9 @@ gtk_selection_request (GtkWidget *widget,
gint length;
mult_atoms = NULL;
if (!gdk_property_get (info->requestor, event->property, GDK_SELECTION_TYPE_ATOM,
if (!gdk_property_get (info->requestor, event->property, 0, /* AnyPropertyType */
0, GTK_SELECTION_MAX_SIZE, FALSE,
&type, &format, &length, &mult_atoms) ||
type != GDK_SELECTION_TYPE_ATOM || format != 8*sizeof(GdkAtom))
&type, &format, &length, &mult_atoms))
{
gdk_selection_send_notify (event->requestor, event->selection,
event->target, GDK_NONE, event->time);
@ -753,7 +868,7 @@ gtk_selection_request (GtkWidget *widget,
event->requestor, event->property);
#endif
gtk_selection_invoke_handler (widget, &data);
gtk_selection_invoke_handler (widget, &data, event->time);
if (data.length < 0)
{
@ -822,7 +937,7 @@ gtk_selection_request (GtkWidget *widget,
gdk_property_change (info->requestor, event->property,
GDK_SELECTION_TYPE_ATOM, 8*sizeof(GdkAtom),
GDK_PROP_MODE_REPLACE,
mult_atoms, info->num_conversions);
mult_atoms, 2*info->num_conversions);
g_free (mult_atoms);
}
@ -1051,7 +1166,7 @@ gtk_selection_notify (GtkWidget *widget,
g_list_free (tmp_list);
/* structure will be freed in timeout */
gtk_selection_retrieval_report (info,
GDK_NONE, 0, NULL, -1);
GDK_NONE, 0, NULL, -1, event->time);
return TRUE;
}
@ -1063,7 +1178,8 @@ gtk_selection_notify (GtkWidget *widget,
{
/* The remainder of the selection will come through PropertyNotify
events */
info->notify_time = event->time;
info->idle_time = 0;
info->offset = 0; /* Mark as OK to proceed */
gdk_window_set_events (widget->window,
@ -1079,7 +1195,7 @@ gtk_selection_notify (GtkWidget *widget,
info->offset = length;
gtk_selection_retrieval_report (info,
type, format,
buffer, length);
buffer, length, event->time);
}
gdk_property_delete (widget->window, event->property);
@ -1157,7 +1273,8 @@ gtk_selection_property_notify (GtkWidget *widget,
gtk_selection_retrieval_report (info,
type, format,
(type == GDK_NONE) ? NULL : info->buffer,
(type == GDK_NONE) ? -1 : info->offset);
(type == GDK_NONE) ? -1 : info->offset,
info->notify_time);
}
else /* append on newly arrived data */
{
@ -1219,7 +1336,7 @@ gtk_selection_retrieval_timeout (GtkRetrievalInfo *info)
{
current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
g_list_free (tmp_list);
gtk_selection_retrieval_report (info, GDK_NONE, 0, NULL, -1);
gtk_selection_retrieval_report (info, GDK_NONE, 0, NULL, -1, GDK_CURRENT_TIME);
}
g_free (info->buffer);
@ -1242,13 +1359,15 @@ gtk_selection_retrieval_timeout (GtkRetrievalInfo *info)
* arguments:
* info: information about the retrieval that completed
* buffer: buffer containing data (NULL => errror)
* time: timestamp for data in buffer
* results:
*************************************************************/
static void
gtk_selection_retrieval_report (GtkRetrievalInfo *info,
GdkAtom type, gint format,
guchar *buffer, gint length)
guchar *buffer, gint length,
guint32 time)
{
GtkSelectionData data;
@ -1261,7 +1380,8 @@ gtk_selection_retrieval_report (GtkRetrievalInfo *info,
data.data = buffer;
gtk_signal_emit_by_name (GTK_OBJECT(info->widget),
"selection_received", &data);
"selection_received",
&data, time);
}
/*************************************************************
@ -1273,6 +1393,7 @@ gtk_selection_retrieval_report (GtkRetrievalInfo *info,
* arguments:
* widget: selection owner
* data: selection data [INOUT]
* time: time from requeset
*
* results:
* Number of bytes written to buffer, -1 if error
@ -1280,44 +1401,26 @@ gtk_selection_retrieval_report (GtkRetrievalInfo *info,
static void
gtk_selection_invoke_handler (GtkWidget *widget,
GtkSelectionData *data)
GtkSelectionData *data,
guint time)
{
GList *tmp_list;
GtkSelectionHandler *handler;
GtkTargetList *target_list;
guint info;
g_return_if_fail (widget != NULL);
tmp_list = gtk_object_get_data (GTK_OBJECT (widget),
gtk_selection_handler_key);
while (tmp_list)
target_list = gtk_selection_target_list_get (widget, data->selection);
if (target_list &&
gtk_target_list_find (target_list, data->target, &info))
{
handler = (GtkSelectionHandler *)tmp_list->data;
if ((handler->selection == data->selection) &&
(handler->target == data->target))
break;
tmp_list = tmp_list->next;
gtk_signal_emit_by_name (GTK_OBJECT (widget),
"selection_get",
data,
info, time);
}
if (tmp_list == NULL)
gtk_selection_default_handler (widget, data);
else
{
if (handler->marshal)
{
GtkArg args[2];
args[0].type = GTK_TYPE_BOXED;
args[0].name = NULL;
GTK_VALUE_BOXED(args[0]) = data;
args[1].type = GTK_TYPE_NONE;
args[1].name = NULL;
handler->marshal (GTK_OBJECT(widget), handler->data, 1, args);
}
else
if (handler->function)
handler->function (widget, data, handler->data);
}
gtk_selection_default_handler (widget, data);
}
/*************************************************************
@ -1369,18 +1472,16 @@ gtk_selection_default_handler (GtkWidget *widget,
GdkAtom *p;
gint count;
GList *tmp_list;
GtkSelectionHandler *handler;
GtkTargetList *target_list;
GtkTargetPair *pair;
count = 3;
tmp_list = gtk_object_get_data (GTK_OBJECT(widget),
gtk_selection_handler_key);
target_list = gtk_selection_target_list_get (widget,
data->selection);
tmp_list = target_list->list;
while (tmp_list)
{
handler = (GtkSelectionHandler *)tmp_list->data;
if (handler->selection == data->selection)
count++;
count++;
tmp_list = tmp_list->next;
}
@ -1395,14 +1496,11 @@ gtk_selection_default_handler (GtkWidget *widget,
*p++ = gtk_selection_atoms[TARGETS];
*p++ = gtk_selection_atoms[MULTIPLE];
tmp_list = gtk_object_get_data (GTK_OBJECT(widget),
gtk_selection_handler_key);
tmp_list = target_list->list;
while (tmp_list)
{
handler = (GtkSelectionHandler *)tmp_list->data;
if (handler->selection == data->selection)
*p++ = handler->target;
pair = (GtkTargetPair *)tmp_list->data;
*p++ = pair->target;
tmp_list = tmp_list->next;
}

View File

@ -29,36 +29,63 @@ extern "C" {
#endif /* __cplusplus */
typedef struct _GtkSelectionData GtkSelectioData;
typedef struct _GtkTargetList GtkTargetList;
typedef struct _GtkTargetEntry GtkTargetEntry;
/* a callback function that provides the selection. Arguments are:
widget: selection owner
offset: offset into selection
buffer: buffer into which to store selection
length: length of buffer
bytes_after: (sizeof(selection) - offset - length ) (return)
data: callback data */
struct _GtkTargetEntry {
gchar *target;
guint flags;
guint info;
};
typedef void (*GtkSelectionFunction) (GtkWidget *widget,
GtkSelectionData *selection_data,
gpointer data);
/* These structures not public, and are here only for the convenience of
* gtkdnd.c
*/
typedef struct _GtkTargetPair GtkTargetPair;
/* This structure is a list of destinations, and associated guint id's */
struct _GtkTargetList {
GList *list;
guint ref_count;
};
struct _GtkTargetPair {
GdkAtom target;
guint flags;
guint info;
};
GtkTargetList *gtk_target_list_new (GtkTargetEntry *targets,
guint ntargets);
void gtk_target_list_ref (GtkTargetList *list);
void gtk_target_list_unref (GtkTargetList *list);
void gtk_target_list_add (GtkTargetList *list,
GdkAtom target,
guint flags,
guint info);
void gtk_target_list_add_table (GtkTargetList *list,
GtkTargetEntry *targets,
guint ntargets);
void gtk_target_list_remove (GtkTargetList *list,
GdkAtom target);
gboolean gtk_target_list_find (GtkTargetList *list,
GdkAtom target,
guint *info);
/* Public interface */
gint gtk_selection_owner_set (GtkWidget *widget,
GdkAtom selection,
guint32 time);
void gtk_selection_add_handler (GtkWidget *widget,
void gtk_selection_add_target (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,
guint info);
void gtk_selection_add_targets (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,
GtkSelectionFunction function,
gpointer data);
void gtk_selection_add_handler_full (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,
GtkSelectionFunction function,
GtkCallbackMarshal marshal,
gpointer data,
GtkDestroyNotify destroy);
GtkTargetEntry *targets,
guint ntargets);
gint gtk_selection_convert (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,

View File

@ -290,7 +290,7 @@ gtk_signal_newv (const gchar *r_name,
if (return_val != GTK_TYPE_NONE &&
(signal_flags & GTK_RUN_BOTH) == GTK_RUN_FIRST)
{
g_warning ("gtk_signal_newv(): signal \"%s\" with return value `%s' excludes GTK_RUN_LAST",
g_warning ("gtk_signal_newv(): signal \"%s\" - return value `%s' incompatible with GTK_RUN_FIRST",
name, gtk_type_name (return_val));
g_free (name);
return 0;

View File

@ -28,7 +28,6 @@
extern "C" {
#endif /* __cplusplus */
typedef struct _GtkStyle GtkStyle;
typedef struct _GtkStyleClass GtkStyleClass;

View File

@ -72,16 +72,18 @@ enum {
SELECTION_CLEAR_EVENT,
SELECTION_REQUEST_EVENT,
SELECTION_NOTIFY_EVENT,
SELECTION_GET,
SELECTION_RECEIVED,
PROXIMITY_IN_EVENT,
PROXIMITY_OUT_EVENT,
DRAG_BEGIN_EVENT,
DRAG_REQUEST_EVENT,
DRAG_END_EVENT,
DROP_ENTER_EVENT,
DROP_LEAVE_EVENT,
DROP_DATA_AVAILABLE_EVENT,
OTHER_EVENT,
DRAG_BEGIN,
DRAG_END,
DRAG_DATA_DELETE,
DRAG_LEAVE,
DRAG_MOTION,
DRAG_DROP,
DRAG_DATA_GET,
DRAG_DATA_RECEIVED,
CLIENT_EVENT,
NO_EXPOSE_EVENT,
VISIBILITY_NOTIFY_EVENT,
@ -548,9 +550,20 @@ gtk_widget_class_init (GtkWidgetClass *klass)
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_received),
gtk_marshal_NONE__ENUM,
GTK_TYPE_NONE, 1,
GTK_TYPE_SELECTION_DATA);
gtk_marshal_NONE__POINTER_UINT,
GTK_TYPE_NONE, 2,
GTK_TYPE_SELECTION_DATA,
GTK_TYPE_UINT);
widget_signals[SELECTION_GET] =
gtk_signal_new ("selection_get",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_get),
gtk_marshal_NONE__POINTER_UINT_UINT,
GTK_TYPE_NONE, 2,
GTK_TYPE_SELECTION_DATA,
GTK_TYPE_UINT,
GTK_TYPE_UINT);
widget_signals[PROXIMITY_IN_EVENT] =
gtk_signal_new ("proximity_in_event",
GTK_RUN_LAST,
@ -567,55 +580,83 @@ gtk_widget_class_init (GtkWidgetClass *klass)
gtk_marshal_BOOL__POINTER,
GTK_TYPE_BOOL, 1,
GTK_TYPE_GDK_EVENT);
widget_signals[DRAG_BEGIN_EVENT] =
gtk_signal_new ("drag_begin_event",
widget_signals[DRAG_LEAVE] =
gtk_signal_new ("drag_leave",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_begin_event),
gtk_marshal_BOOL__POINTER,
GTK_TYPE_BOOL, 1,
GTK_TYPE_GDK_EVENT);
widget_signals[DRAG_REQUEST_EVENT] =
gtk_signal_new ("drag_request_event",
GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_leave),
gtk_marshal_NONE__POINTER_UINT,
GTK_TYPE_NONE, 2,
GTK_TYPE_GDK_DRAG_CONTEXT,
GTK_TYPE_UINT);
widget_signals[DRAG_BEGIN] =
gtk_signal_new ("drag_begin",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_request_event),
gtk_marshal_BOOL__POINTER,
GTK_TYPE_BOOL, 1,
GTK_TYPE_GDK_EVENT);
widget_signals[DRAG_END_EVENT] =
gtk_signal_new ("drag_end_event",
GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_begin),
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1,
GTK_TYPE_GDK_DRAG_CONTEXT);
widget_signals[DRAG_END] =
gtk_signal_new ("drag_end",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_end_event),
gtk_marshal_BOOL__POINTER,
GTK_TYPE_BOOL, 1,
GTK_TYPE_GDK_EVENT);
widget_signals[DROP_ENTER_EVENT] =
gtk_signal_new ("drop_enter_event",
GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_end),
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1,
GTK_TYPE_GDK_DRAG_CONTEXT);
widget_signals[DRAG_DATA_DELETE] =
gtk_signal_new ("drag_data_delete",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkWidgetClass, drop_enter_event),
gtk_marshal_BOOL__POINTER,
GTK_TYPE_BOOL, 1,
GTK_TYPE_GDK_EVENT);
widget_signals[DROP_LEAVE_EVENT] =
gtk_signal_new ("drop_leave_event",
GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_delete),
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1,
GTK_TYPE_GDK_DRAG_CONTEXT);
widget_signals[DRAG_MOTION] =
gtk_signal_new ("drag_motion",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkWidgetClass, drop_leave_event),
gtk_marshal_BOOL__POINTER,
GTK_TYPE_BOOL, 1,
GTK_TYPE_GDK_EVENT);
widget_signals[DROP_DATA_AVAILABLE_EVENT] =
gtk_signal_new ("drop_data_available_event",
GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_motion),
gtk_marshal_BOOL__POINTER_INT_INT_UINT,
GTK_TYPE_BOOL, 4,
GTK_TYPE_GDK_DRAG_CONTEXT,
GTK_TYPE_INT,
GTK_TYPE_INT,
GTK_TYPE_UINT);
widget_signals[DRAG_DROP] =
gtk_signal_new ("drag_drop",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkWidgetClass,
drop_data_available_event),
gtk_marshal_BOOL__POINTER,
GTK_TYPE_BOOL, 1,
GTK_TYPE_GDK_EVENT);
GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_drop),
gtk_marshal_BOOL__POINTER_INT_INT_UINT,
GTK_TYPE_BOOL, 4,
GTK_TYPE_GDK_DRAG_CONTEXT,
GTK_TYPE_INT,
GTK_TYPE_INT,
GTK_TYPE_UINT);
widget_signals[DRAG_DATA_GET] =
gtk_signal_new ("drag_data_get",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_get),
gtk_marshal_NONE__POINTER_POINTER_UINT_UINT,
GTK_TYPE_NONE, 4,
GTK_TYPE_GDK_DRAG_CONTEXT,
GTK_TYPE_SELECTION_DATA,
GTK_TYPE_UINT,
GTK_TYPE_UINT);
widget_signals[DRAG_DATA_RECEIVED] =
gtk_signal_new ("drag_data_received",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_received),
gtk_marshal_NONE__POINTER_POINTER_UINT_UINT,
GTK_TYPE_NONE, 4,
GTK_TYPE_GDK_DRAG_CONTEXT,
GTK_TYPE_SELECTION_DATA,
GTK_TYPE_UINT,
GTK_TYPE_UINT);
widget_signals[VISIBILITY_NOTIFY_EVENT] =
gtk_signal_new ("visibility_notify_event",
GTK_RUN_LAST,
@ -640,14 +681,6 @@ gtk_widget_class_init (GtkWidgetClass *klass)
gtk_marshal_BOOL__POINTER,
GTK_TYPE_BOOL, 1,
GTK_TYPE_GDK_EVENT);
widget_signals[OTHER_EVENT] =
gtk_signal_new ("other_event",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkWidgetClass, other_event),
gtk_marshal_BOOL__POINTER,
GTK_TYPE_BOOL, 1,
GTK_TYPE_GDK_EVENT);
widget_signals[DEBUG_MSG] =
gtk_signal_new ("debug_msg",
GTK_RUN_LAST | GTK_RUN_ACTION,
@ -706,13 +739,15 @@ gtk_widget_class_init (GtkWidgetClass *klass)
klass->selection_received = NULL;
klass->proximity_in_event = NULL;
klass->proximity_out_event = NULL;
klass->drag_begin_event = NULL;
klass->drag_request_event = NULL;
klass->drop_enter_event = NULL;
klass->drop_leave_event = NULL;
klass->drop_data_available_event = NULL;
klass->drag_begin = NULL;
klass->drag_end = NULL;
klass->drag_data_delete = NULL;
klass->drag_leave = NULL;
klass->drag_motion = NULL;
klass->drag_drop = NULL;
klass->drag_data_received = NULL;
klass->no_expose_event = NULL;
klass->other_event = NULL;
klass->debug_msg = gtk_widget_debug_msg;
}
@ -2071,24 +2106,6 @@ gtk_widget_event (GtkWidget *widget,
case GDK_PROXIMITY_OUT:
signal_num = PROXIMITY_OUT_EVENT;
break;
case GDK_DRAG_BEGIN:
signal_num = DRAG_BEGIN_EVENT;
break;
case GDK_DRAG_REQUEST:
signal_num = DRAG_REQUEST_EVENT;
break;
case GDK_DROP_ENTER:
signal_num = DROP_ENTER_EVENT;
break;
case GDK_DROP_LEAVE:
signal_num = DROP_LEAVE_EVENT;
break;
case GDK_DROP_DATA_AVAIL:
signal_num = DROP_DATA_AVAILABLE_EVENT;
break;
case GDK_OTHER_EVENT:
signal_num = OTHER_EVENT;
break;
case GDK_NO_EXPOSE:
signal_num = NO_EXPOSE_EVENT;
break;
@ -2999,6 +3016,51 @@ gtk_widget_set_events (GtkWidget *widget,
}
}
/*****************************************
* gtk_widget_add_events:
*
* arguments:
*
* results:
*****************************************/
void
gtk_widget_add_events (GtkWidget *widget,
gint events)
{
gint *eventp;
g_return_if_fail (widget != NULL);
g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
if (events)
{
if (!eventp)
{
eventp = g_new (gint, 1);
*eventp = 0;
}
*eventp |= events;
if (!event_key_id)
event_key_id = g_quark_from_static_string (event_key);
gtk_object_set_data_by_id (GTK_OBJECT (widget), event_key_id, eventp);
}
else if (eventp)
{
g_free (eventp);
gtk_object_remove_data_by_id (GTK_OBJECT (widget), event_key_id);
}
if (GTK_WIDGET_REALIZED (widget))
{
gdk_window_set_events (widget->window,
gdk_window_get_events (widget->window) | events);
}
}
/*****************************************
* gtk_widget_set_extension_events:
*
@ -3949,96 +4011,6 @@ gtk_widget_shape_combine_mask (GtkWidget *widget,
}
}
/*****************************************
* gtk_widget_dnd_drag_add:
* when you get a DRAG_ENTER event, you can use this
* to tell Gtk ofother widgets that are to be dragged as well
*
* arguments:
*
* results:
*****************************************/
void
gtk_widget_dnd_drag_add (GtkWidget *widget)
{
}
/*****************************************
* gtk_widget_dnd_drag_set:
* these two functions enable drag and/or drop on a
* widget and also let Gtk know what data types will be accepted
* use MIME type naming,plus tacking "URL:" on the front for link
* dragging
*
*
* arguments:
*
* results:
*****************************************/
void
gtk_widget_dnd_drag_set (GtkWidget *widget,
guint8 drag_enable,
gchar **type_accept_list,
guint numtypes)
{
g_return_if_fail(widget != NULL);
if (!widget->window)
gtk_widget_realize (widget);
g_return_if_fail (widget->window != NULL);
gdk_window_dnd_drag_set (widget->window,
drag_enable,
type_accept_list,
numtypes);
}
/*****************************************
* gtk_widget_dnd_drop_set:
*
* arguments:
*
* results:
*****************************************/
void
gtk_widget_dnd_drop_set (GtkWidget *widget,
guint8 drop_enable,
gchar **type_accept_list,
guint numtypes,
guint8 is_destructive_operation)
{
g_return_if_fail(widget != NULL);
if (!widget->window)
gtk_widget_realize (widget);
g_return_if_fail (widget->window != NULL);
gdk_window_dnd_drop_set (widget->window,
drop_enable,
type_accept_list,
numtypes,
is_destructive_operation);
}
/*****************************************
* gtk_widget_dnd_data_set:
*
* arguments:
*
* results:
*****************************************/
void
gtk_widget_dnd_data_set (GtkWidget *widget,
GdkEvent *event,
gpointer data,
gulong data_numbytes)
{
g_return_if_fail (widget != NULL);
g_return_if_fail (widget->window != NULL);
gdk_window_dnd_data_set (widget->window, event, data, data_numbytes);
}
void
gtk_widget_ref (GtkWidget *widget)
{

View File

@ -136,7 +136,7 @@ struct _GtkAllocation
no fields should be modified directly, they should not be created
directly, and pointers to them should not be stored beyond the duration of
a callback. (If the last is changed, we'll need to add reference
counting) */
counting.) The time field gives the timestamp at which the data was sent. */
struct _GtkSelectionData
{
@ -314,31 +314,55 @@ struct _GtkWidgetClass
GdkEventProximity *event);
gint (* proximity_out_event) (GtkWidget *widget,
GdkEventProximity *event);
gint (* drag_begin_event) (GtkWidget *widget,
GdkEventDragBegin *event);
gint (* drag_request_event) (GtkWidget *widget,
GdkEventDragRequest *event);
gint (* drag_end_event) (GtkWidget *widget,
GdkEvent *event);
gint (* drop_enter_event) (GtkWidget *widget,
GdkEventDropEnter *event);
gint (* drop_leave_event) (GtkWidget *widget,
GdkEventDropLeave *event);
gint (* drop_data_available_event)(GtkWidget *widget,
GdkEventDropDataAvailable *event);
gint (* visibility_notify_event) (GtkWidget *widget,
GdkEventVisibility *event);
gint (* client_event) (GtkWidget *widget,
GdkEventClient *event);
gint (* no_expose_event) (GtkWidget *widget,
GdkEventAny *event);
gint (* other_event) (GtkWidget *widget,
GdkEventOther *event);
/* selection */
void (* selection_received) (GtkWidget *widget,
GtkSelectionData *selection_data);
/* selection */
void (* selection_get) (GtkWidget *widget,
GtkSelectionData *selection_data,
guint info,
guint time);
void (* selection_received) (GtkWidget *widget,
GtkSelectionData *selection_data,
guint time);
/* Source side drag signals */
void (* drag_begin) (GtkWidget *widget,
GdkDragContext *context);
void (* drag_end) (GtkWidget *widget,
GdkDragContext *context);
void (* drag_data_get) (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint32 time);
void (* drag_data_delete) (GtkWidget *widget,
GdkDragContext *context);
/* Target side drag signals */
void (* drag_leave) (GtkWidget *widget,
GdkDragContext *context,
guint time);
gboolean (* drag_motion) (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
guint time);
gboolean (* drag_drop) (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
guint time);
void (* drag_data_received) (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint32 time);
/* action signals */
void (* debug_msg) (GtkWidget *widget,
const gchar *string);
@ -460,6 +484,8 @@ void gtk_widget_set_usize (GtkWidget *widget,
gint height);
void gtk_widget_set_events (GtkWidget *widget,
gint events);
void gtk_widget_add_events (GtkWidget *widget,
gint events);
void gtk_widget_set_extension_events (GtkWidget *widget,
GdkExtensionMode mode);
@ -536,33 +562,6 @@ void gtk_widget_class_path (GtkWidget *widget,
gchar **path,
gchar **path_reversed);
/* When you get a drag_enter event, you can use this to tell Gtk of other
* items that are to be dragged as well...
*/
void gtk_widget_dnd_drag_add (GtkWidget *widget);
/* These two functions enable drag and/or drop on a widget,
* and also let Gtk know what data types will be accepted (use MIME
* type naming, plus tacking "URL:" on the front for link dragging)
*/
void gtk_widget_dnd_drag_set (GtkWidget *widget,
guint8 drag_enable,
gchar **type_accept_list,
guint numtypes);
void gtk_widget_dnd_drop_set (GtkWidget *widget,
guint8 drop_enable,
gchar **type_accept_list,
guint numtypes,
guint8 is_destructive_operation);
/* Used to reply to a DRAG_REQUEST event - if you don't want to
* give the data then pass in NULL for it
*/
void gtk_widget_dnd_data_set (GtkWidget *widget,
GdkEvent *event,
gpointer data,
gulong data_numbytes);
#if defined (GTK_TRACE_OBJECTS) && defined (__GNUC__)
# define gtk_widget_ref gtk_object_ref
# define gtk_widget_unref gtk_object_unref

View File

@ -6039,6 +6039,7 @@ create_panes (void)
* Drag -N- Drop
*/
#if 0
gint
dnd_drop_destroy_popup (GtkWidget *widget, GtkWindow **window)
{
@ -6263,6 +6264,7 @@ create_dnd (void)
else
gtk_widget_destroy (window);
}
#endif
/*
* Shaped Windows
@ -7908,7 +7910,7 @@ create_main_window (void)
{ "ctree", create_ctree },
{ "cursors", create_cursors },
{ "dialog", create_dialog },
{ "dnd", create_dnd },
/* { "dnd", create_dnd }, */
{ "entry", create_entry },
{ "file selection", create_file_selection },
{ "font selection", create_font_selection },

View File

@ -48,50 +48,49 @@ typedef struct _Target {
SelType type;
GdkAtom target;
gint format;
GtkSelectionFunction *handler;
} Target;
/* The following is a list of all the selection targets defined
in the ICCCM */
static Target targets[] = {
{ "ADOBE_PORTABLE_DOCUMENT_FORMAT", STRING, 0, 8, NULL },
{ "APPLE_PICT", APPLE_PICT, 0, 8, NULL },
{ "BACKGROUND", PIXEL, 0, 32, NULL },
{ "BITMAP", BITMAP, 0, 32, NULL },
{ "CHARACTER_POSITION", SPAN, 0, 32, NULL },
{ "CLASS", TEXT, 0, 8, NULL },
{ "CLIENT_WINDOW", WINDOW, 0, 32, NULL },
{ "COLORMAP", COLORMAP, 0, 32, NULL },
{ "COLUMN_NUMBER", SPAN, 0, 32, NULL },
{ "COMPOUND_TEXT", COMPOUND_TEXT, 0, 8, NULL },
/* { "DELETE", "NULL", 0, ?, NULL }, */
{ "DRAWABLE", DRAWABLE, 0, 32, NULL },
{ "ENCAPSULATED_POSTSCRIPT", STRING, 0, 8, NULL },
{ "ENCAPSULATED_POSTSCRIPT_INTERCHANGE", STRING, 0, 8, NULL },
{ "FILE_NAME", TEXT, 0, 8, NULL },
{ "FOREGROUND", PIXEL, 0, 32, NULL },
{ "HOST_NAME", TEXT, 0, 8, NULL },
{ "ADOBE_PORTABLE_DOCUMENT_FORMAT", STRING, 0, 8 },
{ "APPLE_PICT", APPLE_PICT, 0, 8 },
{ "BACKGROUND", PIXEL, 0, 32 },
{ "BITMAP", BITMAP, 0, 32 },
{ "CHARACTER_POSITION", SPAN, 0, 32 },
{ "CLASS", TEXT, 0, 8 },
{ "CLIENT_WINDOW", WINDOW, 0, 32 },
{ "COLORMAP", COLORMAP, 0, 32 },
{ "COLUMN_NUMBER", SPAN, 0, 32 },
{ "COMPOUND_TEXT", COMPOUND_TEXT, 0, 8 },
/* { "DELETE", "NULL", 0, ? }, */
{ "DRAWABLE", DRAWABLE, 0, 32 },
{ "ENCAPSULATED_POSTSCRIPT", STRING, 0, 8 },
{ "ENCAPSULATED_POSTSCRIPT_INTERCHANGE", STRING, 0, 8 },
{ "FILE_NAME", TEXT, 0, 8 },
{ "FOREGROUND", PIXEL, 0, 32 },
{ "HOST_NAME", TEXT, 0, 8 },
/* { "INSERT_PROPERTY", "NULL", 0, ? NULL }, */
/* { "INSERT_SELECTION", "NULL", 0, ? NULL }, */
{ "LENGTH", INTEGER, 0, 32, NULL },
{ "LINE_NUMBER", SPAN, 0, 32, NULL },
{ "LIST_LENGTH", INTEGER, 0, 32, NULL },
{ "MODULE", TEXT, 0, 8, NULL },
/* { "MULTIPLE", "ATOM_PAIR", 0, 32, NULL }, */
{ "NAME", TEXT, 0, 8, NULL },
{ "ODIF", TEXT, 0, 8, NULL },
{ "OWNER_OS", TEXT, 0, 8, NULL },
{ "PIXMAP", PIXMAP, 0, 32, NULL },
{ "POSTSCRIPT", STRING, 0, 8, NULL },
{ "PROCEDURE", TEXT, 0, 8, NULL },
{ "PROCESS", INTEGER, 0, 32, NULL },
{ "STRING", STRING, 0, 8, NULL },
{ "TARGETS", ATOM, 0, 32, NULL },
{ "TASK", INTEGER, 0, 32, NULL },
{ "TEXT", TEXT, 0, 8 , NULL },
{ "TIMESTAMP", INTEGER, 0, 32, NULL },
{ "USER", TEXT, 0, 8, NULL },
{ "LENGTH", INTEGER, 0, 32 },
{ "LINE_NUMBER", SPAN, 0, 32 },
{ "LIST_LENGTH", INTEGER, 0, 32 },
{ "MODULE", TEXT, 0, 8 },
/* { "MULTIPLE", "ATOM_PAIR", 0, 32 }, */
{ "NAME", TEXT, 0, 8 },
{ "ODIF", TEXT, 0, 8 },
{ "OWNER_OS", TEXT, 0, 8 },
{ "PIXMAP", PIXMAP, 0, 32 },
{ "POSTSCRIPT", STRING, 0, 8 },
{ "PROCEDURE", TEXT, 0, 8 },
{ "PROCESS", INTEGER, 0, 32 },
{ "STRING", STRING, 0, 8 },
{ "TARGETS", ATOM, 0, 32 },
{ "TASK", INTEGER, 0, 32 },
{ "TEXT", TEXT, 0, 8 },
{ "TIMESTAMP", INTEGER, 0, 32 },
{ "USER", TEXT, 0, 8 },
};
static int num_targets = sizeof(targets)/sizeof(Target);
@ -152,11 +151,15 @@ selection_toggled (GtkWidget *widget)
}
void
selection_handle (GtkWidget *widget,
GtkSelectionData *selection_data, gpointer data)
selection_get (GtkWidget *widget,
GtkSelectionData *selection_data,
guint info,
guint time,
gpointer data)
{
guchar *buffer;
gint len;
GdkAtom type = GDK_NONE;
if (!selection_string)
{
@ -168,11 +171,17 @@ selection_handle (GtkWidget *widget,
buffer = (guchar *)selection_string->str;
len = selection_string->len;
}
switch (info)
{
case COMPOUND_TEXT:
case TEXT:
type = seltypes[COMPOUND_TEXT];
case STRING:
type = seltypes[STRING];
}
gtk_selection_data_set (selection_data,
selection_data->target == seltypes[COMPOUND_TEXT] ?
seltypes[COMPOUND_TEXT] : seltypes[STRING],
8, buffer, len);
gtk_selection_data_set (selection_data, type, 8, buffer, len);
}
gint
@ -373,6 +382,13 @@ main (int argc, char *argv[])
GtkWidget *hscrollbar;
GtkWidget *vscrollbar;
GtkWidget *hbox;
static GtkTargetEntry targetlist[] = {
{ "STRING", STRING },
{ "TEXT", TEXT },
{ "COMPOUND_TEXT", COMPOUND_TEXT }
};
static gint ntargets = sizeof(targetlist) / sizeof(targetlist[0]);
gtk_init (&argc, &argv);
@ -408,15 +424,11 @@ main (int argc, char *argv[])
gtk_signal_connect (GTK_OBJECT(selection_button), "selection_received",
GTK_SIGNAL_FUNC (selection_received), NULL);
gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
seltypes[STRING], selection_handle, NULL);
gtk_selection_add_targets (selection_button, GDK_SELECTION_PRIMARY,
targetlist, ntargets);
gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
seltypes[TEXT], selection_handle, NULL);
gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
seltypes[COMPOUND_TEXT],
selection_handle, NULL);
gtk_signal_connect (GTK_OBJECT(selection_button), "selection_get",
GTK_SIGNAL_FUNC (selection_get), NULL);
selection_text = gtk_text_new (NULL, NULL);
gtk_table_attach_defaults (GTK_TABLE (table), selection_text, 0, 1, 1, 2);

View File

@ -6039,6 +6039,7 @@ create_panes (void)
* Drag -N- Drop
*/
#if 0
gint
dnd_drop_destroy_popup (GtkWidget *widget, GtkWindow **window)
{
@ -6263,6 +6264,7 @@ create_dnd (void)
else
gtk_widget_destroy (window);
}
#endif
/*
* Shaped Windows
@ -7908,7 +7910,7 @@ create_main_window (void)
{ "ctree", create_ctree },
{ "cursors", create_cursors },
{ "dialog", create_dialog },
{ "dnd", create_dnd },
/* { "dnd", create_dnd }, */
{ "entry", create_entry },
{ "file selection", create_file_selection },
{ "font selection", create_font_selection },

View File

@ -48,50 +48,49 @@ typedef struct _Target {
SelType type;
GdkAtom target;
gint format;
GtkSelectionFunction *handler;
} Target;
/* The following is a list of all the selection targets defined
in the ICCCM */
static Target targets[] = {
{ "ADOBE_PORTABLE_DOCUMENT_FORMAT", STRING, 0, 8, NULL },
{ "APPLE_PICT", APPLE_PICT, 0, 8, NULL },
{ "BACKGROUND", PIXEL, 0, 32, NULL },
{ "BITMAP", BITMAP, 0, 32, NULL },
{ "CHARACTER_POSITION", SPAN, 0, 32, NULL },
{ "CLASS", TEXT, 0, 8, NULL },
{ "CLIENT_WINDOW", WINDOW, 0, 32, NULL },
{ "COLORMAP", COLORMAP, 0, 32, NULL },
{ "COLUMN_NUMBER", SPAN, 0, 32, NULL },
{ "COMPOUND_TEXT", COMPOUND_TEXT, 0, 8, NULL },
/* { "DELETE", "NULL", 0, ?, NULL }, */
{ "DRAWABLE", DRAWABLE, 0, 32, NULL },
{ "ENCAPSULATED_POSTSCRIPT", STRING, 0, 8, NULL },
{ "ENCAPSULATED_POSTSCRIPT_INTERCHANGE", STRING, 0, 8, NULL },
{ "FILE_NAME", TEXT, 0, 8, NULL },
{ "FOREGROUND", PIXEL, 0, 32, NULL },
{ "HOST_NAME", TEXT, 0, 8, NULL },
{ "ADOBE_PORTABLE_DOCUMENT_FORMAT", STRING, 0, 8 },
{ "APPLE_PICT", APPLE_PICT, 0, 8 },
{ "BACKGROUND", PIXEL, 0, 32 },
{ "BITMAP", BITMAP, 0, 32 },
{ "CHARACTER_POSITION", SPAN, 0, 32 },
{ "CLASS", TEXT, 0, 8 },
{ "CLIENT_WINDOW", WINDOW, 0, 32 },
{ "COLORMAP", COLORMAP, 0, 32 },
{ "COLUMN_NUMBER", SPAN, 0, 32 },
{ "COMPOUND_TEXT", COMPOUND_TEXT, 0, 8 },
/* { "DELETE", "NULL", 0, ? }, */
{ "DRAWABLE", DRAWABLE, 0, 32 },
{ "ENCAPSULATED_POSTSCRIPT", STRING, 0, 8 },
{ "ENCAPSULATED_POSTSCRIPT_INTERCHANGE", STRING, 0, 8 },
{ "FILE_NAME", TEXT, 0, 8 },
{ "FOREGROUND", PIXEL, 0, 32 },
{ "HOST_NAME", TEXT, 0, 8 },
/* { "INSERT_PROPERTY", "NULL", 0, ? NULL }, */
/* { "INSERT_SELECTION", "NULL", 0, ? NULL }, */
{ "LENGTH", INTEGER, 0, 32, NULL },
{ "LINE_NUMBER", SPAN, 0, 32, NULL },
{ "LIST_LENGTH", INTEGER, 0, 32, NULL },
{ "MODULE", TEXT, 0, 8, NULL },
/* { "MULTIPLE", "ATOM_PAIR", 0, 32, NULL }, */
{ "NAME", TEXT, 0, 8, NULL },
{ "ODIF", TEXT, 0, 8, NULL },
{ "OWNER_OS", TEXT, 0, 8, NULL },
{ "PIXMAP", PIXMAP, 0, 32, NULL },
{ "POSTSCRIPT", STRING, 0, 8, NULL },
{ "PROCEDURE", TEXT, 0, 8, NULL },
{ "PROCESS", INTEGER, 0, 32, NULL },
{ "STRING", STRING, 0, 8, NULL },
{ "TARGETS", ATOM, 0, 32, NULL },
{ "TASK", INTEGER, 0, 32, NULL },
{ "TEXT", TEXT, 0, 8 , NULL },
{ "TIMESTAMP", INTEGER, 0, 32, NULL },
{ "USER", TEXT, 0, 8, NULL },
{ "LENGTH", INTEGER, 0, 32 },
{ "LINE_NUMBER", SPAN, 0, 32 },
{ "LIST_LENGTH", INTEGER, 0, 32 },
{ "MODULE", TEXT, 0, 8 },
/* { "MULTIPLE", "ATOM_PAIR", 0, 32 }, */
{ "NAME", TEXT, 0, 8 },
{ "ODIF", TEXT, 0, 8 },
{ "OWNER_OS", TEXT, 0, 8 },
{ "PIXMAP", PIXMAP, 0, 32 },
{ "POSTSCRIPT", STRING, 0, 8 },
{ "PROCEDURE", TEXT, 0, 8 },
{ "PROCESS", INTEGER, 0, 32 },
{ "STRING", STRING, 0, 8 },
{ "TARGETS", ATOM, 0, 32 },
{ "TASK", INTEGER, 0, 32 },
{ "TEXT", TEXT, 0, 8 },
{ "TIMESTAMP", INTEGER, 0, 32 },
{ "USER", TEXT, 0, 8 },
};
static int num_targets = sizeof(targets)/sizeof(Target);
@ -152,11 +151,15 @@ selection_toggled (GtkWidget *widget)
}
void
selection_handle (GtkWidget *widget,
GtkSelectionData *selection_data, gpointer data)
selection_get (GtkWidget *widget,
GtkSelectionData *selection_data,
guint info,
guint time,
gpointer data)
{
guchar *buffer;
gint len;
GdkAtom type = GDK_NONE;
if (!selection_string)
{
@ -168,11 +171,17 @@ selection_handle (GtkWidget *widget,
buffer = (guchar *)selection_string->str;
len = selection_string->len;
}
switch (info)
{
case COMPOUND_TEXT:
case TEXT:
type = seltypes[COMPOUND_TEXT];
case STRING:
type = seltypes[STRING];
}
gtk_selection_data_set (selection_data,
selection_data->target == seltypes[COMPOUND_TEXT] ?
seltypes[COMPOUND_TEXT] : seltypes[STRING],
8, buffer, len);
gtk_selection_data_set (selection_data, type, 8, buffer, len);
}
gint
@ -373,6 +382,13 @@ main (int argc, char *argv[])
GtkWidget *hscrollbar;
GtkWidget *vscrollbar;
GtkWidget *hbox;
static GtkTargetEntry targetlist[] = {
{ "STRING", STRING },
{ "TEXT", TEXT },
{ "COMPOUND_TEXT", COMPOUND_TEXT }
};
static gint ntargets = sizeof(targetlist) / sizeof(targetlist[0]);
gtk_init (&argc, &argv);
@ -408,15 +424,11 @@ main (int argc, char *argv[])
gtk_signal_connect (GTK_OBJECT(selection_button), "selection_received",
GTK_SIGNAL_FUNC (selection_received), NULL);
gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
seltypes[STRING], selection_handle, NULL);
gtk_selection_add_targets (selection_button, GDK_SELECTION_PRIMARY,
targetlist, ntargets);
gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
seltypes[TEXT], selection_handle, NULL);
gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
seltypes[COMPOUND_TEXT],
selection_handle, NULL);
gtk_signal_connect (GTK_OBJECT(selection_button), "selection_get",
GTK_SIGNAL_FUNC (selection_get), NULL);
selection_text = gtk_text_new (NULL, NULL);
gtk_table_attach_defaults (GTK_TABLE (table), selection_text, 0, 1, 1, 2);