2
* $Id: drop.c,v 1.9 2005/06/25 01:37:44 daichik Exp $
4
* Copyright (c) 2004, Christian Biere
6
*----------------------------------------------------------------------
7
* This file is part of gtk-gnutella.
9
* gtk-gnutella is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
14
* gtk-gnutella is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with gtk-gnutella; if not, write to the Free Software
22
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
*----------------------------------------------------------------------
30
* Drop support - no dragging, just dropping.
32
* @author Christian Biere
40
RCSID("$Id: drop.c,v 1.9 2005/06/25 01:37:44 daichik Exp $");
43
#include "statusbar.h"
46
#include "if/bridge/ui2c.h"
47
#include "if/core/downloads.h" /* URN_INDEX */
48
#include "if/core/guid.h" /* blank_guid[] */
49
#include "if/gui_property_priv.h"
51
#include "lib/glib-missing.h"
54
#include "lib/override.h" /* Must be the last header included */
60
static gboolean handle_not_implemented(gchar *url);
61
static gboolean handle_magnet(gchar *url);
67
static GtkClipboard *cb;
70
const char * const proto;
71
gboolean (* handler)(gchar *url);
72
} proto_handlers[] = {
73
{ "http", handle_not_implemented },
74
{ "ftp", handle_not_implemented },
75
{ "magnet", handle_magnet },
83
handle_not_implemented(gchar *unused_url)
87
statusbar_gui_warning(10,
88
_("Support for this protocol is not yet implemented"));
93
plus_to_space(gchar *s)
98
for (p = s; (c = *p) != '\0'; p++)
104
handle_magnet(gchar *url)
114
} dl = { FALSE, NULL, 0, 0, NULL, NULL };
116
p = strchr(url, ':');
121
g_message("Invalid MAGNET URI");
126
for (/* NOTHING */; p; p = next) {
131
g_message("Invalid MAGNET URI");
135
g_assert((ssize_t) (q - p) > 0);
137
*q++ = '\0'; /* Overwrite '=' and skip to next character */
138
next = strchr(q, '&');
145
if (!url_unescape(q, TRUE)) {
146
g_message("Invalidly encoded MAGNET URI");
150
/* q points to the value; p is free to use */
152
if (0 == strcmp(name, "dn")) {
153
/* Descriptive Name */
155
} else if (0 == strcmp(name, "xs")) {
157
static const char n2r_query[] = "/uri-res/N2R?";
158
static const char http_prefix[] = "http://";
160
gchar digest[SHA1_RAW_SIZE];
163
gchar *hostname = NULL;
166
/* XXX: This should be handled elsewhere e.g., downloads.c in
171
* Alternatives sources should be used
173
g_message("More than one source; skipping");
177
if (NULL == (p = is_strprefix(q, http_prefix))) {
178
statusbar_gui_warning(10, _("MAGNET URI contained source URL "
179
"for an unsupported protocol"));
180
/* Skip this parameter */
184
if (gchar_to_ip_strict(p, &addr, (const gchar **) &ep)) {
192
g_message("Missing path in HTTP URL");
202
*p++ = '\0'; /* Terminate hostname */
203
v = gm_atoul(p, &ep2, &error);
204
if (error || v >= 65535) {
205
g_message("TCP port is out of range");
206
/* Skip this parameter */
217
g_message("Expected port followed by '/'");
218
/* Skip this parameter */
223
if (!is_strprefix(p, n2r_query)) {
225
* Support e.g., "http://example.com/example.txt"
227
g_message("Arbitrary HTTP URLs are not supported yet");
231
*p = '\0'; /* terminate hostname */
232
p += sizeof n2r_query - 1;
233
if (!is_strprefix(p, "urn:sha1:")) {
234
g_message("Expected ``urn:sha1:''");
239
if (!urn_get_sha1(hash, digest)) {
240
g_message("Bad SHA1 in MAGNET URI (%s)", hash);
248
dl.hostname = hostname;
251
} else if (0 == strcmp(name, "xt")) {
252
/* eXact Topic search (by urn:sha1) */
253
if (!is_strprefix(q, "urn:sha1:")) {
254
statusbar_gui_warning(10, _("MAGNET URI contained exact topic "
255
"search other than urn:sha1:"));
256
/* Skip this parameter */
259
search_gui_new_search(q, 0, NULL);
260
} else if (0 == strcmp(name, "kt")) {
261
/* Keyword Topic search */
262
search_gui_new_search(q, 0, NULL);
264
g_message("Unhandled parameter in MAGNET URI \"%s\"", name);
269
/* FIXME: As long as downloading of files without a known size is
270
* defective, we cannot initiate downloads this way. */
275
filename = gm_sanitize_filename(dl.file, FALSE, FALSE);
277
guc_download_new_unknown_size(filename, URN_INDEX, dl.ip,
278
dl.port, blank_guid, dl.hostname, dl.sha1, time(NULL),
280
if (filename != dl.file)
281
G_FREE_NULL(filename);
290
drag_data_received(GtkWidget *unused_widget, GdkDragContext *dc,
291
gint x, gint y, GtkSelectionData *data, guint info, guint stamp,
292
gpointer unused_udata)
294
gboolean succ = FALSE;
296
(void) unused_widget;
300
g_message("drag_data_received: x=%d, y=%d, info=%u, t=%u",
302
if (data->length > 0 && data->format == 8) {
304
gchar *p, *url = (gchar *) data->data;
308
g_message("drag_data_received: url=\"%s\"", url);
311
p = strchr(url, ':');
312
len = p ? p - url : 0;
313
if (!p || (ssize_t) len < 1) {
314
statusbar_gui_warning(10, _("Cannot handle the dropped data"));
318
for (i = 0; i < G_N_ELEMENTS(proto_handlers); i++)
319
if (is_strprefix(url, proto_handlers[i].proto)) {
320
succ = proto_handlers[i].handler(url);
324
if (i == G_N_ELEMENTS(proto_handlers))
325
statusbar_gui_warning(10, _("Protocol is not supported"));
330
gtk_drag_finish(dc, succ, FALSE, stamp);
339
static const GtkTargetEntry targets[] = {
341
{ "text/plain", 0, 23 },
343
GtkWidget *w = GTK_WIDGET(main_window);
345
g_return_if_fail(!cb);
346
cb = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
347
g_return_if_fail(cb);
349
g_signal_connect(G_OBJECT(w), "drag-data-received",
350
G_CALLBACK(drag_data_received), NULL);
352
gtk_drag_dest_set(w, GTK_DEST_DEFAULT_ALL, targets,
353
G_N_ELEMENTS(targets), GDK_ACTION_COPY | GDK_ACTION_MOVE);
354
gtk_drag_dest_set_target_list(w, gtk_target_list_new(targets,
355
G_N_ELEMENTS(targets)));
358
void drop_close(void)
362
#endif /* USE_GTK2 */
367
/* NOT IMPLEMENTED */
370
void drop_close(void)
372
/* NOT IMPLEMENTED */
376
/* vi: set ts=4 sw=4 cindent: */