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