]> Pileus Git - ~andy/gtk/blob - gdk/gdkselection.c
Patches to support internationalized input by:
[~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 Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 #include <X11/Xlib.h>
19 #include <X11/Xatom.h>
20 #include <string.h>
21 #include "gdk.h"
22 #include "gdkprivate.h"
23 #include "gdkx.h"
24
25
26 gint
27 gdk_selection_owner_set (GdkWindow *owner,
28                          GdkAtom    selection,
29                          guint32    time,
30                          gint       send_event)
31 {
32   GdkWindowPrivate *private;
33   Display *xdisplay;
34   Window xwindow;
35
36   if (owner)
37     {
38       private = (GdkWindowPrivate*) owner;
39       xdisplay = private->xdisplay;
40       xwindow = private->xwindow;
41     }
42   else
43     {
44       xdisplay = gdk_display;
45       xwindow = None;
46     }
47
48   XSetSelectionOwner (xdisplay, selection, xwindow, time);
49
50   return (XGetSelectionOwner (xdisplay, selection) == xwindow);
51 }
52
53 GdkWindow*
54 gdk_selection_owner_get (GdkAtom selection)
55 {
56   Window xwindow;
57
58   xwindow = XGetSelectionOwner (gdk_display, selection);
59   if (xwindow == None)
60     return NULL;
61
62   return gdk_window_lookup (xwindow);
63 }
64
65 void
66 gdk_selection_convert (GdkWindow *requestor,
67                        GdkAtom    selection,
68                        GdkAtom    target,
69                        guint32    time)
70 {
71   GdkWindowPrivate *private;
72
73   g_return_if_fail (requestor != NULL);
74
75   private = (GdkWindowPrivate*) requestor;
76
77   XConvertSelection (private->xdisplay, selection, target,
78                      gdk_selection_property, private->xwindow, time);
79 }
80
81 gint
82 gdk_selection_property_get (GdkWindow  *requestor,
83                             guchar    **data,
84                             GdkAtom    *ret_type,
85                             gint       *ret_format)
86 {
87   GdkWindowPrivate *private;
88   gulong nitems;
89   gulong nbytes;
90   gulong length;
91   GdkAtom prop_type;
92   gint prop_format;
93   guchar *t;
94
95   g_return_val_if_fail (requestor != NULL, 0);
96
97   /* If retrieved chunks are typically small, (and the ICCM says the
98      should be) it would be a win to try first with a buffer of
99      moderate length, to avoid two round trips to the server */
100
101   private = (GdkWindowPrivate*) requestor;
102
103   XGetWindowProperty (private->xdisplay, private->xwindow,
104                       gdk_selection_property, 0, 0, False,
105                       AnyPropertyType, &prop_type, &prop_format,
106                       &nitems, &nbytes, &t);
107
108   if (ret_type)
109     *ret_type = prop_type;
110   if (ret_format)
111     *ret_format = prop_format;
112
113   if (prop_type == None)
114     {
115       *data = NULL;
116       return 0;
117     }
118     
119   XFree (t);
120
121   /* Add on an extra byte to handle null termination.  X guarantees
122      that t will be 1 longer than nbytes and null terminated */
123   length = nbytes + 1;
124
125   /* We can't delete the selection here, because it might be the INCR
126      protocol, in which case the client has to make sure they'll be
127      notified of PropertyChange events _before_ the property is deleted.
128      Otherwise there's no guarantee we'll win the race ... */
129   XGetWindowProperty (private->xdisplay, private->xwindow,
130                       gdk_selection_property, 0, (nbytes + 3) / 4, False,
131                       AnyPropertyType, &prop_type, &prop_format,
132                       &nitems, &nbytes, &t);
133
134   if (prop_type != None)
135     {
136       *data = g_new (guchar, length);
137       memcpy (*data, t, length);
138       XFree (t);
139       return length-1;
140     }
141   else
142     {
143       *data = NULL;
144       return 0;
145     }
146 }
147
148
149 void
150 gdk_selection_send_notify (guint32  requestor,
151                            GdkAtom  selection,
152                            GdkAtom  target,
153                            GdkAtom  property,
154                            guint32  time)
155 {
156   XSelectionEvent xevent;
157
158   xevent.type = SelectionNotify;
159   xevent.serial = 0;
160   xevent.send_event = True;
161   xevent.display = gdk_display;
162   xevent.requestor = requestor;
163   xevent.selection = selection;
164   xevent.target = target;
165   xevent.property = property;
166   xevent.time = time;
167
168   XSendEvent (gdk_display, requestor, False, NoEventMask, (XEvent*) &xevent);
169 }
170
171 gint
172 gdk_text_property_to_text_list (GdkAtom encoding, gint format, 
173                              guchar *text, gint length,
174                              gchar ***list)
175 {
176   XTextProperty property;
177   gint count = 0;
178   gint res;
179
180   if (!list) 
181     return 0;
182
183   property.value = text;
184   property.encoding = encoding;
185   property.format = format;
186   property.nitems = length;
187   res = XmbTextPropertyToTextList (GDK_DISPLAY(), &property, list, &count);
188
189   if (res == XNoMemory || res == XLocaleNotSupported || 
190       res == XConverterNotFound)
191     return 0;
192   else
193     return count;
194 }
195
196 void
197 gdk_free_text_list (gchar **list)
198 {
199   XFreeStringList (list);
200 }
201
202 gint
203 gdk_string_to_compound_text (gchar *str,
204                              GdkAtom *encoding, gint *format,
205                              guchar **ctext, gint *length)
206 {
207   gint res;
208   XTextProperty property;
209
210   res = XmbTextListToTextProperty (GDK_DISPLAY(), 
211                                    &str, 1, XCompoundTextStyle,
212                                    &property);
213   if (res != Success)
214     {
215       property.encoding = None;
216       property.format = None;
217       property.value = NULL;
218       property.nitems = 0;
219     }
220
221   if (encoding)
222     *encoding = property.encoding;
223   if (format)
224     *format = property.format;
225   if (ctext)
226     *ctext = property.value;
227   if (length)
228     *length = property.nitems;
229
230   return res;
231 }
232
233 void gdk_free_compound_text (guchar *ctext)
234 {
235   if (ctext)
236     XFree (ctext);
237 }