On 2011-11-03 16:30, Peter John Hartman wrote:
>
> Second of all, and instead, it just prints to stdout (a) the fact that the
> Download has started, together with the filename, and (b) the fact that it
> has finished/cancelled/errored, together with the filename.
Not much more to add a progress bar to that patch.
Patrick
diff -urN surf-tip/surf.c surf-dl/surf.c
--- surf-tip/surf.c 2011-11-04 22:21:52.077749801 +0800
+++ surf-dl/surf.c 2011-11-04 23:35:55.630343708 +0800
@@ -42,6 +42,15 @@
gboolean zoomed;
} Client;
+typedef struct Download {
+ WebKitDownload *download;
+ Client *client;
+ gboolean is_done;
+ char *filename;
+ char *filename_partial;
+ struct Download *next;
+} Download;
+
typedef struct {
char *label;
void (*func)(Client *c, const Arg *arg);
@@ -58,6 +67,7 @@
static Display *dpy;
static Atom atoms[AtomLast];
static Client *clients = NULL;
+static Download *downloads = NULL;
static GdkNativeWindow embed = 0;
static gboolean showxid = FALSE;
static char winid[64];
@@ -340,14 +350,82 @@
soup_cookies_free(l);
}
+int
+downloadstatus(WebKitDownload *download, GParamSpec *pspec, gpointer
user_data) {
+ WebKitDownloadStatus status;
+ Download *d;
+
+ for (d = downloads; d != NULL && d->download != download ; d = d->next )
+ ;
+ if (d == NULL)
+ return fprintf(stderr, "lost download?\n"), -1;
+
+ g_object_get(download, "status", &status, NULL);
+
+ switch(status) {
+ case WEBKIT_DOWNLOAD_STATUS_CREATED:
+ d->client->progress = 0;
+ update(d->client);
+ break;
+ case WEBKIT_DOWNLOAD_STATUS_STARTED:
+ case WEBKIT_DOWNLOAD_STATUS_ERROR:
+ case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
+ break; /* these are irrelevant */
+ case WEBKIT_DOWNLOAD_STATUS_FINISHED: {
+ unlink(d->filename);
+ rename(d->filename_partial, d->filename);
+ g_free(d->filename_partial);
+ g_free(d->filename);
+ d->is_done = TRUE;
+ d->client->progress = 100;
+ update(d->client);
+ }
+ }
+ return 0;
+}
+
+void
+downloadprogress(WebKitDownload *download, GParamSpec *pspec, gpointer
user_data) {
+ Download *d;
+ gdouble progress;
+
+ g_object_get(download, "progress", &progress, NULL);
+ for (d = downloads; d != NULL && d->download != download ; d = d->next )
+ ;
+ if (d == NULL)
+ return;
+ if ( (d->client->progress = (int)(progress * 100)) == 0)
+ d->client->progress = 1;
+ update(d->client);
+}
+
gboolean
initdownload(WebKitWebView *view, WebKitDownload *o, Client *c) {
- Arg arg;
+ char *f;
+ Download *d;
- updatewinid(c);
- arg = (Arg)DOWNLOAD((char *)webkit_download_get_uri(o));
- spawn(c, &arg);
- return FALSE;
+ if (!(d = malloc(sizeof(Download))))
+ die("Cannot malloc!\n");
+ d->next = downloads;
+ d->client = c;
+ d->download = o;
+ d->is_done = FALSE;
+ downloads = d;
+ d->client->progress = 1;
+ update(d->client);
+ g_signal_connect(o, "notify::status", G_CALLBACK(downloadstatus), NULL);
+ g_signal_connect(o, "notify::progress", G_CALLBACK(downloadprogress),
NULL);
+ d->filename = g_strconcat(downloaddir, "/",
+ (char *)webkit_download_get_suggested_filename(o), NULL
+ );
+ d->filename_partial = g_strconcat(d->filename, ".part", NULL);
+ unlink(d->filename_partial);
+
+ f = g_strconcat("file://", d->filename_partial, NULL);
+ webkit_download_set_destination_uri(o, f);
+ webkit_download_start(o);
+ g_free(f);
+ return TRUE;
}
gboolean