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