~kroq-gar78/ubuntu/precise/gnome-control-center/fix-885947

« back to all changes in this revision

Viewing changes to typing-break/drw-selection.c

  • Committer: Bazaar Package Importer
  • Author(s): Rodrigo Moya
  • Date: 2011-05-17 10:47:27 UTC
  • mfrom: (0.1.11 experimental) (1.1.45 upstream)
  • Revision ID: james.westby@ubuntu.com-20110517104727-lqel6m8vhfw5jby1
Tags: 1:3.0.1.1-1ubuntu1
* Rebase on Debian, remaining Ubuntu changes:
* debian/control:
  - Build-Depend on hardening-wrapper, dpkg-dev and dh-autoreconf
  - Add dependency on ubuntu-system-service
  - Remove dependency on gnome-icon-theme-symbolic
  - Move dependency on apg, gnome-icon-theme-symbolic and accountsservice to
    be a Recommends: until we get them in main
* debian/rules:
  - Use autoreconf
  - Add binary-post-install rule for gnome-control-center-data
  - Run dh-autoreconf
* debian/gnome-control-center.dirs:
* debian/gnome-control-center.links:
  - Add a link to the control center shell for indicators
* debian/patches/00_disable-nm.patch:
  - Temporary patch to disable building with NetworkManager until we get
    the new one in the archive
* debian/patches/01_git_remove_gettext_calls.patch:
  - Remove calls to AM_GNU_GETTEXT, IT_PROG_INTLTOOL should be enough
* debian/patches/01_git_kill_warning.patch:
  - Kill warning
* debian/patches/50_ubuntu_systemwide_prefs.patch:
  - Ubuntu specific proxy preferences
* debian/patches/51_ubuntu_system_keyboard.patch:
  - Implement the global keyboard spec at https://wiki.ubuntu.com/DefaultKeyboardSettings

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
 
/* Copyright © 2002 Red Hat, Inc.
3
 
 *
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.
13
 
 *
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.
20
 
 *
21
 
 * Author:  Owen Taylor, Red Hat, Inc.
22
 
 */
23
 
 
24
 
#include <config.h>
25
 
#include <gtk/gtk.h>
26
 
#include <gdk/gdkx.h>
27
 
 
28
 
#include "drw-selection.h"
29
 
 
30
 
struct _DrwSelection
31
 
{
32
 
        GdkWindow *owner_window;
33
 
        GtkWidget *invisible;
34
 
};
35
 
 
36
 
#define SELECTION_NAME "_CODEFACTORY_DRWRIGHT"
37
 
 
38
 
static GdkFilterReturn drw_selection_filter     (GdkXEvent   *xevent,
39
 
                                                 GdkEvent    *event,
40
 
                                                 gpointer     data);
41
 
static void            drw_selection_negotiate  (DrwSelection *drw_selection);
42
 
 
43
 
static void
44
 
drw_selection_reset (DrwSelection *drw_selection)
45
 
{
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;
51
 
        }
52
 
 
53
 
        if (drw_selection->invisible) {
54
 
                gtk_widget_destroy (drw_selection->invisible);
55
 
                drw_selection->invisible = NULL;
56
 
        }
57
 
}
58
 
 
59
 
static void
60
 
drw_selection_clear (GtkWidget         *widget,
61
 
                    GdkEventSelection *event,
62
 
                    gpointer           user_data)
63
 
{
64
 
        DrwSelection *drw_selection = user_data;
65
 
 
66
 
        drw_selection_reset (drw_selection);
67
 
        drw_selection_negotiate (drw_selection);
68
 
}
69
 
 
70
 
static gboolean
71
 
drw_selection_find_existing (DrwSelection *drw_selection)
72
 
{
73
 
        Display *xdisplay = GDK_DISPLAY ();
74
 
        Window old;
75
 
 
76
 
        gdk_error_trap_push ();
77
 
        old = XGetSelectionOwner (xdisplay,
78
 
                                  gdk_x11_get_xatom_by_name (SELECTION_NAME));
79
 
        if (old) {
80
 
                XSelectInput (xdisplay, old, StructureNotifyMask);
81
 
                drw_selection->owner_window = gdk_window_foreign_new (old);
82
 
        }
83
 
        XSync (xdisplay, False);
84
 
 
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);
88
 
 
89
 
                XUngrabServer (xdisplay);
90
 
 
91
 
                return TRUE;
92
 
        } else {
93
 
                if (drw_selection->owner_window) {
94
 
                        g_object_unref (drw_selection->owner_window);
95
 
                        drw_selection->owner_window = NULL;
96
 
                }
97
 
 
98
 
                return FALSE;
99
 
        }
100
 
}
101
 
 
102
 
static gboolean
103
 
drw_selection_claim (DrwSelection *drw_selection)
104
 
{
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);
108
 
 
109
 
 
110
 
        if (gtk_selection_owner_set (drw_selection->invisible,
111
 
                                     gdk_atom_intern (SELECTION_NAME, FALSE),
112
 
                                     GDK_CURRENT_TIME)) {
113
 
                return TRUE;
114
 
        } else {
115
 
                drw_selection_reset (drw_selection);
116
 
                return FALSE;
117
 
        }
118
 
}
119
 
 
120
 
static void
121
 
drw_selection_negotiate (DrwSelection *drw_selection)
122
 
{
123
 
        Display *xdisplay = GDK_DISPLAY ();
124
 
        gboolean found = FALSE;
125
 
 
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
131
 
         * settle down.
132
 
         */
133
 
        while (!found)
134
 
        {
135
 
                XGrabServer (xdisplay);
136
 
 
137
 
                if (drw_selection_find_existing (drw_selection))
138
 
                        found = TRUE;
139
 
                else if (drw_selection_claim (drw_selection))
140
 
                        found = TRUE;
141
 
 
142
 
                XUngrabServer (xdisplay);
143
 
        }
144
 
}
145
 
 
146
 
static GdkFilterReturn
147
 
drw_selection_filter (GdkXEvent *xevent,
148
 
                     GdkEvent  *event,
149
 
                     gpointer   data)
150
 
{
151
 
        DrwSelection *drw_selection = data;
152
 
        XEvent *xev = (XEvent *)xevent;
153
 
 
154
 
        if (xev->xany.type == DestroyNotify &&
155
 
            xev->xdestroywindow.window == xev->xdestroywindow.event)
156
 
        {
157
 
                drw_selection_reset (drw_selection);
158
 
                drw_selection_negotiate (drw_selection);
159
 
 
160
 
                return GDK_FILTER_REMOVE;
161
 
        }
162
 
 
163
 
        return GDK_FILTER_CONTINUE;
164
 
}
165
 
 
166
 
DrwSelection *
167
 
drw_selection_start (void)
168
 
{
169
 
        DrwSelection *drw_selection = g_new (DrwSelection, 1);
170
 
 
171
 
        drw_selection->owner_window = NULL;
172
 
        drw_selection->invisible = NULL;
173
 
 
174
 
        drw_selection_negotiate (drw_selection);
175
 
 
176
 
        return drw_selection;
177
 
}
178
 
 
179
 
void
180
 
drw_selection_stop (DrwSelection *drw_selection)
181
 
{
182
 
        drw_selection_reset (drw_selection);
183
 
        g_free (drw_selection);
184
 
}
185
 
 
186
 
gboolean
187
 
drw_selection_is_master (DrwSelection *drw_selection)
188
 
{
189
 
        return drw_selection->invisible != NULL;
190
 
}