]> Pileus Git - ~andy/gtk/blob - gdk/broadway/gdkselection-broadway.c
Change FSF Address
[~andy/gtk] / gdk / broadway / gdkselection-broadway.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 Lesser 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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 /*
19  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
20  * file for a list of people on the GTK+ Team.  See the ChangeLog
21  * files for a list of changes.  These files are distributed with
22  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
23  */
24
25 #include "config.h"
26
27 #include "gdkselection.h"
28
29 #include "gdkproperty.h"
30 #include "gdkprivate.h"
31 #include "gdkprivate-broadway.h"
32 #include "gdkdisplay-broadway.h"
33
34 #include <string.h>
35
36
37 typedef struct _OwnerInfo OwnerInfo;
38
39 struct _OwnerInfo
40 {
41   GdkAtom    selection;
42   GdkWindow *owner;
43   gulong     serial;
44 };
45
46 static GSList *owner_list;
47
48 /* When a window is destroyed we check if it is the owner
49  * of any selections. This is somewhat inefficient, but
50  * owner_list is typically short, and it is a low memory,
51  * low code solution
52  */
53 void
54 _gdk_broadway_selection_window_destroyed (GdkWindow *window)
55 {
56   GSList *tmp_list = owner_list;
57   while (tmp_list)
58     {
59       OwnerInfo *info = tmp_list->data;
60       tmp_list = tmp_list->next;
61
62       if (info->owner == window)
63         {
64           owner_list = g_slist_remove (owner_list, info);
65           g_free (info);
66         }
67     }
68 }
69
70 gboolean
71 _gdk_broadway_display_set_selection_owner (GdkDisplay *display,
72                                            GdkWindow  *owner,
73                                            GdkAtom     selection,
74                                            guint32     time,
75                                            gboolean    send_event)
76 {
77   GSList *tmp_list;
78   OwnerInfo *info;
79
80   if (gdk_display_is_closed (display))
81     return FALSE;
82
83   tmp_list = owner_list;
84   while (tmp_list)
85     {
86       info = tmp_list->data;
87       if (info->selection == selection)
88         {
89           owner_list = g_slist_remove (owner_list, info);
90           g_free (info);
91           break;
92         }
93       tmp_list = tmp_list->next;
94     }
95
96   if (owner)
97     {
98       info = g_new (OwnerInfo, 1);
99       info->owner = owner;
100       info->serial = _gdk_display_get_next_serial (display);
101
102       info->selection = selection;
103
104       owner_list = g_slist_prepend (owner_list, info);
105     }
106
107   return TRUE;
108 }
109
110 GdkWindow *
111 _gdk_broadway_display_get_selection_owner (GdkDisplay *display,
112                                            GdkAtom     selection)
113 {
114   GSList *tmp_list;
115   OwnerInfo *info;
116
117   if (gdk_display_is_closed (display))
118     return NULL;
119
120   tmp_list = owner_list;
121   while (tmp_list)
122     {
123       info = tmp_list->data;
124       if (info->selection == selection)
125         return info->owner;
126       tmp_list = tmp_list->next;
127     }
128
129   return NULL;
130 }
131
132 void
133 _gdk_broadway_display_convert_selection (GdkDisplay *display,
134                                          GdkWindow *requestor,
135                                          GdkAtom    selection,
136                                          GdkAtom    target,
137                                          guint32    time)
138 {
139   g_warning ("convert_selection not implemented\n");
140 }
141
142 gint
143 _gdk_broadway_display_get_selection_property (GdkDisplay *display,
144                                               GdkWindow  *requestor,
145                                               guchar    **data,
146                                               GdkAtom    *ret_type,
147                                               gint       *ret_format)
148 {
149   if (ret_type)
150     *ret_type = GDK_NONE;
151   if (ret_format)
152     *ret_format = 0;
153   if (data)
154     *data = NULL;
155
156   g_warning ("get_selection_property not implemented\n");
157
158   return 0;
159 }
160
161 void
162 _gdk_broadway_display_send_selection_notify (GdkDisplay      *display,
163                                              GdkWindow       *requestor,
164                                              GdkAtom          selection,
165                                              GdkAtom          target,
166                                              GdkAtom          property, 
167                                              guint32          time)
168 {
169   g_return_if_fail (GDK_IS_DISPLAY (display));
170
171   g_warning ("send_selection_notify not implemented\n");
172 }
173
174
175 static gint
176 make_list (const gchar  *text,
177            gint          length,
178            gboolean      latin1,
179            gchar      ***list)
180 {
181   GSList *strings = NULL;
182   gint n_strings = 0;
183   gint i;
184   const gchar *p = text;
185   const gchar *q;
186   GSList *tmp_list;
187   GError *error = NULL;
188
189   while (p < text + length)
190     {
191       gchar *str;
192
193       q = p;
194       while (*q && q < text + length)
195         q++;
196
197       if (latin1)
198         {
199           str = g_convert (p, q - p,
200                            "UTF-8", "ISO-8859-1",
201                            NULL, NULL, &error);
202
203           if (!str)
204             {
205               g_warning ("Error converting selection from STRING: %s",
206                          error->message);
207               g_error_free (error);
208             }
209         }
210       else
211         {
212           str = g_strndup (p, q - p);
213           if (!g_utf8_validate (str, -1, NULL))
214             {
215               g_warning ("Error converting selection from UTF8_STRING");
216               g_free (str);
217               str = NULL;
218             }
219         }
220
221       if (str)
222         {
223           strings = g_slist_prepend (strings, str);
224           n_strings++;
225         }
226
227       p = q + 1;
228     }
229
230   if (list)
231     {
232       *list = g_new (gchar *, n_strings + 1);
233       (*list)[n_strings] = NULL;
234     }
235
236   i = n_strings;
237   tmp_list = strings;
238   while (tmp_list)
239     {
240       if (list)
241         (*list)[--i] = tmp_list->data;
242       else
243         g_free (tmp_list->data);
244
245       tmp_list = tmp_list->next;
246     }
247
248   g_slist_free (strings);
249
250   return n_strings;
251 }
252
253 gint 
254 _gdk_broadway_display_text_property_to_utf8_list (GdkDisplay    *display,
255                                                   GdkAtom        encoding,
256                                                   gint           format,
257                                                   const guchar  *text,
258                                                   gint           length,
259                                                   gchar       ***list)
260 {
261   g_return_val_if_fail (text != NULL, 0);
262   g_return_val_if_fail (length >= 0, 0);
263   g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
264
265   if (encoding == GDK_TARGET_STRING)
266     {
267       return make_list ((gchar *)text, length, TRUE, list);
268     }
269   else if (encoding == gdk_atom_intern_static_string ("UTF8_STRING"))
270     {
271       return make_list ((gchar *)text, length, FALSE, list);
272     }
273   
274   if (list)
275     *list = NULL;
276   return 0;
277 }
278
279 gchar *
280 _gdk_broadway_display_utf8_to_string_target (GdkDisplay  *display,
281                                              const gchar *str)
282 {
283   return g_strdup (str);
284 }