From d6874d05b1800f3f68cf109fb7818b68b59c213c Mon Sep 17 00:00:00 2001 From: Chris Young Date: Sat, 15 Nov 2008 15:28:17 +0000 Subject: Allow opening of local files from anywhere, not just the parent of the current dir. svn path=/trunk/netsurf/; revision=5695 --- amiga/fetch_file.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++------ amiga/filetype.c | 23 +++++--- amiga/gui.c | 31 ++++++----- amiga/gui.h | 1 + amiga/menu.c | 82 ++++++++++++++++++++--------- amiga/menu.h | 4 +- amiga/misc.c | 30 +++++++++-- amiga/object.h | 4 +- 8 files changed, 258 insertions(+), 69 deletions(-) (limited to 'amiga') diff --git a/amiga/fetch_file.c b/amiga/fetch_file.c index bdf828bcd..905b19ba1 100755 --- a/amiga/fetch_file.c +++ b/amiga/fetch_file.c @@ -1,7 +1,7 @@ /* * Copyright 2008 Chris Young * - * This file is part of NetSurf. + * This file is part of NetSurf, http://www.netsurf-browser.org/ * * NetSurf is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +26,15 @@ #include "utils/url.h" #include #include +#include "amiga/object.h" +#include +#include "content/content.h" +#include +#include +#include "utils/messages.h" + +static struct MinList *ami_file_fetcher_list; +static UBYTE *ami_file_fetcher_buffer = NULL; /** Information for a single fetch. */ struct ami_file_fetch_info { @@ -34,6 +43,13 @@ struct ami_file_fetch_info { bool only_2xx; /**< Only HTTP 2xx responses acceptable. */ char *path; char *url; /**< URL of this fetch. */ + bool aborted; + bool locked; + struct nsObject *obj; + int httpcode; + ULONG len; + char *mimetype; + struct cache_data cachedata; }; static bool ami_fetch_file_initialise(const char *scheme); @@ -75,7 +91,11 @@ void ami_fetch_file_register(void) bool ami_fetch_file_initialise(const char *scheme) { LOG(("Initialise Amiga fetcher for %s", scheme)); - return true; /* Always succeeds */ + ami_file_fetcher_list = NewObjList(); + ami_file_fetcher_buffer = AllocVec(1024,MEMF_PRIVATE); + + if(ami_file_fetcher_list && ami_file_fetcher_buffer) return true; + else return false; } @@ -86,6 +106,8 @@ bool ami_fetch_file_initialise(const char *scheme) void ami_fetch_file_finalise(const char *scheme) { LOG(("Finalise Amiga fetcher %s", scheme)); + FreeObjList(ami_file_fetcher_list); + FreeVec(ami_file_fetcher_buffer); } @@ -124,14 +146,17 @@ void * ami_fetch_file_setup(struct fetch *parent_fetch, const char *url, fetch->fetch_handle = parent_fetch; - LOG(("fetch %p, url '%s'", fetch, url)); - /* construct a new fetch structure */ fetch->fh = 0; fetch->only_2xx = only_2xx; // fetch->url = strdup(url); fetch->path = url_to_path(url); + LOG(("fetch %p, url '%s', path '%s'", fetch, url,fetch->path)); + + fetch->obj = AddObject(ami_file_fetcher_list,AMINS_FETCHER); + fetch->obj->objstruct = fetch; + return fetch; } @@ -143,24 +168,38 @@ bool ami_fetch_file_start(void *vfetch) { struct ami_file_fetch_info *fetch = (struct ami_file_fetch_info*)vfetch; - fetch->fh = FOpen(fetch->path,MODE_OLDFILE,0); + LOG(("ami file fetcher start")); - if(fetch->fh) return true; - else return false; + fetch->cachedata.req_time = time(NULL); + fetch->cachedata.res_time = time(NULL); + fetch->cachedata.date = 0; + fetch->cachedata.expires = 0; + fetch->cachedata.age = INVALID_AGE; + fetch->cachedata.max_age = 0; + fetch->cachedata.no_cache = true; + fetch->cachedata.etag = NULL; + fetch->cachedata.last_modified = 0; + + return true; } void ami_fetch_file_abort(void *vf) { struct ami_file_fetch_info *fetch = (struct ami_file_fetch_info*)vf; + LOG(("ami file fetcher abort")); + if (fetch->fh) { FClose(fetch->fh); fetch->fh = 0; -// f->abort = true; - } else { + fetch->aborted = true; + } +/* +else { fetch_remove_from_queues(fetch->fetch_handle); fetch_free(fetch->fetch_handle); } +*/ } @@ -171,15 +210,24 @@ void ami_fetch_file_abort(void *vf) void ami_fetch_file_free(void *vf) { struct ami_file_fetch_info *fetch = (struct ami_file_fetch_info*)vf; + LOG(("ami file fetcher free %lx",fetch)); - if(fetch->fh) - { - FClose(fetch->fh); - } + if(fetch->fh) FClose(fetch->fh); + if(fetch->mimetype) free(fetch->mimetype); + if(fetch->path) free(fetch->path); - FreeVec(fetch); + DelObject(fetch->obj); // delobject frees fetch } +static void ami_fetch_file_send_callback(fetch_msg msg, + struct ami_file_fetch_info *fetch, const void *data, + unsigned long size) +{ + fetch->locked = true; + LOG(("ami file fetcher callback %ld",msg)); + fetch_send_callback(msg,fetch->fetch_handle,data,size); + fetch->locked = false; +} /** * Do some work on current fetches. @@ -189,5 +237,79 @@ void ami_fetch_file_free(void *vf) void ami_fetch_file_poll(const char *scheme_ignored) { -} + struct nsObject *node; + struct nsObject *nnode; + struct ami_file_fetch_info *fetch; + + if(IsMinListEmpty(ami_file_fetcher_list)) return; + + node = (struct nsObject *)GetHead((struct List *)ami_file_fetcher_list); + do + { + nnode=(struct nsObject *)GetSucc((struct Node *)node); + + fetch = (struct ami_file_fetch_info *)node->objstruct; + LOG(("polling %lx",fetch)); + + if(fetch->locked) continue; + + if(!fetch->aborted) + { + if(fetch->fh) + { + ULONG len; + + len = FRead(fetch->fh,ami_file_fetcher_buffer,1,1024); + + LOG(("fetch %lx read %ld",fetch,len)); + + ami_fetch_file_send_callback(FETCH_DATA, + fetch,ami_file_fetcher_buffer,len); + + if((len<1024) && (!fetch->aborted)) + { + ami_fetch_file_send_callback(FETCH_FINISHED, + fetch, &fetch->cachedata, 0); + + fetch->aborted = true; + } + } + else + { + fetch->fh = FOpen(fetch->path,MODE_OLDFILE,0); + + if(fetch->fh) + { + struct FileInfoBlock fib; + if(ExamineFH(fetch->fh,&fib)) + fetch->len = fib.fib_Size; + + fetch_set_http_code(fetch->fetch_handle,200); + fetch->mimetype = fetch_mimetype(fetch->path); + LOG(("mimetype %s len %ld",fetch->mimetype,fetch->len)); + + ami_fetch_file_send_callback(FETCH_TYPE, + fetch, fetch->mimetype, fetch->len); + } + else + { + STRPTR errorstring; + + errorstring = ASPrintf("%s %s",messages_get("FileError"),fetch->path); + fetch_set_http_code(fetch->fetch_handle,404); + ami_fetch_file_send_callback(FETCH_ERROR, fetch, + errorstring, 0); + fetch->aborted = true; + FreeVec(errorstring); + } + } + } + + if(fetch && fetch->aborted) + { + fetch_remove_from_queues(fetch->fetch_handle); + fetch_free(fetch->fetch_handle); + } + }while(node=nnode); +} diff --git a/amiga/filetype.c b/amiga/filetype.c index 394b6384a..82e3f70d5 100644 --- a/amiga/filetype.c +++ b/amiga/filetype.c @@ -36,8 +36,9 @@ const char *fetch_filetype(const char *unix_path) STRPTR ttype = NULL; struct DiskObject *dobj = NULL; BPTR lock = 0; - struct DataTypeHeader *dth; + struct DataTypeHeader *dth = NULL; struct DataType *dtn; + BOOL found = FALSE; /* First try getting a tooltype "MIMETYPE" and use that as the MIME type. Will fail over to default icons if the file doesn't have a real icon. */ @@ -46,16 +47,21 @@ const char *fetch_filetype(const char *unix_path) TAG_DONE)) { ttype = FindToolType(dobj->do_ToolTypes, "MIMETYPE"); - if(ttype) strcpy(mimetype,ttype); + if(ttype) + { + strcpy(mimetype,ttype); + found = TRUE; + } + FreeDiskObject(dobj); } - if(!mimetype) - { - /* If that didn't work, have a go at guessing it using datatypes.library. This isn't - accurate - the base names differ from those used by MIME and it relies on the - user having a datatype installed which can handle the file. */ + /* If that didn't work, have a go at guessing it using datatypes.library. This isn't + accurate - the base names differ from those used by MIME and it relies on the + user having a datatype installed which can handle the file. */ + if(!found) + { if (lock = Lock (unix_path, ACCESS_READ)) { if (dtn = ObtainDataTypeA (DTST_FILE, (APTR)lock, NULL)) @@ -84,13 +90,14 @@ const char *fetch_filetype(const char *unix_path) sprintf(mimetype,"video/%s",dth->dth_BaseName); break; } + found = TRUE; ReleaseDataType(dtn); } UnLock(lock); } } - if(!mimetype) strcpy(mimetype,"text/html"); /* If all else fails */ + if(!found) strcpy(mimetype,"text/html"); /* If all else fails */ return mimetype; } diff --git a/amiga/gui.c b/amiga/gui.c index 518ecea51..481492b34 100755 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -67,6 +67,7 @@ #include "amiga/clipboard.h" #include #include "amiga/save_complete.h" +#include "amiga/fetch_file.h" #ifdef WITH_HUBBUB #include @@ -243,8 +244,8 @@ void gui_init(int argc, char** argv) messages_load(lang); // check locale language and read appropriate file - default_stylesheet_url = "file://NetSurf/Resources/default.css"; //"http://www.unsatisfactorysoftware.co.uk/newlook.css"; //path_to_url(buf); - adblock_stylesheet_url = "file://NetSurf/Resources/adblock.css"; + default_stylesheet_url = "file:///Resources/default.css"; //"http://www.unsatisfactorysoftware.co.uk/newlook.css"; //path_to_url(buf); + adblock_stylesheet_url = "file:///Resources/adblock.css"; #ifdef WITH_HUBBUB if(hubbub_initialise("Resources/Aliases",myrealloc,NULL) != HUBBUB_OK) @@ -402,6 +403,8 @@ void gui_init2(int argc, char** argv) A_URL }; + ami_fetch_file_register(); + InitRastPort(&dummyrp); dummyrp.BitMap = p96AllocBitMap(1,1,32, BMF_CLEAR | BMF_DISPLAYABLE | BMF_INTERLEAVED, @@ -1195,6 +1198,8 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, char home[100],home_s[100],home_g[100]; char closetab[100]; + if((bw->browser_window_type == BROWSER_WINDOW_IFRAME) && option_no_iframes) return NULL; + if(option_force_tabs && (bw->browser_window_type == BROWSER_WINDOW_NORMAL)) { /* option_force_tabs reverses the new_tab parameter. @@ -1218,17 +1223,6 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, } } - if(bw->browser_window_type == BROWSER_WINDOW_IFRAME) - { - if(option_no_iframes) return NULL; -/* - gwin = bw->parent->window; - printf("%lx\n",gwin); - return gwin; -*/ - } - - gwin = AllocVec(sizeof(struct gui_window),MEMF_PRIVATE | MEMF_CLEAR); if(!gwin) @@ -1237,6 +1231,15 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, return NULL; } +/* + if(bw->browser_window_type == BROWSER_WINDOW_IFRAME) + { + gwin->shared = bw->parent->window->shared; + gwin->bw = bw; + return gwin; + } +*/ + if(new_tab && clone && (bw->browser_window_type == BROWSER_WINDOW_NORMAL)) { gwin->shared = clone->window->shared; @@ -1968,6 +1971,7 @@ void gui_window_position_frame(struct gui_window *g, int x0, int y0, int x1, int y1) { if(!g) return; + ChangeWindowBox(g->shared->win,x0,y0,x1-x0,y1-y0); } @@ -2366,6 +2370,7 @@ struct gui_download_window *gui_download_window_create(const char *url, ASLFR_Screen,scrn, ASLFR_DoSaveMode,TRUE, ASLFR_InitialFile,FilePart(url), + ASLFR_InitialDrawer,option_download_dir, TAG_DONE)) { strlcpy(&fname,filereq->fr_Drawer,1024); diff --git a/amiga/gui.h b/amiga/gui.h index 926df6dc6..1c73a586e 100755 --- a/amiga/gui.h +++ b/amiga/gui.h @@ -120,6 +120,7 @@ struct gui_window int c_h; int scrollx; int scrolly; + struct browser_window *bw; // not used }; void ami_get_msg(void); diff --git a/amiga/menu.c b/amiga/menu.c index abb940298..0b6b0776f 100755 --- a/amiga/menu.c +++ b/amiga/menu.c @@ -60,28 +60,30 @@ void ami_init_menulabs(void) menulab[1] = ami_utf8_easy((char *)messages_get("NewWindowNS")); menulab[2] = ami_utf8_easy((char *)messages_get("NewTab")); menulab[3] = NM_BARLABEL; - menulab[4] = ami_utf8_easy((char *)messages_get("SaveAs")); - menulab[5] = ami_utf8_easy((char *)messages_get("Source")); - menulab[6] = ami_utf8_easy((char *)messages_get("TextNS")); - menulab[7] = ami_utf8_easy((char *)messages_get("SaveCompNS")); - menulab[8] = ami_utf8_easy((char *)messages_get("PDF")); - menulab[9] = NM_BARLABEL; - menulab[10] = ami_utf8_easy((char *)messages_get("CloseTab")); - menulab[11] = ami_utf8_easy((char *)messages_get("CloseWindow")); - menulab[12] = NM_BARLABEL; - menulab[13] = ami_utf8_easy((char *)messages_get("Quit")); - menulab[14] = ami_utf8_easy((char *)messages_get("Edit")); - menulab[15] = ami_utf8_easy((char *)messages_get("CopyNS")); - menulab[16] = ami_utf8_easy((char *)messages_get("Paste")); - menulab[17] = ami_utf8_easy((char *)messages_get("SelectAllNS")); - menulab[18] = ami_utf8_easy((char *)messages_get("ClearNS")); - menulab[19] = ami_utf8_easy((char *)messages_get("Browser")); - menulab[20] = ami_utf8_easy((char *)messages_get("HistGlobalNS")); - menulab[21] = ami_utf8_easy((char *)messages_get("ShowCookies")); - menulab[22] = ami_utf8_easy((char *)messages_get("Hotlist")); - menulab[23] = ami_utf8_easy((char *)messages_get("HotlistAdd")); - menulab[24] = ami_utf8_easy((char *)messages_get("HotlistShowNS")); - menulab[25] = NM_BARLABEL; + menulab[4] = ami_utf8_easy((char *)messages_get("OpenFile")); + menulab[5] = ami_utf8_easy((char *)messages_get("SaveAs")); + menulab[6] = ami_utf8_easy((char *)messages_get("Source")); + menulab[7] = ami_utf8_easy((char *)messages_get("TextNS")); + menulab[8] = ami_utf8_easy((char *)messages_get("SaveCompNS")); + menulab[9] = ami_utf8_easy((char *)messages_get("PDF")); + menulab[10] = NM_BARLABEL; + menulab[11] = ami_utf8_easy((char *)messages_get("CloseTab")); + menulab[12] = ami_utf8_easy((char *)messages_get("CloseWindow")); + menulab[13] = NM_BARLABEL; + menulab[14] = ami_utf8_easy((char *)messages_get("About")); + menulab[15] = ami_utf8_easy((char *)messages_get("Quit")); + menulab[16] = ami_utf8_easy((char *)messages_get("Edit")); + menulab[17] = ami_utf8_easy((char *)messages_get("CopyNS")); + menulab[18] = ami_utf8_easy((char *)messages_get("Paste")); + menulab[19] = ami_utf8_easy((char *)messages_get("SelectAllNS")); + menulab[20] = ami_utf8_easy((char *)messages_get("ClearNS")); + menulab[21] = ami_utf8_easy((char *)messages_get("Browser")); + menulab[22] = ami_utf8_easy((char *)messages_get("HistGlobalNS")); + menulab[23] = ami_utf8_easy((char *)messages_get("ShowCookies")); + menulab[24] = ami_utf8_easy((char *)messages_get("Hotlist")); + menulab[25] = ami_utf8_easy((char *)messages_get("HotlistAdd")); + menulab[26] = ami_utf8_easy((char *)messages_get("HotlistShowNS")); + menulab[27] = NM_BARLABEL; menulab[AMI_MENU_HOTLIST_MAX] = ami_utf8_easy((char *)messages_get("Settings")); menulab[AMI_MENU_HOTLIST_MAX+1] = ami_utf8_easy((char *)messages_get("SnapshotWindow")); @@ -100,6 +102,7 @@ struct NewMenu *ami_create_menu(ULONG type) { NM_ITEM,0,"N",0,0,0,}, // new window { NM_ITEM,0,"T",0,0,0,}, // new tab { NM_ITEM,NM_BARLABEL,0,0,0,0,}, + { NM_ITEM,0,"O",0,0,0,}, // open local file { NM_ITEM,0,0,0,0,0,}, // save { NM_SUB,0,"S",0,0,0,}, // save as source { NM_SUB,0,0,0,0,0,}, // save as text @@ -109,6 +112,7 @@ struct NewMenu *ami_create_menu(ULONG type) { NM_ITEM,0,"K",0,0,0,}, // close tab { NM_ITEM,0,0,0,0,0,}, // close window { NM_ITEM,NM_BARLABEL,0,0,0,0,}, + { NM_ITEM,0,"?",NM_ITEMDISABLED,0,0,}, // about { NM_ITEM,0,"Q",0,0,0,}, // quit {NM_TITLE,0,0,0,0,0,}, // edit { NM_ITEM,0,"C",0,0,0,}, // copy @@ -384,7 +388,29 @@ void ami_menupick(ULONG code,struct gui_window_2 *gwin,struct MenuItem *item) bw = browser_window_create(gwin->bw->current_content->url,gwin->bw, 0, true, opentab); break; - case 3: // save + case 3: // open local file + if(AslRequestTags(filereq, + ASLFR_TitleText,messages_get("NetSurf"), + ASLFR_Screen,scrn, + ASLFR_DoSaveMode,FALSE, +// ASLFR_InitialDrawer,option_arexx_dir, +// ASLFR_InitialPattern,"#?.html", + TAG_DONE)) + { + if(temp = AllocVec(1024,MEMF_PRIVATE | MEMF_CLEAR)) + { + char *temp2; + strlcpy(temp,filereq->fr_Drawer,1024); + AddPart(temp,filereq->fr_File,1024); + temp2 = path_to_url(temp); + browser_window_go(gwin->bw,temp2,NULL, true); + free(temp2); + FreeVec(temp); + } + } + break; + + case 4: // save switch(subnum) { BPTR fh=0; @@ -471,15 +497,19 @@ void ami_menupick(ULONG code,struct gui_window_2 *gwin,struct MenuItem *item) } break; - case 5: // close tab + case 6: // close tab browser_window_destroy(gwin->bw); break; - case 6: // close window + case 7: // close window ami_close_all_tabs(gwin); break; - case 8: // quit + case 9: // about + // do nothing + break; + + case 10: // quit ami_quit_netsurf(); break; } diff --git a/amiga/menu.h b/amiga/menu.h index cc666b5f1..da0f80596 100755 --- a/amiga/menu.h +++ b/amiga/menu.h @@ -28,10 +28,10 @@ /* Maximum number of menu items - first value is number of static items * (ie. everything not intially defined as NM_IGNORE) */ -#define AMI_MENU_MAX 32 + AMI_HOTLIST_ITEMS +#define AMI_MENU_MAX 34 + AMI_HOTLIST_ITEMS /* Where the hotlist entries start */ -#define AMI_MENU_HOTLIST 26 +#define AMI_MENU_HOTLIST 28 /* Where the hotlist entries end */ #define AMI_MENU_HOTLIST_MAX AMI_MENU_HOTLIST+AMI_HOTLIST_ITEMS diff --git a/amiga/misc.c b/amiga/misc.c index 851f3c837..c77788eae 100755 --- a/amiga/misc.c +++ b/amiga/misc.c @@ -1,5 +1,4 @@ /* - * Copyright 2004 James Bursa * Copyright 2008 Chris Young * * This file is part of NetSurf, http://www.netsurf-browser.org/ @@ -24,6 +23,7 @@ #include #include "utils/messages.h" #include +#include void warn_user(const char *warning, const char *detail) { @@ -51,14 +51,36 @@ void die(const char *error) char *url_to_path(const char *url) { - return (char *)strdup(url + 5); + char *tmps,*unesc; + CURL *curl; + + if(tmps = strchr(url,'/')) + { + if(tmps = strchr(tmps+1,'/')) + { + if(tmps = strchr(tmps+1,'/')) + { + if(curl = curl_easy_init()) + { + unesc = curl_easy_unescape(curl,tmps+1,0,NULL); + tmps = strdup(unesc); + curl_free(unesc); + curl_easy_cleanup(curl); + return tmps; + + } + } + } + } + + return strdup((char *)url); } char *path_to_url(const char *path) { - char *r = malloc(strlen(path) + 7 + 1); + char *r = malloc(strlen(path) + 8 + 1); - strcpy(r, "file://"); + strcpy(r, "file:///"); strcat(r, path); return r; diff --git a/amiga/object.h b/amiga/object.h index 909edd468..d7c678a2d 100755 --- a/amiga/object.h +++ b/amiga/object.h @@ -23,12 +23,14 @@ enum { + AMINS_UNKNOWN, AMINS_CALLBACK, AMINS_WINDOW, AMINS_FRAME, AMINS_DLWINDOW, AMINS_LOGINWINDOW, - AMINS_TVWINDOW + AMINS_TVWINDOW, + AMINS_FETCHER, }; struct nsObject -- cgit v1.2.3