]> Pileus Git - ~andy/gtk/blob - gdk/gdkselection.c
changed reversed_[12] to reserved_[12] in gtk_*_get_type functions.
[~andy/gtk] / gdk / gdkselection.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #include <X11/Xlib.h>
20 #include <X11/Xatom.h>
21 #include <string.h>
22 #include "gdk.h"
23 #include "gdkprivate.h"
24 #include "gdkx.h"
25
26
27 gint
28 gdk_selection_owner_set (GdkWindow *owner,
29                          GdkAtom    selection,
30                          guint32    time,
31                          gint       send_event)
32 {
33   Display *xdisplay;
34   Window xwindow;
35
36   if (owner)
37     {
38       GdkWindowPrivate *private;
39
40       private = (GdkWindowPrivate*) owner;
41       if (private->destroyed)
42         return FALSE;
43
44       xdisplay = private->xdisplay;
45       xwindow = private->xwindow;
46     }
47   else
48     {
49       xdisplay = gdk_display;
50       xwindow = None;
51     }
52
53   XSetSelectionOwner (xdisplay, selection, xwindow, time);
54
55   return (XGetSelectionOwner (xdisplay, selection) == xwindow);
56 }
57
58 GdkWindow*
59 gdk_selection_owner_get (GdkAtom selection)
60 {
61   Window xwindow;
62
63   xwindow = XGetSelectionOwner (gdk_display, selection);
64   if (xwindow == None)
65     return NULL;
66
67   return gdk_window_lookup (xwindow);
68 }
69
70 void
71 gdk_selection_convert (GdkWindow *requestor,
72                        GdkAtom    selection,
73                        GdkAtom    target,
74                        guint32    time)
75 {
76   GdkWindowPrivate *private;
77
78   g_return_if_fail (requestor != NULL);
79
80   private = (GdkWindowPrivate*) requestor;
81   if (private->destroyed)
82     return;
83
84   XConvertSelection (private->xdisplay, selection, target,
85                      gdk_selection_property, private->xwindow, time);
86 }
87
88 gint
89 gdk_selection_property_get (GdkWindow  *requestor,
90                             guchar    **data,
91                             GdkAtom    *ret_type,
92                             gint       *ret_format)
93 {
94   GdkWindowPrivate *private;
95   gulong nitems;
96   gulong nbytes;
97   gulong length;
98   GdkAtom prop_type;
99   gint prop_format;
100   guchar *t;
101
102   g_return_val_if_fail (requestor != NULL, 0);
103
104   /* If retrieved chunks are typically small, (and the ICCM says the
105      should be) it would be a win to try first with a buffer of
106      moderate length, to avoid two round trips to the server */
107
108   private = (GdkWindowPrivate*) requestor;
109   if (private->destroyed)
110     return 0;
111
112   t = NULL;
113   XGetWindowProperty (private->xdisplay, private->xwindow,
114                       gdk_selection_property, 0, 0, False,
115                       AnyPropertyType, &prop_type, &prop_format,
116                       &nitems, &nbytes, &t);
117
118   if (ret_type)
119     *ret_type = prop_type;
120   if (ret_format)
121     *ret_format = prop_format;
122
123   if (prop_type == None)
124     {
125       *data = NULL;
126       return 0;
127     }
128     
129   if (t)
130     {
131       t = NULL;
132       XFree (t);
133     }
134
135   /* Add on an extra byte to handle null termination.  X guarantees
136      that t will be 1 longer than nbytes and null terminated */
137   length = nbytes + 1;
138
139   /* We can't delete the selection here, because it might be the INCR
140      protocol, in which case the client has to make sure they'll be
141      notified of PropertyChange events _before_ the property is deleted.
142      Otherwise there's no guarantee we'll win the race ... */
143   XGetWindowProperty (private->xdisplay, private->xwindow,
144                       gdk_selection_property, 0, (nbytes + 3) / 4, False,
145                       AnyPropertyType, &prop_type, &prop_format,
146                       &nitems, &nbytes, &t);
147
148   if (prop_type != None)
149     {
150       *data = g_new (guchar, length);
151       memcpy (*data, t, length);
152       if (t)
153         XFree (t);
154       return length-1;
155     }
156   else
157     {
158       *data = NULL;
159       return 0;
160     }
161 }
162
163
164 void
165 gdk_selection_send_notify (guint32  requestor,
166                            GdkAtom  selection,
167                            GdkAtom  target,
168                            GdkAtom  property,
169                            guint32  time)
170 {
171   XSelectionEvent xevent;
172
173   xevent.type = SelectionNotify;
174   xevent.serial = 0;
175   xevent.send_event = True;
176   xevent.display = gdk_display;
177   xevent.requestor = requestor;
178   xevent.selection = selection;
179   xevent.target = target;
180   xevent.property = property;
181   xevent.time = time;
182
183   XSendEvent (gdk_display, requestor, False, NoEventMask, (XEvent*) &xevent);
184 }
185
186 gint
187 gdk_text_property_to_text_list (GdkAtom encoding, gint format, 
188                              guchar *text, gint length,
189                              gchar ***list)
190 {
191   XTextProperty property;
192   gint count = 0;
193   gint res;
194
195   if (!list) 
196     return 0;
197
198   property.value = text;
199   property.encoding = encoding;
200   property.format = format;
201   property.nitems = length;
202   res = XmbTextPropertyToTextList (GDK_DISPLAY(), &property, list, &count);
203
204   if (res == XNoMemory || res == XLocaleNotSupported || 
205       res == XConverterNotFound)
206     return 0;
207   else
208     return count;
209 }
210
211 void
212 gdk_free_text_list (gchar **list)
213 {
214   g_return_if_fail (list != NULL);
215
216   XFreeStringList (list);
217 }
218
219 gint
220 gdk_string_to_compound_text (gchar *str,
221                              GdkAtom *encoding, gint *format,
222                              guchar **ctext, gint *length)
223 {
224   gint res;
225   XTextProperty property;
226
227   res = XmbTextListToTextProperty (GDK_DISPLAY(), 
228                                    &str, 1, XCompoundTextStyle,
229                                    &property);
230   if (res != Success)
231     {
232       property.encoding = None;
233       property.format = None;
234       property.value = NULL;
235       property.nitems = 0;
236     }
237
238   if (encoding)
239     *encoding = property.encoding;
240   if (format)
241     *format = property.format;
242   if (ctext)
243     *ctext = property.value;
244   if (length)
245     *length = property.nitems;
246
247   return res;
248 }
249
250 void gdk_free_compound_text (guchar *ctext)
251 {
252   if (ctext)
253     XFree (ctext);
254 }