|« Main Page | Index|
Table of Contents
In most cases, it isn't necessary for a XFC application to deal with selections itself. The standard widgets, such as the Entry widget, already have the capability to claim the selection when appropriate (e.g., when the user drags over text), and to retrieve the contents of the selection owned by another widget or another application (e.g., when the user clicks the second mouse button). However, there may be cases in which you want to give other widgets the ability to supply the selection, or you wish to retrieve targets not supported by default.
A fundamental concept needed to understand selection handling is that of the Atom. An atom is an integer that uniquely identifies a string (on a certain display). Certain atoms are predefined by the X server, and in some cases there are constants in <gdk/gdkselection.h> corresponding to these atoms. For instance the constant GDK_SELECTION_PRIMARY corresponds to the string "PRIMARY". In other cases, you should use the functions gdk_atom_intern(), to get the atom corresponding to a string, and gdk_atom_name(), to get the name of an atom. Both selections and targets are identified by atoms.
This converts the selection into the form specified by target. If at all possible, the time field should be the time from the event that triggered the selection. This helps make sure that events occur in the order that the user requested them. However, if it is not available (for instance, if the conversion was triggered by a "clicked" signal), then you can use the constant GDK_CURRENT_TIME.
When the selection owner responds to the request, a "selection_received" signal is sent to your application. The signal handler for this signal receives a reference to a Gtk::SelectionData object which provides the following accessor functions:
The selection() and target() functions return the values you gave in your Gtk::Widget::selection_convert() call. The type() function returns an atom that identifies the type of data returned by the selection owner. Some possible values are "STRING" (a string of latin-1 characters), "ATOM" (a series of atoms), "INTEGER" (an integer), etc. Most targets can only return one type. The format() function returns the length of the units (8 for characters, 32 for integers) in bits. Usually, you don't care about this when receiving data. The data() function returns a pointer to the returned data, and length() returns the length of the returned data, in bytes. If length() is negative, then an error occurred and the selection could not be retrieved. This might happen if no application owned the selection, or if you requested a target that the application didn't support. The buffer is actually guaranteed to be one byte longer than length; the extra byte will always be zero, so it isn't necessary to make a copy of strings just to null-terminate them.
For convenience, there are accessors that return the selection, target and type as a String:
You can retrieve the selection_data as a vector of supported targets. This can be used to interpret the results of getting the standard "TARGETS" target that is always supplied for any selection.
The first get_targets() function retrieves the targets as a vector of Gdk::Atom. The second retrieves the target names as a vector of String.
The following function returns true if the length of the selection data is greater than 0.
You can connect directly to the "selection_received" signal with the following code:
where the "selection_received" signal handler has the following prototype:
ICCCM. The targets MULTIPLE, TARGETS and TIMESTAMP are defined by
X11 architecture as mandatory and are automatically provided by GTK+.
To define the supported target(s) for a certain selection and widget use one of the following Gtk::Widget methods:
The 'selection' argument is the atom corresponding to the selection for which the target(s) will be registered, the 'target' argument is the atom corresponding to the target name you want to register and the 'info' argument is a unique integer id that will be passed back through signals later on. The first two methods register a single target. The second method takes a Gtk::TargetEntry rather than separate target and info arguments. The last method lets you register multiple targets at once by passing a vector of Gtk::TargetEntry.
You can create a new TargetEntry object with one of the following constructors:
The first constructor creates an empty TargetEntry. The second constructor creates a target entry with the specified name and unique id. The 'target_name' argument is a string corresponding to the target atom and 'unique_id' is the unique integer id. The 'drag_flags' argument is only used when implementing Drag and Drop. It restricts the validity of the corresponding target to the same application or the same widget.
If you create an empty TargetEntry, you can set its target_name and unique_id by calling the Gtk::TargetEntry method:
The 'target_name' is the string corresponding to the target atom and unique_id is the unique integer id. The 'drag_flags' argument is used to restrict the validity of the corresponding target and can either be Gtk::TARGET_SAME_APP or Gtk::TARGET_SAME_WIDGET.
Now the targets have been registered, when prompted by the user you need to take ownership of a certain selection. This is done with the following Gtk::Widget method:
The 'selection' argument is the atom corresponding the selection for which the owner should be changed, 'time' is a timestamp with which to claim the selection, or GDK_CURRENT_TIME. The 'display' is the Gdk::Display where the selection is set, or null for the default display. If the return value is true the calling widget owns the selection.
If you need to check whether a widget owns a certain selection you can call the Gtk::Widget accessor:
The 'selection' is an interned atom representing the selection to check. The return value is true if the calling widget owns the specified selection.
To be able to respond to a Gtk::Widget::selection_convert() request, you must either connect to the "selection_get" signal or derive a new class for the selection widget and override the Gtk::WidgetSignals::on_selection_get() virtual signal handler.
To connect to the "selection_get" signal, use the following code:
The selection_get handler has the following prototype:
The 'selection_data' is the SelectionData object to be filled in, 'info' is the info integer that was set when the target was registered, and 'time' is the time of the conversion request as set by the requestor with Gtk::Widget::selection_convert().
When the "selection_get" signal returns, the widget requesting the selection will receive the selection_data. You must call the following Gtk::SelectionData methods to set the selection_data fields:
These methods should only be called from a selection handler callback. The 'type' argument is an atom that describes the 'data' provided and the 'format' is the number of bits required to store one element of the target type. Usually it will be 8 for a character or 32 for an integer. The most commonly used target types are: ATOM, COMPOUND_TEXT, INTEGER and STRING. This method takes care of properly making a copy of the data so that you don't have to worry about keeping it around. The length argument is the data length. The data should be null-terminated.
For convenience, the set_text() method sets the contents of the selection from a UTF-8 encoded string. The string is converted to the form determined by the target and true is returned if the selection was successfully set.
If another application claims ownership of the selection, you will receive a "selection_clear_event" signal. To explicitly release ownership of a selection call the following Gtk::Widget method:
The 'selection' argument is an interned atom representing the selection to release, 'time' is a timestamp, or GDK_CURRENT_TIME and 'display' is the Gdk::Display where the selection is set, or null for the default display. True is returned if the operation succeeded.
The header file for the selection example is <selection.hh>:
and the source file is <selection.cc>:
If you compiled and installed XFC yourself, you will find the source
code for Selection in the
<examples/howto/selection> source directory along with a Makefile. If
XFC came pre-installed, or you installed it from an RPM package, you
find the source code in the
</usr/share/doc/xfcui-X.X/examples/howto/selection> subdirectory. In
this case you will have to create the Makefile yourself (replace X.X
version number of the libXFCui library you have installed).
|Copyright © 2004-2005 The XFC Development Team||Top