summaryrefslogtreecommitdiff
path: root/riscos/download.c
diff options
context:
space:
mode:
Diffstat (limited to 'riscos/download.c')
-rw-r--r--riscos/download.c319
1 files changed, 177 insertions, 142 deletions
diff --git a/riscos/download.c b/riscos/download.c
index ebd981dca..a03ff474b 100644
--- a/riscos/download.c
+++ b/riscos/download.c
@@ -33,6 +33,8 @@
#include <sys/time.h>
#include <time.h>
#include <curl/curl.h>
+#include <libwapcaplet/libwapcaplet.h>
+
#include "oslib/mimemap.h"
#include "oslib/osargs.h"
#include "oslib/osfile.h"
@@ -41,21 +43,27 @@
#include "oslib/osgbpb.h"
#include "oslib/wimp.h"
#include "oslib/wimpspriteop.h"
+
#include "desktop/gui.h"
#include "desktop/netsurf.h"
-#include "riscos/dialog.h"
+#include "desktop/download.h"
#include "utils/nsoption.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsurl.h"
+#include "utils/utf8.h"
+#include "utils/utils.h"
+#include "utils/corestrings.h"
+
+#include "riscos/gui.h"
+#include "riscos/dialog.h"
#include "riscos/mouse.h"
#include "riscos/save.h"
#include "riscos/query.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
-#include "utils/log.h"
-#include "utils/messages.h"
-#include "utils/schedule.h"
-#include "utils/url.h"
-#include "utils/utf8.h"
-#include "utils/utils.h"
+#include "riscos/ucstables.h"
+#include "riscos/filetype.h"
#define ICON_DOWNLOAD_ICON 0
#define ICON_DOWNLOAD_URL 1
@@ -206,6 +214,60 @@ const char *ro_gui_download_temp_name(struct gui_download_window *dw)
return temp_name;
}
+/**
+ * Try and find the correct RISC OS filetype from a download context.
+ */
+static nserror download_ro_filetype(download_context *ctx, bits *ftype_out)
+{
+ nsurl *url = download_context_get_url(ctx);
+ bits ftype = 0;
+ lwc_string *scheme;
+
+ /* If the file is local try and read its filetype */
+ scheme = nsurl_get_component(url, NSURL_SCHEME);
+ if (scheme != NULL) {
+ bool filescheme;
+ if (lwc_string_isequal(scheme,
+ corestring_lwc_file,
+ &filescheme) != lwc_error_ok) {
+ filescheme = false;
+ }
+
+ if (filescheme) {
+ lwc_string *path = nsurl_get_component(url, NSURL_PATH);
+ if (path != NULL && lwc_string_length(path) != 0) {
+ char *raw_path;
+ raw_path = curl_unescape(lwc_string_data(path),
+ lwc_string_length(path));
+ if (raw_path != NULL) {
+ ftype = ro_filetype_from_unix_path(raw_path);
+ curl_free(raw_path);
+ }
+ }
+ }
+ }
+
+ /* If we still don't have a filetype (i.e. failed reading local
+ * one or fetching a remote object), then use the MIME type.
+ */
+ if (ftype == 0) {
+ /* convert MIME type to RISC OS file type */
+ os_error *error;
+ const char *mime_type;
+
+ mime_type = download_context_get_mime_type(ctx);
+ error = xmimemaptranslate_mime_type_to_filetype(mime_type, &ftype);
+ if (error) {
+ LOG(("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("MiscError", error->errmess);
+ ftype = 0xffd;
+ }
+ }
+
+ *ftype_out = ftype;
+ return NSERROR_OK;
+}
/**
* Create and open a download progress window.
@@ -215,20 +277,17 @@ const char *ro_gui_download_temp_name(struct gui_download_window *dw)
* reported
*/
-struct gui_download_window *gui_download_window_create(download_context *ctx,
- struct gui_window *gui)
+static struct gui_download_window *
+gui_download_window_create(download_context *ctx, struct gui_window *gui)
{
- const char *url = download_context_get_url(ctx);
- const char *mime_type = download_context_get_mime_type(ctx);
+ nsurl *url = download_context_get_url(ctx);
const char *temp_name;
- char *scheme = NULL;
char *filename = NULL;
struct gui_download_window *dw;
bool space_warning = false;
os_error *error;
- url_func_result res;
char *local_path;
- utf8_convert_ret err;
+ nserror err;
size_t i, last_dot;
dw = malloc(sizeof *dw);
@@ -244,8 +303,13 @@ struct gui_download_window *gui_download_window_create(download_context *ctx,
dw->query = QUERY_INVALID;
dw->received = 0;
dw->total_size = download_context_get_total_length(ctx);
- strncpy(dw->url, url, sizeof dw->url);
+
+ /** @todo change this to take a reference to the nsurl and use
+ * that value directly rather than using a fixed buffer.
+ */
+ strncpy(dw->url, nsurl_access(url), sizeof dw->url);
dw->url[sizeof dw->url - 1] = 0;
+
dw->status[0] = 0;
gettimeofday(&dw->start_time, 0);
dw->last_time = dw->start_time;
@@ -254,55 +318,12 @@ struct gui_download_window *gui_download_window_create(download_context *ctx,
dw->average_rate = 0;
dw->average_points = 0;
- /* Get scheme from URL */
- res = url_scheme(url, &scheme);
- if (res == URL_FUNC_NOMEM) {
- warn_user("NoMemory", 0);
+ /* get filetype */
+ err = download_ro_filetype(ctx, &dw->file_type);
+ if (err != NSERROR_OK) {
+ warn_user(messages_get_errorcode(err), 0);
free(dw);
return 0;
- } else if (res == URL_FUNC_OK) {
- /* If we have a scheme and it's "file", then
- * attempt to use the local filetype directly */
- if (strcasecmp(scheme, "file") == 0) {
- char *path = NULL;
- res = url_path(url, &path);
- if (res == URL_FUNC_NOMEM) {
- warn_user("NoMemory", 0);
- free(scheme);
- free(dw);
- return 0;
- } else if (res == URL_FUNC_OK) {
- char *raw_path = curl_unescape(path,
- strlen(path));
- if (raw_path == NULL) {
- warn_user("NoMemory", 0);
- free(path);
- free(scheme);
- free(dw);
- return 0;
- }
- dw->file_type =
- ro_filetype_from_unix_path(raw_path);
- curl_free(raw_path);
- free(path);
- }
- }
-
- free(scheme);
- }
-
- /* If we still don't have a filetype (i.e. failed reading local
- * one or fetching a remote object), then use the MIME type */
- if (dw->file_type == 0) {
- /* convert MIME type to RISC OS file type */
- error = xmimemaptranslate_mime_type_to_filetype(mime_type,
- &(dw->file_type));
- if (error) {
- LOG(("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("MiscError", error->errmess);
- dw->file_type = 0xffd;
- }
}
/* open temporary output file */
@@ -375,10 +396,12 @@ struct gui_download_window *gui_download_window_create(download_context *ctx,
snprintf(dw->path, RO_DOWNLOAD_MAX_PATH_LEN, "%s",
filename);
+ free(filename);
+
err = utf8_to_local_encoding(dw->path, 0, &local_path);
- if (err != UTF8_CONVERT_OK) {
+ if (err != NSERROR_OK) {
/* badenc should never happen */
- assert(err != UTF8_CONVERT_BADENC);
+ assert(err !=NSERROR_BAD_ENCODING);
LOG(("utf8_to_local_encoding failed"));
warn_user("NoMemory", 0);
free(dw);
@@ -435,6 +458,57 @@ struct gui_download_window *gui_download_window_create(download_context *ctx,
return dw;
}
+/**
+ * Handle failed downloads.
+ *
+ * \param dw download window
+ * \param error_msg error message
+ */
+
+static void gui_download_window_error(struct gui_download_window *dw,
+ const char *error_msg)
+{
+ os_error *error;
+
+ if (dw->ctx != NULL)
+ download_context_destroy(dw->ctx);
+ dw->ctx = NULL;
+ dw->error = true;
+
+ riscos_schedule(-1, ro_gui_download_update_status_wrapper, dw);
+
+ /* place error message in status icon in red */
+ strncpy(dw->status, error_msg, sizeof dw->status);
+ error = xwimp_set_icon_state(dw->window,
+ ICON_DOWNLOAD_STATUS,
+ wimp_COLOUR_RED << wimp_ICON_FG_COLOUR_SHIFT,
+ wimp_ICON_FG_COLOUR);
+ if (error) {
+ LOG(("xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+
+ /* grey out pathname icon */
+ error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_PATH,
+ wimp_ICON_SHADED, 0);
+ if (error) {
+ LOG(("xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+
+ /* grey out file icon */
+ error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON,
+ wimp_ICON_SHADED, wimp_ICON_SHADED);
+ if (error) {
+ LOG(("xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+
+ ro_gui_download_window_hide_caret(dw);
+}
/**
* Handle received download data.
@@ -445,7 +519,7 @@ struct gui_download_window *gui_download_window_create(download_context *ctx,
* \return NSERROR_OK on success, appropriate error otherwise
*/
-nserror gui_download_window_data(struct gui_download_window *dw,
+static nserror gui_download_window_data(struct gui_download_window *dw,
const char *data, unsigned int size)
{
while (true) {
@@ -526,7 +600,6 @@ nserror gui_download_window_data(struct gui_download_window *dw,
void ro_gui_download_update_status(struct gui_download_window *dw)
{
- char *received;
char *total_size;
char *speed;
char time[20] = "?";
@@ -537,7 +610,7 @@ void ro_gui_download_update_status(struct gui_download_window *dw)
os_error *error;
int width;
char *local_status;
- utf8_convert_ret err;
+ nserror err;
gettimeofday(&t, 0);
dt = (t.tv_sec + 0.000001 * t.tv_usec) - (dw->last_time.tv_sec +
@@ -548,6 +621,7 @@ void ro_gui_download_update_status(struct gui_download_window *dw)
total_size = human_friendly_bytesize(max(dw->received, dw->total_size));
if (dw->ctx) {
+ char *received;
rate = (dw->received - dw->last_received) / dt;
received = human_friendly_bytesize(dw->received);
/* A simple 'modified moving average' download rate calculation
@@ -571,9 +645,9 @@ void ro_gui_download_update_status(struct gui_download_window *dw)
/* convert to local encoding */
err = utf8_to_local_encoding(
messages_get("Download"), 0, &local_status);
- if (err != UTF8_CONVERT_OK) {
+ if (err != NSERROR_OK) {
/* badenc should never happen */
- assert(err != UTF8_CONVERT_BADENC);
+ assert(err != NSERROR_BAD_ENCODING);
/* hide nomem error */
snprintf(dw->status, sizeof dw->status,
messages_get("Download"),
@@ -594,9 +668,9 @@ void ro_gui_download_update_status(struct gui_download_window *dw)
err = utf8_to_local_encoding(
messages_get("DownloadU"), 0, &local_status);
- if (err != UTF8_CONVERT_OK) {
+ if (err != NSERROR_OK) {
/* badenc should never happen */
- assert(err != UTF8_CONVERT_BADENC);
+ assert(err != NSERROR_BAD_ENCODING);
/* hide nomem error */
snprintf(dw->status, sizeof dw->status,
messages_get("DownloadU"),
@@ -622,9 +696,9 @@ void ro_gui_download_update_status(struct gui_download_window *dw)
err = utf8_to_local_encoding(messages_get("Downloaded"), 0,
&local_status);
- if (err != UTF8_CONVERT_OK) {
+ if (err != NSERROR_OK) {
/* badenc should never happen */
- assert(err != UTF8_CONVERT_BADENC);
+ assert(err != NSERROR_BAD_ENCODING);
/* hide nomem error */
snprintf(dw->status, sizeof dw->status,
messages_get("Downloaded"),
@@ -661,15 +735,16 @@ void ro_gui_download_update_status(struct gui_download_window *dw)
warn_user("WimpError", error->errmess);
}
- if (dw->ctx)
- schedule(100, ro_gui_download_update_status_wrapper, dw);
- else
- schedule_remove(ro_gui_download_update_status_wrapper, dw);
+ if (dw->ctx) {
+ riscos_schedule(1000, ro_gui_download_update_status_wrapper, dw);
+ } else {
+ riscos_schedule(-1, ro_gui_download_update_status_wrapper, dw);
+ }
}
/**
- * Wrapper for ro_gui_download_update_status(), suitable for schedule().
+ * Wrapper for ro_gui_download_update_status(), suitable for riscos_schedule().
*/
void ro_gui_download_update_status_wrapper(void *p)
@@ -707,57 +782,6 @@ void ro_gui_download_window_hide_caret(struct gui_download_window *dw)
}
-/**
- * Handle failed downloads.
- *
- * \param dw download window
- * \param error_msg error message
- */
-
-void gui_download_window_error(struct gui_download_window *dw,
- const char *error_msg)
-{
- os_error *error;
-
- if (dw->ctx != NULL)
- download_context_destroy(dw->ctx);
- dw->ctx = NULL;
- dw->error = true;
-
- schedule_remove(ro_gui_download_update_status_wrapper, dw);
-
- /* place error message in status icon in red */
- strncpy(dw->status, error_msg, sizeof dw->status);
- error = xwimp_set_icon_state(dw->window,
- ICON_DOWNLOAD_STATUS,
- wimp_COLOUR_RED << wimp_ICON_FG_COLOUR_SHIFT,
- wimp_ICON_FG_COLOUR);
- if (error) {
- LOG(("xwimp_set_icon_state: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
-
- /* grey out pathname icon */
- error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_PATH,
- wimp_ICON_SHADED, 0);
- if (error) {
- LOG(("xwimp_set_icon_state: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
-
- /* grey out file icon */
- error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON,
- wimp_ICON_SHADED, wimp_ICON_SHADED);
- if (error) {
- LOG(("xwimp_set_icon_state: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
-
- ro_gui_download_window_hide_caret(dw);
-}
/**
@@ -766,7 +790,7 @@ void gui_download_window_error(struct gui_download_window *dw,
* \param dw download window
*/
-void gui_download_window_done(struct gui_download_window *dw)
+static void gui_download_window_done(struct gui_download_window *dw)
{
os_error *error;
@@ -792,10 +816,11 @@ void gui_download_window_done(struct gui_download_window *dw)
warn_user("SaveError", error->errmess);
}
- if (dw->send_dataload)
+ if (dw->send_dataload) {
ro_gui_download_send_dataload(dw);
+ }
- schedule(200, ro_gui_download_window_destroy_wrapper, dw);
+ riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw);
}
}
@@ -810,9 +835,6 @@ void gui_download_window_done(struct gui_download_window *dw)
bool ro_gui_download_click(wimp_pointer *pointer)
{
struct gui_download_window *dw;
- char command[256] = "Filer_OpenDir ";
- char *dot;
- os_error *error;
dw = (struct gui_download_window *)ro_gui_wimp_event_get_user_data(pointer->w);
if ((pointer->buttons & (wimp_DRAG_SELECT | wimp_DRAG_ADJUST)) &&
@@ -836,10 +858,14 @@ bool ro_gui_download_click(wimp_pointer *pointer)
ro_gui_drag_icon(x, y, sprite);
} else if (pointer->i == ICON_DOWNLOAD_DESTINATION) {
+ char command[256] = "Filer_OpenDir ";
+ char *dot;
+
strncpy(command + 14, dw->path, 242);
command[255] = 0;
dot = strrchr(command, '.');
if (dot) {
+ os_error *error;
*dot = 0;
error = xos_cli(command);
if (error) {
@@ -886,7 +912,7 @@ bool ro_gui_download_keypress(wimp_key *key)
!nsoption_bool(confirm_overwrite)) && !dw->ctx)
{
/* finished already */
- schedule(200, ro_gui_download_window_destroy_wrapper, dw);
+ riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw);
}
return true;
}
@@ -982,7 +1008,7 @@ void ro_gui_download_datasave_ack(wimp_message *message)
ro_gui_download_send_dataload(dw);
- schedule(200, ro_gui_download_window_destroy_wrapper, dw);
+ riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw);
}
}
@@ -1414,7 +1440,7 @@ void ro_gui_download_send_dataload(struct gui_download_window *dw)
warn_user("WimpError", error->errmess);
}
- schedule(200, ro_gui_download_window_destroy_wrapper, dw);
+ riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw);
}
@@ -1477,8 +1503,8 @@ bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit)
return false;
}
- schedule_remove(ro_gui_download_update_status_wrapper, dw);
- schedule_remove(ro_gui_download_window_destroy_wrapper, dw);
+ riscos_schedule(-1, ro_gui_download_update_status_wrapper, dw);
+ riscos_schedule(-1, ro_gui_download_window_destroy_wrapper, dw);
/* remove from list */
if (dw->prev)
@@ -1531,7 +1557,7 @@ bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit)
/**
- * Wrapper for ro_gui_download_window_destroy(), suitable for schedule().
+ * Wrapper for ro_gui_download_window_destroy(), suitable for riscos_schedule().
*/
void ro_gui_download_window_destroy_wrapper(void *p)
@@ -1610,7 +1636,7 @@ void ro_gui_download_overwrite_confirmed(query_id id, enum query_response res, v
ro_gui_download_send_dataload(dw);
- schedule(200, ro_gui_download_window_destroy_wrapper, dw);
+ riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw);
}
}
@@ -1631,3 +1657,12 @@ bool ro_gui_download_prequit(void)
}
return true;
}
+
+static struct gui_download_table download_table = {
+ .create = gui_download_window_create,
+ .data = gui_download_window_data,
+ .error = gui_download_window_error,
+ .done = gui_download_window_done,
+};
+
+struct gui_download_table *riscos_download_table = &download_table;