* 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
+ * modify it under the terms of the GNU Lesser 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.
+ * Lesser 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.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
- * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <string.h>
+#include "config.h"
-#include "gdkproperty.h"
#include "gdkselection.h"
-#include "gdkprivate.h"
-#include "gdkx.h"
+#include "gdkproperty.h"
+#include "gdkdisplayprivate.h"
-gint
+
+/**
+ * SECTION:selections
+ * @Short_description: Functions for transfering data via the X selection mechanism
+ * @Title: Selections
+ *
+ * The X selection mechanism provides a way to transfer arbitrary chunks of
+ * data between programs. A <firstterm>selection</firstterm> is a essentially
+ * a named clipboard, identified by a string interned as a #GdkAtom. By
+ * claiming ownership of a selection, an application indicates that it will
+ * be responsible for supplying its contents. The most common selections are
+ * <literal>PRIMARY</literal> and <literal>CLIPBOARD</literal>.
+ *
+ * The contents of a selection can be represented in a number of formats,
+ * called <firstterm>targets</firstterm>. Each target is identified by an atom.
+ * A list of all possible targets supported by the selection owner can be
+ * retrieved by requesting the special target <literal>TARGETS</literal>. When
+ * a selection is retrieved, the data is accompanied by a type (an atom), and
+ * a format (an integer, representing the number of bits per item).
+ * See <link linkend="gdk-Properties-and-Atoms">Properties and Atoms</link>
+ * for more information.
+ *
+ * The functions in this section only contain the lowlevel parts of the
+ * selection protocol. A considerably more complicated implementation is needed
+ * on top of this. GTK+ contains such an implementation in the functions in
+ * <literal>gtkselection.h</literal> and programmers should use those functions
+ * instead of the ones presented here. If you plan to implement selection
+ * handling directly on top of the functions here, you should refer to the
+ * X Inter-client Communication Conventions Manual (ICCCM).
+ */
+
+/**
+ * gdk_selection_owner_set:
+ * @owner: a #GdkWindow or %NULL to indicate that the
+ * the owner for the given should be unset.
+ * @selection: an atom identifying a selection.
+ * @time_: timestamp to use when setting the selection.
+ * If this is older than the timestamp given last
+ * time the owner was set for the given selection, the
+ * request will be ignored.
+ * @send_event: if %TRUE, and the new owner is different
+ * from the current owner, the current owner
+ * will be sent a SelectionClear event.
+ *
+ * Sets the owner of the given selection.
+ *
+ * Returns: %TRUE if the selection owner was successfully
+ * changed to @owner, otherwise %FALSE.
+ */
+gboolean
gdk_selection_owner_set (GdkWindow *owner,
GdkAtom selection,
guint32 time,
- gint send_event)
+ gboolean send_event)
{
- Display *xdisplay;
- Window xwindow;
-
- if (owner)
- {
- GdkWindowPrivate *private;
-
- private = (GdkWindowPrivate*) owner;
- if (private->destroyed)
- return FALSE;
-
- xdisplay = private->xdisplay;
- xwindow = private->xwindow;
- }
- else
- {
- xdisplay = gdk_display;
- xwindow = None;
- }
-
- XSetSelectionOwner (xdisplay, selection, xwindow, time);
-
- return (XGetSelectionOwner (xdisplay, selection) == xwindow);
+ return gdk_selection_owner_set_for_display (gdk_display_get_default (),
+ owner, selection,
+ time, send_event);
}
+/**
+ * gdk_selection_owner_get:
+ * @selection: an atom indentifying a selection.
+ *
+ * Determines the owner of the given selection.
+ *
+ * Returns: (transfer none): if there is a selection owner for
+ * this window, and it is a window known to the current
+ * process, the #GdkWindow that owns the selection, otherwise
+ * %NULL. Note that the return value may be owned
+ * by a different process if a foreign window
+ * was previously created for that window, but
+ * a new foreign window will never be created by
+ * this call.
+ */
GdkWindow*
gdk_selection_owner_get (GdkAtom selection)
{
- Window xwindow;
-
- xwindow = XGetSelectionOwner (gdk_display, selection);
- if (xwindow == None)
- return NULL;
-
- return gdk_window_lookup (xwindow);
+ return gdk_selection_owner_get_for_display (gdk_display_get_default (),
+ selection);
}
+/**
+ * gdk_selection_send_notify:
+ * @requestor: window to which to deliver response.
+ * @selection: selection that was requested.
+ * @target: target that was selected.
+ * @property: property in which the selection owner stored the
+ * data, or %GDK_NONE to indicate that the request
+ * was rejected.
+ * @time_: timestamp.
+ *
+ * Sends a response to SelectionRequest event.
+ */
void
-gdk_selection_convert (GdkWindow *requestor,
- GdkAtom selection,
- GdkAtom target,
- guint32 time)
+gdk_selection_send_notify (GdkWindow *requestor,
+ GdkAtom selection,
+ GdkAtom target,
+ GdkAtom property,
+ guint32 time)
{
- GdkWindowPrivate *private;
-
- g_return_if_fail (requestor != NULL);
-
- private = (GdkWindowPrivate*) requestor;
- if (private->destroyed)
- return;
-
- XConvertSelection (private->xdisplay, selection, target,
- gdk_selection_property, private->xwindow, time);
+ gdk_selection_send_notify_for_display (gdk_window_get_display (requestor),
+ requestor, selection,
+ target, property, time);
}
-gint
-gdk_selection_property_get (GdkWindow *requestor,
- guchar **data,
- GdkAtom *ret_type,
- gint *ret_format)
+/**
+ * gdk_selection_owner_set_for_display:
+ * @display: the #GdkDisplay
+ * @owner: a #GdkWindow or %NULL to indicate that the owner for
+ * the given should be unset
+ * @selection: an atom identifying a selection
+ * @time_: timestamp to use when setting the selection
+ * If this is older than the timestamp given last time the owner was
+ * set for the given selection, the request will be ignored
+ * @send_event: if %TRUE, and the new owner is different from the current
+ * owner, the current owner will be sent a SelectionClear event
+ *
+ * Sets the #GdkWindow @owner as the current owner of the selection @selection.
+ *
+ * Returns: %TRUE if the selection owner was successfully changed to owner,
+ * otherwise %FALSE.
+ *
+ * Since: 2.2
+ */
+gboolean
+gdk_selection_owner_set_for_display (GdkDisplay *display,
+ GdkWindow *owner,
+ GdkAtom selection,
+ guint32 time,
+ gboolean send_event)
{
- GdkWindowPrivate *private;
- gulong nitems;
- gulong nbytes;
- gulong length;
- GdkAtom prop_type;
- gint prop_format;
- guchar *t = NULL;
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+ g_return_val_if_fail (selection != GDK_NONE, FALSE);
- g_return_val_if_fail (requestor != NULL, 0);
-
- /* If retrieved chunks are typically small, (and the ICCCM says the
- should be) it would be a win to try first with a buffer of
- moderate length, to avoid two round trips to the server */
-
- private = (GdkWindowPrivate*) requestor;
- if (private->destroyed)
- return 0;
-
- t = NULL;
- XGetWindowProperty (private->xdisplay, private->xwindow,
- gdk_selection_property, 0, 0, False,
- AnyPropertyType, &prop_type, &prop_format,
- &nitems, &nbytes, &t);
-
- if (ret_type)
- *ret_type = prop_type;
- if (ret_format)
- *ret_format = prop_format;
-
- if (prop_type == None)
- {
- *data = NULL;
- return 0;
- }
-
- if (t)
- {
- XFree (t);
- t = NULL;
- }
-
- /* Add on an extra byte to handle null termination. X guarantees
- that t will be 1 longer than nbytes and null terminated */
- length = nbytes + 1;
+ return GDK_DISPLAY_GET_CLASS (display)
+ ->set_selection_owner (display, owner, selection, time, send_event);
+}
- /* We can't delete the selection here, because it might be the INCR
- protocol, in which case the client has to make sure they'll be
- notified of PropertyChange events _before_ the property is deleted.
- Otherwise there's no guarantee we'll win the race ... */
- XGetWindowProperty (private->xdisplay, private->xwindow,
- gdk_selection_property, 0, (nbytes + 3) / 4, False,
- AnyPropertyType, &prop_type, &prop_format,
- &nitems, &nbytes, &t);
+/**
+ * gdk_selection_owner_get_for_display:
+ * @display: a #GdkDisplay
+ * @selection: an atom indentifying a selection
+ *
+ * Determine the owner of the given selection.
+ *
+ * Note that the return value may be owned by a different
+ * process if a foreign window was previously created for that
+ * window, but a new foreign window will never be created by this call.
+ *
+ * Returns: (transfer none): if there is a selection owner for this window,
+ * and it is a window known to the current process, the #GdkWindow that
+ * owns the selection, otherwise %NULL.
+ *
+ * Since: 2.2
+ */
+GdkWindow *
+gdk_selection_owner_get_for_display (GdkDisplay *display,
+ GdkAtom selection)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+ g_return_val_if_fail (selection != GDK_NONE, NULL);
- if (prop_type != None)
- {
- *data = g_new (guchar, length);
- memcpy (*data, t, length);
- if (t)
- XFree (t);
- return length-1;
- }
- else
- {
- *data = NULL;
- return 0;
- }
+ return GDK_DISPLAY_GET_CLASS (display)->get_selection_owner (display, selection);
}
-
+/**
+ * gdk_selection_send_notify_for_display:
+ * @display: the #GdkDisplay where @requestor is realized
+ * @requestor: window to which to deliver response
+ * @selection: selection that was requested
+ * @target: target that was selected
+ * @property: property in which the selection owner stored the data,
+ * or %GDK_NONE to indicate that the request was rejected
+ * @time_: timestamp
+ *
+ * Send a response to SelectionRequest event.
+ *
+ * Since: 2.2
+ */
void
-gdk_selection_send_notify (guint32 requestor,
- GdkAtom selection,
- GdkAtom target,
- GdkAtom property,
- guint32 time)
+gdk_selection_send_notify_for_display (GdkDisplay *display,
+ GdkWindow *requestor,
+ GdkAtom selection,
+ GdkAtom target,
+ GdkAtom property,
+ guint32 time_)
{
- XSelectionEvent xevent;
+ g_return_if_fail (GDK_IS_DISPLAY (display));
- xevent.type = SelectionNotify;
- xevent.serial = 0;
- xevent.send_event = True;
- xevent.display = gdk_display;
- xevent.requestor = requestor;
- xevent.selection = selection;
- xevent.target = target;
- xevent.property = property;
- xevent.time = time;
-
- gdk_send_xevent (requestor, False, NoEventMask, (XEvent*) &xevent);
+ GDK_DISPLAY_GET_CLASS (display)
+ ->send_selection_notify (display, requestor, selection,target, property, time_);
}
+/**
+ * gdk_selection_property_get: (skip)
+ * @requestor: the window on which the data is stored
+ * @data: location to store a pointer to the retrieved data.
+ If the retrieval failed, %NULL we be stored here, otherwise, it
+ will be non-%NULL and the returned data should be freed with g_free()
+ when you are finished using it. The length of the
+ allocated memory is one more than the length
+ of the returned data, and the final byte will always
+ be zero, to ensure nul-termination of strings
+ * @prop_type: location to store the type of the property
+ * @prop_format: location to store the format of the property
+ *
+ * Retrieves selection data that was stored by the selection
+ * data in response to a call to gdk_selection_convert(). This function
+ * will not be used by applications, who should use the #GtkClipboard
+ * API instead.
+ *
+ * Return value: the length of the retrieved data.
+ */
gint
-gdk_text_property_to_text_list (GdkAtom encoding, gint format,
- guchar *text, gint length,
- gchar ***list)
+gdk_selection_property_get (GdkWindow *requestor,
+ guchar **data,
+ GdkAtom *ret_type,
+ gint *ret_format)
{
- XTextProperty property;
- gint count = 0;
- gint res;
+ GdkDisplay *display;
- if (!list)
- return 0;
+ g_return_val_if_fail (GDK_IS_WINDOW (requestor), 0);
- property.value = text;
- property.encoding = encoding;
- property.format = format;
- property.nitems = length;
- res = XmbTextPropertyToTextList (GDK_DISPLAY(), &property, list, &count);
+ display = gdk_window_get_display (requestor);
- if (res == XNoMemory || res == XLocaleNotSupported ||
- res == XConverterNotFound)
- return 0;
- else
- return count;
+ return GDK_DISPLAY_GET_CLASS (display)
+ ->get_selection_property (display, requestor, data, ret_type, ret_format);
}
void
-gdk_free_text_list (gchar **list)
+gdk_selection_convert (GdkWindow *requestor,
+ GdkAtom selection,
+ GdkAtom target,
+ guint32 time)
{
- g_return_if_fail (list != NULL);
+ GdkDisplay *display;
+
+ g_return_if_fail (selection != GDK_NONE);
- XFreeStringList (list);
+ display = gdk_window_get_display (requestor);
+
+ GDK_DISPLAY_GET_CLASS (display)
+ ->convert_selection (display, requestor, selection, target, time);
}
+/**
+ * gdk_text_property_to_utf8_list_for_display:
+ * @display: a #GdkDisplay
+ * @encoding: an atom representing the encoding of the text
+ * @format: the format of the property
+ * @text: (array length=length): the text to convert
+ * @length: the length of @text, in bytes
+ * @list: (out) (array zero-terminated=1): location to store the list
+ * of strings or %NULL. The list should be freed with
+ * g_strfreev().
+ *
+ * Converts a text property in the given encoding to
+ * a list of UTF-8 strings.
+ *
+ * Return value: the number of strings in the resulting list
+ *
+ * Since: 2.2
+ */
gint
-gdk_string_to_compound_text (gchar *str,
- GdkAtom *encoding, gint *format,
- guchar **ctext, gint *length)
+gdk_text_property_to_utf8_list_for_display (GdkDisplay *display,
+ GdkAtom encoding,
+ gint format,
+ const guchar *text,
+ gint length,
+ gchar ***list)
{
- gint res;
- XTextProperty property;
-
- res = XmbTextListToTextProperty (GDK_DISPLAY(),
- &str, 1, XCompoundTextStyle,
- &property);
- if (res != Success)
- {
- property.encoding = None;
- property.format = None;
- property.value = NULL;
- property.nitems = 0;
- }
+ g_return_val_if_fail (text != NULL, 0);
+ g_return_val_if_fail (length >= 0, 0);
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
- if (encoding)
- *encoding = property.encoding;
- if (format)
- *format = property.format;
- if (ctext)
- *ctext = property.value;
- if (length)
- *length = property.nitems;
-
- return res;
+ return GDK_DISPLAY_GET_CLASS (display)
+ ->text_property_to_utf8_list (display, encoding, format, text, length, list);
}
-void gdk_free_compound_text (guchar *ctext)
+/**
+ * gdk_utf8_to_string_target:
+ * @str: a UTF-8 string
+ *
+ * Converts an UTF-8 string into the best possible representation
+ * as a STRING. The representation of characters not in STRING
+ * is not specified; it may be as pseudo-escape sequences
+ * \x{ABCD}, or it may be in some other form of approximation.
+ *
+ * Return value: the newly-allocated string, or %NULL if the
+ * conversion failed. (It should not fail for
+ * any properly formed UTF-8 string unless system
+ * limits like memory or file descriptors are exceeded.)
+ **/
+gchar *
+gdk_utf8_to_string_target (const gchar *str)
{
- if (ctext)
- XFree (ctext);
+ GdkDisplay *display = gdk_display_get_default ();
+
+ return GDK_DISPLAY_GET_CLASS (display)->utf8_to_string_target (display, str);
}