1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
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.
21 * Modified by the GTK+ Team and others 1997-1999. 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/.
34 /* We emulate the GDK_SELECTION window properties by storing
35 * it's data in a per-window hashtable.
45 static GHashTable *sel_prop_table = NULL;
48 gdk_selection_init (void)
50 if (sel_prop_table == NULL)
51 sel_prop_table = g_hash_table_new (g_int_hash, g_int_equal);
55 gdk_sel_prop_store (GdkWindow *owner,
63 prop = g_hash_table_lookup (sel_prop_table, &GDK_DRAWABLE_XID (owner));
67 g_hash_table_remove (sel_prop_table, &GDK_DRAWABLE_XID (owner));
69 prop = g_new (GdkSelProp, 1);
71 prop->length = length;
72 prop->format = format;
74 g_hash_table_insert (sel_prop_table, &GDK_DRAWABLE_XID (owner), prop);
78 gdk_selection_owner_set (GdkWindow *owner,
87 (sel_name = gdk_atom_name (selection),
88 g_print ("gdk_selection_owner_set: %#x %#x (%s)\n",
89 (owner ? GDK_DRAWABLE_XID (owner) : 0),
93 if (selection != gdk_clipboard_atom)
97 xwindow = GDK_DRAWABLE_XID (owner);
101 GDK_NOTE (SELECTION, g_print ("...OpenClipboard(%#x)\n", xwindow));
102 if (!OpenClipboard (xwindow))
104 g_warning ("gdk_selection_owner_set: OpenClipboard failed");
107 GDK_NOTE (SELECTION, g_print ("...EmptyClipboard()\n"));
108 if (!EmptyClipboard ())
110 g_warning ("gdk_selection_owner_set: EmptyClipboard failed");
115 /* No delayed rendering */
117 SetClipboardData (CF_TEXT, NULL);
119 GDK_NOTE (SELECTION, g_print ("...CloseClipboard()\n"));
120 if (!CloseClipboard ())
122 g_warning ("gdk_selection_owner_set: CloseClipboard failed");
127 /* Send ourselves an ersatz selection request message so that
128 * gdk_property_change will be called to store the clipboard data.
130 SendMessage (xwindow, gdk_selection_request_msg,
138 gdk_selection_owner_get (GdkAtom selection)
144 /* XXX Hmm, gtk selections seem to work best with this. This causes
145 * gtk to always get the clipboard contents from Windows, and not
146 * from the editable's own stashed-away copy.
150 if (selection != gdk_clipboard_atom)
153 window = gdk_window_lookup (GetClipboardOwner ());
158 (sel_name = gdk_atom_name (selection),
159 g_print ("gdk_selection_owner_get: %#x (%s) = %#x\n",
161 (window ? GDK_DRAWABLE_XID (window) : 0)),
168 gdk_selection_convert (GdkWindow *requestor,
175 guchar *ptr, *data, *datap, *p;
176 guint i, length, slength;
177 gchar *sel_name, *tgt_name;
179 g_return_if_fail (requestor != NULL);
180 if (GDK_DRAWABLE_DESTROYED (requestor))
184 (sel_name = gdk_atom_name (selection),
185 tgt_name = gdk_atom_name (target),
186 g_print ("gdk_selection_convert: %#x %#x (%s) %#x (%s)\n",
187 GDK_DRAWABLE_XID (requestor), selection, sel_name, target, tgt_name),
191 if (selection == gdk_clipboard_atom)
193 /* Converting the CLIPBOARD selection means he wants the
194 * contents of the clipboard. Get the clipboard data,
195 * and store it for later.
197 GDK_NOTE (SELECTION, g_print ("...OpenClipboard(%#x)\n",
198 GDK_DRAWABLE_XID (requestor)));
199 if (!OpenClipboard (GDK_DRAWABLE_XID (requestor)))
201 g_warning ("gdk_selection_convert: OpenClipboard failed");
205 GDK_NOTE (SELECTION, g_print ("...GetClipboardData(CF_TEXT)\n"));
206 if ((hdata = GetClipboardData (CF_TEXT)) != NULL)
208 if ((ptr = GlobalLock (hdata)) != NULL)
210 length = GlobalSize (hdata);
212 GDK_NOTE (SELECTION, g_print ("...got data: %d bytes: %.10s\n",
217 for (i = 0; i < length; i++)
226 data = datap = g_malloc (slength + 1);
228 for (i = 0; i < length; i++)
237 gdk_sel_prop_store (requestor, GDK_TARGET_STRING, 8,
238 data, strlen (data) + 1);
240 GlobalUnlock (hdata);
243 GDK_NOTE (SELECTION, g_print ("...CloseClipboard()\n"));
247 /* Send ourselves an ersatz selection notify message so that we actually
250 SendMessage (GDK_DRAWABLE_XID (requestor), gdk_selection_notify_msg, selection, target);
252 else if (selection == gdk_win32_dropfiles_atom)
254 /* This means he wants the names of the dropped files.
255 * gdk_dropfiles_filter already has stored the text/uri-list
256 * data, tempoarily on gdk_root_parent's selection "property".
260 prop = g_hash_table_lookup (sel_prop_table, &gdk_root_parent->drawable.xwindow);
264 g_hash_table_remove (sel_prop_table, &gdk_root_parent->drawable.xwindow);
265 gdk_sel_prop_store (requestor, prop->type, prop->format,
266 prop->data, prop->length);
268 SendMessage (GDK_DRAWABLE_XID (requestor), gdk_selection_notify_msg, selection, target);
273 g_warning ("gdk_selection_convert: General case not implemented");
278 gdk_selection_property_get (GdkWindow *requestor,
285 g_return_val_if_fail (requestor != NULL, 0);
286 g_return_val_if_fail (GDK_IS_WINDOW (requestor), 0);
288 if (GDK_DRAWABLE_DESTROYED (requestor))
291 GDK_NOTE (SELECTION, g_print ("gdk_selection_property_get: %#x\n",
292 GDK_DRAWABLE_XID (requestor)));
294 prop = g_hash_table_lookup (sel_prop_table, &GDK_DRAWABLE_XID (requestor));
301 *data = g_malloc (prop->length);
302 if (prop->length > 0)
303 memmove (*data, prop->data, prop->length);
305 *ret_type = prop->type;
307 *ret_format = prop->format;
313 gdk_selection_property_delete (GdkWindow *window)
317 prop = g_hash_table_lookup (sel_prop_table, &GDK_DRAWABLE_XID (window));
321 g_hash_table_remove (sel_prop_table, &GDK_DRAWABLE_XID (window));
328 gdk_selection_send_notify (guint32 requestor,
334 gchar *sel_name, *tgt_name, *prop_name;
337 (sel_name = gdk_atom_name (selection),
338 tgt_name = gdk_atom_name (target),
339 prop_name = gdk_atom_name (property),
340 g_print ("gdk_selection_send_notify: %#x %#x (%s) %#x (%s) %#x (%s)\n",
344 property, prop_name),
347 g_free (prop_name)));
349 /* Send ourselves a selection clear message so that gtk thinks we don't
350 * have the selection, and will claim it anew when needed, and
351 * we thus get a chance to store data in the Windows clipboard.
352 * Otherwise, if a gtkeditable does a copy to clipboard several times
353 * only the first one actually gets copied to the Windows clipboard,
354 * as only he first one causes a call to gdk_property_change.
356 * Hmm, there is something fishy with this. Cut and paste inside the
357 * same app didn't work, the gtkeditable immediately forgot the
358 * clipboard contents in gtk_editable_selection_clear as a result of
359 * this message. OTOH, when I changed gdk_selection_owner_get to
360 * always return NULL, it works. Sigh.
363 SendMessage ((HWND) requestor, gdk_selection_clear_msg, selection, 0);
367 gdk_text_property_to_text_list (GdkAtom encoding,
374 g_print ("gdk_text_property_to_text_list not implemented\n"));
380 gdk_free_text_list (gchar **list)
382 g_return_if_fail (list != NULL);
388 gdk_string_to_compound_text (gchar *str,
394 g_warning ("gdk_string_to_compound_text: Not implemented");
400 gdk_free_compound_text (guchar *ctext)
402 g_warning ("gdk_free_compound_text: Not implemented");