1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
/* Copyright © 2002 Red Hat, Inc.
4
* Permission to use, copy, modify, distribute, and sell this software and its
5
* documentation for any purpose is hereby granted without fee, provided that
6
* the above copyright notice appear in all copies and that both that
7
* copyright notice and this permission notice appear in supporting
8
* documentation, and that the name of Red Hat not be used in advertising or
9
* publicity pertaining to distribution of the software without specific,
10
* written prior permission. Red Hat makes no representations about the
11
* suitability of this software for any purpose. It is provided "as is"
12
* without express or implied warranty.
14
* RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
15
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
16
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
18
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
19
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
* Author: Owen Taylor, Red Hat, Inc.
28
#include "drw-selection.h"
32
GdkWindow *owner_window;
36
#define SELECTION_NAME "_CODEFACTORY_DRWRIGHT"
38
static GdkFilterReturn drw_selection_filter (GdkXEvent *xevent,
41
static void drw_selection_negotiate (DrwSelection *drw_selection);
44
drw_selection_reset (DrwSelection *drw_selection)
46
if (drw_selection->owner_window) {
47
gdk_window_remove_filter (drw_selection->owner_window,
48
drw_selection_filter, drw_selection);
49
g_object_unref (drw_selection->owner_window);
50
drw_selection->owner_window = NULL;
53
if (drw_selection->invisible) {
54
gtk_widget_destroy (drw_selection->invisible);
55
drw_selection->invisible = NULL;
60
drw_selection_clear (GtkWidget *widget,
61
GdkEventSelection *event,
64
DrwSelection *drw_selection = user_data;
66
drw_selection_reset (drw_selection);
67
drw_selection_negotiate (drw_selection);
71
drw_selection_find_existing (DrwSelection *drw_selection)
73
Display *xdisplay = GDK_DISPLAY ();
76
gdk_error_trap_push ();
77
old = XGetSelectionOwner (xdisplay,
78
gdk_x11_get_xatom_by_name (SELECTION_NAME));
80
XSelectInput (xdisplay, old, StructureNotifyMask);
81
drw_selection->owner_window = gdk_window_foreign_new (old);
83
XSync (xdisplay, False);
85
if (gdk_error_trap_pop () == 0 && drw_selection->owner_window) {
86
gdk_window_add_filter (drw_selection->owner_window,
87
drw_selection_filter, drw_selection);
89
XUngrabServer (xdisplay);
93
if (drw_selection->owner_window) {
94
g_object_unref (drw_selection->owner_window);
95
drw_selection->owner_window = NULL;
103
drw_selection_claim (DrwSelection *drw_selection)
105
drw_selection->invisible = gtk_invisible_new ();
106
g_signal_connect (drw_selection->invisible, "selection-clear-event",
107
G_CALLBACK (drw_selection_clear), drw_selection);
110
if (gtk_selection_owner_set (drw_selection->invisible,
111
gdk_atom_intern (SELECTION_NAME, FALSE),
115
drw_selection_reset (drw_selection);
121
drw_selection_negotiate (DrwSelection *drw_selection)
123
Display *xdisplay = GDK_DISPLAY ();
124
gboolean found = FALSE;
126
/* We don't need both the XGrabServer() and the loop here;
127
* the XGrabServer() should make sure that we only go through
128
* the loop once. It also works if you remove the XGrabServer()
129
* and just have the loop, but then the selection ownership
130
* can get transfered a bunch of times before things
135
XGrabServer (xdisplay);
137
if (drw_selection_find_existing (drw_selection))
139
else if (drw_selection_claim (drw_selection))
142
XUngrabServer (xdisplay);
146
static GdkFilterReturn
147
drw_selection_filter (GdkXEvent *xevent,
151
DrwSelection *drw_selection = data;
152
XEvent *xev = (XEvent *)xevent;
154
if (xev->xany.type == DestroyNotify &&
155
xev->xdestroywindow.window == xev->xdestroywindow.event)
157
drw_selection_reset (drw_selection);
158
drw_selection_negotiate (drw_selection);
160
return GDK_FILTER_REMOVE;
163
return GDK_FILTER_CONTINUE;
167
drw_selection_start (void)
169
DrwSelection *drw_selection = g_new (DrwSelection, 1);
171
drw_selection->owner_window = NULL;
172
drw_selection->invisible = NULL;
174
drw_selection_negotiate (drw_selection);
176
return drw_selection;
180
drw_selection_stop (DrwSelection *drw_selection)
182
drw_selection_reset (drw_selection);
183
g_free (drw_selection);
187
drw_selection_is_master (DrwSelection *drw_selection)
189
return drw_selection->invisible != NULL;