mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-11-24 23:39:51 +03:00
Merge jmb/new-cache; r=dsilvers,rs=vince
svn path=/trunk/netsurf/; revision=10180
This commit is contained in:
parent
21da4f5bdf
commit
270ef59a98
@ -5,13 +5,13 @@
|
||||
# for each build.
|
||||
#
|
||||
|
||||
S_CONTENT := content.c fetch.c fetchcache.c urldb.c \
|
||||
S_CONTENT := content.c fetch.c hlcache.c llcache.c urldb.c \
|
||||
fetchers/fetch_curl.c fetchers/fetch_data.c
|
||||
S_CSS := css.c dump.c internal.c select.c utils.c
|
||||
S_RENDER := box.c box_construct.c box_normalise.c directory.c favicon.c \
|
||||
font.c form.c html.c html_redraw.c hubbub_binding.c imagemap.c \
|
||||
layout.c list.c table.c textplain.c
|
||||
S_UTILS := base64.c filename.c hashtable.c locale.c \
|
||||
S_UTILS := base64.c filename.c hashtable.c http.c locale.c \
|
||||
messages.c talloc.c url.c utf8.c utils.c useragent.c
|
||||
S_DESKTOP := knockout.c options.c plot_style.c print.c search.c \
|
||||
searchweb.c scroll.c textarea.c tree.c version.c
|
||||
|
@ -252,14 +252,15 @@ void ami_free_download_list(struct List *dllist)
|
||||
}while(node=nnode);
|
||||
}
|
||||
|
||||
void gui_window_save_as_link(struct gui_window *g, struct content *c)
|
||||
void
|
||||
gui_window_save_link(struct gui_window *g, const char *url, const char *title)
|
||||
{
|
||||
BPTR fh = 0;
|
||||
char fname[1024];
|
||||
STRPTR openurlstring,linkname;
|
||||
struct DiskObject *dobj = NULL;
|
||||
|
||||
linkname = ASPrintf("Link_to_%s",FilePart(c->url));
|
||||
linkname = ASPrintf("Link_to_%s",FilePart(url));
|
||||
|
||||
if(AslRequestTags(savereq,
|
||||
ASLFR_TitleText,messages_get("NetSurf"),
|
||||
@ -272,11 +273,11 @@ void gui_window_save_as_link(struct gui_window *g, struct content *c)
|
||||
ami_update_pointer(g->shared->win,GUI_POINTER_WAIT);
|
||||
if(fh = FOpen(fname,MODE_NEWFILE,0))
|
||||
{
|
||||
openurlstring = ASPrintf("openurl \"%s\"\n",c->url);
|
||||
openurlstring = ASPrintf("openurl \"%s\"\n",url);
|
||||
FWrite(fh,openurlstring,1,strlen(openurlstring));
|
||||
FClose(fh);
|
||||
FreeVec(openurlstring);
|
||||
SetComment(fname,c->url);
|
||||
SetComment(fname,url);
|
||||
|
||||
dobj = GetIconTags(NULL,ICONGETA_GetDefaultName,"url",
|
||||
ICONGETA_GetDefaultType,WBPROJECT,
|
||||
|
@ -56,7 +56,7 @@ static bool ami_fetch_file_initialise(const char *scheme);
|
||||
static void ami_fetch_file_finalise(const char *scheme);
|
||||
static void * ami_fetch_file_setup(struct fetch *parent_fetch, const char *url,
|
||||
bool only_2xx, const char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
const char **headers);
|
||||
static bool ami_fetch_file_start(void *vfetch);
|
||||
static void ami_fetch_file_abort(void *vf);
|
||||
@ -135,7 +135,7 @@ void ami_fetch_file_finalise(const char *scheme)
|
||||
|
||||
void * ami_fetch_file_setup(struct fetch *parent_fetch, const char *url,
|
||||
bool only_2xx, const char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
const char **headers)
|
||||
{
|
||||
struct ami_file_fetch_info *fetch;
|
||||
@ -280,6 +280,7 @@ void ami_fetch_file_poll(const char *scheme_ignored)
|
||||
|
||||
if(fetch->fh)
|
||||
{
|
||||
char header[64];
|
||||
struct ExamineData *fib;
|
||||
if(fib = ExamineObjectTags(EX_FileHandleInput,fetch->fh,TAG_DONE))
|
||||
{
|
||||
@ -291,9 +292,18 @@ void ami_fetch_file_poll(const char *scheme_ignored)
|
||||
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, (ULONG)fetch->len,
|
||||
errorcode);
|
||||
snprintf(header, sizeof header,
|
||||
"Content-Type: %s",
|
||||
fetch->mimetype);
|
||||
ami_fetch_file_send_callback(FETCH_HEADER,
|
||||
fetch, header, strlen(header), errorcode);
|
||||
|
||||
snprintf(header, sizeof header,
|
||||
"Content-Length: %ld",
|
||||
fetch->len);
|
||||
ami_fetch_file_send_callback(FETCH_HEADER,
|
||||
fetch, header, strlen(header), errorcode);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -38,7 +38,6 @@ extern "C" {
|
||||
#include "content/urldb.h"
|
||||
#include "desktop/netsurf.h"
|
||||
#include "desktop/options.h"
|
||||
#include "render/form.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/url.h"
|
||||
@ -83,7 +82,7 @@ static void fetch_rsrc_finalise(const char *scheme)
|
||||
|
||||
static void *fetch_rsrc_setup(struct fetch *parent_fetch, const char *url,
|
||||
bool only_2xx, const char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
const char **headers)
|
||||
{
|
||||
struct fetch_rsrc_context *ctx;
|
||||
@ -277,6 +276,8 @@ static void fetch_rsrc_poll(const char *scheme)
|
||||
|
||||
/* Only process non-aborted fetches */
|
||||
if (!c->aborted && fetch_rsrc_process(c) == true) {
|
||||
char header[64];
|
||||
|
||||
fetch_set_http_code(c->parent_fetch, 200);
|
||||
LOG(("setting rsrc: MIME type to %s, length to %zd",
|
||||
c->mimetype, c->datalen));
|
||||
@ -284,8 +285,16 @@ static void fetch_rsrc_poll(const char *scheme)
|
||||
* Therefore, we _must_ check for this after _every_
|
||||
* call to fetch_rsrc_send_callback().
|
||||
*/
|
||||
fetch_rsrc_send_callback(FETCH_TYPE,
|
||||
c, c->mimetype, c->datalen, FETCH_ERROR_NO_ERROR);
|
||||
snprintf(header, sizeof header, "Content-Type: %s",
|
||||
c->mimetype);
|
||||
fetch_rsrc_send_callback(FETCH_HEADER, c, header,
|
||||
strlen(header), FETCH_ERROR_NO_ERROR);
|
||||
|
||||
snprintf(header, sizeof header, "Content-Length: %zd",
|
||||
c->datalen);
|
||||
fetch_rsrc_send_callback(FETCH_HEADER, c, header,
|
||||
strlen(header), FETCH_ERROR_NO_ERROR);
|
||||
|
||||
if (!c->aborted) {
|
||||
fetch_rsrc_send_callback(FETCH_DATA,
|
||||
c, c->data, c->datalen, FETCH_ERROR_NO_ERROR);
|
||||
|
@ -424,7 +424,15 @@ static int32 bapp_thread(void *arg)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
setbuf(stderr, NULL);
|
||||
return netsurf_main(argc, argv);
|
||||
|
||||
/* initialise netsurf */
|
||||
netsurf_init(argc, argv);
|
||||
|
||||
netsurf_main_loop();
|
||||
|
||||
netsurf_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gui_init(int argc, char** argv)
|
||||
@ -843,7 +851,8 @@ void gui_create_form_select_menu(struct browser_window *bw,
|
||||
#endif
|
||||
}
|
||||
|
||||
void gui_window_save_as_link(struct gui_window *g, struct content *c)
|
||||
void
|
||||
gui_window_save_link(struct gui_window *g, const char *url, const char *title)
|
||||
{
|
||||
}
|
||||
|
||||
|
1007
content/content.c
1007
content/content.c
File diff suppressed because it is too large
Load Diff
@ -26,64 +26,31 @@
|
||||
#ifndef _NETSURF_CONTENT_CONTENT_H_
|
||||
#define _NETSURF_CONTENT_CONTENT_H_
|
||||
|
||||
/* Irritatingly this must come first, or odd include errors
|
||||
* will occur to do with setjmp.h.
|
||||
*/
|
||||
#ifdef WITH_PNG
|
||||
#include "image/png.h"
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include "utils/config.h"
|
||||
#include "content/content_type.h"
|
||||
#include "css/css.h"
|
||||
#include "render/html.h"
|
||||
#include "render/textplain.h"
|
||||
#ifdef WITH_JPEG
|
||||
#include "image/jpeg.h"
|
||||
#endif
|
||||
#ifdef WITH_GIF
|
||||
#include "image/gif.h"
|
||||
#endif
|
||||
#ifdef WITH_BMP
|
||||
#include "image/bmp.h"
|
||||
#include "image/ico.h"
|
||||
#endif
|
||||
#ifdef WITH_PLUGIN
|
||||
#include "riscos/plugin.h"
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
#include "image/mng.h"
|
||||
#endif
|
||||
#ifdef WITH_SPRITE
|
||||
#include "riscos/sprite.h"
|
||||
#endif
|
||||
#ifdef WITH_NSSPRITE
|
||||
#include "image/nssprite.h"
|
||||
#endif
|
||||
#ifdef WITH_DRAW
|
||||
#include "riscos/draw.h"
|
||||
#endif
|
||||
#ifdef WITH_ARTWORKS
|
||||
#include "riscos/artworks.h"
|
||||
#endif
|
||||
#ifdef WITH_NS_SVG
|
||||
#include "image/svg.h"
|
||||
#endif
|
||||
#ifdef WITH_RSVG
|
||||
#include "image/rsvg.h"
|
||||
#endif
|
||||
#include "desktop/plot_style.h"
|
||||
|
||||
struct llcache_handle;
|
||||
|
||||
struct bitmap;
|
||||
struct box;
|
||||
struct browser_window;
|
||||
struct content;
|
||||
struct fetch;
|
||||
struct hlcache_handle;
|
||||
struct object_params;
|
||||
struct ssl_cert_info;
|
||||
|
||||
/** Status of a content */
|
||||
typedef enum {
|
||||
CONTENT_STATUS_TYPE_UNKNOWN, /**< Type not yet known. */
|
||||
CONTENT_STATUS_LOADING, /**< Content is being fetched or
|
||||
converted and is not safe to display. */
|
||||
CONTENT_STATUS_READY, /**< Some parts of content still being
|
||||
loaded, but can be displayed. */
|
||||
CONTENT_STATUS_DONE, /**< All finished. */
|
||||
CONTENT_STATUS_ERROR /**< Error occurred, content will be
|
||||
destroyed imminently. */
|
||||
} content_status;
|
||||
|
||||
/** Used in callbacks to indicate what has occurred. */
|
||||
typedef enum {
|
||||
@ -129,204 +96,64 @@ union content_msg_data {
|
||||
} ssl;
|
||||
};
|
||||
|
||||
struct cache_data {
|
||||
time_t req_time; /**< Time of request */
|
||||
time_t res_time; /**< Time of response */
|
||||
time_t date; /**< Date: response header */
|
||||
time_t expires; /**< Expires: response header */
|
||||
#define INVALID_AGE -1
|
||||
int age; /**< Age: response header */
|
||||
int max_age; /**< Max-age Cache-control parameter */
|
||||
bool no_cache; /**< no-cache Cache-control parameter */
|
||||
char *etag; /**< Etag: response header */
|
||||
time_t last_modified; /**< Last-Modified: response header */
|
||||
};
|
||||
|
||||
/** Linked list of users of a content. */
|
||||
struct content_user
|
||||
{
|
||||
void (*callback)(content_msg msg, struct content *c, intptr_t p1,
|
||||
intptr_t p2, union content_msg_data data);
|
||||
intptr_t p1;
|
||||
intptr_t p2;
|
||||
bool stop;
|
||||
struct content_user *next;
|
||||
};
|
||||
|
||||
/** Corresponds to a single URL. */
|
||||
struct content {
|
||||
char *url; /**< URL, in standard form as from url_join. */
|
||||
content_type type; /**< Type of content. */
|
||||
char *mime_type; /**< Original MIME type of data, or 0. */
|
||||
|
||||
enum {
|
||||
CONTENT_STATUS_TYPE_UNKNOWN, /**< Type not yet known. */
|
||||
CONTENT_STATUS_LOADING, /**< Content is being fetched or
|
||||
converted and is not safe to display. */
|
||||
CONTENT_STATUS_READY, /**< Some parts of content still being
|
||||
loaded, but can be displayed. */
|
||||
CONTENT_STATUS_DONE, /**< All finished. */
|
||||
CONTENT_STATUS_ERROR /**< Error occurred, content will be
|
||||
destroyed imminently. */
|
||||
} status; /**< Current status. */
|
||||
|
||||
int width, height; /**< Dimensions, if applicable. */
|
||||
int available_width; /**< Available width (eg window width). */
|
||||
|
||||
/** Data dependent on type. */
|
||||
union {
|
||||
struct content_html_data html;
|
||||
struct content_textplain_data textplain;
|
||||
struct content_css_data css;
|
||||
#ifdef WITH_JPEG
|
||||
struct content_jpeg_data jpeg;
|
||||
#endif
|
||||
#ifdef WITH_GIF
|
||||
struct content_gif_data gif;
|
||||
#endif
|
||||
#ifdef WITH_BMP
|
||||
struct content_bmp_data bmp;
|
||||
struct content_ico_data ico;
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
struct content_mng_data mng;
|
||||
#endif
|
||||
#ifdef WITH_SPRITE
|
||||
struct content_sprite_data sprite;
|
||||
#endif
|
||||
#ifdef WITH_NSSPRITE
|
||||
struct content_nssprite_data nssprite;
|
||||
#endif
|
||||
#ifdef WITH_DRAW
|
||||
struct content_draw_data draw;
|
||||
#endif
|
||||
#ifdef WITH_PLUGIN
|
||||
struct content_plugin_data plugin;
|
||||
#endif
|
||||
#ifdef WITH_ARTWORKS
|
||||
struct content_artworks_data artworks;
|
||||
#endif
|
||||
#ifdef WITH_NS_SVG
|
||||
struct content_svg_data svg;
|
||||
#endif
|
||||
#ifdef WITH_RSVG
|
||||
struct content_rsvg_data rsvg;
|
||||
#endif
|
||||
#ifdef WITH_PNG
|
||||
struct content_png_data png;
|
||||
#endif
|
||||
} data;
|
||||
|
||||
/**< URL for refresh request, in standard form as from url_join. */
|
||||
char *refresh;
|
||||
|
||||
/** Bitmap, for various image contents. */
|
||||
struct bitmap *bitmap;
|
||||
|
||||
/** This content may be given to new users. Indicates that the content
|
||||
* was fetched using a simple GET, has not expired, and may be
|
||||
* shared between users. */
|
||||
bool fresh;
|
||||
struct cache_data cache_data; /**< Cache control data */
|
||||
unsigned int time; /**< Creation time, if TYPE_UNKNOWN,
|
||||
LOADING or READY,
|
||||
otherwise total time. */
|
||||
|
||||
unsigned int reformat_time; /**< Earliest time to attempt a
|
||||
period reflow while fetching a
|
||||
page's objects. */
|
||||
|
||||
unsigned int size; /**< Estimated size of all data
|
||||
associated with this content, except
|
||||
alloced as talloc children of this. */
|
||||
off_t talloc_size; /**< Used by content_clean() */
|
||||
char *title; /**< Title for browser window. */
|
||||
unsigned int active; /**< Number of child fetches or
|
||||
conversions currently in progress. */
|
||||
struct content_user *user_list; /**< List of users. */
|
||||
char status_message[120]; /**< Full text for status bar. */
|
||||
char sub_status[80]; /**< Status of content. */
|
||||
/** Content is being processed: data structures may be inconsistent
|
||||
* and content must not be redrawn or modified. */
|
||||
bool locked;
|
||||
|
||||
struct fetch *fetch; /**< Associated fetch, or 0. */
|
||||
char *source_data; /**< Source data, as received. */
|
||||
unsigned long source_size; /**< Amount of data fetched so far. */
|
||||
unsigned long source_allocated; /**< Amount of space allocated so far. */
|
||||
unsigned long total_size; /**< Total data size, 0 if unknown. */
|
||||
long http_code; /**< HTTP status code, 0 if not HTTP. */
|
||||
|
||||
bool no_error_pages; /**< Used by fetchcache(). */
|
||||
bool download; /**< Used by fetchcache(). */
|
||||
bool tried_with_auth; /**< Used by fetchcache(). */
|
||||
unsigned int redirect_count; /**< Used by fetchcache(). */
|
||||
|
||||
/** Array of first n rendering errors or warnings. */
|
||||
struct {
|
||||
const char *token;
|
||||
unsigned int line; /**< Line no, 0 if not applicable. */
|
||||
} error_list[40];
|
||||
unsigned int error_count; /**< Number of valid error entries. */
|
||||
|
||||
struct content *prev; /**< Previous in global content list. */
|
||||
struct content *next; /**< Next in global content list. */
|
||||
};
|
||||
|
||||
extern struct content *content_list;
|
||||
extern const char * const content_type_name[];
|
||||
extern const char * const content_status_name[];
|
||||
|
||||
|
||||
/* The following are for hlcache */
|
||||
content_type content_lookup(const char *mime_type);
|
||||
struct content * content_create(const char *url);
|
||||
struct content * content_get(const char *url);
|
||||
struct content * content_get_ready(const char *url);
|
||||
bool content_can_reformat(struct content *c);
|
||||
bool content_set_type(struct content *c, content_type type,
|
||||
const char *mime_type, const char *params[],
|
||||
struct content *parent);
|
||||
void content_set_status(struct content *c, const char *status_message, ...);
|
||||
bool content_process_data(struct content *c, const char *data,
|
||||
unsigned int size);
|
||||
void content_convert(struct content *c, int width, int height);
|
||||
void content_set_done(struct content *c);
|
||||
void content_reformat(struct content *c, int width, int height);
|
||||
void content_clean(void);
|
||||
void content_reset(struct content *c);
|
||||
void content_quit(void);
|
||||
bool content_redraw(struct content *c, int x, int y,
|
||||
struct content *content_create(struct llcache_handle *llcache,
|
||||
const char *fallback_charset, bool quirks);
|
||||
void content_destroy(struct content *c);
|
||||
|
||||
bool content_add_user(struct content *h,
|
||||
void (*callback)(struct content *c, content_msg msg,
|
||||
union content_msg_data data, void *pw),
|
||||
void *pw);
|
||||
void content_remove_user(struct content *c,
|
||||
void (*callback)(struct content *c, content_msg msg,
|
||||
union content_msg_data data, void *pw),
|
||||
void *pw);
|
||||
|
||||
const struct llcache_handle *content_get_llcache_handle(struct content *c);
|
||||
|
||||
|
||||
/* Client functions */
|
||||
bool content_can_reformat(struct hlcache_handle *h);
|
||||
void content_reformat(struct hlcache_handle *h, int width, int height);
|
||||
void content_request_redraw(struct hlcache_handle *h,
|
||||
int x, int y, int width, int height);
|
||||
bool content_redraw(struct hlcache_handle *h, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, colour background_colour);
|
||||
bool content_redraw_tiled(struct content *c, int x, int y,
|
||||
bool content_redraw_tiled(struct hlcache_handle *h, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, colour background_colour,
|
||||
bool repeat_x, bool repeat_y);
|
||||
bool content_add_user(struct content *c,
|
||||
void (*callback)(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data),
|
||||
intptr_t p1, intptr_t p2);
|
||||
struct content_user * content_find_user(struct content *c,
|
||||
void (*callback)(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data),
|
||||
intptr_t p1, intptr_t p2);
|
||||
void content_remove_user(struct content *c,
|
||||
void (*callback)(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data),
|
||||
intptr_t p1, intptr_t p2);
|
||||
void content_broadcast(struct content *c, content_msg msg,
|
||||
union content_msg_data data);
|
||||
void content_stop(struct content *c,
|
||||
void (*callback)(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data),
|
||||
intptr_t p1, intptr_t p2);
|
||||
void content_open(struct content *c, struct browser_window *bw,
|
||||
void content_stop(struct hlcache_handle *h,
|
||||
void (*callback)(struct content *c, content_msg msg,
|
||||
union content_msg_data data, void *pw),
|
||||
void *pw);
|
||||
void content_open(struct hlcache_handle *h, struct browser_window *bw,
|
||||
struct content *page, unsigned int index, struct box *box,
|
||||
struct object_params *params);
|
||||
void content_close(struct content *c);
|
||||
void content_add_error(struct content *c, const char *token,
|
||||
unsigned int line);
|
||||
void content_close(struct hlcache_handle *h);
|
||||
|
||||
/* Member accessors */
|
||||
content_type content_get_type(struct hlcache_handle *c);
|
||||
const char *content_get_url(struct hlcache_handle *c);
|
||||
const char *content_get_title(struct hlcache_handle *c);
|
||||
content_status content_get_status(struct hlcache_handle *c);
|
||||
const char *content_get_status_message(struct hlcache_handle *c);
|
||||
int content_get_width(struct hlcache_handle *c);
|
||||
int content_get_height(struct hlcache_handle *c);
|
||||
int content_get_available_width(struct hlcache_handle *c);
|
||||
const char *content_get_source_data(struct hlcache_handle *c,
|
||||
unsigned long *size);
|
||||
void content_invalidate_reuse_data(struct hlcache_handle *c);
|
||||
const char *content_get_refresh_url(struct hlcache_handle *c);
|
||||
struct bitmap *content_get_bitmap(struct hlcache_handle *c);
|
||||
|
||||
/* Download support */
|
||||
struct llcache_handle *content_convert_to_download(struct hlcache_handle *c);
|
||||
|
||||
#endif
|
||||
|
221
content/content_protected.h
Normal file
221
content/content_protected.h
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright 2005-2007 James Bursa <bursa@users.sourceforge.net>
|
||||
* Copyright 2003 Philip Pemberton <philpem@users.sourceforge.net>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Content handling (interface).
|
||||
*
|
||||
* The content functions manipulate struct contents, which correspond to URLs.
|
||||
*/
|
||||
|
||||
#ifndef _NETSURF_CONTENT_CONTENT_PROTECTED_H_
|
||||
#define _NETSURF_CONTENT_CONTENT_PROTECTED_H_
|
||||
|
||||
/* Irritatingly this must come first, or odd include errors
|
||||
* will occur to do with setjmp.h.
|
||||
*/
|
||||
#ifdef WITH_PNG
|
||||
#include "image/png.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "content/llcache.h"
|
||||
#include "css/css.h"
|
||||
#include "render/html.h"
|
||||
#include "render/textplain.h"
|
||||
#ifdef WITH_JPEG
|
||||
#include "image/jpeg.h"
|
||||
#endif
|
||||
#ifdef WITH_GIF
|
||||
#include "image/gif.h"
|
||||
#endif
|
||||
#ifdef WITH_BMP
|
||||
#include "image/bmp.h"
|
||||
#include "image/ico.h"
|
||||
#endif
|
||||
#ifdef WITH_PLUGIN
|
||||
#include "riscos/plugin.h"
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
#include "image/mng.h"
|
||||
#endif
|
||||
#ifdef WITH_SPRITE
|
||||
#include "riscos/sprite.h"
|
||||
#endif
|
||||
#ifdef WITH_NSSPRITE
|
||||
#include "image/nssprite.h"
|
||||
#endif
|
||||
#ifdef WITH_DRAW
|
||||
#include "riscos/draw.h"
|
||||
#endif
|
||||
#ifdef WITH_ARTWORKS
|
||||
#include "riscos/artworks.h"
|
||||
#endif
|
||||
#ifdef WITH_NS_SVG
|
||||
#include "image/svg.h"
|
||||
#endif
|
||||
#ifdef WITH_RSVG
|
||||
#include "image/rsvg.h"
|
||||
#endif
|
||||
|
||||
|
||||
struct bitmap;
|
||||
struct content;
|
||||
|
||||
/** Linked list of users of a content. */
|
||||
struct content_user
|
||||
{
|
||||
void (*callback)(struct content *c, content_msg msg,
|
||||
union content_msg_data data, void *pw);
|
||||
void *pw;
|
||||
|
||||
struct content_user *next;
|
||||
};
|
||||
|
||||
/** Corresponds to a single URL. */
|
||||
struct content {
|
||||
llcache_handle *llcache; /**< Low-level cache object */
|
||||
|
||||
content_type type; /**< Type of content. */
|
||||
char *mime_type; /**< Original MIME type of data, or 0. */
|
||||
|
||||
content_status status; /**< Current status. */
|
||||
|
||||
int width, height; /**< Dimensions, if applicable. */
|
||||
int available_width; /**< Available width (eg window width). */
|
||||
|
||||
bool quirks; /**< Content is in quirks mode */
|
||||
char *fallback_charset; /**< Fallback charset, or NULL */
|
||||
|
||||
/** Data dependent on type. */
|
||||
union {
|
||||
struct content_html_data html;
|
||||
struct content_textplain_data textplain;
|
||||
struct content_css_data css;
|
||||
#ifdef WITH_JPEG
|
||||
struct content_jpeg_data jpeg;
|
||||
#endif
|
||||
#ifdef WITH_GIF
|
||||
struct content_gif_data gif;
|
||||
#endif
|
||||
#ifdef WITH_BMP
|
||||
struct content_bmp_data bmp;
|
||||
struct content_ico_data ico;
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
struct content_mng_data mng;
|
||||
#endif
|
||||
#ifdef WITH_SPRITE
|
||||
struct content_sprite_data sprite;
|
||||
#endif
|
||||
#ifdef WITH_NSSPRITE
|
||||
struct content_nssprite_data nssprite;
|
||||
#endif
|
||||
#ifdef WITH_DRAW
|
||||
struct content_draw_data draw;
|
||||
#endif
|
||||
#ifdef WITH_PLUGIN
|
||||
struct content_plugin_data plugin;
|
||||
#endif
|
||||
#ifdef WITH_ARTWORKS
|
||||
struct content_artworks_data artworks;
|
||||
#endif
|
||||
#ifdef WITH_NS_SVG
|
||||
struct content_svg_data svg;
|
||||
#endif
|
||||
#ifdef WITH_RSVG
|
||||
struct content_rsvg_data rsvg;
|
||||
#endif
|
||||
#ifdef WITH_PNG
|
||||
struct content_png_data png;
|
||||
#endif
|
||||
} data;
|
||||
|
||||
/**< URL for refresh request, in standard form as from url_join. */
|
||||
char *refresh;
|
||||
|
||||
/** Bitmap, for various image contents. */
|
||||
struct bitmap *bitmap;
|
||||
|
||||
/** This content may be given to new users. Indicates that the content
|
||||
* was fetched using a simple GET, has not expired, and may be
|
||||
* shared between users. */
|
||||
bool fresh;
|
||||
unsigned int time; /**< Creation time, if TYPE_UNKNOWN,
|
||||
LOADING or READY,
|
||||
otherwise total time. */
|
||||
|
||||
unsigned int reformat_time; /**< Earliest time to attempt a
|
||||
period reflow while fetching a
|
||||
page's objects. */
|
||||
|
||||
unsigned int size; /**< Estimated size of all data
|
||||
associated with this content, except
|
||||
alloced as talloc children of this. */
|
||||
off_t talloc_size; /**< Used by content_clean() */
|
||||
char *title; /**< Title for browser window. */
|
||||
unsigned int active; /**< Number of child fetches or
|
||||
conversions currently in progress. */
|
||||
struct content_user *user_list; /**< List of users. */
|
||||
char status_message[120]; /**< Full text for status bar. */
|
||||
char sub_status[80]; /**< Status of content. */
|
||||
/** Content is being processed: data structures may be inconsistent
|
||||
* and content must not be redrawn or modified. */
|
||||
bool locked;
|
||||
|
||||
unsigned long total_size; /**< Total data size, 0 if unknown. */
|
||||
long http_code; /**< HTTP status code, 0 if not HTTP. */
|
||||
|
||||
/** Array of first n rendering errors or warnings. */
|
||||
struct {
|
||||
const char *token;
|
||||
unsigned int line; /**< Line no, 0 if not applicable. */
|
||||
} error_list[40];
|
||||
unsigned int error_count; /**< Number of valid error entries. */
|
||||
};
|
||||
|
||||
extern const char * const content_type_name[];
|
||||
extern const char * const content_status_name[];
|
||||
|
||||
void content_set_done(struct content *c);
|
||||
void content_set_status(struct content *c, const char *status_message, ...);
|
||||
void content_broadcast(struct content *c, content_msg msg,
|
||||
union content_msg_data data);
|
||||
void content_add_error(struct content *c, const char *token,
|
||||
unsigned int line);
|
||||
|
||||
void content__reformat(struct content *c, int width, int height);
|
||||
|
||||
|
||||
content_type content__get_type(struct content *c);
|
||||
const char *content__get_url(struct content *c);
|
||||
const char *content__get_title(struct content *c);
|
||||
content_status content__get_status(struct content *c);
|
||||
const char *content__get_status_message(struct content *c);
|
||||
int content__get_width(struct content *c);
|
||||
int content__get_height(struct content *c);
|
||||
int content__get_available_width(struct content *c);
|
||||
const char *content__get_source_data(struct content *c, unsigned long *size);
|
||||
void content__invalidate_reuse_data(struct content *c);
|
||||
const char *content__get_refresh_url(struct content *c);
|
||||
struct bitmap *content__get_bitmap(struct content *c);
|
||||
|
||||
#endif
|
@ -41,7 +41,6 @@
|
||||
#include "content/urldb.h"
|
||||
#include "desktop/netsurf.h"
|
||||
#include "desktop/options.h"
|
||||
#include "render/form.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/url.h"
|
||||
@ -213,7 +212,7 @@ void fetch_unref_fetcher(scheme_fetcher *fetcher)
|
||||
struct fetch * fetch_start(const char *url, const char *referer,
|
||||
fetch_callback callback,
|
||||
void *p, bool only_2xx, const char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
bool verifiable, struct content *parent,
|
||||
char *headers[])
|
||||
{
|
||||
@ -598,6 +597,78 @@ bool fetch_get_verifiable(struct fetch *fetch)
|
||||
return fetch->verifiable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone a linked list of fetch_multipart_data.
|
||||
*
|
||||
* \param list List to clone
|
||||
* \return Pointer to head of cloned list, or NULL on failure
|
||||
*/
|
||||
struct fetch_multipart_data *fetch_multipart_data_clone(
|
||||
const struct fetch_multipart_data *list)
|
||||
{
|
||||
struct fetch_multipart_data *clone, *last = NULL;
|
||||
struct fetch_multipart_data *result = NULL;
|
||||
|
||||
for (; list != NULL; list = list->next) {
|
||||
clone = malloc(sizeof(struct fetch_multipart_data));
|
||||
if (clone == NULL) {
|
||||
if (result != NULL)
|
||||
fetch_multipart_data_destroy(result);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clone->file = list->file;
|
||||
|
||||
clone->name = strdup(list->name);
|
||||
if (clone->name == NULL) {
|
||||
free(clone);
|
||||
if (result != NULL)
|
||||
fetch_multipart_data_destroy(result);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clone->value = strdup(list->value);
|
||||
if (clone->value == NULL) {
|
||||
free(clone->name);
|
||||
free(clone);
|
||||
if (result != NULL)
|
||||
fetch_multipart_data_destroy(result);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clone->next = NULL;
|
||||
|
||||
if (result == NULL)
|
||||
result = clone;
|
||||
else
|
||||
last->next = clone;
|
||||
|
||||
last = clone;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a linked list of fetch_multipart_data.
|
||||
*
|
||||
* \param list Pointer to head of list to free
|
||||
*/
|
||||
void fetch_multipart_data_destroy(struct fetch_multipart_data *list)
|
||||
{
|
||||
struct fetch_multipart_data *next;
|
||||
|
||||
for (; list != NULL; list = next) {
|
||||
next = list->next;
|
||||
free(list->name);
|
||||
free(list->value);
|
||||
free(list);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fetch_send_callback(fetch_msg msg, struct fetch *fetch, const void *data,
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
@ -666,7 +737,7 @@ fetch_set_cookie(struct fetch *fetch, const char *data)
|
||||
* so don't pass in the parent in this case. */
|
||||
urldb_set_cookie(data, fetch->url,
|
||||
fetch->verifiable ? NULL
|
||||
: fetch->parent->url);
|
||||
: content_get_url(fetch->parent));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,15 @@ typedef enum {
|
||||
|
||||
struct content;
|
||||
struct fetch;
|
||||
struct form_successful_control;
|
||||
|
||||
/** Fetch POST multipart data */
|
||||
struct fetch_multipart_data {
|
||||
bool file; /**< Item is a file */
|
||||
char *name; /**< Name of item */
|
||||
char *value; /**< Item value */
|
||||
|
||||
struct fetch_multipart_data *next; /**< Next in linked list */
|
||||
};
|
||||
|
||||
struct ssl_cert_info {
|
||||
long version; /**< Certificate version */
|
||||
@ -77,7 +85,7 @@ void fetch_init(void);
|
||||
struct fetch * fetch_start(const char *url, const char *referer,
|
||||
fetch_callback callback,
|
||||
void *p, bool only_2xx, const char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
bool verifiable, struct content *parent,
|
||||
char *headers[]);
|
||||
void fetch_abort(struct fetch *f);
|
||||
@ -94,12 +102,16 @@ const char *fetch_get_referer(struct fetch *fetch);
|
||||
struct content *fetch_get_parent(struct fetch *fetch);
|
||||
bool fetch_get_verifiable(struct fetch *fetch);
|
||||
|
||||
void fetch_multipart_data_destroy(struct fetch_multipart_data *list);
|
||||
struct fetch_multipart_data *fetch_multipart_data_clone(
|
||||
const struct fetch_multipart_data *list);
|
||||
|
||||
/* API for fetchers themselves */
|
||||
|
||||
typedef bool (*fetcher_initialise)(const char *);
|
||||
typedef void* (*fetcher_setup_fetch)(struct fetch *, const char *,
|
||||
bool, const char *,
|
||||
struct form_successful_control *,
|
||||
struct fetch_multipart_data *,
|
||||
const char **);
|
||||
typedef bool (*fetcher_start_fetch)(void *);
|
||||
typedef void (*fetcher_abort_fetch)(void *);
|
||||
|
@ -102,7 +102,7 @@ struct content * fetchcache(const char *url,
|
||||
int width, int height,
|
||||
bool no_error_pages,
|
||||
char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
bool verifiable,
|
||||
bool download)
|
||||
{
|
||||
@ -250,7 +250,7 @@ void fetchcache_go(struct content *content, const char *referer,
|
||||
intptr_t p1, intptr_t p2,
|
||||
int width, int height,
|
||||
char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
bool verifiable, struct content *parent)
|
||||
{
|
||||
char error_message[500];
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <stdint.h>
|
||||
#include "content/content.h"
|
||||
|
||||
struct form_successful_control;
|
||||
struct fetch_multipart_data;
|
||||
|
||||
void fetchcache_init(void);
|
||||
struct content * fetchcache(const char *url,
|
||||
@ -40,7 +40,7 @@ struct content * fetchcache(const char *url,
|
||||
int width, int height,
|
||||
bool no_error_pages,
|
||||
char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
bool verifiable,
|
||||
bool download);
|
||||
void fetchcache_go(struct content *content, const char *referer,
|
||||
@ -49,7 +49,7 @@ void fetchcache_go(struct content *content, const char *referer,
|
||||
intptr_t p1, intptr_t p2,
|
||||
int width, int height,
|
||||
char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
bool verifiable, struct content *parent);
|
||||
|
||||
#endif
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
@ -43,7 +44,6 @@
|
||||
#include "content/urldb.h"
|
||||
#include "desktop/netsurf.h"
|
||||
#include "desktop/options.h"
|
||||
#include "render/form.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/url.h"
|
||||
@ -104,7 +104,7 @@ static bool fetch_curl_initialise(const char *scheme);
|
||||
static void fetch_curl_finalise(const char *scheme);
|
||||
static void * fetch_curl_setup(struct fetch *parent_fetch, const char *url,
|
||||
bool only_2xx, const char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
const char **headers);
|
||||
static bool fetch_curl_start(void *vfetch);
|
||||
static bool fetch_curl_initiate_fetch(struct curl_fetch_info *fetch,
|
||||
@ -132,7 +132,7 @@ static size_t fetch_curl_header(char *data, size_t size, size_t nmemb,
|
||||
void *_f);
|
||||
static bool fetch_curl_process_headers(struct curl_fetch_info *f);
|
||||
static struct curl_httppost *fetch_curl_post_convert(
|
||||
struct form_successful_control *control);
|
||||
struct fetch_multipart_data *control);
|
||||
static int fetch_curl_verify_callback(int preverify_ok,
|
||||
X509_STORE_CTX *x509_ctx);
|
||||
static int fetch_curl_cert_verify_callback(X509_STORE_CTX *x509_ctx,
|
||||
@ -294,7 +294,7 @@ void fetch_curl_finalise(const char *scheme)
|
||||
|
||||
void * fetch_curl_setup(struct fetch *parent_fetch, const char *url,
|
||||
bool only_2xx, const char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
const char **headers)
|
||||
{
|
||||
char *host;
|
||||
@ -1108,10 +1108,7 @@ size_t fetch_curl_header(char *data, size_t size, size_t nmemb,
|
||||
bool fetch_curl_process_headers(struct curl_fetch_info *f)
|
||||
{
|
||||
long http_code;
|
||||
const char *type;
|
||||
CURLcode code;
|
||||
struct stat s;
|
||||
char *url_path = 0;
|
||||
|
||||
f->had_headers = true;
|
||||
|
||||
@ -1156,49 +1153,64 @@ bool fetch_curl_process_headers(struct curl_fetch_info *f)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* find MIME type from headers or filetype for local files */
|
||||
code = curl_easy_getinfo(f->curl_handle, CURLINFO_CONTENT_TYPE, &type);
|
||||
assert(code == CURLE_OK);
|
||||
/* find MIME type from filetype for local files */
|
||||
if (strncmp(f->url, "file:///", 8) == 0) {
|
||||
struct stat s;
|
||||
char *url_path = curl_unescape(f->url + 7,
|
||||
(int) strlen(f->url + 7));
|
||||
|
||||
if (strncmp(f->url, "file:///", 8) == 0)
|
||||
url_path = curl_unescape(f->url + 7,
|
||||
(int) strlen(f->url) - 7);
|
||||
|
||||
if (url_path && stat(url_path, &s) == 0) {
|
||||
if (url_path != NULL && stat(url_path, &s) == 0) {
|
||||
/* file: URL and file exists */
|
||||
char header[64];
|
||||
const char *type;
|
||||
|
||||
/* create etag */
|
||||
char etag_buf[20];
|
||||
snprintf(etag_buf, sizeof etag_buf,
|
||||
"ETag: \"%10d\"", (int) s.st_mtime);
|
||||
snprintf(header, sizeof header,
|
||||
"ETag: \"%10" PRId64 "\"",
|
||||
(int64_t) s.st_mtime);
|
||||
/* And send it to the header handler */
|
||||
fetch_send_callback(FETCH_HEADER, f->fetch_handle, etag_buf,
|
||||
strlen(etag_buf), FETCH_ERROR_NO_ERROR);
|
||||
fetch_send_callback(FETCH_HEADER, f->fetch_handle,
|
||||
header, strlen(header),
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
|
||||
/* don't set last modified time so as to ensure that local
|
||||
* files are revalidated at all times. */
|
||||
/* create Content-Type */
|
||||
type = fetch_filetype(url_path);
|
||||
snprintf(header, sizeof header,
|
||||
"Content-Type: %s", type);
|
||||
/* Send it to the header handler */
|
||||
fetch_send_callback(FETCH_HEADER, f->fetch_handle,
|
||||
header, strlen(header),
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
|
||||
/* If performed a conditional request and unmodified ... */
|
||||
/* create Content-Length */
|
||||
type = fetch_filetype(url_path);
|
||||
snprintf(header, sizeof header,
|
||||
"Content-Length: %" PRId64,
|
||||
(int64_t) s.st_size);
|
||||
/* Send it to the header handler */
|
||||
fetch_send_callback(FETCH_HEADER, f->fetch_handle,
|
||||
header, strlen(header),
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
|
||||
/* don't set last modified time so as to ensure that
|
||||
* local files are revalidated at all times. */
|
||||
|
||||
/* Report not modified, if appropriate */
|
||||
if (f->last_modified && f->file_etag &&
|
||||
f->last_modified > s.st_mtime &&
|
||||
f->file_etag == s.st_mtime) {
|
||||
fetch_send_callback(FETCH_NOTMODIFIED, f->fetch_handle,
|
||||
0, 0, FETCH_ERROR_NO_ERROR);
|
||||
fetch_send_callback(FETCH_NOTMODIFIED,
|
||||
f->fetch_handle, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
curl_free(url_path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == 0) {
|
||||
type = "text/plain";
|
||||
if (url_path) {
|
||||
type = fetch_filetype(url_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (url_path != NULL)
|
||||
curl_free(url_path);
|
||||
}
|
||||
|
||||
LOG(("FETCH_TYPE, '%s'", type));
|
||||
fetch_send_callback(FETCH_TYPE, f->fetch_handle, type, f->content_length, FETCH_ERROR_NO_ERROR);
|
||||
if (f->abort)
|
||||
return true;
|
||||
|
||||
@ -1207,11 +1219,11 @@ bool fetch_curl_process_headers(struct curl_fetch_info *f)
|
||||
|
||||
|
||||
/**
|
||||
* Convert a list of struct ::form_successful_control to a list of
|
||||
* Convert a list of struct ::fetch_multipart_data to a list of
|
||||
* struct curl_httppost for libcurl.
|
||||
*/
|
||||
struct curl_httppost *
|
||||
fetch_curl_post_convert(struct form_successful_control *control)
|
||||
fetch_curl_post_convert(struct fetch_multipart_data *control)
|
||||
{
|
||||
struct curl_httppost *post = 0, *last = 0;
|
||||
CURLFORMcode code;
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "content/urldb.h"
|
||||
#include "desktop/netsurf.h"
|
||||
#include "desktop/options.h"
|
||||
#include "render/form.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/url.h"
|
||||
@ -78,7 +77,7 @@ static void fetch_data_finalise(const char *scheme)
|
||||
|
||||
static void *fetch_data_setup(struct fetch *parent_fetch, const char *url,
|
||||
bool only_2xx, const char *post_urlenc,
|
||||
struct form_successful_control *post_multipart,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
const char **headers)
|
||||
{
|
||||
struct fetch_data_context *ctx = calloc(1, sizeof(*ctx));
|
||||
@ -232,20 +231,9 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
static void fetch_data_poll(const char *scheme)
|
||||
{
|
||||
struct fetch_data_context *c, *next;
|
||||
struct cache_data cachedata;
|
||||
|
||||
if (ring == NULL) return;
|
||||
|
||||
cachedata.req_time = time(NULL);
|
||||
cachedata.res_time = time(NULL);
|
||||
cachedata.date = 0;
|
||||
cachedata.expires = 0;
|
||||
cachedata.age = INVALID_AGE;
|
||||
cachedata.max_age = 0;
|
||||
cachedata.no_cache = true;
|
||||
cachedata.etag = NULL;
|
||||
cachedata.last_modified = 0;
|
||||
|
||||
/* Iterate over ring, processing each pending fetch */
|
||||
c = ring;
|
||||
do {
|
||||
@ -265,6 +253,8 @@ static void fetch_data_poll(const char *scheme)
|
||||
|
||||
/* Only process non-aborted fetches */
|
||||
if (!c->aborted && fetch_data_process(c) == true) {
|
||||
char header[64];
|
||||
|
||||
fetch_set_http_code(c->parent_fetch, 200);
|
||||
LOG(("setting data: MIME type to %s, length to %zd",
|
||||
c->mimetype, c->datalen));
|
||||
@ -272,9 +262,16 @@ static void fetch_data_poll(const char *scheme)
|
||||
* Therefore, we _must_ check for this after _every_
|
||||
* call to fetch_data_send_callback().
|
||||
*/
|
||||
fetch_data_send_callback(FETCH_TYPE,
|
||||
c, c->mimetype, c->datalen,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
snprintf(header, sizeof header, "Content-Type: %s",
|
||||
c->mimetype);
|
||||
fetch_data_send_callback(FETCH_HEADER, c, header,
|
||||
strlen(header), FETCH_ERROR_NO_ERROR);
|
||||
|
||||
snprintf(header, sizeof header, "Content-Length: %zd",
|
||||
c->datalen);
|
||||
fetch_data_send_callback(FETCH_HEADER, c, header,
|
||||
strlen(header), FETCH_ERROR_NO_ERROR);
|
||||
|
||||
if (!c->aborted) {
|
||||
fetch_data_send_callback(FETCH_DATA,
|
||||
c, c->data, c->datalen,
|
||||
@ -282,8 +279,7 @@ static void fetch_data_poll(const char *scheme)
|
||||
}
|
||||
if (!c->aborted) {
|
||||
fetch_data_send_callback(FETCH_FINISHED,
|
||||
c, &cachedata, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
c, 0, 0, FETCH_ERROR_NO_ERROR);
|
||||
}
|
||||
} else {
|
||||
LOG(("Processing of %s failed!", c->url));
|
||||
|
362
content/hlcache.c
Normal file
362
content/hlcache.c
Normal file
@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* High-level resource cache (implementation)
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/url.h"
|
||||
|
||||
typedef struct hlcache_entry hlcache_entry;
|
||||
typedef struct hlcache_retrieval_ctx hlcache_retrieval_ctx;
|
||||
|
||||
/** High-level cache retrieval context */
|
||||
struct hlcache_retrieval_ctx {
|
||||
llcache_handle *llcache; /**< Low-level cache handle */
|
||||
|
||||
hlcache_handle *handle; /**< High-level handle for object */
|
||||
|
||||
/* The following are only used if a child content is requested */
|
||||
const char *charset; /**< Fallback charset, or NULL */
|
||||
bool quirks; /**< Whether object should be quirky */
|
||||
};
|
||||
|
||||
/** High-level cache handle */
|
||||
struct hlcache_handle {
|
||||
hlcache_entry *entry; /**< Pointer to cache entry */
|
||||
|
||||
hlcache_handle_callback cb; /**< Client callback */
|
||||
void *pw; /**< Client data */
|
||||
};
|
||||
|
||||
/** Entry in high-level cache */
|
||||
struct hlcache_entry {
|
||||
struct content *content; /**< Pointer to associated content */
|
||||
|
||||
hlcache_entry *next; /**< Next sibling */
|
||||
hlcache_entry *prev; /**< Previous sibling */
|
||||
};
|
||||
|
||||
/** List of cached content objects */
|
||||
static hlcache_entry *hlcache_content_list;
|
||||
|
||||
static nserror hlcache_llcache_callback(llcache_handle *handle,
|
||||
const llcache_event *event, void *pw);
|
||||
static nserror hlcache_find_content(hlcache_retrieval_ctx *ctx);
|
||||
static void hlcache_content_callback(struct content *c,
|
||||
content_msg msg, union content_msg_data data, void *pw);
|
||||
|
||||
/******************************************************************************
|
||||
* Public API *
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Retrieve a high-level cache handle for an object
|
||||
*
|
||||
* \param url URL of the object to retrieve handle for
|
||||
* \param flags Object retrieval flags
|
||||
* \param referer Referring URL, or NULL if none
|
||||
* \param post POST data, or NULL for a GET request
|
||||
* \param width Available width for content
|
||||
* \param height Available height for content
|
||||
* \param cb Callback to handle object events
|
||||
* \param pw Pointer to client-specific data for callback
|
||||
* \param child Child retrieval context, or NULL for top-level content
|
||||
* \param result Pointer to location to recieve cache handle
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*
|
||||
* \todo Is there any way to sensibly reduce the number of parameters here?
|
||||
*/
|
||||
nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
|
||||
const char *referer, llcache_post_data *post,
|
||||
uint32_t width, uint32_t height,
|
||||
hlcache_handle_callback cb, void *pw,
|
||||
hlcache_child_context *child, hlcache_handle **result)
|
||||
{
|
||||
hlcache_retrieval_ctx *ctx;
|
||||
nserror error;
|
||||
|
||||
assert(cb != NULL);
|
||||
|
||||
ctx = calloc(1, sizeof(hlcache_retrieval_ctx));
|
||||
if (ctx == NULL)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
ctx->handle = calloc(1, sizeof(hlcache_handle));
|
||||
if (ctx->handle == NULL) {
|
||||
free(ctx);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
if (child != NULL) {
|
||||
/** \todo Is the charset guaranteed to exist during fetch? */
|
||||
ctx->charset = child->charset;
|
||||
ctx->quirks = child->quirks;
|
||||
}
|
||||
|
||||
/** \todo What happens with width/height? */
|
||||
|
||||
ctx->handle->cb = cb;
|
||||
ctx->handle->pw = pw;
|
||||
|
||||
error = llcache_handle_retrieve(url, flags, referer, post,
|
||||
hlcache_llcache_callback, ctx,
|
||||
&ctx->llcache);
|
||||
if (error != NSERROR_OK) {
|
||||
free(ctx->handle);
|
||||
free(ctx);
|
||||
return error;
|
||||
}
|
||||
|
||||
*result = ctx->handle;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release a high-level cache handle
|
||||
*
|
||||
* \param handle Handle to release
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*/
|
||||
nserror hlcache_handle_release(hlcache_handle *handle)
|
||||
{
|
||||
/** \todo What if this is called during fetch? */
|
||||
|
||||
if (handle->entry != NULL) {
|
||||
content_remove_user(handle->entry->content,
|
||||
hlcache_content_callback, handle);
|
||||
}
|
||||
|
||||
handle->cb = NULL;
|
||||
handle->pw = NULL;
|
||||
|
||||
/** \todo Provide hlcache_poll() to perform cache maintenance */
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a content object from a cache handle
|
||||
*
|
||||
* \param handle Cache handle to dereference
|
||||
* \return Pointer to content object, or NULL if there is none
|
||||
*
|
||||
* \todo This may not be correct. Ideally, the client should never need to
|
||||
* directly access a content object. It may, therefore, be better to provide a
|
||||
* bunch of veneers here that take a hlcache_handle and invoke the
|
||||
* corresponding content_ API. If there's no content object associated with the
|
||||
* hlcache_handle (e.g. because the source data is still being fetched, so it
|
||||
* doesn't exist yet), then these veneers would behave as a NOP. The important
|
||||
* thing being that the client need not care about this possibility and can
|
||||
* just call the functions with impugnity.
|
||||
*/
|
||||
struct content *hlcache_handle_get_content(const hlcache_handle *handle)
|
||||
{
|
||||
assert(handle != NULL);
|
||||
|
||||
if (handle->entry != NULL)
|
||||
return handle->entry->content;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* High-level cache internals *
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Handler for low-level cache events
|
||||
*
|
||||
* \param handle Handle for which event is issued
|
||||
* \param event Event data
|
||||
* \param pw Pointer to client-specific data
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*/
|
||||
nserror hlcache_llcache_callback(llcache_handle *handle,
|
||||
const llcache_event *event, void *pw)
|
||||
{
|
||||
hlcache_retrieval_ctx *ctx = pw;
|
||||
nserror error;
|
||||
|
||||
assert(ctx->llcache == handle);
|
||||
|
||||
switch (event->type) {
|
||||
case LLCACHE_EVENT_HAD_HEADERS:
|
||||
error = hlcache_find_content(ctx);
|
||||
if (error != NSERROR_OK)
|
||||
return error;
|
||||
/* No longer require retrieval context */
|
||||
free(ctx);
|
||||
break;
|
||||
case LLCACHE_EVENT_HAD_DATA:
|
||||
/* fall through */
|
||||
case LLCACHE_EVENT_DONE:
|
||||
/* should never happen: the handler must be changed */
|
||||
break;
|
||||
case LLCACHE_EVENT_ERROR:
|
||||
/** \todo handle errors */
|
||||
break;
|
||||
case LLCACHE_EVENT_PROGRESS:
|
||||
break;
|
||||
}
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a content for the high-level cache handle
|
||||
*
|
||||
* \param ctx High-level cache retrieval context
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*
|
||||
* \pre handle::state == HLCACHE_HANDLE_NEW
|
||||
* \pre Headers must have been received for associated low-level handle
|
||||
* \post Low-level handle is either released, or associated with new content
|
||||
* \post High-level handle is registered with content
|
||||
*/
|
||||
nserror hlcache_find_content(hlcache_retrieval_ctx *ctx)
|
||||
{
|
||||
hlcache_entry *entry;
|
||||
hlcache_event event;
|
||||
|
||||
/* Search list of cached contents for a suitable one */
|
||||
for (entry = hlcache_content_list; entry != NULL; entry = entry->next) {
|
||||
const llcache_handle *entry_llcache;
|
||||
|
||||
/** \todo Need to ensure that quirks mode matches */
|
||||
/** \todo Need to ensure that content is shareable */
|
||||
/** \todo Need to ensure that content can be reused */
|
||||
if (entry->content == NULL)
|
||||
continue;
|
||||
|
||||
/* Ensure that content uses same low-level object as
|
||||
* low-level handle */
|
||||
entry_llcache = content_get_llcache_handle(entry->content);
|
||||
|
||||
if (llcache_handle_references_same_object(entry_llcache,
|
||||
ctx->llcache))
|
||||
break;
|
||||
}
|
||||
|
||||
if (entry == NULL) {
|
||||
/* No existing entry, so need to create one */
|
||||
entry = malloc(sizeof(hlcache_entry));
|
||||
if (entry == NULL)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
/* Create content using llhandle */
|
||||
entry->content = content_create(ctx->llcache,
|
||||
ctx->charset, ctx->quirks);
|
||||
if (entry->content == NULL) {
|
||||
free(entry);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
/* Insert into cache */
|
||||
entry->prev = NULL;
|
||||
entry->next = hlcache_content_list;
|
||||
if (hlcache_content_list != NULL)
|
||||
hlcache_content_list->prev = entry;
|
||||
hlcache_content_list = entry;
|
||||
} else {
|
||||
/* Found a suitable content: no longer need low-level handle */
|
||||
llcache_handle_release(ctx->llcache);
|
||||
}
|
||||
|
||||
/* Associate handle with content */
|
||||
if (content_add_user(entry->content,
|
||||
hlcache_content_callback, ctx->handle) == false)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
/* Associate cache entry with handle */
|
||||
ctx->handle->entry = entry;
|
||||
|
||||
/* Catch handle up with state of content */
|
||||
if (ctx->handle->cb != NULL) {
|
||||
content_status status = content_get_status(ctx->handle);
|
||||
|
||||
if (status == CONTENT_STATUS_LOADING) {
|
||||
event.type = CONTENT_MSG_LOADING;
|
||||
ctx->handle->cb(ctx->handle, &event, ctx->handle->pw);
|
||||
} else if (status == CONTENT_STATUS_READY) {
|
||||
event.type = CONTENT_MSG_LOADING;
|
||||
ctx->handle->cb(ctx->handle, &event, ctx->handle->pw);
|
||||
|
||||
if (ctx->handle->cb != NULL) {
|
||||
event.type = CONTENT_MSG_READY;
|
||||
ctx->handle->cb(ctx->handle, &event,
|
||||
ctx->handle->pw);
|
||||
}
|
||||
} else if (status == CONTENT_STATUS_DONE) {
|
||||
event.type = CONTENT_MSG_LOADING;
|
||||
ctx->handle->cb(ctx->handle, &event, ctx->handle->pw);
|
||||
|
||||
/** \todo Reflow content to new width
|
||||
if (content_get_available_width(ctx->handle) != width)
|
||||
content_reformat(ctx->handle, width, height);
|
||||
*/
|
||||
|
||||
if (ctx->handle->cb != NULL) {
|
||||
event.type = CONTENT_MSG_READY;
|
||||
ctx->handle->cb(ctx->handle, &event,
|
||||
ctx->handle->pw);
|
||||
}
|
||||
|
||||
if (ctx->handle->cb != NULL) {
|
||||
event.type = CONTENT_MSG_DONE;
|
||||
ctx->handle->cb(ctx->handle, &event,
|
||||
ctx->handle->pw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Veneer between content callback API and hlcache callback API
|
||||
*
|
||||
* \param c Content to emit message for
|
||||
* \param msg Message to emit
|
||||
* \param data Data for message
|
||||
* \param pw Pointer to private data (hlcache_handle)
|
||||
*/
|
||||
void hlcache_content_callback(struct content *c, content_msg msg,
|
||||
union content_msg_data data, void *pw)
|
||||
{
|
||||
hlcache_handle *handle = pw;
|
||||
hlcache_event event;
|
||||
nserror error;
|
||||
|
||||
event.type = msg;
|
||||
event.data = data;
|
||||
|
||||
|
||||
error = handle->cb(handle, &event, handle->pw);
|
||||
if (error != NSERROR_OK)
|
||||
LOG(("Error in callback: %d", error));
|
||||
}
|
||||
|
110
content/hlcache.h
Normal file
110
content/hlcache.h
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* High-level resource cache (interface)
|
||||
*/
|
||||
|
||||
#ifndef NETSURF_CONTENT_HLCACHE_H_
|
||||
#define NETSURF_CONTENT_HLCACHE_H_
|
||||
|
||||
#include "content/content.h"
|
||||
#include "content/llcache.h"
|
||||
#include "utils/errors.h"
|
||||
|
||||
/** High-level cache handle */
|
||||
typedef struct hlcache_handle hlcache_handle;
|
||||
|
||||
/** Context for retrieving a child object */
|
||||
typedef struct hlcache_child_context {
|
||||
const char *charset; /**< Charset of parent */
|
||||
bool quirks; /**< Whether parent is quirky */
|
||||
} hlcache_child_context;
|
||||
|
||||
/** High-level cache event */
|
||||
typedef struct {
|
||||
content_msg type; /**< Event type */
|
||||
union content_msg_data data; /**< Event data */
|
||||
} hlcache_event;
|
||||
|
||||
/**
|
||||
* Client callback for high-level cache events
|
||||
*
|
||||
* \param handle Handle to object generating event
|
||||
* \param event Event data
|
||||
* \param pw Pointer to client-specific data
|
||||
* \return NSERROR_OK on success, appropriate error otherwise.
|
||||
*/
|
||||
typedef nserror (*hlcache_handle_callback)(hlcache_handle *handle,
|
||||
const hlcache_event *event, void *pw);
|
||||
|
||||
/**
|
||||
* Retrieve a high-level cache handle for an object
|
||||
*
|
||||
* \param url URL of the object to retrieve handle for
|
||||
* \param flags Object retrieval flags
|
||||
* \param referer Referring URL, or NULL if none
|
||||
* \param post POST data, or NULL for a GET request
|
||||
* \param width Available width for content
|
||||
* \param height Available height for content
|
||||
* \param cb Callback to handle object events
|
||||
* \param pw Pointer to client-specific data for callback
|
||||
* \param child Child retrieval context, or NULL for top-level content
|
||||
* \param result Pointer to location to recieve cache handle
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*
|
||||
* Child contents are keyed on the tuple < URL, quirks >.
|
||||
* The quirks field is ignored for child contents whose behaviour is not
|
||||
* affected by quirks mode.
|
||||
*
|
||||
* \todo The above rules should be encoded in the handler_map.
|
||||
*
|
||||
* \todo Is there any way to sensibly reduce the number of parameters here?
|
||||
*/
|
||||
nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
|
||||
const char *referer, llcache_post_data *post,
|
||||
uint32_t width, uint32_t height,
|
||||
hlcache_handle_callback cb, void *pw,
|
||||
hlcache_child_context *child, hlcache_handle **result);
|
||||
|
||||
/**
|
||||
* Release a high-level cache handle
|
||||
*
|
||||
* \param handle Handle to release
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*/
|
||||
nserror hlcache_handle_release(hlcache_handle *handle);
|
||||
|
||||
/**
|
||||
* Retrieve a content object from a cache handle
|
||||
*
|
||||
* \param handle Cache handle to dereference
|
||||
* \return Pointer to content object, or NULL if there is none
|
||||
*
|
||||
* \todo This may not be correct. Ideally, the client should never need to
|
||||
* directly access a content object. It may, therefore, be better to provide a
|
||||
* bunch of veneers here that take a hlcache_handle and invoke the
|
||||
* corresponding content_ API. If there's no content object associated with the
|
||||
* hlcache_handle (e.g. because the source data is still being fetched, so it
|
||||
* doesn't exist yet), then these veneers would behave as a NOP. The important
|
||||
* thing being that the client need not care about this possibility and can
|
||||
* just call the functions with impugnity.
|
||||
*/
|
||||
struct content *hlcache_handle_get_content(const hlcache_handle *handle);
|
||||
|
||||
#endif
|
1815
content/llcache.c
Normal file
1815
content/llcache.c
Normal file
File diff suppressed because it is too large
Load Diff
238
content/llcache.h
Normal file
238
content/llcache.h
Normal file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Low-level resource cache (interface)
|
||||
*/
|
||||
|
||||
#ifndef NETSURF_CONTENT_LLCACHE_H_
|
||||
#define NETSURF_CONTENT_LLCACHE_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "utils/errors.h"
|
||||
|
||||
struct ssl_cert_info;
|
||||
struct fetch_multipart_data;
|
||||
|
||||
/** Handle for low-level cache object */
|
||||
typedef struct llcache_handle llcache_handle;
|
||||
|
||||
/** POST data object for low-level cache requests */
|
||||
typedef struct {
|
||||
enum {
|
||||
LLCACHE_POST_URL_ENCODED,
|
||||
LLCACHE_POST_MULTIPART
|
||||
} type; /**< Type of POST data */
|
||||
union {
|
||||
char *urlenc; /**< URL encoded data */
|
||||
struct fetch_multipart_data *multipart; /**< Multipart data */
|
||||
} data; /**< POST data content */
|
||||
} llcache_post_data;
|
||||
|
||||
/** Low-level cache event types */
|
||||
typedef enum {
|
||||
LLCACHE_EVENT_HAD_HEADERS, /**< Received all headers */
|
||||
LLCACHE_EVENT_HAD_DATA, /**< Received some data */
|
||||
LLCACHE_EVENT_DONE, /**< Finished fetching data */
|
||||
|
||||
LLCACHE_EVENT_ERROR, /**< An error occurred during fetch */
|
||||
LLCACHE_EVENT_PROGRESS, /**< Fetch progress update */
|
||||
} llcache_event_type;
|
||||
|
||||
/** Low-level cache events */
|
||||
typedef struct {
|
||||
llcache_event_type type; /**< Type of event */
|
||||
union {
|
||||
struct {
|
||||
const uint8_t *buf; /**< Buffer of data */
|
||||
size_t len; /**< Length of buffer, in bytes */
|
||||
} data; /**< Received data */
|
||||
const char *msg; /**< Error or progress message */
|
||||
} data; /**< Event data */
|
||||
} llcache_event;
|
||||
|
||||
/**
|
||||
* Client callback for low-level cache events
|
||||
*
|
||||
* \param handle Handle for which event is issued
|
||||
* \param event Event data
|
||||
* \param pw Pointer to client-specific data
|
||||
* \return NSERROR_OK on success, appropriate error otherwise.
|
||||
*/
|
||||
typedef nserror (*llcache_handle_callback)(llcache_handle *handle,
|
||||
const llcache_event *event, void *pw);
|
||||
|
||||
/** Flags for low-level cache object retrieval */
|
||||
#define LLCACHE_RETRIEVE_FORCE_FETCH (1 << 0) /* Force a new fetch */
|
||||
#define LLCACHE_RETRIEVE_VERIFIABLE (1 << 1) /* Requested URL was verified */
|
||||
#define LLCACHE_RETRIEVE_SNIFF_TYPE (1 << 2) /* Permit content-type sniffing */
|
||||
#define LLCACHE_RETRIEVE_NO_ERROR_PAGES (1 << 3) /* No error pages */
|
||||
|
||||
/** Low-level cache query types */
|
||||
typedef enum {
|
||||
LLCACHE_QUERY_AUTH, /**< Need authentication details */
|
||||
LLCACHE_QUERY_REDIRECT, /**< Need permission to redirect */
|
||||
LLCACHE_QUERY_SSL /**< SSL chain needs inspection */
|
||||
} llcache_query_type;
|
||||
|
||||
/** Low-level cache query */
|
||||
typedef struct {
|
||||
llcache_query_type type; /**< Type of query */
|
||||
|
||||
const char *url; /**< URL being fetched */
|
||||
|
||||
union {
|
||||
struct {
|
||||
const char *realm; /**< Authentication realm */
|
||||
} auth;
|
||||
|
||||
struct {
|
||||
const char *target; /**< Redirect target */
|
||||
} redirect;
|
||||
|
||||
struct {
|
||||
const struct ssl_cert_info *certs;
|
||||
size_t num; /**< Number of certs in chain */
|
||||
} ssl;
|
||||
} data;
|
||||
} llcache_query;
|
||||
|
||||
/**
|
||||
* Response handler for fetch-related queries
|
||||
*
|
||||
* \param proceed Whether to proceed with the fetch or not
|
||||
* \param cbpw Opaque value provided to llcache_query_callback
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*/
|
||||
typedef nserror (*llcache_query_response)(bool proceed, void *cbpw);
|
||||
|
||||
/**
|
||||
* Callback to handle fetch-related queries
|
||||
*
|
||||
* \param query Object containing details of query
|
||||
* \param pw Pointer to callback-specific data
|
||||
* \param cb Callback that client should call once query is satisfied
|
||||
* \param cbpw Opaque value to pass into \a cb
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*
|
||||
* \note This callback should return immediately. Once a suitable answer to
|
||||
* the query has been obtained, the provided response callback should be
|
||||
* called. This is intended to be an entirely asynchronous process.
|
||||
*/
|
||||
typedef nserror (*llcache_query_callback)(const llcache_query *query, void *pw,
|
||||
llcache_query_response cb, void *cbpw);
|
||||
|
||||
/**
|
||||
* Initialise the low-level cache
|
||||
*
|
||||
* \param cb Query handler
|
||||
* \param pw Pointer to query handler data
|
||||
* \return NSERROR_OK on success, appropriate error otherwise.
|
||||
*/
|
||||
nserror llcache_initialise(llcache_query_callback cb, void *pw);
|
||||
|
||||
/**
|
||||
* Poll the low-level cache
|
||||
*
|
||||
* \return NSERROR_OK on success, appropriate error otherwise.
|
||||
*/
|
||||
nserror llcache_poll(void);
|
||||
|
||||
/**
|
||||
* Retrieve a handle for a low-level cache object
|
||||
*
|
||||
* \param url URL of the object to fetch
|
||||
* \param flags Object retrieval flags
|
||||
* \param referer Referring URL, or NULL if none
|
||||
* \param post POST data, or NULL for a GET request
|
||||
* \param cb Client callback for events
|
||||
* \param pw Pointer to client-specific data
|
||||
* \param result Pointer to location to recieve cache handle
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*/
|
||||
nserror llcache_handle_retrieve(const char *url, uint32_t flags,
|
||||
const char *referer, const llcache_post_data *post,
|
||||
llcache_handle_callback cb, void *pw,
|
||||
llcache_handle **result);
|
||||
|
||||
/**
|
||||
* Change the callback associated with a low-level cache handle
|
||||
*
|
||||
* \param handle Handle to change callback of
|
||||
* \param cb New callback
|
||||
* \param pw Client data for new callback
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*/
|
||||
nserror llcache_handle_change_callback(llcache_handle *handle,
|
||||
llcache_handle_callback cb, void *pw);
|
||||
|
||||
/**
|
||||
* Release a low-level cache handle
|
||||
*
|
||||
* \param handle Handle to release
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*/
|
||||
nserror llcache_handle_release(llcache_handle *handle);
|
||||
|
||||
/**
|
||||
* Retrieve the post-redirect URL of a low-level cache object
|
||||
*
|
||||
* \param handle Handle to retrieve URL from
|
||||
* \return Post-redirect URL of cache object
|
||||
*/
|
||||
const char *llcache_handle_get_url(const llcache_handle *handle);
|
||||
|
||||
/**
|
||||
* Retrieve source data of a low-level cache object
|
||||
*
|
||||
* \param handle Handle to retrieve source data from
|
||||
* \param size Pointer to location to receive byte length of data
|
||||
* \return Pointer to source data
|
||||
*/
|
||||
const uint8_t *llcache_handle_get_source_data(const llcache_handle *handle,
|
||||
size_t *size);
|
||||
|
||||
/**
|
||||
* Retrieve a header value associated with a low-level cache object
|
||||
*
|
||||
* \param handle Handle to retrieve header from
|
||||
* \param key Header name
|
||||
* \return Header value, or NULL if header does not exist
|
||||
*
|
||||
* \todo Make the key an enumeration, to avoid needless string comparisons
|
||||
* \todo Forcing the client to parse the header value seems wrong.
|
||||
* Better would be to return the actual value part and an array of
|
||||
* key-value pairs for any additional parameters.
|
||||
*/
|
||||
const char *llcache_handle_get_header(const llcache_handle *handle,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* Determine if the same underlying object is referenced by the given handles
|
||||
*
|
||||
* \param a First handle
|
||||
* \param b Second handle
|
||||
* \return True if handles reference the same object, false otherwise
|
||||
*/
|
||||
bool llcache_handle_references_same_object(const llcache_handle *a,
|
||||
const llcache_handle *b);
|
||||
|
||||
#endif
|
488
css/css.c
488
css/css.c
@ -20,17 +20,18 @@
|
||||
|
||||
#include <libwapcaplet/libwapcaplet.h>
|
||||
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "content/fetch.h"
|
||||
#include "content/fetchcache.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "css/css.h"
|
||||
#include "css/internal.h"
|
||||
#include "desktop/gui.h"
|
||||
#include "render/html.h"
|
||||
#include "utils/http.h"
|
||||
#include "utils/messages.h"
|
||||
|
||||
static void nscss_import(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data);
|
||||
static nserror nscss_import(hlcache_handle *handle,
|
||||
const hlcache_event *event, void *pw);
|
||||
|
||||
/**
|
||||
* Allocation callback for libcss
|
||||
@ -49,119 +50,28 @@ static void *myrealloc(void *ptr, size_t size, void *pw)
|
||||
* Initialise a CSS content
|
||||
*
|
||||
* \param c Content to initialise
|
||||
* \param parent Parent content, or NULL if top-level
|
||||
* \param params Content-Type parameters
|
||||
* \return true on success, false on failure
|
||||
*/
|
||||
bool nscss_create(struct content *c, struct content *parent,
|
||||
const char *params[])
|
||||
bool nscss_create(struct content *c, const http_parameter *params)
|
||||
{
|
||||
const char *charset = NULL;
|
||||
css_origin origin = CSS_ORIGIN_AUTHOR;
|
||||
uint64_t media = CSS_MEDIA_ALL;
|
||||
lwc_context *dict = NULL;
|
||||
bool quirks = true;
|
||||
uint32_t i;
|
||||
union content_msg_data msg_data;
|
||||
css_error error;
|
||||
nserror error;
|
||||
|
||||
/** \todo what happens about the allocator? */
|
||||
/** \todo proper error reporting */
|
||||
|
||||
/* Find charset specified on HTTP layer, if any */
|
||||
/** \todo What happens if there isn't one and parent content exists? */
|
||||
for (i = 0; params[i] != NULL; i += 2) {
|
||||
if (strcasecmp(params[i], "charset") == 0) {
|
||||
charset = params[i + 1];
|
||||
break;
|
||||
}
|
||||
error = http_parameter_list_find_item(params, "charset", &charset);
|
||||
if (error != NSERROR_OK) {
|
||||
/* No charset specified, use fallback, if any */
|
||||
/** \todo libcss will take this as gospel, which is wrong */
|
||||
charset = c->fallback_charset;
|
||||
}
|
||||
|
||||
if (parent != NULL) {
|
||||
assert(parent->type == CONTENT_HTML ||
|
||||
parent->type == CONTENT_CSS);
|
||||
|
||||
if (parent->type == CONTENT_HTML) {
|
||||
assert(parent->data.html.dict != NULL);
|
||||
|
||||
if (c == parent->data.html.
|
||||
stylesheets[STYLESHEET_BASE].c ||
|
||||
c == parent->data.html.
|
||||
stylesheets[STYLESHEET_QUIRKS].c ||
|
||||
c == parent->data.html.
|
||||
stylesheets[STYLESHEET_ADBLOCK].c)
|
||||
origin = CSS_ORIGIN_UA;
|
||||
|
||||
quirks = (parent->data.html.quirks !=
|
||||
BINDING_QUIRKS_MODE_NONE);
|
||||
|
||||
for (i = 0; i < parent->data.html.stylesheet_count;
|
||||
i++) {
|
||||
if (parent->data.html.stylesheets[i].c == c) {
|
||||
media = parent->data.html.
|
||||
stylesheets[i].media;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dict = parent->data.html.dict;
|
||||
} else {
|
||||
assert(parent->data.css.sheet != NULL);
|
||||
assert(parent->data.css.dict != NULL);
|
||||
|
||||
error = css_stylesheet_get_origin(
|
||||
parent->data.css.sheet, &origin);
|
||||
if (error != CSS_OK) {
|
||||
msg_data.error = "?";
|
||||
content_broadcast(c, CONTENT_MSG_ERROR,
|
||||
msg_data);
|
||||
return false;
|
||||
}
|
||||
|
||||
error = css_stylesheet_quirks_allowed(
|
||||
parent->data.css.sheet, &quirks);
|
||||
if (error != CSS_OK) {
|
||||
msg_data.error = "?";
|
||||
content_broadcast(c, CONTENT_MSG_ERROR,
|
||||
msg_data);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < parent->data.css.import_count; i++) {
|
||||
if (parent->data.css.imports[i].c == c) {
|
||||
media = parent->data.css.
|
||||
imports[i].media;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dict = parent->data.css.dict;
|
||||
}
|
||||
}
|
||||
|
||||
if (dict == NULL) {
|
||||
lwc_error lerror = lwc_create_context(myrealloc, NULL, &dict);
|
||||
|
||||
if (lerror != lwc_error_ok) {
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
c->data.css.dict = lwc_context_ref(dict);
|
||||
c->data.css.import_count = 0;
|
||||
c->data.css.imports = NULL;
|
||||
|
||||
error = css_stylesheet_create(CSS_LEVEL_21, charset,
|
||||
c->url, NULL, origin, media, quirks, false,
|
||||
c->data.css.dict,
|
||||
myrealloc, NULL,
|
||||
nscss_resolve_url, NULL,
|
||||
&c->data.css.sheet);
|
||||
if (error != CSS_OK) {
|
||||
lwc_context_unref(c->data.css.dict);
|
||||
c->data.css.dict = NULL;
|
||||
if (nscss_create_css_data(&c->data.css, content__get_url(c),
|
||||
charset, c->quirks) != NSERROR_OK) {
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
return false;
|
||||
@ -170,6 +80,35 @@ bool nscss_create(struct content *c, struct content *parent,
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a struct content_css_data, creating a stylesheet object
|
||||
*
|
||||
* \param c Struct to populate
|
||||
* \param url URL of stylesheet
|
||||
* \param charset Stylesheet charset
|
||||
* \param quirks Stylesheet quirks mode
|
||||
* \return NSERROR_OK on success, NSERROR_NOMEM on memory exhaustion
|
||||
*/
|
||||
nserror nscss_create_css_data(struct content_css_data *c,
|
||||
const char *url, const char *charset, bool quirks)
|
||||
{
|
||||
css_error error;
|
||||
|
||||
c->import_count = 0;
|
||||
c->imports = NULL;
|
||||
|
||||
error = css_stylesheet_create(CSS_LEVEL_21, charset,
|
||||
url, NULL, quirks, false,
|
||||
myrealloc, NULL,
|
||||
nscss_resolve_url, NULL,
|
||||
&c->sheet);
|
||||
if (error != CSS_OK) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process CSS source data
|
||||
*
|
||||
@ -183,9 +122,7 @@ bool nscss_process_data(struct content *c, char *data, unsigned int size)
|
||||
union content_msg_data msg_data;
|
||||
css_error error;
|
||||
|
||||
error = css_stylesheet_append_data(c->data.css.sheet,
|
||||
(const uint8_t *) data, size);
|
||||
|
||||
error = nscss_process_css_data(&c->data.css, data, size);
|
||||
if (error != CSS_OK && error != CSS_NEEDDATA) {
|
||||
msg_data.error = "?";
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
@ -194,6 +131,21 @@ bool nscss_process_data(struct content *c, char *data, unsigned int size)
|
||||
return (error == CSS_OK || error == CSS_NEEDDATA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process CSS data
|
||||
*
|
||||
* \param c CSS content object
|
||||
* \param data Data to process
|
||||
* \param size Number of bytes to process
|
||||
* \return CSS_OK on success, appropriate error otherwise
|
||||
*/
|
||||
css_error nscss_process_css_data(struct content_css_data *c, char *data,
|
||||
unsigned int size)
|
||||
{
|
||||
return css_stylesheet_append_data(c->sheet,
|
||||
(const uint8_t *) data, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CSS content ready for use
|
||||
*
|
||||
@ -209,90 +161,7 @@ bool nscss_convert(struct content *c, int w, int h)
|
||||
size_t size;
|
||||
css_error error;
|
||||
|
||||
error = css_stylesheet_data_done(c->data.css.sheet);
|
||||
|
||||
/* Process pending imports */
|
||||
while (error == CSS_IMPORTS_PENDING) {
|
||||
struct nscss_import *imports;
|
||||
lwc_string *uri;
|
||||
uint64_t media;
|
||||
css_stylesheet *sheet;
|
||||
|
||||
error = css_stylesheet_next_pending_import(c->data.css.sheet,
|
||||
&uri, &media);
|
||||
if (error != CSS_OK && error != CSS_INVALID) {
|
||||
msg_data.error = "?";
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
c->status = CONTENT_STATUS_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Give up if there are no more imports */
|
||||
if (error == CSS_INVALID) {
|
||||
error = CSS_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Increase space in table */
|
||||
imports = realloc(c->data.css.imports,
|
||||
(c->data.css.import_count + 1) *
|
||||
sizeof(struct nscss_import));
|
||||
if (imports == NULL) {
|
||||
msg_data.error = "?";
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
c->status = CONTENT_STATUS_ERROR;
|
||||
return false;
|
||||
}
|
||||
c->data.css.imports = imports;
|
||||
|
||||
/* Create content */
|
||||
i = c->data.css.import_count;
|
||||
c->data.css.imports[c->data.css.import_count].media = media;
|
||||
c->data.css.imports[c->data.css.import_count++].c =
|
||||
fetchcache(lwc_string_data(uri),
|
||||
nscss_import, (intptr_t) c, i,
|
||||
c->width, c->height, true, NULL, NULL,
|
||||
false, false);
|
||||
if (c->data.css.imports[i].c == NULL) {
|
||||
msg_data.error = "?";
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
c->status = CONTENT_STATUS_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Fetch content */
|
||||
c->active++;
|
||||
fetchcache_go(c->data.css.imports[i].c, c->url,
|
||||
nscss_import, (intptr_t) c, i,
|
||||
c->width, c->height, NULL, NULL, false, c);
|
||||
|
||||
/* Wait for import to fetch + convert */
|
||||
while (c->active > 0) {
|
||||
fetch_poll();
|
||||
gui_multitask();
|
||||
}
|
||||
|
||||
if (c->data.css.imports[i].c != NULL) {
|
||||
sheet = c->data.css.imports[i].c->data.css.sheet;
|
||||
c->data.css.imports[i].c->data.css.sheet = NULL;
|
||||
} else {
|
||||
error = css_stylesheet_create(CSS_LEVEL_DEFAULT,
|
||||
NULL, "", NULL, CSS_ORIGIN_AUTHOR,
|
||||
media, false, false, c->data.css.dict,
|
||||
myrealloc, NULL,
|
||||
nscss_resolve_url, NULL,
|
||||
&sheet);
|
||||
if (error != CSS_OK) {
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
content_broadcast(c, CONTENT_MSG_ERROR,
|
||||
msg_data);
|
||||
c->status = CONTENT_STATUS_ERROR;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
error = css_stylesheet_register_import(
|
||||
c->data.css.sheet, sheet);
|
||||
error = nscss_convert_css_data(&c->data.css, w, h);
|
||||
if (error != CSS_OK) {
|
||||
msg_data.error = "?";
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
@ -300,9 +169,6 @@ bool nscss_convert(struct content *c, int w, int h)
|
||||
return false;
|
||||
}
|
||||
|
||||
error = CSS_IMPORTS_PENDING;
|
||||
}
|
||||
|
||||
/* Retrieve the size of this sheet */
|
||||
error = css_stylesheet_size(c->data.css.sheet, &size);
|
||||
if (error != CSS_OK) {
|
||||
@ -313,115 +179,223 @@ bool nscss_convert(struct content *c, int w, int h)
|
||||
}
|
||||
c->size += size;
|
||||
|
||||
/* Add on the size of the imported sheets, removing ourselves from
|
||||
* their user list as we go (they're of no use to us now, as we've
|
||||
* inserted the sheet into ourselves) */
|
||||
/* Add on the size of the imported sheets */
|
||||
for (i = 0; i < c->data.css.import_count; i++) {
|
||||
if (c->data.css.imports[i].c != NULL) {
|
||||
c->size += c->data.css.imports[i].c->size;
|
||||
struct content *import = hlcache_handle_get_content(
|
||||
c->data.css.imports[i].c);
|
||||
|
||||
content_remove_user(c->data.css.imports[i].c,
|
||||
nscss_import, (uintptr_t) c, i);
|
||||
if (import != NULL) {
|
||||
c->size += import->size;
|
||||
}
|
||||
|
||||
c->data.css.imports[i].c = NULL;
|
||||
}
|
||||
|
||||
/* Remove the imports */
|
||||
c->data.css.import_count = 0;
|
||||
free(c->data.css.imports);
|
||||
c->data.css.imports = NULL;
|
||||
|
||||
c->status = CONTENT_STATUS_DONE;
|
||||
|
||||
/* Filthy hack to stop this content being reused
|
||||
* when whatever is using it has finished with it. */
|
||||
c->fresh = false;
|
||||
|
||||
return error == CSS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert CSS data ready for use
|
||||
*
|
||||
* \param c CSS data to convert
|
||||
* \param w Width of area content will be displayed in
|
||||
* \param h Height of area content will be displayed in
|
||||
* \return CSS error
|
||||
*/
|
||||
css_error nscss_convert_css_data(struct content_css_data *c, int w, int h)
|
||||
{
|
||||
const char *referer;
|
||||
uint32_t i = 0;
|
||||
css_error error;
|
||||
nserror nerror;
|
||||
|
||||
error = css_stylesheet_get_url(c->sheet, &referer);
|
||||
if (error != CSS_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = css_stylesheet_data_done(c->sheet);
|
||||
|
||||
/* Process pending imports */
|
||||
while (error == CSS_IMPORTS_PENDING) {
|
||||
hlcache_child_context child;
|
||||
struct nscss_import *imports;
|
||||
lwc_string *uri;
|
||||
uint64_t media;
|
||||
css_stylesheet *sheet;
|
||||
|
||||
error = css_stylesheet_next_pending_import(c->sheet,
|
||||
&uri, &media);
|
||||
if (error != CSS_OK && error != CSS_INVALID) {
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Give up if there are no more imports */
|
||||
if (error == CSS_INVALID) {
|
||||
error = CSS_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Increase space in table */
|
||||
imports = realloc(c->imports, (c->import_count + 1) *
|
||||
sizeof(struct nscss_import));
|
||||
if (imports == NULL) {
|
||||
return CSS_NOMEM;
|
||||
}
|
||||
c->imports = imports;
|
||||
|
||||
/** \todo fallback charset */
|
||||
child.charset = NULL;
|
||||
error = css_stylesheet_quirks_allowed(c->sheet, &child.quirks);
|
||||
if (error != CSS_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Create content */
|
||||
i = c->import_count;
|
||||
c->imports[c->import_count].media = media;
|
||||
nerror = hlcache_handle_retrieve(lwc_string_data(uri),
|
||||
0, referer, NULL, w, h, nscss_import, c,
|
||||
&child, &c->imports[c->import_count++].c);
|
||||
if (error != NSERROR_OK) {
|
||||
return CSS_NOMEM;
|
||||
}
|
||||
|
||||
/* Wait for import to fetch + convert */
|
||||
/** \todo This blocking approach needs to die */
|
||||
while (c->imports[i].c != NULL &&
|
||||
content_get_status(c->imports[i].c) !=
|
||||
CONTENT_STATUS_DONE) {
|
||||
fetch_poll();
|
||||
gui_multitask();
|
||||
}
|
||||
|
||||
if (c->imports[i].c != NULL) {
|
||||
struct content *s = hlcache_handle_get_content(
|
||||
c->imports[i].c);
|
||||
sheet = s->data.css.sheet;
|
||||
} else {
|
||||
error = css_stylesheet_create(CSS_LEVEL_DEFAULT,
|
||||
NULL, "", NULL, false, false,
|
||||
myrealloc, NULL,
|
||||
nscss_resolve_url, NULL,
|
||||
&sheet);
|
||||
if (error != CSS_OK) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
error = css_stylesheet_register_import(c->sheet, sheet);
|
||||
if (error != CSS_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = CSS_IMPORTS_PENDING;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up a CSS content
|
||||
*
|
||||
* \param c Content to clean up
|
||||
*/
|
||||
void nscss_destroy(struct content *c)
|
||||
{
|
||||
nscss_destroy_css_data(&c->data.css);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up CSS data
|
||||
*
|
||||
* \param c CSS data to clean up
|
||||
*/
|
||||
void nscss_destroy_css_data(struct content_css_data *c)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < c->data.css.import_count; i++) {
|
||||
if (c->data.css.imports[i].c != NULL) {
|
||||
content_remove_user(c->data.css.imports[i].c,
|
||||
nscss_import, (uintptr_t) c, i);
|
||||
for (i = 0; i < c->import_count; i++) {
|
||||
if (c->imports[i].c != NULL) {
|
||||
hlcache_handle_release(c->imports[i].c);
|
||||
}
|
||||
c->data.css.imports[i].c = NULL;
|
||||
c->imports[i].c = NULL;
|
||||
}
|
||||
|
||||
free(c->data.css.imports);
|
||||
free(c->imports);
|
||||
|
||||
if (c->data.css.sheet != NULL) {
|
||||
css_stylesheet_destroy(c->data.css.sheet);
|
||||
c->data.css.sheet = NULL;
|
||||
}
|
||||
|
||||
if (c->data.css.dict != NULL) {
|
||||
lwc_context_unref(c->data.css.dict);
|
||||
c->data.css.dict = NULL;
|
||||
if (c->sheet != NULL) {
|
||||
css_stylesheet_destroy(c->sheet);
|
||||
c->sheet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetchcache handler for imported stylesheets
|
||||
* Retrieve imported stylesheets
|
||||
*
|
||||
* \param msg Message type
|
||||
* \param c Content being fetched
|
||||
* \param p1 Parent content
|
||||
* \param p2 Index into parent's imported stylesheet array
|
||||
* \param data Message data
|
||||
* \param h Stylesheet containing imports
|
||||
* \param n Pointer to location to receive number of imports
|
||||
* \return Pointer to array of imported stylesheets
|
||||
*/
|
||||
void nscss_import(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data)
|
||||
struct nscss_import *nscss_get_imports(hlcache_handle *h, uint32_t *n)
|
||||
{
|
||||
struct content *parent = (struct content *) p1;
|
||||
uint32_t i = (uint32_t) p2;
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
|
||||
switch (msg) {
|
||||
case CONTENT_MSG_LOADING:
|
||||
if (c->type != CONTENT_CSS) {
|
||||
content_remove_user(c, nscss_import, p1, p2);
|
||||
if (c->user_list->next == NULL) {
|
||||
fetch_abort(c->fetch);
|
||||
c->fetch = NULL;
|
||||
c->status = CONTENT_STATUS_ERROR;
|
||||
assert(c != NULL);
|
||||
assert(c->type == CONTENT_CSS);
|
||||
assert(n != NULL);
|
||||
|
||||
*n = c->data.css.import_count;
|
||||
|
||||
return c->data.css.imports;
|
||||
}
|
||||
|
||||
parent->data.css.imports[i].c = NULL;
|
||||
parent->active--;
|
||||
content_add_error(parent, "NotCSS", 0);
|
||||
/**
|
||||
* Handler for imported stylesheet events
|
||||
*
|
||||
* \param handle Handle for stylesheet
|
||||
* \param event Event object
|
||||
* \param pw Callback context
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*/
|
||||
nserror nscss_import(hlcache_handle *handle,
|
||||
const hlcache_event *event, void *pw)
|
||||
{
|
||||
struct content_css_data *parent = pw;
|
||||
uint32_t i = 0;
|
||||
|
||||
switch (event->type) {
|
||||
case CONTENT_MSG_LOADING:
|
||||
if (content_get_type(handle) != CONTENT_CSS) {
|
||||
hlcache_handle_release(handle);
|
||||
|
||||
for (i = 0; i < parent->import_count; i++) {
|
||||
if (parent->imports[i].c == handle) {
|
||||
parent->imports[i].c = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CONTENT_MSG_READY:
|
||||
break;
|
||||
case CONTENT_MSG_DONE:
|
||||
parent->active--;
|
||||
break;
|
||||
case CONTENT_MSG_AUTH:
|
||||
case CONTENT_MSG_SSL:
|
||||
case CONTENT_MSG_LAUNCH:
|
||||
case CONTENT_MSG_ERROR:
|
||||
if (parent->data.css.imports[i].c == c) {
|
||||
parent->data.css.imports[i].c = NULL;
|
||||
parent->active--;
|
||||
hlcache_handle_release(handle);
|
||||
for (i = 0; i < parent->import_count; i++) {
|
||||
if (parent->imports[i].c == handle) {
|
||||
parent->imports[i].c = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CONTENT_MSG_STATUS:
|
||||
break;
|
||||
case CONTENT_MSG_NEWPTR:
|
||||
parent->data.css.imports[i].c = c;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
20
css/css.h
20
css/css.h
@ -23,7 +23,11 @@
|
||||
|
||||
#include <libcss/libcss.h>
|
||||
|
||||
#include "utils/errors.h"
|
||||
|
||||
struct content;
|
||||
struct hlcache_handle;
|
||||
struct http_parameter;
|
||||
struct nscss_import;
|
||||
|
||||
/**
|
||||
@ -31,8 +35,6 @@ struct nscss_import;
|
||||
*/
|
||||
struct content_css_data
|
||||
{
|
||||
lwc_context *dict; /**< Dictionary to intern strings in */
|
||||
|
||||
css_stylesheet *sheet; /**< Stylesheet object */
|
||||
|
||||
uint32_t import_count; /**< Number of sheets imported */
|
||||
@ -43,12 +45,11 @@ struct content_css_data
|
||||
* Imported stylesheet record
|
||||
*/
|
||||
struct nscss_import {
|
||||
struct content *c; /**< Content containing sheet */
|
||||
struct hlcache_handle *c; /**< Content containing sheet */
|
||||
uint64_t media; /**< Media types that sheet applies to */
|
||||
};
|
||||
|
||||
bool nscss_create(struct content *c, struct content *parent,
|
||||
const char *params[]);
|
||||
bool nscss_create(struct content *c, const struct http_parameter *params);
|
||||
|
||||
bool nscss_process_data(struct content *c, char *data, unsigned int size);
|
||||
|
||||
@ -56,5 +57,14 @@ bool nscss_convert(struct content *c, int w, int h);
|
||||
|
||||
void nscss_destroy(struct content *c);
|
||||
|
||||
nserror nscss_create_css_data(struct content_css_data *c,
|
||||
const char *url, const char *charset, bool quirks);
|
||||
css_error nscss_process_css_data(struct content_css_data *c, char *data,
|
||||
unsigned int size);
|
||||
css_error nscss_convert_css_data(struct content_css_data *c, int w, int h);
|
||||
void nscss_destroy_css_data(struct content_css_data *c);
|
||||
|
||||
struct nscss_import *nscss_get_imports(struct hlcache_handle *h, uint32_t *n);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
* URL resolution callback for libcss
|
||||
*
|
||||
* \param pw Resolution context
|
||||
* \param ctx Dictionary to intern result in
|
||||
* \param base Base URI
|
||||
* \param rel Relative URL
|
||||
* \param abs Pointer to location to receive resolved URL
|
||||
@ -34,8 +33,8 @@
|
||||
* CSS_NOMEM on memory exhaustion,
|
||||
* CSS_INVALID if resolution failed.
|
||||
*/
|
||||
css_error nscss_resolve_url(void *pw, lwc_context *ctx,
|
||||
const char *base, lwc_string *rel, lwc_string **abs)
|
||||
css_error nscss_resolve_url(void *pw, const char *base,
|
||||
lwc_string *rel, lwc_string **abs)
|
||||
{
|
||||
lwc_error lerror;
|
||||
char *abs_url, *norm_url;
|
||||
@ -57,7 +56,7 @@ css_error nscss_resolve_url(void *pw, lwc_context *ctx,
|
||||
free(abs_url);
|
||||
|
||||
/* Intern it */
|
||||
lerror = lwc_context_intern(ctx, norm_url, strlen(norm_url), abs);
|
||||
lerror = lwc_intern_string(norm_url, strlen(norm_url), abs);
|
||||
if (lerror != lwc_error_ok) {
|
||||
*abs = NULL;
|
||||
free(norm_url);
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include "css/css.h"
|
||||
|
||||
css_error nscss_resolve_url(void *pw, lwc_context *ctx,
|
||||
const char *base, lwc_string *rel, lwc_string **abs);
|
||||
css_error nscss_resolve_url(void *pw, const char *base,
|
||||
lwc_string *rel, lwc_string **abs);
|
||||
|
||||
#endif
|
||||
|
41
css/select.c
41
css/select.c
@ -21,7 +21,7 @@
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "content/urldb.h"
|
||||
#include "css/internal.h"
|
||||
#include "css/select.h"
|
||||
@ -31,12 +31,10 @@
|
||||
#include "utils/url.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
static css_error node_name(void *pw, void *node,
|
||||
lwc_context *dict, lwc_string **name);
|
||||
static css_error node_name(void *pw, void *node, lwc_string **name);
|
||||
static css_error node_classes(void *pw, void *node,
|
||||
lwc_context *dict, lwc_string ***classes, uint32_t *n_classes);
|
||||
static css_error node_id(void *pw, void *node,
|
||||
lwc_context *dict, lwc_string **id);
|
||||
lwc_string ***classes, uint32_t *n_classes);
|
||||
static css_error node_id(void *pw, void *node, lwc_string **id);
|
||||
static css_error named_ancestor_node(void *pw, void *node,
|
||||
lwc_string *name, void **ancestor);
|
||||
static css_error named_parent_node(void *pw, void *node,
|
||||
@ -125,21 +123,20 @@ static css_select_handler selection_handler = {
|
||||
* \param charset Charset of data, or NULL if unknown
|
||||
* \param url URL of document containing data
|
||||
* \param allow_quirks True to permit CSS parsing quirks
|
||||
* \param dict String internment context
|
||||
* \param alloc Memory allocation function
|
||||
* \param pw Private word for allocator
|
||||
* \return Pointer to stylesheet, or NULL on failure.
|
||||
*/
|
||||
css_stylesheet *nscss_create_inline_style(const uint8_t *data, size_t len,
|
||||
const char *charset, const char *url, bool allow_quirks,
|
||||
lwc_context *dict, css_allocator_fn alloc, void *pw)
|
||||
css_allocator_fn alloc, void *pw)
|
||||
{
|
||||
css_stylesheet *sheet;
|
||||
css_error error;
|
||||
|
||||
error = css_stylesheet_create(CSS_LEVEL_DEFAULT, charset, url, NULL,
|
||||
CSS_ORIGIN_AUTHOR, CSS_MEDIA_ALL, allow_quirks, true,
|
||||
dict, alloc, pw, nscss_resolve_url, NULL, &sheet);
|
||||
allow_quirks, true, alloc, pw, nscss_resolve_url,
|
||||
NULL, &sheet);
|
||||
if (error != CSS_OK) {
|
||||
LOG(("Failed creating sheet: %d", error));
|
||||
return NULL;
|
||||
@ -413,18 +410,16 @@ bool nscss_parse_colour(const char *data, css_color *result)
|
||||
*
|
||||
* \param pw HTML document
|
||||
* \param node DOM node
|
||||
* \param dict Dictionary to intern result in
|
||||
* \param name Pointer to location to receive node name
|
||||
* \return CSS_OK on success,
|
||||
* CSS_NOMEM on memory exhaustion.
|
||||
*/
|
||||
css_error node_name(void *pw, void *node,
|
||||
lwc_context *dict, lwc_string **name)
|
||||
css_error node_name(void *pw, void *node, lwc_string **name)
|
||||
{
|
||||
xmlNode *n = node;
|
||||
lwc_error lerror;
|
||||
|
||||
lerror = lwc_context_intern(dict, (const char *) n->name,
|
||||
lerror = lwc_intern_string((const char *) n->name,
|
||||
strlen((const char *) n->name), name);
|
||||
switch (lerror) {
|
||||
case lwc_error_oom:
|
||||
@ -444,7 +439,6 @@ css_error node_name(void *pw, void *node,
|
||||
*
|
||||
* \param pw HTML document
|
||||
* \param node DOM node
|
||||
* \param dict Dictionary to intern result in
|
||||
* \param classes Pointer to location to receive class name array
|
||||
* \param n_classes Pointer to location to receive length of class name array
|
||||
* \return CSS_OK on success,
|
||||
@ -455,7 +449,7 @@ css_error node_name(void *pw, void *node,
|
||||
* selection.
|
||||
*/
|
||||
css_error node_classes(void *pw, void *node,
|
||||
lwc_context *dict, lwc_string ***classes, uint32_t *n_classes)
|
||||
lwc_string ***classes, uint32_t *n_classes)
|
||||
{
|
||||
xmlNode *n = node;
|
||||
xmlAttr *class;
|
||||
@ -503,8 +497,7 @@ css_error node_classes(void *pw, void *node,
|
||||
}
|
||||
result = temp;
|
||||
|
||||
lerror = lwc_context_intern(dict, start, p - start,
|
||||
&result[items]);
|
||||
lerror = lwc_intern_string(start, p - start, &result[items]);
|
||||
switch (lerror) {
|
||||
case lwc_error_oom:
|
||||
error = CSS_NOMEM;
|
||||
@ -536,7 +529,7 @@ cleanup:
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < items; i++)
|
||||
lwc_context_string_unref(dict, result[i]);
|
||||
lwc_string_unref(result[i]);
|
||||
|
||||
free(result);
|
||||
}
|
||||
@ -553,13 +546,11 @@ cleanup:
|
||||
*
|
||||
* \param pw HTML document
|
||||
* \param node DOM node
|
||||
* \param dict Dictionary to intern result in
|
||||
* \param id Pointer to location to receive id value
|
||||
* \return CSS_OK on success,
|
||||
* CSS_NOMEM on memory exhaustion.
|
||||
*/
|
||||
css_error node_id(void *pw, void *node,
|
||||
lwc_context *dict, lwc_string **id)
|
||||
css_error node_id(void *pw, void *node, lwc_string **id)
|
||||
{
|
||||
xmlNode *n = node;
|
||||
xmlAttr *attr;
|
||||
@ -590,7 +581,7 @@ css_error node_id(void *pw, void *node,
|
||||
}
|
||||
|
||||
/* Intern value */
|
||||
lerror = lwc_context_intern(dict, start, strlen(start), id);
|
||||
lerror = lwc_intern_string(start, strlen(start), id);
|
||||
switch (lerror) {
|
||||
case lwc_error_oom:
|
||||
error = CSS_NOMEM;
|
||||
@ -1285,9 +1276,7 @@ css_error node_presentational_hint(void *pw, void *node,
|
||||
lwc_string *iurl;
|
||||
lwc_error lerror;
|
||||
|
||||
lerror = lwc_context_intern(
|
||||
html->data.html.dict, url,
|
||||
strlen(url), &iurl);
|
||||
lerror = lwc_intern_string(url, strlen(url), &iurl);
|
||||
|
||||
free(url);
|
||||
|
||||
|
@ -29,7 +29,7 @@ struct content;
|
||||
|
||||
css_stylesheet *nscss_create_inline_style(const uint8_t *data, size_t len,
|
||||
const char *charset, const char *url, bool allow_quirks,
|
||||
lwc_context *dict, css_allocator_fn alloc, void *pw);
|
||||
css_allocator_fn alloc, void *pw);
|
||||
|
||||
css_computed_style *nscss_get_style(struct content *html, xmlNode *n,
|
||||
uint32_t pseudo_element, uint64_t media,
|
||||
|
@ -21,10 +21,10 @@
|
||||
|
||||
#include "utils/config.h"
|
||||
|
||||
#include "content/content.h"
|
||||
#include "desktop/browser.h"
|
||||
struct hlcache_handle;
|
||||
struct browser_window;
|
||||
|
||||
void gui_401login_open(struct browser_window *bw, struct content *c,
|
||||
void gui_401login_open(struct browser_window *bw, struct hlcache_handle *c,
|
||||
const char *realm);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -31,10 +31,9 @@
|
||||
#include "render/html.h"
|
||||
|
||||
struct box;
|
||||
struct content;
|
||||
struct hlcache_handle;
|
||||
struct form;
|
||||
struct form_control;
|
||||
struct form_successful_control;
|
||||
struct gui_window;
|
||||
struct history;
|
||||
struct selection;
|
||||
@ -55,9 +54,9 @@ typedef void (*browser_move_callback)(struct browser_window *bw,
|
||||
/** Browser window data. */
|
||||
struct browser_window {
|
||||
/** Page currently displayed, or 0. Must have status READY or DONE. */
|
||||
struct content *current_content;
|
||||
struct hlcache_handle *current_content;
|
||||
/** Page being loaded, or 0. */
|
||||
struct content *loading_content;
|
||||
struct hlcache_handle *loading_content;
|
||||
|
||||
/** Window history structure. */
|
||||
struct history *history;
|
||||
@ -109,9 +108,6 @@ struct browser_window {
|
||||
/** Scroll capturing all mouse events */
|
||||
struct scroll *scroll;
|
||||
|
||||
/** Referrer for current fetch, or 0. */
|
||||
char *referer;
|
||||
|
||||
/** Current fetch is download */
|
||||
bool download;
|
||||
|
||||
@ -238,7 +234,7 @@ void browser_window_go(struct browser_window *bw, const char *url,
|
||||
const char *referrer, bool history_add);
|
||||
void browser_window_go_unverifiable(struct browser_window *bw,
|
||||
const char *url, const char *referrer, bool history_add,
|
||||
struct content *parent);
|
||||
struct hlcache_handle *parent);
|
||||
void browser_window_download(struct browser_window *bw,
|
||||
const char *url, const char *referrer);
|
||||
void browser_window_update(struct browser_window *bw, bool scroll_to_top);
|
||||
@ -264,9 +260,10 @@ bool browser_window_paste_text(struct browser_window *bw, const char *utf8,
|
||||
unsigned utf8_len, bool last);
|
||||
void browser_window_form_select(struct browser_window *bw,
|
||||
struct form_control *control, int item);
|
||||
void browser_redraw_box(struct content *c, struct box *box);
|
||||
void browser_form_submit(struct browser_window *bw, struct browser_window *target,
|
||||
struct form *form, struct form_control *submit_button);
|
||||
void browser_redraw_box(struct hlcache_handle *c, struct box *box);
|
||||
void browser_form_submit(struct browser_window *bw,
|
||||
struct browser_window *target, struct form *form,
|
||||
struct form_control *submit_button);
|
||||
|
||||
void browser_scroll_callback(void *client_data,
|
||||
struct scroll_msg_data *scroll_data);
|
||||
@ -282,7 +279,7 @@ bool browser_window_reload_available(struct browser_window *bw);
|
||||
bool browser_window_stop_available(struct browser_window *bw);
|
||||
|
||||
/* In platform specific hotlist.c. */
|
||||
void hotlist_visited(struct content *content);
|
||||
void hotlist_visited(struct hlcache_handle *content);
|
||||
|
||||
/* In platform specific global_history.c. */
|
||||
void global_history_add(const char *url);
|
||||
@ -290,7 +287,7 @@ void global_history_add_recent(const char *url);
|
||||
char **global_history_get_recent(int *count);
|
||||
|
||||
/* In platform specific thumbnail.c. */
|
||||
bool thumbnail_create(struct content *content, struct bitmap *bitmap,
|
||||
bool thumbnail_create(struct hlcache_handle *content, struct bitmap *bitmap,
|
||||
const char *url);
|
||||
|
||||
/* In platform specific schedule.c. */
|
||||
@ -300,7 +297,7 @@ bool schedule_run(void);
|
||||
|
||||
/* In platform specific theme_install.c. */
|
||||
#ifdef WITH_THEME_INSTALL
|
||||
void theme_install_start(struct content *c);
|
||||
void theme_install_start(struct hlcache_handle *c);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include "utils/config.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/frames.h"
|
||||
#include "desktop/history_core.h"
|
||||
@ -105,8 +106,8 @@ void browser_window_create_iframes(struct browser_window *bw,
|
||||
window = &(bw->iframes[index++]);
|
||||
if (cur->url)
|
||||
browser_window_go_unverifiable(window, cur->url,
|
||||
bw->current_content->url, false,
|
||||
bw->current_content);
|
||||
content_get_url(bw->current_content),
|
||||
false, bw->current_content);
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,7 +156,7 @@ void browser_window_create_frameset(struct browser_window *bw,
|
||||
int row, col, index;
|
||||
struct content_html_frames *frame;
|
||||
struct browser_window *window;
|
||||
struct content *parent;
|
||||
hlcache_handle *parent;
|
||||
|
||||
assert(bw && frameset);
|
||||
|
||||
@ -231,7 +232,8 @@ void browser_window_create_frameset(struct browser_window *bw,
|
||||
* as the referer */
|
||||
for (window = bw; window->parent; window = window->parent) {
|
||||
if (window->current_content &&
|
||||
window->current_content->type == CONTENT_HTML)
|
||||
content_get_type(window->current_content) ==
|
||||
CONTENT_HTML)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -247,8 +249,7 @@ void browser_window_create_frameset(struct browser_window *bw,
|
||||
if (frame->url) {
|
||||
browser_window_go_unverifiable(window,
|
||||
frame->url,
|
||||
parent != NULL
|
||||
? parent->url : NULL,
|
||||
content_get_url(parent),
|
||||
true,
|
||||
parent);
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ typedef enum {
|
||||
GUI_SAVE_CLIPBOARD_CONTENTS
|
||||
} gui_save_type;
|
||||
|
||||
struct fetch;
|
||||
struct gui_window;
|
||||
struct gui_download_window;
|
||||
|
||||
@ -55,6 +56,7 @@ typedef enum { GUI_POINTER_DEFAULT, GUI_POINTER_POINT, GUI_POINTER_CARET,
|
||||
#include <stdbool.h>
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/search.h"
|
||||
|
||||
@ -89,8 +91,8 @@ void gui_window_hide_pointer(struct gui_window *g);
|
||||
void gui_window_set_url(struct gui_window *g, const char *url);
|
||||
void gui_window_start_throbber(struct gui_window *g);
|
||||
void gui_window_stop_throbber(struct gui_window *g);
|
||||
void gui_window_set_icon(struct gui_window *g, struct content *icon);
|
||||
void gui_window_set_search_ico(struct content *ico);
|
||||
void gui_window_set_icon(struct gui_window *g, hlcache_handle *icon);
|
||||
void gui_window_set_search_ico(hlcache_handle *ico);
|
||||
void gui_window_place_caret(struct gui_window *g, int x, int y, int height);
|
||||
void gui_window_remove_caret(struct gui_window *g);
|
||||
void gui_window_new_content(struct gui_window *g);
|
||||
@ -98,7 +100,8 @@ bool gui_window_scroll_start(struct gui_window *g);
|
||||
bool gui_window_box_scroll_start(struct gui_window *g,
|
||||
int x0, int y0, int x1, int y1);
|
||||
bool gui_window_frame_resize_start(struct gui_window *g);
|
||||
void gui_window_save_as_link(struct gui_window *g, struct content *c);
|
||||
void gui_window_save_link(struct gui_window *g, const char *url,
|
||||
const char *title);
|
||||
void gui_window_set_scale(struct gui_window *g, float scale);
|
||||
|
||||
struct gui_download_window *gui_download_window_create(const char *url,
|
||||
@ -110,7 +113,7 @@ void gui_download_window_error(struct gui_download_window *dw,
|
||||
const char *error_msg);
|
||||
void gui_download_window_done(struct gui_download_window *dw);
|
||||
|
||||
void gui_drag_save_object(gui_save_type type, struct content *c,
|
||||
void gui_drag_save_object(gui_save_type type, hlcache_handle *c,
|
||||
struct gui_window *g);
|
||||
void gui_drag_save_selection(struct selection *s, struct gui_window *g);
|
||||
void gui_start_selection(struct gui_window *g);
|
||||
@ -133,7 +136,7 @@ bool gui_search_term_highlighted(struct gui_window *g,
|
||||
|
||||
struct ssl_cert_info;
|
||||
|
||||
void gui_cert_verify(struct browser_window *bw, struct content *c,
|
||||
void gui_cert_verify(struct browser_window *bw, hlcache_handle *c,
|
||||
const struct ssl_cert_info *certs, unsigned long num);
|
||||
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "content/urldb.h"
|
||||
#include "css/css.h"
|
||||
#include "desktop/gui.h"
|
||||
@ -220,7 +221,7 @@ struct history_entry *history_clone_entry(struct history *history,
|
||||
* The page is added after the current entry and becomes current.
|
||||
*/
|
||||
|
||||
void history_add(struct history *history, struct content *content,
|
||||
void history_add(struct history *history, hlcache_handle *content,
|
||||
char *frag_id)
|
||||
{
|
||||
url_func_result res;
|
||||
@ -237,14 +238,14 @@ void history_add(struct history *history, struct content *content,
|
||||
if (entry == NULL)
|
||||
return;
|
||||
|
||||
res = url_normalize(content->url, &url);
|
||||
res = url_normalize(content_get_url(content), &url);
|
||||
if (res != URL_FUNC_OK) {
|
||||
warn_user("NoMemory", 0);
|
||||
free(entry);
|
||||
return;
|
||||
}
|
||||
|
||||
title = strdup(content->title ? content->title : url);
|
||||
title = strdup(content_get_title(content));
|
||||
if (title == NULL) {
|
||||
warn_user("NoMemory", 0);
|
||||
free(url);
|
||||
@ -303,11 +304,9 @@ void history_add(struct history *history, struct content *content,
|
||||
* \param content content for current entry
|
||||
*/
|
||||
|
||||
void history_update(struct history *history, struct content *content)
|
||||
void history_update(struct history *history, hlcache_handle *content)
|
||||
{
|
||||
char *title;
|
||||
char *url;
|
||||
url_func_result res;
|
||||
|
||||
if (!history || !history->current || !history->current->bitmap)
|
||||
return;
|
||||
@ -315,20 +314,11 @@ void history_update(struct history *history, struct content *content)
|
||||
assert(history->current->page.url);
|
||||
assert(history->current->page.title);
|
||||
|
||||
if (content->title) {
|
||||
title = strdup(content->title);
|
||||
title = strdup(content_get_title(content));
|
||||
if (!title) {
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
res = url_normalize(content->url, &url);
|
||||
if (res != URL_FUNC_OK) {
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
title = url;
|
||||
}
|
||||
|
||||
assert(title);
|
||||
free(history->current->page.title);
|
||||
|
@ -25,15 +25,15 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct content;
|
||||
struct hlcache_handle;
|
||||
struct history;
|
||||
struct browser_window;
|
||||
|
||||
struct history *history_create(void);
|
||||
struct history *history_clone(struct history *history);
|
||||
void history_add(struct history *history, struct content *content,
|
||||
void history_add(struct history *history, struct hlcache_handle *content,
|
||||
char *frag_id);
|
||||
void history_update(struct history *history, struct content *content);
|
||||
void history_update(struct history *history, struct hlcache_handle *content);
|
||||
void history_destroy(struct history *history);
|
||||
void history_back(struct browser_window *bw, struct history *history);
|
||||
void history_forward(struct browser_window *bw, struct history *history);
|
||||
|
@ -28,10 +28,13 @@
|
||||
#include <libxml/globals.h>
|
||||
#include <libxml/xmlversion.h>
|
||||
|
||||
#include <libwapcaplet/libwapcaplet.h>
|
||||
|
||||
#include "utils/config.h"
|
||||
#include "utils/utsname.h"
|
||||
#include "content/fetch.h"
|
||||
#include "content/fetchcache.h"
|
||||
#include "content/llcache.h"
|
||||
#include "content/urldb.h"
|
||||
#include "desktop/netsurf.h"
|
||||
#include "desktop/browser.h"
|
||||
@ -44,39 +47,11 @@
|
||||
bool netsurf_quit = false;
|
||||
bool verbose_log = false;
|
||||
|
||||
static void netsurf_poll(void);
|
||||
static void lib_init(void);
|
||||
|
||||
|
||||
/**
|
||||
* Gui NetSurf main().
|
||||
*/
|
||||
|
||||
int netsurf_main(int argc, char** argv)
|
||||
static void *netsurf_lwc_alloc(void *ptr, size_t len, void *pw)
|
||||
{
|
||||
netsurf_init(argc, argv);
|
||||
|
||||
netsurf_main_loop();
|
||||
|
||||
netsurf_exit();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
return realloc(ptr, len);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gui NetSurf main loop.
|
||||
*/
|
||||
|
||||
int netsurf_main_loop(void)
|
||||
{
|
||||
while (!netsurf_quit)
|
||||
netsurf_poll();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise components used by gui NetSurf.
|
||||
*/
|
||||
@ -126,35 +101,30 @@ void netsurf_init(int argc, char** argv)
|
||||
utsname.nodename, utsname.release,
|
||||
utsname.version, utsname.machine));
|
||||
|
||||
lib_init();
|
||||
lwc_initialise(netsurf_lwc_alloc, NULL, 0);
|
||||
url_init();
|
||||
gui_init(argc, argv);
|
||||
setlocale(LC_ALL, "C");
|
||||
fetch_init();
|
||||
fetchcache_init();
|
||||
/** \todo The frontend needs to provide the llcache_query_handler */
|
||||
llcache_initialise(NULL, NULL);
|
||||
gui_init2(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Poll components which require it.
|
||||
* Gui NetSurf main loop.
|
||||
*/
|
||||
|
||||
void netsurf_poll(void)
|
||||
int netsurf_main_loop(void)
|
||||
{
|
||||
static unsigned int last_clean = 0;
|
||||
unsigned int current_time = wallclock();
|
||||
|
||||
/* avoid calling content_clean() more often than once every 5
|
||||
* seconds.
|
||||
*/
|
||||
if (last_clean + 500 < current_time) {
|
||||
last_clean = current_time;
|
||||
content_clean();
|
||||
}
|
||||
while (!netsurf_quit) {
|
||||
gui_poll(fetch_active);
|
||||
fetch_poll();
|
||||
llcache_poll();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up components used by gui NetSurf.
|
||||
@ -164,8 +134,6 @@ void netsurf_exit(void)
|
||||
{
|
||||
LOG(("Closing GUI"));
|
||||
gui_quit();
|
||||
LOG(("Closing content"));
|
||||
content_quit();
|
||||
LOG(("Closing fetches"));
|
||||
fetch_quit();
|
||||
LOG(("Closing utf8"));
|
||||
@ -176,18 +144,3 @@ void netsurf_exit(void)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialises the libraries used in NetSurf.
|
||||
*/
|
||||
void lib_init(void)
|
||||
{
|
||||
LOG(("xmlParserVersion %s, LIBXML_VERSION_STRING %s",
|
||||
xmlParserVersion, LIBXML_VERSION_STRING));
|
||||
|
||||
/* Using encoding "X-SJIS" (unknown to libxmp2/iconv) instead as
|
||||
* "Shift-JIS" is rather popular.
|
||||
*/
|
||||
if (xmlAddEncodingAlias(xmlGetCharEncodingName(
|
||||
XML_CHAR_ENCODING_SHIFT_JIS), "X-SJIS") != 0)
|
||||
die("Failed to add encoding alias");
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ extern const int netsurf_version_minor;
|
||||
|
||||
extern void netsurf_init(int argc, char** argv);
|
||||
extern void netsurf_exit(void);
|
||||
extern int netsurf_main(int argc, char** argv);
|
||||
extern int netsurf_main_loop(void);
|
||||
|
||||
#endif
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "css/utils.h"
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/print.h"
|
||||
@ -39,11 +40,11 @@
|
||||
#define DEFAULT_PAGE_HEIGHT 840
|
||||
#define DEFAULT_COPIES 1
|
||||
|
||||
static struct content *print_init(struct content *, struct print_settings *);
|
||||
static bool print_apply_settings(struct content *, struct print_settings *);
|
||||
static hlcache_handle *print_init(hlcache_handle *, struct print_settings *);
|
||||
static bool print_apply_settings(hlcache_handle *, struct print_settings *);
|
||||
|
||||
static float page_content_width, page_content_height;
|
||||
static struct content *printed_content;
|
||||
static hlcache_handle *printed_content;
|
||||
static float done_height;
|
||||
|
||||
bool html_redraw_printing = false;
|
||||
@ -59,7 +60,7 @@ int html_redraw_printing_top_cropped = 0;
|
||||
* \param settings The settings for printing to use
|
||||
* \return true if successful, false otherwise
|
||||
*/
|
||||
bool print_basic_run(struct content *content,
|
||||
bool print_basic_run(hlcache_handle *content,
|
||||
const struct printer *printer,
|
||||
struct print_settings *settings)
|
||||
{
|
||||
@ -70,7 +71,7 @@ bool print_basic_run(struct content *content,
|
||||
if (!print_set_up(content, printer, settings, NULL))
|
||||
ret = false;
|
||||
|
||||
while (ret && (done_height < printed_content->height) )
|
||||
while (ret && (done_height < content_get_height(printed_content)) )
|
||||
ret = print_draw_next_page(printer, settings);
|
||||
|
||||
print_cleanup(content, printer, settings);
|
||||
@ -88,7 +89,7 @@ bool print_basic_run(struct content *content,
|
||||
* \param height updated to the height of the printed content
|
||||
* \return true if successful, false otherwise
|
||||
*/
|
||||
bool print_set_up(struct content *content,
|
||||
bool print_set_up(hlcache_handle *content,
|
||||
const struct printer *printer, struct print_settings *settings,
|
||||
double *height)
|
||||
{
|
||||
@ -100,7 +101,7 @@ bool print_set_up(struct content *content,
|
||||
print_apply_settings(printed_content, settings);
|
||||
|
||||
if (height)
|
||||
*height = printed_content->height;
|
||||
*height = content_get_height(printed_content);
|
||||
|
||||
printer->print_begin(settings);
|
||||
|
||||
@ -158,11 +159,13 @@ bool print_draw_next_page(const struct printer *printer,
|
||||
* \param settings The settings for printing to use
|
||||
* \return true if successful, false otherwise
|
||||
*/
|
||||
struct content *print_init(struct content *content,
|
||||
hlcache_handle *print_init(hlcache_handle *content,
|
||||
struct print_settings *settings)
|
||||
{
|
||||
struct content* printed_content;
|
||||
struct content_user *user_sentinel;
|
||||
// newcache
|
||||
#if 0
|
||||
hlcache_handle* printed_content;
|
||||
hlcache_handle_user *user_sentinel;
|
||||
|
||||
content_add_user(content, NULL, (intptr_t) print_init, 0);
|
||||
|
||||
@ -173,7 +176,7 @@ struct content *print_init(struct content *content,
|
||||
|
||||
printed_content->data.html.bw = 0;
|
||||
|
||||
user_sentinel = talloc(printed_content, struct content_user);
|
||||
user_sentinel = talloc(printed_content, hlcache_handle_user);
|
||||
user_sentinel->callback = 0;
|
||||
user_sentinel->p1 = user_sentinel->p2 = 0;
|
||||
user_sentinel->next = 0;
|
||||
@ -194,6 +197,9 @@ struct content *print_init(struct content *content,
|
||||
printed_content->data.html.font_func = settings->font_func;
|
||||
|
||||
return printed_content;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,7 +209,7 @@ struct content *print_init(struct content *content,
|
||||
* \param settings The settings for printing to use
|
||||
* \return true if successful, false otherwise
|
||||
*/
|
||||
bool print_apply_settings(struct content *content,
|
||||
bool print_apply_settings(hlcache_handle *content,
|
||||
struct print_settings *settings)
|
||||
{
|
||||
if (settings == NULL)
|
||||
@ -222,7 +228,8 @@ bool print_apply_settings(struct content *content,
|
||||
content_reformat(content, page_content_width, 0);
|
||||
|
||||
LOG(("New layout applied.New height = %d ; New width = %d ",
|
||||
content->height, content->width));
|
||||
content_get_height(content),
|
||||
content_get_width(content)));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -234,7 +241,7 @@ bool print_apply_settings(struct content *content,
|
||||
* \param printer The printer interface for the printer to be used
|
||||
* \return true if successful, false otherwise
|
||||
*/
|
||||
bool print_cleanup(struct content *content, const struct printer *printer,
|
||||
bool print_cleanup(hlcache_handle *content, const struct printer *printer,
|
||||
struct print_settings *settings)
|
||||
{
|
||||
printer->print_end();
|
||||
@ -242,12 +249,11 @@ bool print_cleanup(struct content *content, const struct printer *printer,
|
||||
html_redraw_printing = false;
|
||||
|
||||
if (printed_content) {
|
||||
content_remove_user(printed_content, NULL,
|
||||
(intptr_t) print_init, 0);
|
||||
content_remove_user(printed_content, NULL, print_init);
|
||||
talloc_free(printed_content);
|
||||
}
|
||||
|
||||
content_remove_user(content, NULL, (intptr_t)print_init, 0);
|
||||
content_remove_user(content, NULL, print_init);
|
||||
|
||||
free((void *)settings->output);
|
||||
free(settings);
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
#include "css/css.h"
|
||||
|
||||
struct content;
|
||||
struct hlcache_handle;
|
||||
struct printer;
|
||||
|
||||
enum { MARGINLEFT = 0, MARGINRIGHT = 1, MARGINTOP = 2, MARGINBOTTOM = 3};
|
||||
@ -64,13 +64,13 @@ struct print_settings{
|
||||
};
|
||||
|
||||
|
||||
bool print_basic_run(struct content *, const struct printer *,
|
||||
bool print_basic_run(struct hlcache_handle *, const struct printer *,
|
||||
struct print_settings *);
|
||||
bool print_set_up(struct content *content, const struct printer *printer,
|
||||
bool print_set_up(struct hlcache_handle *content, const struct printer *printer,
|
||||
struct print_settings *settings, double *height);
|
||||
bool print_draw_next_page(const struct printer *printer,
|
||||
struct print_settings *settings);
|
||||
bool print_cleanup(struct content *, const struct printer *,
|
||||
bool print_cleanup(struct hlcache_handle *, const struct printer *,
|
||||
struct print_settings *settings);
|
||||
|
||||
struct print_settings *print_make_settings(print_configuration configuration,
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <libxml/parserInternals.h>
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "css/css.h"
|
||||
#include "render/box.h"
|
||||
#include "desktop/save_complete.h"
|
||||
@ -46,14 +47,14 @@ regex_t save_complete_import_re;
|
||||
|
||||
/** An entry in save_complete_list. */
|
||||
struct save_complete_entry {
|
||||
struct content *content;
|
||||
hlcache_handle *content;
|
||||
struct save_complete_entry *next; /**< Next entry in list */
|
||||
};
|
||||
|
||||
static bool save_complete_html(struct content *c, const char *path,
|
||||
static bool save_complete_html(hlcache_handle *c, const char *path,
|
||||
bool index, struct save_complete_entry **list);
|
||||
static bool save_imported_sheets(struct content *c, const char *path,
|
||||
struct save_complete_entry **list);
|
||||
static bool save_imported_sheets(struct nscss_import *imports, uint32_t count,
|
||||
const char *path, struct save_complete_entry **list);
|
||||
static char * rewrite_stylesheet_urls(const char *source, unsigned int size,
|
||||
int *osize, const char *base,
|
||||
struct save_complete_entry *list);
|
||||
@ -63,11 +64,11 @@ static bool rewrite_urls(xmlNode *n, const char *base,
|
||||
struct save_complete_entry *list);
|
||||
static bool rewrite_url(xmlNode *n, const char *attr, const char *base,
|
||||
struct save_complete_entry *list);
|
||||
static bool save_complete_list_add(struct content *content,
|
||||
static bool save_complete_list_add(hlcache_handle *content,
|
||||
struct save_complete_entry **list);
|
||||
static struct content * save_complete_list_find(const char *url,
|
||||
static hlcache_handle * save_complete_list_find(const char *url,
|
||||
struct save_complete_entry *list);
|
||||
static bool save_complete_list_check(struct content *content,
|
||||
static bool save_complete_list_check(hlcache_handle *content,
|
||||
struct save_complete_entry *list);
|
||||
/* static void save_complete_list_dump(void); */
|
||||
static bool save_complete_inventory(const char *path,
|
||||
@ -81,7 +82,7 @@ static bool save_complete_inventory(const char *path,
|
||||
* \return true on success, false on error and error reported
|
||||
*/
|
||||
|
||||
bool save_complete(struct content *c, const char *path)
|
||||
bool save_complete(hlcache_handle *c, const char *path)
|
||||
{
|
||||
bool result;
|
||||
struct save_complete_entry *list = NULL;
|
||||
@ -111,50 +112,69 @@ bool save_complete(struct content *c, const char *path)
|
||||
* \return true on success, false on error and error reported
|
||||
*/
|
||||
|
||||
bool save_complete_html(struct content *c, const char *path, bool index,
|
||||
bool save_complete_html(hlcache_handle *c, const char *path, bool index,
|
||||
struct save_complete_entry **list)
|
||||
{
|
||||
struct html_stylesheet *sheets;
|
||||
struct content_html_object *objects;
|
||||
const char *base_url;
|
||||
char filename[256];
|
||||
unsigned int i;
|
||||
unsigned int i, count;
|
||||
xmlDocPtr doc;
|
||||
bool res;
|
||||
|
||||
if (c->type != CONTENT_HTML)
|
||||
if (content_get_type(c) != CONTENT_HTML)
|
||||
return false;
|
||||
|
||||
if (save_complete_list_check(c, *list))
|
||||
return true;
|
||||
|
||||
base_url = html_get_base_url(c);
|
||||
|
||||
/* save stylesheets, ignoring the base and adblocking sheets */
|
||||
for (i = STYLESHEET_START; i != c->data.html.stylesheet_count; i++) {
|
||||
struct content *css = c->data.html.stylesheets[i].c;
|
||||
sheets = html_get_stylesheets(c, &count);
|
||||
|
||||
for (i = STYLESHEET_START; i != count; i++) {
|
||||
hlcache_handle *css;
|
||||
const char *css_data;
|
||||
unsigned long css_size;
|
||||
char *source;
|
||||
int source_len;
|
||||
bool is_style;
|
||||
struct nscss_import *imports;
|
||||
uint32_t import_count;
|
||||
|
||||
if (sheets[i].type == HTML_STYLESHEET_INTERNAL) {
|
||||
if (save_imported_sheets(
|
||||
sheets[i].data.internal->imports,
|
||||
sheets[i].data.internal->import_count,
|
||||
path, list) == false)
|
||||
return false;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
css = sheets[i].data.external;
|
||||
|
||||
if (!css)
|
||||
continue;
|
||||
if (save_complete_list_check(css, *list))
|
||||
continue;
|
||||
|
||||
is_style = (strcmp(css->url, c->data.html.base_url) == 0);
|
||||
|
||||
if (is_style == false) {
|
||||
if (!save_complete_list_add(css, list)) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!save_imported_sheets(css, path, list))
|
||||
imports = nscss_get_imports(css, &import_count);
|
||||
if (!save_imported_sheets(imports, import_count, path, list))
|
||||
return false;
|
||||
|
||||
if (is_style)
|
||||
continue; /* don't save <style> elements */
|
||||
|
||||
snprintf(filename, sizeof filename, "%p", css);
|
||||
source = rewrite_stylesheet_urls(css->source_data,
|
||||
css->source_size, &source_len, css->url,
|
||||
|
||||
css_data = content_get_source_data(css, &css_size);
|
||||
|
||||
source = rewrite_stylesheet_urls(css_data, css_size,
|
||||
&source_len, content_get_url(css),
|
||||
*list);
|
||||
if (!source) {
|
||||
warn_user("NoMemory", 0);
|
||||
@ -168,12 +188,21 @@ bool save_complete_html(struct content *c, const char *path, bool index,
|
||||
}
|
||||
|
||||
/* save objects */
|
||||
for (i = 0; i != c->data.html.object_count; i++) {
|
||||
struct content *obj = c->data.html.object[i].content;
|
||||
objects = html_get_objects(c, &count);
|
||||
|
||||
/* skip difficult content types */
|
||||
if (!obj || obj->type >= CONTENT_OTHER || !obj->source_data)
|
||||
for (i = 0; i != count; i++) {
|
||||
hlcache_handle *obj = objects[i].content;
|
||||
const char *obj_data;
|
||||
unsigned long obj_size;
|
||||
|
||||
if (obj == NULL || content_get_type(obj) >= CONTENT_OTHER)
|
||||
continue;
|
||||
|
||||
obj_data = content_get_source_data(obj, &obj_size);
|
||||
|
||||
if (obj_data == NULL)
|
||||
continue;
|
||||
|
||||
if (save_complete_list_check(obj, *list))
|
||||
continue;
|
||||
|
||||
@ -182,7 +211,7 @@ bool save_complete_html(struct content *c, const char *path, bool index,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj->type == CONTENT_HTML) {
|
||||
if (content_get_type(obj) == CONTENT_HTML) {
|
||||
if (!save_complete_html(obj, path, false, list))
|
||||
return false;
|
||||
continue;
|
||||
@ -190,7 +219,7 @@ bool save_complete_html(struct content *c, const char *path, bool index,
|
||||
|
||||
snprintf(filename, sizeof filename, "%p", obj);
|
||||
res = save_complete_gui_save(path, filename,
|
||||
obj->source_size, obj->source_data, obj->type);
|
||||
obj_size, obj_data, content_get_type(obj));
|
||||
if(res == false)
|
||||
return false;
|
||||
}
|
||||
@ -198,14 +227,14 @@ bool save_complete_html(struct content *c, const char *path, bool index,
|
||||
/*save_complete_list_dump();*/
|
||||
|
||||
/* copy document */
|
||||
doc = xmlCopyDoc(c->data.html.document, 1);
|
||||
doc = xmlCopyDoc(html_get_document(c), 1);
|
||||
if (doc == NULL) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* rewrite all urls we know about */
|
||||
if (!rewrite_document_urls(doc, c->data.html.base_url, *list)) {
|
||||
if (!rewrite_document_urls(doc, html_get_base_url(c), *list)) {
|
||||
xmlFreeDoc(doc);
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
@ -237,13 +266,13 @@ bool save_complete_html(struct content *c, const char *path, bool index,
|
||||
/**
|
||||
* Save stylesheets imported by a CONTENT_CSS.
|
||||
*
|
||||
* \param c a CONTENT_CSS
|
||||
* \param path path to save to
|
||||
* \param imports Array of imports
|
||||
* \param count Number of imports in list
|
||||
* \param path Path to save to
|
||||
* \return true on success, false on error and error reported
|
||||
*/
|
||||
|
||||
bool save_imported_sheets(struct content *c, const char *path,
|
||||
struct save_complete_entry **list)
|
||||
bool save_imported_sheets(struct nscss_import *imports, uint32_t count,
|
||||
const char *path, struct save_complete_entry **list)
|
||||
{
|
||||
char filename[256];
|
||||
unsigned int j;
|
||||
@ -251,10 +280,14 @@ bool save_imported_sheets(struct content *c, const char *path,
|
||||
int source_len;
|
||||
bool res;
|
||||
|
||||
for (j = 0; j != c->data.css.import_count; j++) {
|
||||
struct content *css = c->data.css.imports[j].c;
|
||||
for (j = 0; j != count; j++) {
|
||||
hlcache_handle *css = imports[j].c;
|
||||
const char *css_data;
|
||||
unsigned long css_size;
|
||||
struct nscss_import *child_imports;
|
||||
uint32_t child_import_count;
|
||||
|
||||
if (!css)
|
||||
if (css == NULL)
|
||||
continue;
|
||||
if (save_complete_list_check(css, *list))
|
||||
continue;
|
||||
@ -264,12 +297,17 @@ bool save_imported_sheets(struct content *c, const char *path,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!save_imported_sheets(css, path, list))
|
||||
child_imports = nscss_get_imports(css, &child_import_count);
|
||||
if (!save_imported_sheets(child_imports, child_import_count,
|
||||
path, list))
|
||||
return false;
|
||||
|
||||
snprintf(filename, sizeof filename, "%p", css);
|
||||
source = rewrite_stylesheet_urls(css->source_data,
|
||||
css->source_size, &source_len, css->url,
|
||||
|
||||
css_data = content_get_source_data(css, &css_size);
|
||||
|
||||
source = rewrite_stylesheet_urls(css_data, css_size,
|
||||
&source_len, content_get_url(css),
|
||||
*list);
|
||||
if (!source) {
|
||||
warn_user("NoMemory", 0);
|
||||
@ -344,7 +382,7 @@ char * rewrite_stylesheet_urls(const char *source, unsigned int size,
|
||||
char buf[20];
|
||||
unsigned int offset = 0;
|
||||
int url_len = 0;
|
||||
struct content *content;
|
||||
hlcache_handle *content;
|
||||
int m;
|
||||
unsigned int i;
|
||||
unsigned int imports = 0;
|
||||
@ -609,7 +647,7 @@ bool rewrite_url(xmlNode *n, const char *attr, const char *base,
|
||||
{
|
||||
char *url, *data;
|
||||
char rel[20];
|
||||
struct content *content;
|
||||
hlcache_handle *content;
|
||||
url_func_result res;
|
||||
|
||||
if (!xmlHasProp(n, (const xmlChar *) attr))
|
||||
@ -654,7 +692,7 @@ bool rewrite_url(xmlNode *n, const char *attr, const char *base,
|
||||
* \return true on success, false on out of memory
|
||||
*/
|
||||
|
||||
bool save_complete_list_add(struct content *content,
|
||||
bool save_complete_list_add(hlcache_handle *content,
|
||||
struct save_complete_entry **list)
|
||||
{
|
||||
struct save_complete_entry *entry;
|
||||
@ -675,12 +713,12 @@ bool save_complete_list_add(struct content *content,
|
||||
* \return content if found, 0 otherwise
|
||||
*/
|
||||
|
||||
struct content * save_complete_list_find(const char *url,
|
||||
hlcache_handle * save_complete_list_find(const char *url,
|
||||
struct save_complete_entry *list)
|
||||
{
|
||||
struct save_complete_entry *entry;
|
||||
for (entry = list; entry; entry = entry->next)
|
||||
if (strcmp(url, entry->content->url) == 0)
|
||||
if (strcmp(url, content_get_url(entry->content)) == 0)
|
||||
return entry->content;
|
||||
return 0;
|
||||
}
|
||||
@ -693,7 +731,7 @@ struct content * save_complete_list_find(const char *url,
|
||||
* \return true if the content is in the save_complete_list
|
||||
*/
|
||||
|
||||
bool save_complete_list_check(struct content *content,
|
||||
bool save_complete_list_check(hlcache_handle *content,
|
||||
struct save_complete_entry *list)
|
||||
{
|
||||
struct save_complete_entry *entry;
|
||||
@ -746,8 +784,10 @@ bool save_complete_inventory(const char *path,
|
||||
return false;
|
||||
}
|
||||
|
||||
for (entry = list; entry; entry = entry->next)
|
||||
fprintf(fp, "%p %s\n", entry->content, entry->content->url);
|
||||
for (entry = list; entry; entry = entry->next) {
|
||||
fprintf(fp, "%p %s\n", entry->content,
|
||||
content_get_url(entry->content));
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
|
@ -28,10 +28,10 @@
|
||||
#include <libxml/HTMLtree.h>
|
||||
#include "content/content.h"
|
||||
|
||||
struct content;
|
||||
struct hlcache_handle;
|
||||
|
||||
void save_complete_init(void);
|
||||
bool save_complete(struct content *c, const char *path);
|
||||
bool save_complete(struct hlcache_handle *c, const char *path);
|
||||
|
||||
bool save_complete_gui_save(const char *path, const char *filename,
|
||||
size_t len, const char *sourcedata, content_type type);
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include <hpdf.h>
|
||||
|
||||
#include "content/hlcache.h"
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/plotters.h"
|
||||
#include "desktop/print.h"
|
||||
@ -410,21 +411,26 @@ bool pdf_plot_bitmap_tile(int x, int y, int width, int height,
|
||||
HPDF_Image pdf_extract_image(struct bitmap *bitmap)
|
||||
{
|
||||
HPDF_Image image = NULL;
|
||||
struct content *content = NULL;
|
||||
hlcache_handle *content = NULL;
|
||||
|
||||
/* TODO - get content from bitmap pointer */
|
||||
|
||||
if (content) {
|
||||
const char *source_data;
|
||||
unsigned long source_size;
|
||||
|
||||
/*Not sure if I don't have to check if downloading has been
|
||||
finished.
|
||||
Other way - lock pdf plotting while fetching a website
|
||||
*/
|
||||
switch(content->type){
|
||||
source_data = content_get_source_data(content, &source_size);
|
||||
|
||||
switch(content_get_type(content)){
|
||||
/*Handle "embeddable" types of images*/
|
||||
case CONTENT_JPEG:
|
||||
image = HPDF_LoadJpegImageFromMem(pdf_doc,
|
||||
(const HPDF_BYTE *)content->source_data,
|
||||
content->source_size);
|
||||
(const HPDF_BYTE *) source_data,
|
||||
source_size);
|
||||
break;
|
||||
|
||||
/*Disabled until HARU PNG support will be more stable.
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "desktop/save_text.h"
|
||||
#include "render/box.h"
|
||||
#include "utils/log.h"
|
||||
@ -48,7 +49,7 @@ static bool save_text_add_to_buffer(const char *text, size_t length,
|
||||
* \param path Path to save text file too.
|
||||
*/
|
||||
|
||||
void save_as_text(struct content *c, char *path)
|
||||
void save_as_text(hlcache_handle *c, char *path)
|
||||
{
|
||||
FILE *out;
|
||||
struct save_text_state save = { NULL, 0, 0 };
|
||||
@ -57,11 +58,11 @@ void save_as_text(struct content *c, char *path)
|
||||
utf8_convert_ret ret;
|
||||
char *result;
|
||||
|
||||
if (!c || c->type != CONTENT_HTML) {
|
||||
if (!c || content_get_type(c) != CONTENT_HTML) {
|
||||
return;
|
||||
}
|
||||
|
||||
extract_text(c->data.html.layout, &first, &before, &save);
|
||||
extract_text(html_get_box_tree(c), &first, &before, &save);
|
||||
if (!save.block)
|
||||
return;
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#define _NETSURF_DESKTOP_SAVE_TEXT_H_
|
||||
|
||||
struct box;
|
||||
struct content;
|
||||
struct hlcache_handle;
|
||||
|
||||
/* text currently being saved */
|
||||
struct save_text_state {
|
||||
@ -41,7 +41,7 @@ typedef enum {
|
||||
WHITESPACE_TWO_NEW_LINES
|
||||
} save_text_whitespace;
|
||||
|
||||
void save_as_text(struct content *c, char *path);
|
||||
void save_as_text(struct hlcache_handle *c, char *path);
|
||||
void save_text_solve_whitespace(struct box *box, bool *first,
|
||||
save_text_whitespace *before, const char **whitespace_text,
|
||||
size_t *whitespace_length);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/gui.h"
|
||||
#include "desktop/options.h"
|
||||
@ -33,6 +34,7 @@
|
||||
#include "desktop/selection.h"
|
||||
#include "render/box.h"
|
||||
#include "render/html.h"
|
||||
#include "render/textplain.h"
|
||||
#include "utils/config.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
@ -60,7 +62,7 @@ struct list_entry {
|
||||
|
||||
struct search_context {
|
||||
struct browser_window *bw;
|
||||
struct content *content;
|
||||
hlcache_handle *content;
|
||||
char *string;
|
||||
bool prev_case_sens;
|
||||
bool newsearch;
|
||||
@ -80,7 +82,7 @@ static bool find_occurrences_html(const char *pattern, int p_len,
|
||||
struct box *cur, bool case_sens,
|
||||
struct search_context *context);
|
||||
static bool find_occurrences_text(const char *pattern, int p_len,
|
||||
struct content *c, bool case_sens,
|
||||
hlcache_handle *c, bool case_sens,
|
||||
struct search_context *context);
|
||||
static struct list_entry *add_entry(unsigned start_idx, unsigned end_idx,
|
||||
struct search_context *context);
|
||||
@ -236,7 +238,7 @@ void search_text(const char *string, int string_len,
|
||||
struct search_context *context, search_flags_t flags)
|
||||
{
|
||||
struct rect bounds;
|
||||
struct content *c;
|
||||
hlcache_handle *c;
|
||||
struct box *box;
|
||||
bool case_sensitive, forwards, showall;
|
||||
|
||||
@ -250,11 +252,11 @@ void search_text(const char *string, int string_len,
|
||||
c = context->bw->current_content;
|
||||
|
||||
/* only handle html contents */
|
||||
if ((!c) || (c->type != CONTENT_HTML &&
|
||||
c->type != CONTENT_TEXTPLAIN))
|
||||
if ((!c) || (content_get_type(c) != CONTENT_HTML &&
|
||||
content_get_type(c) != CONTENT_TEXTPLAIN))
|
||||
return;
|
||||
|
||||
box = c->data.html.layout;
|
||||
box = html_get_box_tree(c);
|
||||
|
||||
if (!box)
|
||||
return;
|
||||
@ -282,11 +284,11 @@ void search_text(const char *string, int string_len,
|
||||
(context->callbacks->hourglass != NULL))
|
||||
context->callbacks->hourglass(true, context->p);
|
||||
|
||||
if (c->type == CONTENT_HTML)
|
||||
if (content_get_type(c) == CONTENT_HTML)
|
||||
res = find_occurrences_html(string, string_len,
|
||||
box, case_sensitive, context);
|
||||
else {
|
||||
assert(c->type == CONTENT_TEXTPLAIN);
|
||||
assert(content_get_type(c) == CONTENT_TEXTPLAIN);
|
||||
res = find_occurrences_text(string, string_len,
|
||||
c, case_sensitive, context);
|
||||
}
|
||||
@ -342,7 +344,7 @@ void search_text(const char *string, int string_len,
|
||||
if (context->current == NULL)
|
||||
return;
|
||||
|
||||
switch (c->type) {
|
||||
switch (content_get_type(c)) {
|
||||
case CONTENT_HTML:
|
||||
/* get box position and jump to it */
|
||||
box_coords(context->current->start_box,
|
||||
@ -356,7 +358,7 @@ void search_text(const char *string, int string_len,
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(c->type == CONTENT_TEXTPLAIN);
|
||||
assert(content_get_type(c) == CONTENT_TEXTPLAIN);
|
||||
textplain_coords_from_range(c,
|
||||
context->current->start_idx,
|
||||
context->current->end_idx, &bounds);
|
||||
@ -551,7 +553,7 @@ bool find_occurrences_html(const char *pattern, int p_len, struct box *cur,
|
||||
*/
|
||||
|
||||
bool find_occurrences_text(const char *pattern, int p_len,
|
||||
struct content *c, bool case_sens,
|
||||
hlcache_handle *c, bool case_sens,
|
||||
struct search_context *context)
|
||||
{
|
||||
int nlines = textplain_line_count(c);
|
||||
@ -642,15 +644,15 @@ void search_show_all(bool all, struct search_context *context)
|
||||
if (add && !a->sel) {
|
||||
a->sel = selection_create(context->bw);
|
||||
if (a->sel) {
|
||||
struct content *c = context->bw->
|
||||
hlcache_handle *c = context->bw->
|
||||
current_content;
|
||||
switch (c->type) {
|
||||
switch (content_get_type(c)) {
|
||||
case CONTENT_HTML:
|
||||
selection_init(a->sel,
|
||||
c->data.html.layout);
|
||||
html_get_box_tree(c));
|
||||
break;
|
||||
default:
|
||||
assert(c->type ==
|
||||
assert(content_get_type(c) ==
|
||||
CONTENT_TEXTPLAIN);
|
||||
selection_init(a->sel, NULL);
|
||||
break;
|
||||
|
@ -24,8 +24,7 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "content/content.h"
|
||||
#include "content/fetchcache.h"
|
||||
#include "content/fetch.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/gui.h"
|
||||
#include "desktop/options.h"
|
||||
@ -43,10 +42,13 @@ static struct search_provider {
|
||||
char *ico; /** < location of domain's favicon */
|
||||
} current_search_provider;
|
||||
|
||||
static struct content *search_ico = NULL;
|
||||
static hlcache_handle *search_ico = NULL;
|
||||
char *search_engines_file_location;
|
||||
char *search_default_ico_location;
|
||||
|
||||
static nserror search_web_ico_callback(hlcache_handle *ico,
|
||||
const hlcache_event *event, void *pw);
|
||||
|
||||
/**
|
||||
* creates a new browser window according to the search term
|
||||
* \param searchterm such as "my search term"
|
||||
@ -205,7 +207,8 @@ char *search_web_get_url(const char *encsearchterm)
|
||||
void search_web_retrieve_ico(bool localdefault)
|
||||
{
|
||||
char *url;
|
||||
struct content *icocontent;
|
||||
nserror error;
|
||||
|
||||
if (localdefault) {
|
||||
if (search_default_ico_location == NULL)
|
||||
return;
|
||||
@ -221,26 +224,17 @@ void search_web_retrieve_ico(bool localdefault)
|
||||
url = search_web_ico_name();
|
||||
}
|
||||
|
||||
icocontent = NULL;
|
||||
if (url == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return;
|
||||
}
|
||||
icocontent = fetchcache(url, search_web_ico_callback,
|
||||
0, 0, 20, 20, true, 0,
|
||||
0, false, false);
|
||||
|
||||
error = hlcache_handle_retrieve(url, 0, NULL, NULL, 20, 20,
|
||||
search_web_ico_callback, NULL, NULL, &search_ico);
|
||||
if (error != NSERROR_OK)
|
||||
search_ico = NULL;
|
||||
|
||||
free(url);
|
||||
if (icocontent == NULL)
|
||||
return;
|
||||
|
||||
fetchcache_go(icocontent, 0, search_web_ico_callback,
|
||||
0, 0, 20, 20,
|
||||
0, 0, false, 0);
|
||||
|
||||
if (icocontent == NULL)
|
||||
LOG(("web search ico loading delayed"));
|
||||
else
|
||||
search_ico = icocontent;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -249,7 +243,7 @@ void search_web_retrieve_ico(bool localdefault)
|
||||
* responsibility
|
||||
*/
|
||||
|
||||
struct content *search_web_ico(void)
|
||||
hlcache_handle *search_web_ico(void)
|
||||
{
|
||||
return search_ico;
|
||||
}
|
||||
@ -259,20 +253,18 @@ struct content *search_web_ico(void)
|
||||
* else retry default from local file system
|
||||
*/
|
||||
|
||||
void search_web_ico_callback(content_msg msg, struct content *ico,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data)
|
||||
nserror search_web_ico_callback(hlcache_handle *ico,
|
||||
const hlcache_event *event, void *pw)
|
||||
{
|
||||
|
||||
switch (msg) {
|
||||
switch (event->type) {
|
||||
case CONTENT_MSG_LOADING:
|
||||
case CONTENT_MSG_READY:
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_DONE:
|
||||
LOG(("got favicon '%s'", ico->url));
|
||||
LOG(("got favicon '%s'", content_get_url(ico)));
|
||||
#ifdef WITH_BMP
|
||||
if (ico->type == CONTENT_ICO) {
|
||||
search_ico = ico; /* cache */
|
||||
if (content_get_type(ico) == CONTENT_ICO) {
|
||||
gui_window_set_search_ico(search_ico);
|
||||
} else
|
||||
#endif
|
||||
@ -281,20 +273,20 @@ void search_web_ico_callback(content_msg msg, struct content *ico,
|
||||
}
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_LAUNCH:
|
||||
case CONTENT_MSG_ERROR:
|
||||
LOG(("favicon %s error: %s", ico->url, data.error));
|
||||
ico = 0;
|
||||
LOG(("favicon %s error: %s",
|
||||
content_get_url(ico), event->data.error));
|
||||
hlcache_handle_release(search_ico);
|
||||
search_ico = NULL;
|
||||
search_web_retrieve_ico(true);
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_STATUS:
|
||||
case CONTENT_MSG_NEWPTR:
|
||||
case CONTENT_MSG_AUTH:
|
||||
case CONTENT_MSG_SSL:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
@ -20,9 +20,11 @@
|
||||
#define _NETSURF_DESKTOP_SEARCH_WEB_H_
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "content/content.h"
|
||||
#include "desktop/browser.h"
|
||||
|
||||
struct browser_window;
|
||||
struct hlcache_handle;
|
||||
|
||||
extern char *search_engines_file_location;
|
||||
extern char *search_default_ico_location;
|
||||
@ -71,9 +73,6 @@ bool search_is_url(const char *url);
|
||||
|
||||
void search_web_retrieve_ico(bool localdefault);
|
||||
|
||||
struct content *search_web_ico(void);
|
||||
|
||||
void search_web_ico_callback(content_msg msg, struct content *ico,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data);
|
||||
struct hlcache_handle *search_web_ico(void);
|
||||
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "content/hlcache.h"
|
||||
#include "desktop/gui.h"
|
||||
#include "desktop/plotters.h"
|
||||
#include "desktop/save_text.h"
|
||||
@ -155,8 +156,8 @@ void selection_reinit(struct selection *s, struct box *root)
|
||||
s->max_idx = selection_label_subtree(root, root_idx);
|
||||
}
|
||||
else {
|
||||
struct content *c = s->bw->current_content;
|
||||
if (c && c->type == CONTENT_TEXTPLAIN)
|
||||
hlcache_handle *c = s->bw->current_content;
|
||||
if (c && content_get_type(c) == CONTENT_TEXTPLAIN)
|
||||
s->max_idx = textplain_size(c);
|
||||
else
|
||||
s->max_idx = 0;
|
||||
@ -560,7 +561,7 @@ bool traverse_tree(struct box *box, unsigned start_idx, unsigned end_idx,
|
||||
bool selection_traverse(struct selection *s, seln_traverse_handler handler,
|
||||
void *handle)
|
||||
{
|
||||
struct content *c;
|
||||
hlcache_handle *c;
|
||||
save_text_whitespace before = WHITESPACE_NONE;
|
||||
bool first = true;
|
||||
const char *text;
|
||||
@ -664,8 +665,9 @@ void selection_redraw(struct selection *s, unsigned start_idx, unsigned end_idx)
|
||||
return;
|
||||
}
|
||||
else {
|
||||
struct content *c = s->bw->current_content;
|
||||
if (c && c->type == CONTENT_TEXTPLAIN && end_idx > start_idx) {
|
||||
hlcache_handle *c = s->bw->current_content;
|
||||
if (c && content_get_type(c) == CONTENT_TEXTPLAIN &&
|
||||
end_idx > start_idx) {
|
||||
textplain_coords_from_range(c, start_idx,
|
||||
end_idx, &rdw.r);
|
||||
rdw.inited = true;
|
||||
@ -952,7 +954,7 @@ bool save_handler(const char *text, size_t length, struct box *box,
|
||||
|
||||
bool selection_save_text(struct selection *s, const char *path)
|
||||
{
|
||||
struct content *c = s->bw->current_content;
|
||||
hlcache_handle *c = s->bw->current_content;
|
||||
struct save_text_state sv = { NULL, 0, 0 };
|
||||
utf8_convert_ret ret;
|
||||
char *result;
|
||||
|
@ -2091,11 +2091,14 @@ bool textarea_cut(struct browser_window *bw,
|
||||
void textarea_reflow(struct browser_window *bw, struct box *textarea,
|
||||
struct box *inline_container)
|
||||
{
|
||||
struct content *c = hlcache_handle_get_content(bw->current_content);
|
||||
int width = textarea->width;
|
||||
int height = textarea->height;
|
||||
|
||||
assert(c != NULL);
|
||||
|
||||
if (!layout_inline_container(inline_container, width,
|
||||
textarea, 0, 0,
|
||||
bw->current_content))
|
||||
textarea, 0, 0, c))
|
||||
warn_user("NoMemory", 0);
|
||||
textarea->width = width;
|
||||
textarea->height = height;
|
||||
|
@ -70,15 +70,6 @@ struct gui_window *window_list = NULL;
|
||||
|
||||
bool redraws_pending = false;
|
||||
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/* private data for browser user widget */
|
||||
struct browser_widget_s {
|
||||
struct browser_window *bw; /**< The browser window connected to this gui window */
|
||||
@ -102,10 +93,10 @@ fb_queue_redraw(struct fbtk_widget_s *widget, int x0, int y0, int x1, int y1)
|
||||
{
|
||||
struct browser_widget_s *bwidget = fbtk_get_userpw(widget);
|
||||
|
||||
bwidget->redraw_box.x0 = MIN(bwidget->redraw_box.x0, x0);
|
||||
bwidget->redraw_box.y0 = MIN(bwidget->redraw_box.y0, y0);
|
||||
bwidget->redraw_box.x1 = MAX(bwidget->redraw_box.x1, x1);
|
||||
bwidget->redraw_box.y1 = MAX(bwidget->redraw_box.y1, y1);
|
||||
bwidget->redraw_box.x0 = min(bwidget->redraw_box.x0, x0);
|
||||
bwidget->redraw_box.y0 = min(bwidget->redraw_box.y0, y0);
|
||||
bwidget->redraw_box.x1 = max(bwidget->redraw_box.x1, x1);
|
||||
bwidget->redraw_box.y1 = max(bwidget->redraw_box.y1, y1);
|
||||
|
||||
if (fbtk_clip_to_widget(widget, &bwidget->redraw_box)) {
|
||||
bwidget->redraw_required = true;
|
||||
@ -121,7 +112,6 @@ static void fb_pan(fbtk_widget_t *widget,
|
||||
struct browser_widget_s *bwidget,
|
||||
struct browser_window *bw)
|
||||
{
|
||||
struct content *c;
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
@ -129,13 +119,11 @@ static void fb_pan(fbtk_widget_t *widget,
|
||||
nsfb_bbox_t srcbox;
|
||||
nsfb_bbox_t dstbox;
|
||||
|
||||
c = bw->current_content;
|
||||
|
||||
if ((!c) || (c->locked))
|
||||
return;
|
||||
|
||||
nsfb_t *nsfb = fbtk_get_nsfb(widget);
|
||||
|
||||
int content_height = content_get_height(bw->current_content);
|
||||
int content_width = content_get_width(bw->current_content);
|
||||
|
||||
height = fbtk_get_height(widget);
|
||||
width = fbtk_get_width(widget);
|
||||
x = fbtk_get_x(widget);
|
||||
@ -146,16 +134,16 @@ static void fb_pan(fbtk_widget_t *widget,
|
||||
bwidget->pany = - bwidget->scrolly;
|
||||
|
||||
/* do not pan off the bottom of the content */
|
||||
if ((bwidget->scrolly + bwidget->pany) > (c->height - height))
|
||||
bwidget->pany = (c->height - height) - bwidget->scrolly;
|
||||
if ((bwidget->scrolly + bwidget->pany) > (content_height - height))
|
||||
bwidget->pany = (content_height - height) - bwidget->scrolly;
|
||||
|
||||
/* dont pan off the left */
|
||||
if ((bwidget->scrollx + bwidget->panx) < 0)
|
||||
bwidget->panx = - bwidget->scrollx;
|
||||
|
||||
/* do not pan off the right of the content */
|
||||
if ((bwidget->scrollx + bwidget->panx) > (c->width - width))
|
||||
bwidget->panx = (c->width - width) - bwidget->scrollx;
|
||||
if ((bwidget->scrollx + bwidget->panx) > (content_width - width))
|
||||
bwidget->panx = (content_width - width) - bwidget->scrollx;
|
||||
|
||||
LOG(("panning %d, %d",bwidget->panx, bwidget->pany));
|
||||
|
||||
@ -268,16 +256,11 @@ static void fb_redraw(fbtk_widget_t *widget,
|
||||
struct browser_widget_s *bwidget,
|
||||
struct browser_window *bw)
|
||||
{
|
||||
struct content *c;
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
c = bw->current_content;
|
||||
|
||||
if ((!c) || (c->locked))
|
||||
return;
|
||||
|
||||
LOG(("redraw box %d,%d to %d,%d",bwidget->redraw_box.x0,bwidget->redraw_box.y0, bwidget->redraw_box.x1, bwidget->redraw_box.y1));
|
||||
|
||||
@ -292,13 +275,11 @@ static void fb_redraw(fbtk_widget_t *widget,
|
||||
bwidget->redraw_box.x0 += x;
|
||||
bwidget->redraw_box.x1 += x;
|
||||
|
||||
|
||||
|
||||
nsfb_claim(fbtk_get_nsfb(widget), &bwidget->redraw_box);
|
||||
|
||||
/* redraw bounding box is relative to window */
|
||||
current_redraw_browser = bw;
|
||||
content_redraw(c,
|
||||
content_redraw(bw->current_content,
|
||||
x - bwidget->scrollx, y - bwidget->scrolly,
|
||||
width, height,
|
||||
bwidget->redraw_box.x0, bwidget->redraw_box.y0,
|
||||
@ -328,9 +309,9 @@ fb_browser_window_redraw(fbtk_widget_t *root, fbtk_widget_t *widget, void *pw)
|
||||
if (bwidget->pan_required) {
|
||||
int pos;
|
||||
fb_pan(widget, bwidget, gw->bw);
|
||||
pos = (bwidget->scrollx * 100) / gw->bw->current_content->width;
|
||||
pos = (bwidget->scrollx * 100) / content_get_width(gw->bw->current_content);
|
||||
fbtk_set_scroll_pos(gw->hscroll, pos);
|
||||
pos = (bwidget->scrolly * 100) / gw->bw->current_content->height;
|
||||
pos = (bwidget->scrolly * 100) / content_get_height(gw->bw->current_content);
|
||||
fbtk_set_scroll_pos(gw->vscroll, pos);
|
||||
|
||||
}
|
||||
@ -409,11 +390,23 @@ static bool process_cmdline(int argc, char** argv)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Normal entry point from OS */
|
||||
/** Entry point from OS.
|
||||
*
|
||||
* /param argc The number of arguments in the string vector.
|
||||
* /param argv The argument string vector.
|
||||
* /return The return code to the OS
|
||||
*/
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
setbuf(stderr, NULL);
|
||||
return netsurf_main(argc, argv);
|
||||
|
||||
netsurf_init(argc, argv);
|
||||
|
||||
netsurf_main_loop();
|
||||
|
||||
netsurf_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gui_init(int argc, char** argv)
|
||||
@ -1176,15 +1169,17 @@ void gui_window_get_dimensions(struct gui_window *g, int *width, int *height,
|
||||
*height = fbtk_get_height(g->browser);
|
||||
}
|
||||
|
||||
void gui_window_update_extent(struct gui_window *g)
|
||||
void gui_window_update_extent(struct gui_window *gw)
|
||||
{
|
||||
int pct;
|
||||
|
||||
pct = (fbtk_get_width(g->browser) * 100) / g->bw->current_content->width;
|
||||
fbtk_set_scroll(g->hscroll, pct);
|
||||
pct = (fbtk_get_width(gw->browser) * 100) /
|
||||
content_get_width(gw->bw->current_content);
|
||||
fbtk_set_scroll(gw->hscroll, pct);
|
||||
|
||||
pct = (fbtk_get_height(g->browser) * 100) / g->bw->current_content->height;
|
||||
fbtk_set_scroll(g->vscroll, pct);
|
||||
pct = (fbtk_get_height(gw->browser) * 100) /
|
||||
content_get_height(gw->bw->current_content);
|
||||
fbtk_set_scroll(gw->vscroll, pct);
|
||||
|
||||
}
|
||||
|
||||
@ -1328,7 +1323,8 @@ bool gui_window_frame_resize_start(struct gui_window *g)
|
||||
return true;
|
||||
}
|
||||
|
||||
void gui_window_save_as_link(struct gui_window *g, struct content *c)
|
||||
void
|
||||
gui_window_save_link(struct gui_window *g, const char *url, const char *title)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1340,7 +1336,8 @@ void gui_window_set_scale(struct gui_window *g, float scale)
|
||||
/**
|
||||
* set favicon
|
||||
*/
|
||||
void gui_window_set_icon(struct gui_window *g, struct content *icon)
|
||||
void
|
||||
gui_window_set_icon(struct gui_window *g, hlcache_handle *icon)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1349,7 +1346,8 @@ void gui_window_set_icon(struct gui_window *g, struct content *icon)
|
||||
* \param ico may be NULL for local calls; then access current cache from
|
||||
* search_web_ico()
|
||||
*/
|
||||
void gui_window_set_search_ico(struct content *ico)
|
||||
void
|
||||
gui_window_set_search_ico(hlcache_handle *ico)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1374,8 +1372,8 @@ void gui_download_window_done(struct gui_download_window *dw)
|
||||
{
|
||||
}
|
||||
|
||||
void gui_drag_save_object(gui_save_type type, struct content *c,
|
||||
struct gui_window *g)
|
||||
void gui_drag_save_object(gui_save_type type, hlcache_handle *c,
|
||||
struct gui_window *w)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1420,7 +1418,7 @@ void gui_launch_url(const char *url)
|
||||
{
|
||||
}
|
||||
|
||||
void gui_cert_verify(struct browser_window *bw, struct content *c,
|
||||
void gui_cert_verify(struct browser_window *bw, struct hlcache_handle *c,
|
||||
const struct ssl_cert_info *certs, unsigned long num)
|
||||
{
|
||||
}
|
||||
|
@ -18,6 +18,6 @@
|
||||
|
||||
#include "desktop/browser.h"
|
||||
|
||||
void hotlist_visited(struct content *content)
|
||||
void hotlist_visited(struct hlcache_handle *content)
|
||||
{
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include "desktop/401login.h"
|
||||
|
||||
void gui_401login_open(struct browser_window *bw, struct content *c,
|
||||
void gui_401login_open(struct browser_window *bw, struct hlcache_handle *c,
|
||||
const char *realm)
|
||||
{
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include "desktop/browser.h"
|
||||
|
||||
bool thumbnail_create(struct content *content, struct bitmap *bitmap,
|
||||
bool thumbnail_create(struct hlcache_handle *content, struct bitmap *bitmap,
|
||||
const char *url)
|
||||
{
|
||||
return false;
|
||||
|
@ -570,7 +570,7 @@ ENTRY_CHANGED(entryHomePageURL, option_homepage_url)
|
||||
END_HANDLER
|
||||
|
||||
BUTTON_CLICKED(setCurrentPage)
|
||||
const gchar *url = current_browser->current_content->url;
|
||||
const gchar *url = content_get_url(current_browser->current_content);
|
||||
gtk_entry_set_text(GTK_ENTRY(entryHomePageURL), url);
|
||||
option_homepage_url =
|
||||
strdup(gtk_entry_get_text(GTK_ENTRY(entryHomePageURL)));
|
||||
|
@ -107,7 +107,7 @@ void nsgtk_source_dialog_init(GtkWindow *parent, struct browser_window *bw)
|
||||
{
|
||||
char glade_Location[strlen(res_dir_location) + SLEN("source.glade")
|
||||
+ 1];
|
||||
if (bw->current_content->type != CONTENT_HTML)
|
||||
if (content_get_type(bw->current_content) != CONTENT_HTML)
|
||||
return;
|
||||
|
||||
if (option_source_tab) {
|
||||
@ -121,12 +121,17 @@ void nsgtk_source_dialog_init(GtkWindow *parent, struct browser_window *bw)
|
||||
LOG(("error loading glade tree"));
|
||||
}
|
||||
|
||||
const char *source_data;
|
||||
unsigned long source_size;
|
||||
char *data = NULL;
|
||||
|
||||
source_data = content_get_source_data(bw->current_content,
|
||||
&source_size);
|
||||
|
||||
utf8_convert_ret r = utf8_from_enc(
|
||||
bw->current_content->source_data,
|
||||
bw->current_content->data.html.encoding,
|
||||
bw->current_content->source_size,
|
||||
source_data,
|
||||
html_get_encoding(bw->current_content),
|
||||
source_size,
|
||||
&data);
|
||||
if (r == UTF8_CONVERT_NOMEM) {
|
||||
warn_user("NoMemory",0);
|
||||
@ -160,7 +165,7 @@ void nsgtk_source_dialog_init(GtkWindow *parent, struct browser_window *bw)
|
||||
return;
|
||||
}
|
||||
|
||||
thiswindow->url = strdup(bw->current_content->url);
|
||||
thiswindow->url = strdup(content_get_url(bw->current_content));
|
||||
if (thiswindow->url == NULL) {
|
||||
free(thiswindow);
|
||||
free(data);
|
||||
@ -173,8 +178,8 @@ void nsgtk_source_dialog_init(GtkWindow *parent, struct browser_window *bw)
|
||||
thiswindow->sourcewindow = wndSource;
|
||||
thiswindow->bw = bw;
|
||||
|
||||
char title[strlen(bw->current_content->url) + SLEN("Source of ") + 1];
|
||||
sprintf(title, "Source of %s", bw->current_content->url);
|
||||
char title[strlen(thiswindow->url) + SLEN("Source of ") + 1];
|
||||
sprintf(title, "Source of %s", thiswindow->url);
|
||||
|
||||
thiswindow->next = nsgtk_source_list;
|
||||
thiswindow->prev = NULL;
|
||||
@ -209,11 +214,17 @@ void nsgtk_source_dialog_init(GtkWindow *parent, struct browser_window *bw)
|
||||
}
|
||||
void nsgtk_source_tab_init(GtkWindow *parent, struct browser_window *bw)
|
||||
{
|
||||
const char *source_data;
|
||||
unsigned long source_size;
|
||||
char *ndata = 0;
|
||||
|
||||
source_data = content_get_source_data(bw->current_content,
|
||||
&source_size);
|
||||
|
||||
utf8_convert_ret r = utf8_from_enc(
|
||||
bw->current_content->source_data,
|
||||
bw->current_content->data.html.encoding,
|
||||
bw->current_content->source_size,
|
||||
source_data,
|
||||
html_get_encoding(bw->current_content),
|
||||
source_size,
|
||||
&ndata);
|
||||
if (r == UTF8_CONVERT_NOMEM) {
|
||||
warn_user("NoMemory",0);
|
||||
@ -245,18 +256,9 @@ void nsgtk_source_tab_init(GtkWindow *parent, struct browser_window *bw)
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return;
|
||||
}
|
||||
struct browser_window *newbw = browser_window_create(fileurl, bw,
|
||||
NULL, false, true);
|
||||
/* Open tab */
|
||||
browser_window_create(fileurl, bw, NULL, false, true);
|
||||
free(fileurl);
|
||||
if (newbw->current_content) {
|
||||
newbw->current_content->title = malloc(
|
||||
strlen(bw->current_content->url) +
|
||||
SLEN("source of ") + 1);
|
||||
if (newbw->current_content->title == NULL)
|
||||
return;
|
||||
sprintf(newbw->current_content->title, "source of %s",
|
||||
bw->current_content->url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "content/content.h"
|
||||
#include "content/fetch.h"
|
||||
#include "content/fetchers/fetch_curl.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "content/urldb.h"
|
||||
#include "desktop/401login.h"
|
||||
#include "desktop/browser.h"
|
||||
@ -122,7 +123,14 @@ int main(int argc, char** argv)
|
||||
|
||||
setbuf(stderr, NULL);
|
||||
|
||||
return netsurf_main(argc, argv);
|
||||
/* initialise netsurf */
|
||||
netsurf_init(argc, argv);
|
||||
|
||||
netsurf_main_loop();
|
||||
|
||||
netsurf_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -599,7 +607,8 @@ void gui_create_form_select_menu(struct browser_window *bw,
|
||||
|
||||
}
|
||||
|
||||
void gui_window_save_as_link(struct gui_window *g, struct content *c)
|
||||
void gui_window_save_link(struct gui_window *g, const char *url,
|
||||
const char *title)
|
||||
{
|
||||
}
|
||||
|
||||
@ -630,12 +639,11 @@ void die(const char * const error)
|
||||
}
|
||||
|
||||
|
||||
void hotlist_visited(struct content *content)
|
||||
void hotlist_visited(hlcache_handle *content)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void gui_cert_verify(struct browser_window *bw, struct content *c,
|
||||
void gui_cert_verify(struct browser_window *bw, hlcache_handle *c,
|
||||
const struct ssl_cert_info *certs, unsigned long num)
|
||||
{
|
||||
GladeXML *x = glade_xml_new(glade_ssl_file_location, NULL, NULL);
|
||||
@ -644,7 +652,7 @@ void gui_cert_verify(struct browser_window *bw, struct content *c,
|
||||
void **session = calloc(sizeof(void *), 4);
|
||||
|
||||
session[0] = bw;
|
||||
session[1] = strdup(c->url);
|
||||
session[1] = strdup(content_get_url(c));
|
||||
session[2] = x;
|
||||
session[3] = wnd;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "utils/log.h"
|
||||
#include "gtk/gtk_gui.h"
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "content/urldb.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/401login.h"
|
||||
@ -51,16 +52,16 @@ static void nsgtk_login_next(GtkWidget *w, gpointer data);
|
||||
static void nsgtk_login_ok_clicked(GtkButton *w, gpointer data);
|
||||
static void nsgtk_login_cancel_clicked(GtkButton *w, gpointer data);
|
||||
|
||||
void gui_401login_open(struct browser_window *bw, struct content *c,
|
||||
void gui_401login_open(struct browser_window *bw, hlcache_handle *c,
|
||||
const char *realm)
|
||||
{
|
||||
char *host;
|
||||
url_func_result res;
|
||||
|
||||
res = url_host(c->url, &host);
|
||||
res = url_host(content_get_url(c), &host);
|
||||
assert(res == URL_FUNC_OK);
|
||||
|
||||
create_login_window(bw, host, realm, c->url);
|
||||
create_login_window(bw, host, realm, content_get_url(c));
|
||||
|
||||
free(host);
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/plotters.h"
|
||||
#include "desktop/print.h"
|
||||
@ -48,7 +49,7 @@
|
||||
/* Globals */
|
||||
cairo_t *gtk_print_current_cr;
|
||||
static struct print_settings* settings;
|
||||
struct content *content_to_print;
|
||||
hlcache_handle *content_to_print;
|
||||
static GdkRectangle cliprect;
|
||||
|
||||
static inline void nsgtk_print_set_colour(colour c)
|
||||
|
@ -26,9 +26,11 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
struct hlcache_handle;
|
||||
|
||||
extern cairo_t *gtk_print_current_cr;
|
||||
|
||||
extern struct content *content_to_print;
|
||||
extern struct hlcache_handle *content_to_print;
|
||||
|
||||
|
||||
/*handlers for signals from the GTK print operation*/
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <libxml/debugXML.h>
|
||||
#include "gtk/gtk_scaffolding.h"
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "css/utils.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/history_core.h"
|
||||
@ -271,8 +272,10 @@ void nsgtk_window_update_back_forward(struct gtk_scaffolding *g)
|
||||
nsgtk_scaffolding_set_sensitivity(g);
|
||||
|
||||
/* update the url bar, particularly necessary when tabbing */
|
||||
if (bw->current_content != NULL && bw->current_content->url != NULL)
|
||||
browser_window_refresh_url_bar(bw, bw->current_content->url,
|
||||
if (bw->current_content != NULL &&
|
||||
content_get_url(bw->current_content) != NULL)
|
||||
browser_window_refresh_url_bar(bw,
|
||||
content_get_url(bw->current_content),
|
||||
bw->frag_id);
|
||||
|
||||
/* update the local history window, as well as queuing a redraw
|
||||
@ -493,8 +496,8 @@ MULTIHANDLER(savepage)
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fc), filter);
|
||||
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fc), filter);
|
||||
|
||||
res = url_nice(gui_window_get_browser_window(
|
||||
g->top_level)->current_content->url, &path, false);
|
||||
res = url_nice(content_get_url(gui_window_get_browser_window(
|
||||
g->top_level)->current_content), &path, false);
|
||||
if (res != URL_FUNC_OK) {
|
||||
path = strdup(messages_get("SaveText"));
|
||||
if (path == NULL) {
|
||||
@ -549,7 +552,7 @@ MULTIHANDLER(pdf)
|
||||
|
||||
LOG(("Print preview (generating PDF) started."));
|
||||
|
||||
res = url_nice(bw->current_content->url, &url_name, true);
|
||||
res = url_nice(content_get_url(bw->current_content), &url_name, true);
|
||||
if (res != URL_FUNC_OK) {
|
||||
warn_user(messages_get(res == URL_FUNC_NOMEM ? "NoMemory"
|
||||
: "URIError"), 0);
|
||||
@ -622,8 +625,8 @@ MULTIHANDLER(plaintext)
|
||||
char *filename;
|
||||
url_func_result res;
|
||||
|
||||
res = url_nice(gui_window_get_browser_window(
|
||||
g->top_level)->current_content->url, &filename, false);
|
||||
res = url_nice(content_get_url(gui_window_get_browser_window(
|
||||
g->top_level)->current_content), &filename, false);
|
||||
if (res != URL_FUNC_OK) {
|
||||
filename = strdup(messages_get("SaveText"));
|
||||
if (filename == NULL) {
|
||||
@ -710,7 +713,7 @@ MULTIHANDLER(print)
|
||||
G_CALLBACK(gtk_print_signal_draw_page), NULL);
|
||||
g_signal_connect(print_op, "end_print",
|
||||
G_CALLBACK(gtk_print_signal_end_print), settings);
|
||||
if (bw->current_content->type != CONTENT_TEXTPLAIN)
|
||||
if (content_get_type(bw->current_content) != CONTENT_TEXTPLAIN)
|
||||
res = gtk_print_operation_run(print_op,
|
||||
GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
|
||||
g->window,
|
||||
@ -762,7 +765,7 @@ MENUHANDLER(savelink)
|
||||
return FALSE;
|
||||
|
||||
browser_window_download(bw, current_menu_link_box->href,
|
||||
bw->current_content->url);
|
||||
content_get_url(bw->current_content));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1126,10 +1129,10 @@ MULTIHANDLER(saveboxtree)
|
||||
bw = gui_window_get_browser_window(g->top_level);
|
||||
|
||||
if (bw->current_content &&
|
||||
bw->current_content->type ==
|
||||
content_get_type(bw->current_content) ==
|
||||
CONTENT_HTML) {
|
||||
box_dump(fh,
|
||||
bw->current_content->data.html.layout,
|
||||
html_get_box_tree(bw->current_content),
|
||||
0);
|
||||
}
|
||||
|
||||
@ -1175,11 +1178,10 @@ MULTIHANDLER(savedomtree)
|
||||
bw = gui_window_get_browser_window(g->top_level);
|
||||
|
||||
if (bw->current_content &&
|
||||
bw->current_content->type ==
|
||||
content_get_type(bw->current_content) ==
|
||||
CONTENT_HTML) {
|
||||
xmlDebugDumpDocument(fh,
|
||||
bw->current_content->
|
||||
data.html.document);
|
||||
html_get_document(bw->current_content));
|
||||
}
|
||||
|
||||
fclose(fh);
|
||||
@ -1871,80 +1873,93 @@ void gui_window_stop_throbber(struct gui_window* _g)
|
||||
/**
|
||||
* set favicon
|
||||
*/
|
||||
void gui_window_set_icon(struct gui_window *_g, struct content *icon)
|
||||
void gui_window_set_icon(struct gui_window *_g, hlcache_handle *icon)
|
||||
{
|
||||
struct gtk_scaffolding *g = nsgtk_get_scaffold(_g);
|
||||
GtkImage *iconImage = NULL;
|
||||
if (g->icoFav != NULL)
|
||||
g_object_unref(g->icoFav);
|
||||
struct bitmap *icon_bitmap;
|
||||
GtkImage *iconImage;
|
||||
|
||||
if (icon == NULL)
|
||||
return;
|
||||
|
||||
#ifdef WITH_BMP
|
||||
if ((icon != NULL) && (icon->type == CONTENT_ICO)) {
|
||||
if (content_get_type(icon) == CONTENT_ICO)
|
||||
nsico_set_bitmap_from_size(icon, 16, 16);
|
||||
}
|
||||
#endif
|
||||
if ((icon != NULL) && (icon->bitmap != NULL)) {
|
||||
GdkPixbuf *pb = gtk_bitmap_get_primary(icon->bitmap);
|
||||
if ((pb != NULL) && (gdk_pixbuf_get_width(pb) > 0) &&
|
||||
(gdk_pixbuf_get_height(pb) > 0)) {
|
||||
pb = gdk_pixbuf_scale_simple(pb, 16, 16,
|
||||
GDK_INTERP_HYPER);
|
||||
iconImage = GTK_IMAGE(
|
||||
gtk_image_new_from_pixbuf(pb));
|
||||
|
||||
icon_bitmap = content_get_bitmap(icon);
|
||||
if (icon_bitmap == NULL)
|
||||
return;
|
||||
|
||||
GdkPixbuf *pb = gtk_bitmap_get_primary(icon_bitmap);
|
||||
if (pb != NULL && gdk_pixbuf_get_width(pb) > 0 &&
|
||||
gdk_pixbuf_get_height(pb) > 0) {
|
||||
pb = gdk_pixbuf_scale_simple(pb, 16, 16, GDK_INTERP_HYPER);
|
||||
iconImage = GTK_IMAGE(gtk_image_new_from_pixbuf(pb));
|
||||
} else {
|
||||
iconImage = NULL;
|
||||
}
|
||||
}
|
||||
if (iconImage == NULL) {
|
||||
char imagepath[strlen(res_dir_location) + SLEN("favicon.png")
|
||||
+ 1];
|
||||
/** \todo Does pb need cleaning up? */
|
||||
char imagepath[strlen(res_dir_location) +
|
||||
SLEN("favicon.png") + 1];
|
||||
sprintf(imagepath, "%sfavicon.png", res_dir_location);
|
||||
iconImage = GTK_IMAGE(gtk_image_new_from_file(imagepath));
|
||||
}
|
||||
|
||||
if (iconImage == NULL)
|
||||
return;
|
||||
|
||||
if (g->icoFav != NULL)
|
||||
g_object_unref(g->icoFav);
|
||||
g->icoFav = iconImage;
|
||||
|
||||
sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(g->url_bar),
|
||||
SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(g->icoFav));
|
||||
gtk_widget_show_all(GTK_WIDGET(g->buttons[URL_BAR_ITEM]->button));
|
||||
}
|
||||
|
||||
void gui_window_set_search_ico(struct content *ico)
|
||||
void gui_window_set_search_ico(hlcache_handle *ico)
|
||||
{
|
||||
GdkPixbuf *pbico = NULL;
|
||||
GtkImage *searchico = NULL;
|
||||
GdkPixbuf *pbico;
|
||||
GtkImage *searchico;
|
||||
struct bitmap *ico_bitmap;
|
||||
nsgtk_scaffolding *current;
|
||||
if (ico == NULL)
|
||||
ico = search_web_ico();
|
||||
|
||||
if (ico == NULL && (ico = search_web_ico()) == NULL)
|
||||
return;
|
||||
|
||||
#ifdef WITH_BMP
|
||||
if ((ico != NULL) && (ico->type == CONTENT_ICO)) {
|
||||
if (content_get_type(ico) == CONTENT_ICO)
|
||||
nsico_set_bitmap_from_size(ico, 20, 20);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ico != NULL) && (ico->bitmap != NULL)) {
|
||||
pbico = gtk_bitmap_get_primary(ico->bitmap);
|
||||
if ((pbico != NULL) && (gdk_pixbuf_get_width(pbico) > 0) &&
|
||||
(gdk_pixbuf_get_height(pbico) > 0)) {
|
||||
ico_bitmap = content_get_bitmap(ico);
|
||||
if (ico_bitmap == NULL)
|
||||
return;
|
||||
|
||||
pbico = gtk_bitmap_get_primary(ico_bitmap);
|
||||
if (pbico != NULL && gdk_pixbuf_get_width(pbico) > 0 &&
|
||||
gdk_pixbuf_get_height(pbico) > 0) {
|
||||
pbico = gdk_pixbuf_scale_simple(pbico, 20, 20,
|
||||
GDK_INTERP_HYPER);
|
||||
current = scaf_list;
|
||||
searchico = GTK_IMAGE(
|
||||
gtk_image_new_from_pixbuf(pbico));
|
||||
searchico = GTK_IMAGE(gtk_image_new_from_pixbuf(pbico));
|
||||
} else {
|
||||
searchico = NULL;
|
||||
/** \todo Does pbico need cleaning up? */
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* add ico to toolbar */
|
||||
current = scaf_list;
|
||||
while (current) {
|
||||
|
||||
/* add ico to each window's toolbar */
|
||||
for (current = scaf_list; current != NULL; current = current->next) {
|
||||
if (searchico != NULL) {
|
||||
/** \todo Are we leaking webSearchIco here? */
|
||||
current->webSearchIco = searchico;
|
||||
sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(
|
||||
current->webSearchEntry),
|
||||
SEXY_ICON_ENTRY_PRIMARY,
|
||||
current->webSearchIco);
|
||||
}
|
||||
if (pbico != NULL)
|
||||
searchico = GTK_IMAGE(gtk_image_new_from_pixbuf(pbico));
|
||||
current = current->next;
|
||||
else
|
||||
searchico = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2117,33 +2132,26 @@ void nsgtk_scaffolding_set_top_level (struct gui_window *gw)
|
||||
nsgtk_get_scaffold(gw)->top_level = gw;
|
||||
struct browser_window *bw = gui_window_get_browser_window(gw);
|
||||
|
||||
assert(bw != NULL);
|
||||
|
||||
/* Synchronise the history (will also update the URL bar) */
|
||||
nsgtk_window_update_back_forward(nsgtk_get_scaffold(gw));
|
||||
|
||||
/* clear effects of potential searches */
|
||||
if ((bw != NULL) && (bw->search_context != NULL))
|
||||
if (bw->search_context != NULL)
|
||||
search_destroy_context(bw->search_context);
|
||||
|
||||
nsgtk_search_set_forward_state(true, bw);
|
||||
nsgtk_search_set_back_state(true, bw);
|
||||
|
||||
/* Ensure the window's title bar as well as favicon are updated */
|
||||
if (gui_window_get_browser_window(gw) != NULL &&
|
||||
gui_window_get_browser_window(gw)->current_content
|
||||
!= NULL) {
|
||||
if (gui_window_get_browser_window(gw)->current_content->title
|
||||
!= NULL) {
|
||||
if (bw->current_content != NULL) {
|
||||
gui_window_set_title(gw,
|
||||
gui_window_get_browser_window(gw)->
|
||||
current_content->title);
|
||||
} else {
|
||||
gui_window_set_title(gw,
|
||||
gui_window_get_browser_window(gw)->
|
||||
current_content->url);
|
||||
}
|
||||
if (gui_window_get_browser_window(gw)->current_content->type
|
||||
== CONTENT_HTML)
|
||||
content_get_title(bw->current_content));
|
||||
|
||||
if (content_get_type(bw->current_content) == CONTENT_HTML)
|
||||
gui_window_set_icon(gw,
|
||||
gui_window_get_browser_window(gw)->
|
||||
current_content->data.html.favicon);
|
||||
html_get_favicon(bw->current_content));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2287,7 +2295,8 @@ static guint nsgtk_scaffolding_update_link_operations_sensitivity(
|
||||
struct browser_window *bw = gui_window_get_browser_window(g->top_level);
|
||||
current_menu_link_box = NULL;
|
||||
|
||||
if (bw->current_content && bw->current_content->type == CONTENT_HTML) {
|
||||
if (bw->current_content &&
|
||||
content_get_type(bw->current_content) == CONTENT_HTML) {
|
||||
current_menu_link_box = box_href_at_point(bw->current_content,
|
||||
x, y);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "gtk/gtk_window.h"
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/gui.h"
|
||||
#include "desktop/search.h"
|
||||
@ -99,7 +100,7 @@ gboolean nsgtk_search_back_button_clicked(GtkWidget *widget, gpointer data)
|
||||
|
||||
void nsgtk_search_init(struct gtk_scaffolding *g)
|
||||
{
|
||||
struct content *c;
|
||||
hlcache_handle *c;
|
||||
|
||||
assert(gui_window_get_browser_window(nsgtk_scaffolding_top_level(g))
|
||||
!= NULL);
|
||||
@ -107,7 +108,8 @@ void nsgtk_search_init(struct gtk_scaffolding *g)
|
||||
c = gui_window_get_browser_window(nsgtk_scaffolding_top_level(g))->
|
||||
current_content;
|
||||
|
||||
if ((!c) || (c->type != CONTENT_HTML && c->type != CONTENT_TEXTPLAIN))
|
||||
if ((!c) || (content_get_type(c) != CONTENT_HTML &&
|
||||
content_get_type(c) != CONTENT_TEXTPLAIN))
|
||||
return;
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <unistd.h>
|
||||
#include "content/content.h"
|
||||
#include "content/content_type.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "gtk/gtk_gui.h"
|
||||
#include "gtk/gtk_scaffolding.h"
|
||||
#include "gtk/gtk_menu.h"
|
||||
@ -62,10 +63,10 @@ static void nsgtk_theme_cache_searchimage(nsgtk_search_buttons i,
|
||||
const char *filename, const char *path);
|
||||
|
||||
#ifdef WITH_THEME_INSTALL
|
||||
static struct content *theme_install_content = NULL;
|
||||
static hlcache_handle *theme_install_content = NULL;
|
||||
|
||||
static void theme_install_callback(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data);
|
||||
static void theme_install_callback(hlcache_handle *c, content_msg msg,
|
||||
union content_msg_data data, void *pw);
|
||||
static bool theme_install_read(const char *data, unsigned long len);
|
||||
#endif
|
||||
|
||||
@ -674,14 +675,14 @@ GtkImage *nsgtk_theme_image_default(nsgtk_toolbar_button i, GtkIconSize s)
|
||||
/**
|
||||
* when CONTENT_THEME needs handling call this function
|
||||
*/
|
||||
void theme_install_start(struct content *c)
|
||||
void theme_install_start(hlcache_handle *c)
|
||||
{
|
||||
assert(c);
|
||||
assert(c->type == CONTENT_THEME);
|
||||
assert(content_get_type(c) == CONTENT_THEME);
|
||||
|
||||
/* stop theme sitting in memory cache */
|
||||
c->fresh = false;
|
||||
if (!content_add_user(c, theme_install_callback, 0, 0)) {
|
||||
content_invalidate_reuse_data(c);
|
||||
if (!content_add_user(c, theme_install_callback, NULL)) {
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
@ -692,17 +693,25 @@ void theme_install_start(struct content *c)
|
||||
* Callback for fetchcache() for theme install fetches.
|
||||
*/
|
||||
|
||||
void theme_install_callback(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data)
|
||||
void theme_install_callback(hlcache_handle *c, content_msg msg,
|
||||
union content_msg_data data, void *pw)
|
||||
{
|
||||
switch (msg) {
|
||||
case CONTENT_MSG_READY:
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_DONE:
|
||||
{
|
||||
const char *source_data;
|
||||
unsigned long source_size;
|
||||
|
||||
theme_install_content = c;
|
||||
if (!theme_install_read(c->source_data, c->source_size))
|
||||
|
||||
source_data = content_get_source_data(c, &source_size);
|
||||
|
||||
if (!theme_install_read(source_data, source_size))
|
||||
warn_user("ThemeInvalid", 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_ERROR:
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <assert.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "content/content.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "content/urldb.h"
|
||||
#include "desktop/plotters.h"
|
||||
#include "desktop/browser.h"
|
||||
@ -45,7 +46,7 @@
|
||||
* \param bitmap the bitmap to draw to
|
||||
* \param url the URL the thumnail belongs to, or NULL
|
||||
*/
|
||||
bool thumbnail_create(struct content *content, struct bitmap *bitmap,
|
||||
bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap,
|
||||
const char *url)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
@ -59,8 +60,8 @@ bool thumbnail_create(struct content *content, struct bitmap *bitmap,
|
||||
assert(content);
|
||||
assert(bitmap);
|
||||
|
||||
cwidth = min(content->width, 1024);
|
||||
cheight = min(content->height, 768);
|
||||
cwidth = min(content_get_width(content), 1024);
|
||||
cheight = min(content_get_height(content), 768);
|
||||
|
||||
pixbuf = gtk_bitmap_get_primary(bitmap);
|
||||
width = gdk_pixbuf_get_width(pixbuf);
|
||||
@ -68,7 +69,8 @@ bool thumbnail_create(struct content *content, struct bitmap *bitmap,
|
||||
depth = (gdk_screen_get_system_visual(gdk_screen_get_default()))->depth;
|
||||
|
||||
LOG(("Trying to create a thumbnail pixmap for a content of %dx%d@%d",
|
||||
content->width, content->width, depth));
|
||||
content_get_width(content), content_get_height(content),
|
||||
depth));
|
||||
|
||||
pixmap = gdk_pixmap_new(NULL, cwidth, cwidth, depth);
|
||||
|
||||
@ -87,7 +89,8 @@ bool thumbnail_create(struct content *content, struct bitmap *bitmap,
|
||||
/* set the plotting functions up */
|
||||
plot = nsgtk_plotters;
|
||||
|
||||
nsgtk_plot_set_scale((double) cwidth / (double) content->width);
|
||||
nsgtk_plot_set_scale((double) cwidth /
|
||||
(double) content_get_width(content));
|
||||
|
||||
/* set to plot to pixmap */
|
||||
current_drawable = pixmap;
|
||||
@ -98,8 +101,10 @@ bool thumbnail_create(struct content *content, struct bitmap *bitmap,
|
||||
plot.rectangle(0, 0, cwidth, cwidth, plot_style_fill_white);
|
||||
|
||||
/* render the content */
|
||||
content_redraw(content, 0, 0, content->width, content->width,
|
||||
0, 0, content->width, content->width, 1.0, 0xFFFFFF);
|
||||
content_redraw(content, 0, 0, content_get_width(content),
|
||||
content_get_width(content),
|
||||
0, 0, content_get_width(content),
|
||||
content_get_width(content), 1.0, 0xFFFFFF);
|
||||
|
||||
/* resample the large plot down to the size of our thumbnail */
|
||||
big = gdk_pixbuf_get_from_drawable(NULL, pixmap, NULL, 0, 0, 0, 0,
|
||||
|
@ -412,15 +412,16 @@ void nsgtk_toolbar_close(nsgtk_scaffolding *g)
|
||||
NSGTK_WINDOW_SIGNAL_REDRAW));
|
||||
if ((gui_window_get_browser_window(nsgtk_scaffolding_top_level(
|
||||
list))->current_content != NULL) &&
|
||||
(gui_window_get_browser_window(
|
||||
(content_get_url(gui_window_get_browser_window(
|
||||
nsgtk_scaffolding_top_level(list))->
|
||||
current_content->url != NULL))
|
||||
current_content) != NULL))
|
||||
browser_window_refresh_url_bar(
|
||||
gui_window_get_browser_window(
|
||||
nsgtk_scaffolding_top_level(list)),
|
||||
content_get_url(
|
||||
gui_window_get_browser_window(
|
||||
nsgtk_scaffolding_top_level(list))->
|
||||
current_content->url,
|
||||
current_content),
|
||||
gui_window_get_browser_window(
|
||||
nsgtk_scaffolding_top_level(list))->
|
||||
frag_id);
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include "content/hlcache.h"
|
||||
#include "gtk/gtk_window.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/options.h"
|
||||
@ -144,7 +145,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
|
||||
struct gui_window *g; /**< what we're creating to return */
|
||||
GtkPolicyType scrollpolicy;
|
||||
|
||||
g = malloc(sizeof(*g));
|
||||
g = calloc(1, sizeof(*g));
|
||||
if (!g) {
|
||||
warn_user("NoMemory", 0);
|
||||
return 0;
|
||||
@ -349,7 +350,7 @@ gboolean nsgtk_window_expose_event(GtkWidget *widget,
|
||||
GdkEventExpose *event, gpointer data)
|
||||
{
|
||||
struct gui_window *g = data;
|
||||
struct content *c;
|
||||
hlcache_handle *c;
|
||||
float scale = g->bw->scale;
|
||||
|
||||
assert(g);
|
||||
@ -366,7 +367,7 @@ gboolean nsgtk_window_expose_event(GtkWidget *widget,
|
||||
return FALSE;
|
||||
|
||||
/* HTML rendering handles scale itself */
|
||||
if (c->type == CONTENT_HTML)
|
||||
if (content_get_type(c) == CONTENT_HTML)
|
||||
scale = 1;
|
||||
|
||||
current_widget = (GtkWidget *)g->drawing_area;
|
||||
@ -712,7 +713,7 @@ void gui_window_redraw_window(struct gui_window *g)
|
||||
void gui_window_update_box(struct gui_window *g,
|
||||
const union content_msg_data *data)
|
||||
{
|
||||
struct content *c = g->bw->current_content;
|
||||
hlcache_handle *c = g->bw->current_content;
|
||||
|
||||
if (c == NULL)
|
||||
return;
|
||||
@ -788,8 +789,8 @@ void gui_window_update_extent(struct gui_window *g)
|
||||
return;
|
||||
|
||||
gtk_widget_set_size_request(GTK_WIDGET(g->drawing_area),
|
||||
g->bw->current_content->width * g->bw->scale,
|
||||
g->bw->current_content->height * g->bw->scale);
|
||||
content_get_width(g->bw->current_content) * g->bw->scale,
|
||||
content_get_height(g->bw->current_content) * g->bw->scale);
|
||||
|
||||
gtk_widget_set_size_request(GTK_WIDGET(g->viewport), 0, 0);
|
||||
|
||||
@ -958,7 +959,7 @@ bool gui_window_box_scroll_start(struct gui_window *g,
|
||||
return true;
|
||||
}
|
||||
|
||||
void gui_drag_save_object(gui_save_type type, struct content *c,
|
||||
void gui_drag_save_object(gui_save_type type, hlcache_handle *c,
|
||||
struct gui_window *g)
|
||||
{
|
||||
|
||||
|
13
image/bmp.c
13
image/bmp.c
@ -30,7 +30,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <libnsbmp.h>
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "desktop/plotters.h"
|
||||
#include "image/bitmap.h"
|
||||
#include "image/bmp.h"
|
||||
@ -49,8 +49,7 @@ bmp_bitmap_callback_vt bmp_bitmap_callbacks = {
|
||||
.bitmap_get_bpp = bitmap_get_bpp
|
||||
};
|
||||
|
||||
bool nsbmp_create(struct content *c, struct content *parent,
|
||||
const char *params[])
|
||||
bool nsbmp_create(struct content *c, const struct http_parameter *params)
|
||||
{
|
||||
union content_msg_data msg_data;
|
||||
|
||||
@ -71,12 +70,16 @@ bool nsbmp_convert(struct content *c, int iwidth, int iheight)
|
||||
bmp_image *bmp;
|
||||
union content_msg_data msg_data;
|
||||
uint32_t swidth;
|
||||
const char *data;
|
||||
unsigned long size;
|
||||
|
||||
/* set the bmp data */
|
||||
bmp = c->data.bmp.bmp;
|
||||
|
||||
data = content__get_source_data(c, &size);
|
||||
|
||||
/* analyse the BMP */
|
||||
res = bmp_analyse(bmp, c->source_size, (unsigned char *)c->source_data);
|
||||
res = bmp_analyse(bmp, size, (unsigned char *) data);
|
||||
switch (res) {
|
||||
case BMP_OK:
|
||||
break;
|
||||
@ -98,7 +101,7 @@ bool nsbmp_convert(struct content *c, int iwidth, int iheight)
|
||||
c->title = malloc(100);
|
||||
if (c->title)
|
||||
snprintf(c->title, 100, messages_get("BMPTitle"), c->width,
|
||||
c->height, c->source_size);
|
||||
c->height, size);
|
||||
swidth = bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bitmap) * bmp->width;
|
||||
c->size += (swidth * bmp->height) + 16 + 44 + 100;
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
struct content;
|
||||
struct bitmap;
|
||||
struct http_parameter;
|
||||
|
||||
struct content_bmp_data {
|
||||
bmp_image *bmp; /** BMP image data */
|
||||
@ -40,8 +41,7 @@ struct content_bmp_data {
|
||||
|
||||
extern bmp_bitmap_callback_vt bmp_bitmap_callbacks; /** Only to be used by ICO code. */
|
||||
|
||||
bool nsbmp_create(struct content *c, struct content *parent,
|
||||
const char *params[]);
|
||||
bool nsbmp_create(struct content *c, const struct http_parameter *params);
|
||||
bool nsbmp_convert(struct content *c, int width, int height);
|
||||
void nsbmp_destroy(struct content *c);
|
||||
bool nsbmp_redraw(struct content *c, int x, int y,
|
||||
|
23
image/gif.c
23
image/gif.c
@ -37,7 +37,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <libnsgif.h>
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/plotters.h"
|
||||
@ -64,8 +64,7 @@ gif_bitmap_callback_vt gif_bitmap_callbacks = {
|
||||
};
|
||||
|
||||
|
||||
bool nsgif_create(struct content *c, struct content *parent,
|
||||
const char *params[])
|
||||
bool nsgif_create(struct content *c, const struct http_parameter *params)
|
||||
{
|
||||
union content_msg_data msg_data;
|
||||
/* Initialise our data structure */
|
||||
@ -85,25 +84,27 @@ bool nsgif_convert(struct content *c, int iwidth, int iheight)
|
||||
int res;
|
||||
struct gif_animation *gif;
|
||||
union content_msg_data msg_data;
|
||||
const char *data;
|
||||
unsigned long size;
|
||||
|
||||
/* Get the animation */
|
||||
gif = c->data.gif.gif;
|
||||
|
||||
data = content__get_source_data(c, &size);
|
||||
|
||||
/* Initialise the GIF */
|
||||
do {
|
||||
res = gif_initialise(gif, c->source_size,
|
||||
(unsigned char *)c->source_data);
|
||||
if (res != GIF_OK && res != GIF_WORKING && res != GIF_INSUFFICIENT_FRAME_DATA) {
|
||||
switch (res)
|
||||
{
|
||||
res = gif_initialise(gif, size, (unsigned char *) data);
|
||||
if (res != GIF_OK && res != GIF_WORKING &&
|
||||
res != GIF_INSUFFICIENT_FRAME_DATA) {
|
||||
switch (res) {
|
||||
case GIF_FRAME_DATA_ERROR:
|
||||
case GIF_INSUFFICIENT_DATA:
|
||||
case GIF_DATA_ERROR:
|
||||
msg_data.error = messages_get("BadGIF");
|
||||
break;
|
||||
case GIF_INSUFFICIENT_MEMORY:
|
||||
msg_data.error = messages_get(
|
||||
"NoMemory");
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
break;
|
||||
}
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
@ -125,7 +126,7 @@ bool nsgif_convert(struct content *c, int iwidth, int iheight)
|
||||
c->title = malloc(100);
|
||||
if (c->title) {
|
||||
snprintf(c->title, 100, messages_get("GIFTitle"), c->width,
|
||||
c->height, c->source_size);
|
||||
c->height, size);
|
||||
}
|
||||
c->size += (gif->width * gif->height * 4) + 16 + 44 + 100;
|
||||
|
||||
|
@ -31,14 +31,14 @@
|
||||
#include <libnsgif.h>
|
||||
|
||||
struct content;
|
||||
struct http_parameter;
|
||||
|
||||
struct content_gif_data {
|
||||
struct gif_animation *gif; /**< GIF animation data */
|
||||
int current_frame; /**< current frame to display [0...(max-1)] */
|
||||
};
|
||||
|
||||
bool nsgif_create(struct content *c, struct content *parent,
|
||||
const char *params[]);
|
||||
bool nsgif_create(struct content *c, const struct http_parameter *params);
|
||||
bool nsgif_convert(struct content *c, int width, int height);
|
||||
void nsgif_destroy(struct content *c);
|
||||
bool nsgif_redraw(struct content *c, int x, int y,
|
||||
|
27
image/ico.c
27
image/ico.c
@ -29,7 +29,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <libnsbmp.h>
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "desktop/plotters.h"
|
||||
#include "image/bitmap.h"
|
||||
#include "image/ico.h"
|
||||
@ -37,8 +38,7 @@
|
||||
#include "utils/messages.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
bool nsico_create(struct content *c, struct content *parent,
|
||||
const char *params[])
|
||||
bool nsico_create(struct content *c, const struct http_parameter *params)
|
||||
{
|
||||
union content_msg_data msg_data;
|
||||
c->data.ico.ico = calloc(sizeof(ico_collection), 1);
|
||||
@ -58,13 +58,16 @@ bool nsico_convert(struct content *c, int iwidth, int iheight)
|
||||
bmp_result res;
|
||||
ico_collection *ico;
|
||||
union content_msg_data msg_data;
|
||||
const char *data;
|
||||
unsigned long size;
|
||||
|
||||
/* set the ico data */
|
||||
ico = c->data.ico.ico;
|
||||
|
||||
data = content__get_source_data(c, &size);
|
||||
|
||||
/* analyse the ico */
|
||||
res = ico_analyse(ico, c->source_size, (unsigned char *)
|
||||
c->source_data);
|
||||
res = ico_analyse(ico, size, (unsigned char *) data);
|
||||
|
||||
switch (res) {
|
||||
case BMP_OK:
|
||||
@ -86,7 +89,7 @@ bool nsico_convert(struct content *c, int iwidth, int iheight)
|
||||
c->title = malloc(100);
|
||||
if (c->title)
|
||||
snprintf(c->title, 100, messages_get("ICOTitle"), c->width,
|
||||
c->height, c->source_size);
|
||||
c->height, size);
|
||||
c->size += (ico->width * ico->height * 4) + 16 + 44 + 100;
|
||||
|
||||
/* exit as a success */
|
||||
@ -117,14 +120,22 @@ bool nsico_redraw(struct content *c, int x, int y,
|
||||
|
||||
/** sets the bitmap for an ico according to the dimensions */
|
||||
|
||||
bool nsico_set_bitmap_from_size(struct content *c, int width, int height)
|
||||
bool nsico_set_bitmap_from_size(hlcache_handle *h, int width, int height)
|
||||
{
|
||||
struct bmp_image *bmp = ico_find(c->data.ico.ico, width, height);
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
struct bmp_image *bmp;
|
||||
|
||||
assert(c != NULL);
|
||||
|
||||
bmp = ico_find(c->data.ico.ico, width, height);
|
||||
if (bmp == NULL)
|
||||
return false;
|
||||
|
||||
if ((bmp->decoded == false) && (bmp_decode(bmp) != BMP_OK))
|
||||
return false;
|
||||
|
||||
c->bitmap = bmp->bitmap;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -30,13 +30,14 @@
|
||||
#include <libnsbmp.h>
|
||||
|
||||
struct content;
|
||||
struct hlcache_handle;
|
||||
struct http_parameter;
|
||||
|
||||
struct content_ico_data {
|
||||
struct ico_collection *ico; /** ICO collection data */
|
||||
};
|
||||
|
||||
bool nsico_create(struct content *c, struct content *parent,
|
||||
const char *params[]);
|
||||
bool nsico_create(struct content *c, const struct http_parameter *params);
|
||||
bool nsico_convert(struct content *c, int width, int height);
|
||||
void nsico_destroy(struct content *c);
|
||||
bool nsico_redraw(struct content *c, int x, int y,
|
||||
@ -48,7 +49,8 @@ bool nsico_redraw_tiled(struct content *c, int x, int y,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, colour background_colour,
|
||||
bool repeat_x, bool repeat_y);
|
||||
bool nsico_set_bitmap_from_size(struct content *c, int width, int height);
|
||||
bool nsico_set_bitmap_from_size(struct hlcache_handle *h,
|
||||
int width, int height);
|
||||
|
||||
#endif /* WITH_BMP */
|
||||
|
||||
|
12
image/jpeg.c
12
image/jpeg.c
@ -27,7 +27,7 @@
|
||||
#ifdef WITH_JPEG
|
||||
|
||||
/* This must come first due to libpng issues */
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <setjmp.h>
|
||||
@ -89,6 +89,10 @@ bool nsjpeg_convert(struct content *c, int w, int h)
|
||||
uint8_t * volatile pixels = NULL;
|
||||
size_t rowstride;
|
||||
union content_msg_data msg_data;
|
||||
const char *data;
|
||||
unsigned long size;
|
||||
|
||||
data = content__get_source_data(c, &size);
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = nsjpeg_error_exit;
|
||||
@ -102,8 +106,8 @@ bool nsjpeg_convert(struct content *c, int w, int h)
|
||||
return false;
|
||||
}
|
||||
jpeg_create_decompress(&cinfo);
|
||||
source_mgr.next_input_byte = (unsigned char *) c->source_data;
|
||||
source_mgr.bytes_in_buffer = c->source_size;
|
||||
source_mgr.next_input_byte = (unsigned char *) data;
|
||||
source_mgr.bytes_in_buffer = size;
|
||||
cinfo.src = &source_mgr;
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
cinfo.out_color_space = JCS_RGB;
|
||||
@ -161,7 +165,7 @@ bool nsjpeg_convert(struct content *c, int w, int h)
|
||||
c->title = malloc(100);
|
||||
if (c->title)
|
||||
snprintf(c->title, 100, messages_get("JPEGTitle"),
|
||||
width, height, c->source_size);
|
||||
width, height, size);
|
||||
c->size += height * rowstride + 100;
|
||||
c->status = CONTENT_STATUS_DONE;
|
||||
/* Done: update status bar */
|
||||
|
29
image/mng.c
29
image/mng.c
@ -24,7 +24,7 @@
|
||||
#ifdef WITH_MNG
|
||||
|
||||
/* This must come first due to libpng issues */
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
@ -69,8 +69,7 @@ static void nsmng_free(mng_ptr p, mng_size_t n);
|
||||
#endif
|
||||
|
||||
|
||||
bool nsmng_create(struct content *c, struct content *parent,
|
||||
const char *params[])
|
||||
bool nsmng_create(struct content *c, const struct http_parameter *params)
|
||||
{
|
||||
mng_retcode code;
|
||||
union content_msg_data msg_data;
|
||||
@ -179,6 +178,8 @@ mng_bool nsmng_readdata(mng_handle mng, mng_ptr buffer, mng_uint32 size,
|
||||
mng_uint32 *bytesread)
|
||||
{
|
||||
struct content *c;
|
||||
const char *data;
|
||||
unsigned long data_size;
|
||||
|
||||
assert(mng != NULL);
|
||||
assert(buffer != NULL);
|
||||
@ -191,12 +192,13 @@ mng_bool nsmng_readdata(mng_handle mng, mng_ptr buffer, mng_uint32 size,
|
||||
|
||||
/* Copy any data we have (maximum of 'size')
|
||||
*/
|
||||
*bytesread = ((c->source_size - c->data.mng.read_size) < size) ?
|
||||
(c->source_size - c->data.mng.read_size) : size;
|
||||
data = content__get_source_data(c, &data_size);
|
||||
|
||||
*bytesread = ((data_size - c->data.mng.read_size) < size) ?
|
||||
(data_size - c->data.mng.read_size) : size;
|
||||
|
||||
if ((*bytesread) > 0) {
|
||||
memcpy(buffer, c->source_data + c->data.mng.read_size,
|
||||
*bytesread);
|
||||
memcpy(buffer, data + c->data.mng.read_size, *bytesread);
|
||||
c->data.mng.read_size += *bytesread;
|
||||
}
|
||||
|
||||
@ -302,9 +304,13 @@ bool nsmng_convert(struct content *c, int width, int height)
|
||||
mng_retcode status;
|
||||
|
||||
union content_msg_data msg_data;
|
||||
const char *data;
|
||||
unsigned long size;
|
||||
|
||||
assert(c != NULL);
|
||||
|
||||
data = content__get_source_data(c, &size);
|
||||
|
||||
/* by this point, the png should have been parsed
|
||||
* and the bitmap created, so ensure that's the case
|
||||
*/
|
||||
@ -322,13 +328,13 @@ bool nsmng_convert(struct content *c, int width, int height)
|
||||
|
||||
if (c->type == CONTENT_MNG) {
|
||||
snprintf(c->title, 100, messages_get("MNGTitle"),
|
||||
c->width, c->height, c->source_size);
|
||||
c->width, c->height, size);
|
||||
} else if (c->type == CONTENT_PNG) {
|
||||
snprintf(c->title, 100, messages_get("PNGTitle"),
|
||||
c->width, c->height, c->source_size);
|
||||
c->width, c->height, size);
|
||||
} else {
|
||||
snprintf(c->title, 100, messages_get("JNGTitle"),
|
||||
c->width, c->height, c->source_size);
|
||||
c->width, c->height, size);
|
||||
}
|
||||
|
||||
c->size += c->width * c->height * 4 + 100;
|
||||
@ -658,7 +664,8 @@ mng_bool nsmng_errorproc(mng_handle mng, mng_int32 code,
|
||||
chunk[3] = (char)((chunktype ) & 0xFF);
|
||||
chunk[4] = '\0';
|
||||
|
||||
LOG(("error playing '%s' chunk %s (%d):", c->url, chunk, chunkseq));
|
||||
LOG(("error playing '%s' chunk %s (%d):",
|
||||
content__get_url(c), chunk, chunkseq));
|
||||
LOG(("code %d severity %d extra1 %d extra2 %d text:'%s'", code,
|
||||
severity, extra1, extra2, text));
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
struct content;
|
||||
struct http_parameter;
|
||||
|
||||
struct content_mng_data {
|
||||
bool opaque_test_pending;
|
||||
@ -40,8 +41,7 @@ struct content_mng_data {
|
||||
void *handle;
|
||||
};
|
||||
|
||||
bool nsmng_create(struct content *c, struct content *parent,
|
||||
const char *params[]);
|
||||
bool nsmng_create(struct content *c, const struct http_parameter *params);
|
||||
bool nsmng_process_data(struct content *c, char *data, unsigned int size);
|
||||
bool nsmng_convert(struct content *c, int width, int height);
|
||||
void nsmng_destroy(struct content *c);
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "utils/config.h"
|
||||
#include "desktop/plotters.h"
|
||||
#include "image/bitmap.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/utils.h"
|
||||
@ -61,8 +61,13 @@ bool nssprite_convert(struct content *c, int width, int height)
|
||||
union content_msg_data msg_data;
|
||||
|
||||
struct rosprite_mem_context* ctx;
|
||||
ERRCHK(rosprite_create_mem_context((uint8_t *) c->source_data,
|
||||
c->source_size, &ctx));
|
||||
|
||||
const char *data;
|
||||
unsigned long size;
|
||||
|
||||
data = content__get_source_data(c, &size);
|
||||
|
||||
ERRCHK(rosprite_create_mem_context((uint8_t *) data, size, &ctx));
|
||||
|
||||
struct rosprite_area* sprite_area;
|
||||
ERRCHK(rosprite_load(rosprite_mem_reader, ctx, &sprite_area));
|
||||
|
12
image/png.c
12
image/png.c
@ -30,7 +30,7 @@
|
||||
|
||||
#include "desktop/plotters.h"
|
||||
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
|
||||
#include "image/bitmap.h"
|
||||
|
||||
@ -62,8 +62,7 @@ static void row_callback(png_structp png, png_bytep new_row,
|
||||
static void end_callback(png_structp png, png_infop info);
|
||||
|
||||
|
||||
bool nspng_create(struct content *c, struct content *parent,
|
||||
const char *params[])
|
||||
bool nspng_create(struct content *c, const struct http_parameter *params)
|
||||
{
|
||||
union content_msg_data msg_data;
|
||||
|
||||
@ -264,16 +263,21 @@ void end_callback(png_structp png, png_infop info)
|
||||
|
||||
bool nspng_convert(struct content *c, int width, int height)
|
||||
{
|
||||
const char *data;
|
||||
unsigned long size;
|
||||
|
||||
assert(c->data.png.png != NULL);
|
||||
assert(c->data.png.info != NULL);
|
||||
|
||||
data = content__get_source_data(c, &size);
|
||||
|
||||
png_destroy_read_struct(&c->data.png.png, &c->data.png.info, 0);
|
||||
|
||||
c->title = malloc(NSPNG_TITLE_LEN);
|
||||
|
||||
if (c->title != NULL) {
|
||||
snprintf(c->title, NSPNG_TITLE_LEN, messages_get("PNGTitle"),
|
||||
c->width, c->height, c->source_size);
|
||||
c->width, c->height, size);
|
||||
}
|
||||
|
||||
c->size += (c->width * c->height * 4) + NSPNG_TITLE_LEN;
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
struct content;
|
||||
struct bitmap;
|
||||
struct http_parameter;
|
||||
|
||||
struct content_png_data {
|
||||
png_structp png;
|
||||
@ -41,8 +42,7 @@ struct content_png_data {
|
||||
size_t rowbytes; /**< Number of bytes per row */
|
||||
};
|
||||
|
||||
bool nspng_create(struct content *c, struct content *parent,
|
||||
const char *params[]);
|
||||
bool nspng_create(struct content *c, const struct http_parameter *params);
|
||||
bool nspng_process_data(struct content *c, char *data, unsigned int size);
|
||||
bool nspng_convert(struct content *c, int width, int height);
|
||||
void nspng_destroy(struct content *c);
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include <librsvg/rsvg-cairo.h>
|
||||
|
||||
#include "image/rsvg.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "desktop/plotters.h"
|
||||
#include "image/bitmap.h"
|
||||
#include "utils/log.h"
|
||||
@ -49,8 +49,7 @@
|
||||
static inline void rsvg_argb_to_abgr(uint32_t pixels[], int width, int height,
|
||||
size_t rowstride);
|
||||
|
||||
bool rsvg_create(struct content *c, struct content *parent,
|
||||
const char *params[])
|
||||
bool rsvg_create(struct content *c, const struct http_parameter *params)
|
||||
{
|
||||
struct content_rsvg_data *d = &c->data.rsvg;
|
||||
union content_msg_data msg_data;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "image/bitmap.h"
|
||||
|
||||
struct content;
|
||||
struct http_parameter;
|
||||
|
||||
struct content_rsvg_data {
|
||||
RsvgHandle *rsvgh; /**< Context handle for RSVG renderer */
|
||||
@ -41,8 +42,7 @@ struct content_rsvg_data {
|
||||
struct bitmap *bitmap; /**< Created NetSurf bitmap */
|
||||
};
|
||||
|
||||
bool rsvg_create(struct content *c, struct content *parent,
|
||||
const char *params[]);
|
||||
bool rsvg_create(struct content *c, const struct http_parameter *params);
|
||||
bool rsvg_process_data(struct content *c, char *data, unsigned int size);
|
||||
bool rsvg_convert(struct content *c, int width, int height);
|
||||
void rsvg_destroy(struct content *c);
|
||||
|
@ -40,7 +40,7 @@
|
||||
* Create a CONTENT_SVG.
|
||||
*/
|
||||
|
||||
bool svg_create(struct content *c, struct content *parent, const char *params[])
|
||||
bool svg_create(struct content *c, const struct http_parameter *params)
|
||||
{
|
||||
union content_msg_data msg_data;
|
||||
|
||||
|
@ -26,14 +26,14 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
struct content;
|
||||
struct http_parameter;
|
||||
struct svgtiny_diagram;
|
||||
|
||||
struct content_svg_data {
|
||||
struct svgtiny_diagram *diagram;
|
||||
};
|
||||
|
||||
bool svg_create(struct content *c, struct content *parent,
|
||||
const char *params[]);
|
||||
bool svg_create(struct content *c, const struct http_parameter *params);
|
||||
bool svg_convert(struct content *c, int width, int height);
|
||||
void svg_destroy(struct content *c);
|
||||
bool svg_redraw(struct content *c, int x, int y,
|
||||
|
76
render/box.c
76
render/box.c
@ -26,7 +26,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "css/css.h"
|
||||
#include "css/dump.h"
|
||||
#include "desktop/scroll.h"
|
||||
@ -312,7 +313,7 @@ void box_bounds(struct box *box, struct rect *r)
|
||||
|
||||
struct box *box_at_point(struct box *box, const int x, const int y,
|
||||
int *box_x, int *box_y,
|
||||
struct content **content)
|
||||
hlcache_handle **content)
|
||||
{
|
||||
int bx = *box_x, by = *box_y;
|
||||
struct box *child, *sibling;
|
||||
@ -321,11 +322,14 @@ struct box *box_at_point(struct box *box, const int x, const int y,
|
||||
assert(box);
|
||||
|
||||
/* drill into HTML objects */
|
||||
if (box->object) {
|
||||
if (box->object->type == CONTENT_HTML &&
|
||||
box->object->data.html.layout) {
|
||||
if (box->object != NULL) {
|
||||
struct box *layout;
|
||||
|
||||
if (content_get_type(box->object) == CONTENT_HTML &&
|
||||
(layout = html_get_box_tree(box->object)) !=
|
||||
NULL) {
|
||||
*content = box->object;
|
||||
box = box->object->data.html.layout;
|
||||
box = layout;
|
||||
} else {
|
||||
goto siblings;
|
||||
}
|
||||
@ -503,20 +507,24 @@ bool box_contains_point(struct box *box, int x, int y, bool *physically)
|
||||
/**
|
||||
* Find the box containing an object at the given coordinates, if any.
|
||||
*
|
||||
* \param c content to search, must have type CONTENT_HTML
|
||||
* \param h content to search, must have type CONTENT_HTML
|
||||
* \param x coordinates in document units
|
||||
* \param y coordinates in document units
|
||||
*/
|
||||
|
||||
struct box *box_object_at_point(struct content *c, int x, int y)
|
||||
struct box *box_object_at_point(hlcache_handle *h, int x, int y)
|
||||
{
|
||||
struct box *box = c->data.html.layout;
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
struct box *box;
|
||||
int box_x = 0, box_y = 0;
|
||||
struct content *content = c;
|
||||
hlcache_handle *content = h;
|
||||
struct box *object_box = 0;
|
||||
|
||||
assert(c != NULL);
|
||||
assert(c->type == CONTENT_HTML);
|
||||
|
||||
box = c->data.html.layout;
|
||||
|
||||
while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) {
|
||||
if (box->style && css_computed_visibility(box->style) ==
|
||||
CSS_VISIBILITY_HIDDEN)
|
||||
@ -533,20 +541,24 @@ struct box *box_object_at_point(struct content *c, int x, int y)
|
||||
/**
|
||||
* Find the box containing an href at the given coordinates, if any.
|
||||
*
|
||||
* \param c content to search, must have type CONTENT_HTML
|
||||
* \param h content to search, must have type CONTENT_HTML
|
||||
* \param x coordinates in document units
|
||||
* \param y coordinates in document units
|
||||
*/
|
||||
|
||||
struct box *box_href_at_point(struct content *c, int x, int y)
|
||||
struct box *box_href_at_point(hlcache_handle *h, int x, int y)
|
||||
{
|
||||
struct box *box = c->data.html.layout;
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
struct box *box;
|
||||
int box_x = 0, box_y = 0;
|
||||
struct content *content = c;
|
||||
hlcache_handle *content = h;
|
||||
struct box *href_box = 0;
|
||||
|
||||
assert(c != NULL);
|
||||
assert(c->type == CONTENT_HTML);
|
||||
|
||||
box = c->data.html.layout;
|
||||
|
||||
while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) {
|
||||
if (box->style && css_computed_visibility(box->style) ==
|
||||
CSS_VISIBILITY_HIDDEN)
|
||||
@ -663,8 +675,10 @@ void box_dump(FILE *stream, struct box *box, unsigned int depth)
|
||||
(int) box->length, box->text);
|
||||
if (box->space)
|
||||
fprintf(stream, "space ");
|
||||
if (box->object)
|
||||
fprintf(stream, "(object '%s') ", box->object->url);
|
||||
if (box->object) {
|
||||
fprintf(stream, "(object '%s') ",
|
||||
content_get_url(box->object));
|
||||
}
|
||||
if (box->gadget)
|
||||
fprintf(stream, "(gadget) ");
|
||||
if (box->style)
|
||||
@ -860,42 +874,42 @@ bool box_duplicate_main_tree(struct box *box, struct content *c, int *count)
|
||||
|
||||
box->last = prev;
|
||||
|
||||
if (box->object && option_suppress_images && (
|
||||
if (box->object != NULL && option_suppress_images && (
|
||||
#ifdef WITH_JPEG
|
||||
box->object->type == CONTENT_JPEG ||
|
||||
content_get_type(box->object) == CONTENT_JPEG ||
|
||||
#endif
|
||||
#ifdef WITH_GIF
|
||||
box->object->type == CONTENT_GIF ||
|
||||
content_get_type(box->object) == CONTENT_GIF ||
|
||||
#endif
|
||||
#ifdef WITH_BMP
|
||||
box->object->type == CONTENT_BMP ||
|
||||
box->object->type == CONTENT_ICO ||
|
||||
content_get_type(box->object) == CONTENT_BMP ||
|
||||
content_get_type(box->object) == CONTENT_ICO ||
|
||||
#endif
|
||||
#if defined(WITH_MNG) || defined(WITH_PNG)
|
||||
box->object->type == CONTENT_PNG ||
|
||||
content_get_type(box->object) == CONTENT_PNG ||
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
box->object->type == CONTENT_JNG ||
|
||||
box->object->type == CONTENT_MNG ||
|
||||
content_get_type(box->object) == CONTENT_JNG ||
|
||||
content_get_type(box->object) == CONTENT_MNG ||
|
||||
#endif
|
||||
#if defined(WITH_SPRITE) || defined(WITH_NSSPRITE)
|
||||
box->object->type == CONTENT_SPRITE ||
|
||||
content_get_type(box->object) == CONTENT_SPRITE ||
|
||||
#endif
|
||||
#ifdef WITH_DRAW
|
||||
box->object->type == CONTENT_DRAW ||
|
||||
content_get_type(box->object) == CONTENT_DRAW ||
|
||||
#endif
|
||||
#ifdef WITH_PLUGIN
|
||||
box->object->type == CONTENT_PLUGIN ||
|
||||
content_get_type(box->object) == CONTENT_PLUGIN ||
|
||||
#endif
|
||||
box->object->type == CONTENT_DIRECTORY ||
|
||||
content_get_type(box->object) == CONTENT_DIRECTORY ||
|
||||
#ifdef WITH_THEME_INSTALL
|
||||
box->object->type == CONTENT_THEME ||
|
||||
content_get_type(box->object) == CONTENT_THEME ||
|
||||
#endif
|
||||
#ifdef WITH_ARTWORKS
|
||||
box->object->type == CONTENT_ARTWORKS ||
|
||||
content_get_type(box->object) == CONTENT_ARTWORKS ||
|
||||
#endif
|
||||
#if defined(WITH_NS_SVG) || defined(WITH_RSVG)
|
||||
box->object->type == CONTENT_SVG ||
|
||||
content_get_type(box->object) == CONTENT_SVG ||
|
||||
#endif
|
||||
false))
|
||||
box->object = NULL;
|
||||
|
10
render/box.h
10
render/box.h
@ -239,10 +239,10 @@ struct box {
|
||||
char *id; /**< value of id attribute (or name for anchors) */
|
||||
|
||||
/** Background image for this box, or 0 if none */
|
||||
struct content *background;
|
||||
struct hlcache_handle *background;
|
||||
|
||||
/** Object in this box (usually an image), or 0 if none. */
|
||||
struct content* object;
|
||||
struct hlcache_handle* object;
|
||||
/** Parameters for the object, or 0. */
|
||||
struct object_params *object_params;
|
||||
};
|
||||
@ -307,9 +307,9 @@ void box_free_object_params(struct object_params *op);
|
||||
void box_bounds(struct box *box, struct rect *r);
|
||||
void box_coords(struct box *box, int *x, int *y);
|
||||
struct box *box_at_point(struct box *box, const int x, const int y,
|
||||
int *box_x, int *box_y, struct content **content);
|
||||
struct box *box_object_at_point(struct content *c, int x, int y);
|
||||
struct box *box_href_at_point(struct content *c, int x, int y);
|
||||
int *box_x, int *box_y, struct hlcache_handle **content);
|
||||
struct box *box_object_at_point(struct hlcache_handle *h, int x, int y);
|
||||
struct box *box_href_at_point(struct hlcache_handle *h, int x, int y);
|
||||
struct box *box_find_by_id(struct box *box, const char *id);
|
||||
bool box_visible(struct box *box);
|
||||
void box_dump(FILE *stream, struct box *box, unsigned int depth);
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <libxml/HTMLparser.h>
|
||||
#include <libxml/parserInternals.h>
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "css/css.h"
|
||||
#include "css/utils.h"
|
||||
#include "css/select.h"
|
||||
@ -841,9 +841,9 @@ css_computed_style *box_get_style(struct content *c,
|
||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "style"))) {
|
||||
inline_style = nscss_create_inline_style(
|
||||
(uint8_t *) s, strlen(s),
|
||||
c->data.html.encoding, c->url,
|
||||
c->data.html.encoding, content__get_url(c),
|
||||
c->data.html.quirks != BINDING_QUIRKS_MODE_NONE,
|
||||
c->data.html.dict, myrealloc, c);
|
||||
myrealloc, c);
|
||||
|
||||
xmlFree(s);
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "render/directory.h"
|
||||
#include "render/html.h"
|
||||
#include "utils/messages.h"
|
||||
@ -40,9 +40,8 @@ static const char header[] = "<html>\n<head>\n<title>\n";
|
||||
static const char footer[] = "</pre>\n</body>\n</html>\n";
|
||||
|
||||
|
||||
bool directory_create(struct content *c, struct content *parent,
|
||||
const char *params[]) {
|
||||
if (!html_create(c, parent, params))
|
||||
bool directory_create(struct content *c, const struct http_parameter *params) {
|
||||
if (!html_create(c, params))
|
||||
/* html_create() must have broadcast MSG_ERROR already, so we
|
||||
* don't need to. */
|
||||
return false;
|
||||
@ -64,7 +63,7 @@ bool directory_convert(struct content *c, int width, int height) {
|
||||
bool compare;
|
||||
char *up;
|
||||
|
||||
path = url_to_path(c->url);
|
||||
path = url_to_path(content__get_url(c));
|
||||
if (!path) {
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
@ -100,9 +99,9 @@ bool directory_convert(struct content *c, int width, int height) {
|
||||
binding_parse_chunk(c->data.html.parser_binding,
|
||||
(uint8_t *) buffer, strlen(buffer));
|
||||
|
||||
res = url_parent(c->url, &up);
|
||||
res = url_parent(content__get_url(c), &up);
|
||||
if (res == URL_FUNC_OK) {
|
||||
res = url_compare(c->url, up, false, &compare);
|
||||
res = url_compare(content__get_url(c), up, false, &compare);
|
||||
if ((res == URL_FUNC_OK) && !compare) {
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"<a href=\"..\">[..]</a>\n");
|
||||
@ -124,7 +123,8 @@ bool directory_convert(struct content *c, int width, int height) {
|
||||
continue;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "<a href=\"%s/%s\">%s</a>\n",
|
||||
c->url, entry->d_name, entry->d_name);
|
||||
content__get_url(c), entry->d_name,
|
||||
entry->d_name);
|
||||
|
||||
binding_parse_chunk(c->data.html.parser_binding,
|
||||
(uint8_t *) buffer, strlen(buffer));
|
||||
|
@ -28,9 +28,9 @@
|
||||
#include <stdbool.h>
|
||||
#include "content/content_type.h"
|
||||
|
||||
struct http_parameter;
|
||||
|
||||
bool directory_create(struct content *c, struct content *parent,
|
||||
const char *params[]);
|
||||
bool directory_create(struct content *c, const struct http_parameter *params);
|
||||
bool directory_convert(struct content *c, int width, int height);
|
||||
void directory_destroy(struct content *c);
|
||||
|
||||
|
161
render/favicon.c
161
render/favicon.c
@ -18,8 +18,8 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "content/fetch.h"
|
||||
#include "content/fetchcache.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "render/favicon.h"
|
||||
#include "render/html.h"
|
||||
#include "utils/log.h"
|
||||
@ -29,8 +29,8 @@
|
||||
#include "utils/utils.h"
|
||||
|
||||
static char *favicon_get_icon_ref(struct content *c, xmlNode *html);
|
||||
static void favicon_callback(content_msg msg, struct content *icon,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data);
|
||||
static nserror favicon_callback(hlcache_handle *icon,
|
||||
const hlcache_event *event, void *pw);
|
||||
|
||||
/**
|
||||
* retrieve 1 url reference to 1 favicon
|
||||
@ -39,68 +39,80 @@ static void favicon_callback(content_msg msg, struct content *icon,
|
||||
*/
|
||||
char *favicon_get_icon_ref(struct content *c, xmlNode *html)
|
||||
{
|
||||
xmlNode *node;
|
||||
char *rel, *href, *url, *url2;
|
||||
xmlNode *node = html;
|
||||
char *rel, *href, *url, *url2 = NULL;
|
||||
url_func_result res;
|
||||
union content_msg_data msg_data;
|
||||
|
||||
url2 = NULL;
|
||||
node = html;
|
||||
while (node) {
|
||||
if (node->children) { /* children */
|
||||
if (node->children != NULL) { /* children */
|
||||
node = node->children;
|
||||
} else if (node->next) { /* siblings */
|
||||
} else if (node->next != NULL) { /* siblings */
|
||||
node = node->next;
|
||||
} else { /* ancestor siblings */
|
||||
while (node && !node->next)
|
||||
while (node != NULL && node->next == NULL)
|
||||
node = node->parent;
|
||||
if (!node)
|
||||
|
||||
if (node == NULL)
|
||||
break;
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
assert(node);
|
||||
|
||||
assert(node != NULL);
|
||||
|
||||
if (node->type != XML_ELEMENT_NODE)
|
||||
continue;
|
||||
|
||||
if (strcmp((const char *) node->name, "link") == 0) {
|
||||
/* rel=<space separated list, including 'icon'> */
|
||||
if ((rel = (char *) xmlGetProp(node,
|
||||
(const xmlChar *) "rel")) == NULL)
|
||||
continue;
|
||||
|
||||
if (strcasestr(rel, "icon") == 0) {
|
||||
xmlFree(rel);
|
||||
continue;
|
||||
}
|
||||
LOG(("icon node found"));
|
||||
|
||||
if (strcasecmp(rel, "apple-touch-icon") == 0) {
|
||||
xmlFree(rel);
|
||||
continue;
|
||||
}
|
||||
|
||||
xmlFree(rel);
|
||||
|
||||
if ((href = (char *) xmlGetProp(node,
|
||||
(const xmlChar *) "href")) == NULL)
|
||||
continue;
|
||||
res = url_join(href, c->data.html.base_url,
|
||||
&url);
|
||||
|
||||
res = url_join(href, c->data.html.base_url, &url);
|
||||
|
||||
xmlFree(href);
|
||||
|
||||
if (res != URL_FUNC_OK)
|
||||
continue;
|
||||
LOG(("most recent favicon '%s'", url));
|
||||
|
||||
if (url2 != NULL) {
|
||||
free(url2);
|
||||
url2 = NULL;
|
||||
}
|
||||
|
||||
res = url_normalize(url, &url2);
|
||||
|
||||
free(url);
|
||||
|
||||
if (res != URL_FUNC_OK) {
|
||||
url2 = NULL;
|
||||
|
||||
if (res == URL_FUNC_NOMEM)
|
||||
goto no_memory;
|
||||
return NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (url2 == NULL) {
|
||||
char *scheme;
|
||||
|
||||
@ -123,12 +135,8 @@ char *favicon_get_icon_ref(struct content *c, xmlNode *html)
|
||||
!= URL_FUNC_OK)
|
||||
return NULL;
|
||||
}
|
||||
LOG(("favicon %s", url2));
|
||||
|
||||
return url2;
|
||||
no_memory:
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
/* content_broadcast(c, CONTENT_MSG_ERROR, msg_data); */
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,31 +148,27 @@ no_memory:
|
||||
|
||||
bool favicon_get_icon(struct content *c, xmlNode *html)
|
||||
{
|
||||
char *url = favicon_get_icon_ref(c, html);
|
||||
struct content *favcontent = NULL;
|
||||
char *url;
|
||||
nserror error;
|
||||
|
||||
url = favicon_get_icon_ref(c, html);
|
||||
if (url == NULL)
|
||||
return false;
|
||||
|
||||
favcontent = fetchcache(url, favicon_callback, (intptr_t) c, 0,
|
||||
c->width, c->height, true, 0, 0, false, false);
|
||||
error = hlcache_handle_retrieve(url, 0, NULL, NULL, c->width, c->height,
|
||||
favicon_callback, c, NULL, &c->data.html.favicon);
|
||||
|
||||
free(url);
|
||||
if (favcontent == NULL)
|
||||
return false;
|
||||
|
||||
c->data.html.favicon = favcontent;
|
||||
|
||||
fetchcache_go(favcontent, c->url, favicon_callback, (intptr_t) c, 0,
|
||||
c->width, c->height, 0, 0, false, c);
|
||||
|
||||
return true;
|
||||
return error == NSERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for fetchcache() for linked favicon
|
||||
*/
|
||||
|
||||
void favicon_callback(content_msg msg, struct content *icon,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data)
|
||||
nserror favicon_callback(hlcache_handle *icon,
|
||||
const hlcache_event *event, void *pw)
|
||||
{
|
||||
static const content_type permitted_types[] = {
|
||||
#ifdef WITH_BMP
|
||||
@ -178,88 +182,57 @@ void favicon_callback(content_msg msg, struct content *icon,
|
||||
#endif
|
||||
CONTENT_UNKNOWN
|
||||
};
|
||||
struct content *c = (struct content *) p1;
|
||||
unsigned int i = p2;
|
||||
struct content *c = pw;
|
||||
const content_type *type;
|
||||
|
||||
|
||||
switch (msg) {
|
||||
switch (event->type) {
|
||||
case CONTENT_MSG_LOADING:
|
||||
/* check that the favicon is really a correct image type */
|
||||
for (type = permitted_types; *type != CONTENT_UNKNOWN; type++)
|
||||
if (icon->type == *type)
|
||||
if (content_get_type(icon) == *type)
|
||||
break;
|
||||
|
||||
if (*type == CONTENT_UNKNOWN) {
|
||||
c->data.html.favicon = 0;
|
||||
LOG(("%s is not a favicon", icon->url));
|
||||
union content_msg_data msg_data;
|
||||
|
||||
hlcache_handle_release(c->data.html.favicon);
|
||||
c->data.html.favicon = NULL;
|
||||
LOG(("%s is not a favicon", content_get_url(icon)));
|
||||
content_add_error(c, "NotFavIco", 0);
|
||||
html_set_status(c, messages_get("NotFavIco"));
|
||||
content_broadcast(c, CONTENT_MSG_STATUS, data);
|
||||
content_remove_user(icon,
|
||||
favicon_callback,
|
||||
(intptr_t) c, i);
|
||||
if (!icon->user_list->next) {
|
||||
/* we were the only user and we don't want this
|
||||
* content, so stop it fetching and mark it as
|
||||
* having an error so it gets removed from the
|
||||
* cache next time content_clean() gets called
|
||||
*/
|
||||
fetch_abort(icon->fetch);
|
||||
icon->fetch = 0;
|
||||
icon->status = CONTENT_STATUS_ERROR;
|
||||
}
|
||||
|
||||
msg_data.error = messages_get("NotFavIco");
|
||||
content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
|
||||
}
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_READY:
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_DONE:
|
||||
LOG(("got favicon '%s'", icon->url));
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_LAUNCH:
|
||||
/* Fall through */
|
||||
case CONTENT_MSG_DONE:
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_ERROR:
|
||||
LOG(("favicon %s failed: %s", icon->url, data.error));
|
||||
/* The favicon we were fetching may have been
|
||||
* redirected, in that case, the object pointers
|
||||
* will differ, so ensure that the object that's
|
||||
* in error is still in use by us before invalidating
|
||||
* the pointer */
|
||||
if (c->data.html.favicon == icon) {
|
||||
c->data.html.favicon = 0;
|
||||
LOG(("favicon %s failed: %s",
|
||||
content_get_url(icon), event->data.error));
|
||||
hlcache_handle_release(c->data.html.favicon);
|
||||
c->data.html.favicon = NULL;
|
||||
|
||||
content_add_error(c, "?", 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_STATUS:
|
||||
html_set_status(c, icon->status_message);
|
||||
content_broadcast(c, CONTENT_MSG_STATUS, data);
|
||||
content_broadcast(c, CONTENT_MSG_STATUS, event->data);
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_NEWPTR:
|
||||
c->data.html.favicon = icon;
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_AUTH:
|
||||
c->data.html.favicon = 0;
|
||||
content_add_error(c, "?", 0);
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_SSL:
|
||||
c->data.html.favicon = 0;
|
||||
content_add_error(c, "?", 0);
|
||||
break;
|
||||
case CONTENT_MSG_REDRAW:
|
||||
/* currently no support for favicon animations */
|
||||
/* Fall through */
|
||||
case CONTENT_MSG_REFRESH:
|
||||
break;
|
||||
/* Fall through */
|
||||
case CONTENT_MSG_REFORMAT:
|
||||
/* would be unusual :) */
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
@ -20,7 +20,8 @@
|
||||
#define _NETSURF_RENDER_FAVICON_H_
|
||||
|
||||
#include <libxml/tree.h>
|
||||
#include "content/content.h"
|
||||
|
||||
struct content;
|
||||
|
||||
bool favicon_get_icon(struct content *c, xmlNode *html);
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "content/fetch.h"
|
||||
#include "css/css.h"
|
||||
#include "css/utils.h"
|
||||
#include "desktop/gui.h"
|
||||
@ -308,18 +309,18 @@ bool form_add_option(struct form_control *control, char *value, char *text,
|
||||
* \param form form to search for successful controls
|
||||
* \param submit_button control used to submit the form, if any
|
||||
* \param successful_controls updated to point to linked list of
|
||||
* form_successful_control, 0 if no controls
|
||||
* fetch_multipart_data, 0 if no controls
|
||||
* \return true on success, false on memory exhaustion
|
||||
*
|
||||
* See HTML 4.01 section 17.13.2.
|
||||
*/
|
||||
bool form_successful_controls(struct form *form,
|
||||
struct form_control *submit_button,
|
||||
struct form_successful_control **successful_controls)
|
||||
struct fetch_multipart_data **successful_controls)
|
||||
{
|
||||
struct form_control *control;
|
||||
struct form_option *option;
|
||||
struct form_successful_control sentinel, *last_success, *success_new;
|
||||
struct fetch_multipart_data sentinel, *last_success, *success_new;
|
||||
char *value = NULL;
|
||||
bool had_submit = false;
|
||||
char *charset;
|
||||
@ -603,7 +604,7 @@ bool form_successful_controls(struct form *form,
|
||||
|
||||
no_memory:
|
||||
warn_user("NoMemory", 0);
|
||||
form_free_successful(sentinel.next);
|
||||
fetch_multipart_data_destroy(sentinel.next);
|
||||
return false;
|
||||
|
||||
#undef ENCODE_ITEM
|
||||
@ -659,12 +660,12 @@ char *form_textarea_value(struct form_control *textarea)
|
||||
* Encode controls using application/x-www-form-urlencoded.
|
||||
*
|
||||
* \param form form to which successful controls relate
|
||||
* \param control linked list of form_successful_control
|
||||
* \param control linked list of fetch_multipart_data
|
||||
* \return URL-encoded form, or 0 on memory exhaustion
|
||||
*/
|
||||
|
||||
char *form_url_encode(struct form *form,
|
||||
struct form_successful_control *control)
|
||||
struct fetch_multipart_data *control)
|
||||
{
|
||||
char *name, *value;
|
||||
char *s = malloc(1), *s2;
|
||||
@ -713,24 +714,6 @@ char *form_url_encode(struct form *form,
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free a linked list of form_successful_control.
|
||||
*
|
||||
* \param control Pointer to head of list to free
|
||||
*/
|
||||
|
||||
void form_free_successful(struct form_successful_control *control)
|
||||
{
|
||||
struct form_successful_control *next;
|
||||
for (; control; control = next) {
|
||||
next = control->next;
|
||||
free(control->name);
|
||||
free(control->value);
|
||||
free(control);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an acceptable character set encoding with which to submit the form
|
||||
*
|
||||
|
@ -125,14 +125,6 @@ struct form_option {
|
||||
struct form_option* next;
|
||||
};
|
||||
|
||||
/** Successful control, as defined by HTML 4.01 17.13. */
|
||||
struct form_successful_control {
|
||||
bool file; /**< It's a file */
|
||||
char *name; /**< Control name. */
|
||||
char *value; /**< Current value. */
|
||||
struct form_successful_control *next; /**< Next in linked list. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Called by the select menu when it wants an area to be redrawn. The
|
||||
* coordinates are menu origin relative.
|
||||
@ -157,10 +149,9 @@ bool form_add_option(struct form_control *control, char *value, char *text,
|
||||
bool selected);
|
||||
bool form_successful_controls(struct form *form,
|
||||
struct form_control *submit_button,
|
||||
struct form_successful_control **successful_controls);
|
||||
struct fetch_multipart_data **successful_controls);
|
||||
char *form_url_encode(struct form *form,
|
||||
struct form_successful_control *control);
|
||||
void form_free_successful(struct form_successful_control *control);
|
||||
struct fetch_multipart_data *control);
|
||||
|
||||
bool form_open_select_menu(void *client_data,
|
||||
struct form_control *control,
|
||||
|
811
render/html.c
811
render/html.c
File diff suppressed because it is too large
Load Diff
@ -31,11 +31,13 @@
|
||||
#include "desktop/plot_style.h"
|
||||
#include "render/parser_binding.h"
|
||||
|
||||
struct fetch_multipart_data;
|
||||
struct box;
|
||||
struct rect;
|
||||
struct browser_window;
|
||||
struct content;
|
||||
struct form_successful_control;
|
||||
struct hlcache_handle;
|
||||
struct http_parameter;
|
||||
struct imagemap;
|
||||
struct object_params;
|
||||
struct plotters;
|
||||
@ -50,6 +52,18 @@ extern char *default_stylesheet_url;
|
||||
extern char *adblock_stylesheet_url;
|
||||
extern char *quirks_stylesheet_url;
|
||||
|
||||
/**
|
||||
* Container for stylesheets used by an HTML document
|
||||
*/
|
||||
struct html_stylesheet {
|
||||
/** Type of sheet */
|
||||
enum { HTML_STYLESHEET_EXTERNAL, HTML_STYLESHEET_INTERNAL } type;
|
||||
union {
|
||||
struct hlcache_handle *external;
|
||||
struct content_css_data *internal;
|
||||
} data; /**< Sheet data */
|
||||
};
|
||||
|
||||
struct frame_dimension {
|
||||
float value;
|
||||
enum {
|
||||
@ -68,7 +82,7 @@ typedef enum {
|
||||
|
||||
/** An object (<img>, <object>, etc.) in a CONTENT_HTML document. */
|
||||
struct content_html_object {
|
||||
struct content *content; /**< Content, or 0. */
|
||||
struct hlcache_handle *content; /**< Content, or 0. */
|
||||
struct box *box; /**< Node in box tree containing it. */
|
||||
/** Pointer to array of permitted content_type, terminated by
|
||||
* CONTENT_UNKNOWN, or 0 if any type is acceptable. */
|
||||
@ -120,8 +134,6 @@ struct content_html_data {
|
||||
xmlDoc *document;
|
||||
binding_quirks_mode quirks; /**< Quirkyness of document */
|
||||
|
||||
lwc_context *dict; /**< Internment context for this document */
|
||||
|
||||
char *encoding; /**< Encoding of source, 0 if unknown. */
|
||||
binding_encoding_source encoding_source;
|
||||
/**< Source of encoding information. */
|
||||
@ -133,12 +145,12 @@ struct content_html_data {
|
||||
colour background_colour; /**< Document background colour. */
|
||||
const struct font_functions *font_func;
|
||||
|
||||
struct content *favicon; /**< the favicon for the page */
|
||||
struct hlcache_handle *favicon; /**< the favicon for the page */
|
||||
|
||||
/** Number of entries in stylesheet_content. */
|
||||
unsigned int stylesheet_count;
|
||||
/** Stylesheets. Each may be 0. */
|
||||
struct nscss_import *stylesheets;
|
||||
struct html_stylesheet *stylesheets;
|
||||
/**< Style selection context */
|
||||
css_select_ctx *select_ctx;
|
||||
|
||||
@ -173,8 +185,7 @@ struct content_html_data {
|
||||
extern bool html_redraw_debug;
|
||||
|
||||
|
||||
bool html_create(struct content *c, struct content *parent,
|
||||
const char *params[]);
|
||||
bool html_create(struct content *c, const struct http_parameter *params);
|
||||
bool html_process_data(struct content *c, char *data, unsigned int size);
|
||||
bool html_convert(struct content *c, int width, int height);
|
||||
void html_reformat(struct content *c, int width, int height);
|
||||
@ -183,9 +194,6 @@ bool html_fetch_object(struct content *c, const char *url, struct box *box,
|
||||
const content_type *permitted_types,
|
||||
int available_width, int available_height,
|
||||
bool background);
|
||||
bool html_replace_object(struct content *c, unsigned int i, char *url,
|
||||
char *post_urlenc,
|
||||
struct form_successful_control *post_multipart);
|
||||
void html_stop(struct content *c);
|
||||
void html_open(struct content *c, struct browser_window *bw,
|
||||
struct content *page, unsigned int index, struct box *box,
|
||||
@ -212,4 +220,17 @@ bool text_redraw(const char *utf8_text, size_t utf8_len,
|
||||
float scale,
|
||||
bool excluded);
|
||||
|
||||
xmlDoc *html_get_document(struct hlcache_handle *h);
|
||||
struct box *html_get_box_tree(struct hlcache_handle *h);
|
||||
const char *html_get_encoding(struct hlcache_handle *h);
|
||||
struct content_html_frames *html_get_frameset(struct hlcache_handle *h);
|
||||
struct content_html_iframe *html_get_iframe(struct hlcache_handle *h);
|
||||
const char *html_get_base_url(struct hlcache_handle *h);
|
||||
const char *html_get_base_target(struct hlcache_handle *h);
|
||||
struct html_stylesheet *html_get_stylesheets(struct hlcache_handle *h,
|
||||
unsigned int *n);
|
||||
struct content_html_object *html_get_objects(struct hlcache_handle *h,
|
||||
unsigned int *n);
|
||||
struct hlcache_handle *html_get_favicon(struct hlcache_handle *h);
|
||||
|
||||
#endif
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "css/css.h"
|
||||
#include "css/utils.h"
|
||||
#include "desktop/gui.h"
|
||||
@ -1590,12 +1590,15 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
|
||||
/* handle background-repeat */
|
||||
switch (css_computed_background_repeat(background->style)) {
|
||||
case CSS_BACKGROUND_REPEAT_REPEAT:
|
||||
{
|
||||
struct bitmap *bmp = content_get_bitmap(
|
||||
background->background);
|
||||
repeat_x = repeat_y = true;
|
||||
/* optimisation: only plot the colour if
|
||||
* bitmap is not opaque */
|
||||
if (background->background->bitmap)
|
||||
plot_colour = !bitmap_get_opaque(
|
||||
background->background->bitmap);
|
||||
if (bmp != NULL)
|
||||
plot_colour = !bitmap_get_opaque(bmp);
|
||||
}
|
||||
break;
|
||||
case CSS_BACKGROUND_REPEAT_REPEAT_X:
|
||||
repeat_x = true;
|
||||
@ -1613,7 +1616,8 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
|
||||
css_computed_background_position(background->style,
|
||||
&hpos, &hunit, &vpos, &vunit);
|
||||
if (hunit == CSS_UNIT_PCT) {
|
||||
x += (width - background->background->width) *
|
||||
x += (width -
|
||||
content_get_width(background->background)) *
|
||||
scale * FIXTOFLT(hpos) / 100.;
|
||||
} else {
|
||||
x += (int) (FIXTOFLT(nscss_len2px(hpos, hunit,
|
||||
@ -1621,7 +1625,8 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
|
||||
}
|
||||
|
||||
if (vunit == CSS_UNIT_PCT) {
|
||||
y += (height - background->background->height) *
|
||||
y += (height -
|
||||
content_get_height(background->background)) *
|
||||
scale * FIXTOFLT(vpos) / 100.;
|
||||
} else {
|
||||
y += (int) (FIXTOFLT(nscss_len2px(vpos, vunit,
|
||||
@ -1651,6 +1656,8 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
|
||||
for (; clip_box; clip_box = clip_box->next) {
|
||||
/* clip to child boxes if needed */
|
||||
if (clip_to_children) {
|
||||
struct bitmap *bmp = NULL;
|
||||
|
||||
assert(clip_box->type == BOX_TABLE_CELL);
|
||||
|
||||
/* update clip_* to the child cell */
|
||||
@ -1668,15 +1675,15 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
|
||||
if (clip_x1 > px1) clip_x1 = px1;
|
||||
if (clip_y1 > py1) clip_y1 = py1;
|
||||
|
||||
if (clip_box->background != NULL)
|
||||
bmp = content_get_bitmap(clip_box->background);
|
||||
|
||||
/* <td> attributes override <tr> */
|
||||
if ((clip_x0 >= clip_x1) || (clip_y0 >= clip_y1) ||
|
||||
(css_computed_background_color(
|
||||
clip_box->style, &bgcol) !=
|
||||
CSS_BACKGROUND_COLOR_TRANSPARENT) ||
|
||||
(clip_box->background &&
|
||||
clip_box->background->bitmap &&
|
||||
bitmap_get_opaque(
|
||||
clip_box->background->bitmap)))
|
||||
(bmp != NULL && bitmap_get_opaque(bmp)))
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1693,35 +1700,30 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
|
||||
}
|
||||
/* and plot the image */
|
||||
if (plot_content) {
|
||||
width = content_get_width(background->background);
|
||||
height = content_get_height(background->background);
|
||||
|
||||
if (!repeat_x) {
|
||||
if (clip_x0 < x)
|
||||
clip_x0 = x;
|
||||
if (clip_x1 > x +
|
||||
background->background->width *
|
||||
scale)
|
||||
clip_x1 = x + background->background->
|
||||
width * scale;
|
||||
if (clip_x1 > x + width * scale)
|
||||
clip_x1 = x + width * scale;
|
||||
}
|
||||
if (!repeat_y) {
|
||||
if (clip_y0 < y)
|
||||
clip_y0 = y;
|
||||
if (clip_y1 > y +
|
||||
background->background->height *
|
||||
scale)
|
||||
clip_y1 = y + background->background->
|
||||
height * scale;
|
||||
if (clip_y1 > y + height * scale)
|
||||
clip_y1 = y + height * scale;
|
||||
}
|
||||
/* valid clipping rectangles only */
|
||||
if ((clip_x0 < clip_x1) && (clip_y0 < clip_y1)) {
|
||||
if (!plot.clip(clip_x0, clip_y0,
|
||||
clip_x1, clip_y1))
|
||||
return false;
|
||||
if (!content_redraw_tiled(background->
|
||||
background, x, y,
|
||||
ceilf(background->background->
|
||||
width * scale),
|
||||
ceilf(background->background->
|
||||
height * scale),
|
||||
if (!content_redraw_tiled(
|
||||
background->background, x, y,
|
||||
ceilf(width * scale),
|
||||
ceilf(height * scale),
|
||||
clip_x0, clip_y0,
|
||||
clip_x1, clip_y1,
|
||||
scale, *background_colour,
|
||||
@ -1785,12 +1787,15 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
|
||||
/* handle background-repeat */
|
||||
switch (css_computed_background_repeat(box->style)) {
|
||||
case CSS_BACKGROUND_REPEAT_REPEAT:
|
||||
{
|
||||
struct bitmap *bmp =
|
||||
content_get_bitmap(box->background);
|
||||
repeat_x = repeat_y = true;
|
||||
/* optimisation: only plot the colour if
|
||||
* bitmap is not opaque */
|
||||
if (box->background->bitmap)
|
||||
plot_colour = !bitmap_get_opaque(
|
||||
box->background->bitmap);
|
||||
if (bmp != NULL)
|
||||
plot_colour = !bitmap_get_opaque(bmp);
|
||||
}
|
||||
break;
|
||||
case CSS_BACKGROUND_REPEAT_REPEAT_X:
|
||||
repeat_x = true;
|
||||
@ -1808,8 +1813,8 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
|
||||
css_computed_background_position(box->style,
|
||||
&hpos, &hunit, &vpos, &vunit);
|
||||
if (hunit == CSS_UNIT_PCT) {
|
||||
x += (px1 - px0 - box->background->width * scale) *
|
||||
FIXTOFLT(hpos) / 100.;
|
||||
x += (px1 - px0 - content_get_width(box->background) *
|
||||
scale) * FIXTOFLT(hpos) / 100.;
|
||||
|
||||
if (!repeat_x && ((hpos < 2 && !first) ||
|
||||
(hpos > 98 && !last))){
|
||||
@ -1821,8 +1826,8 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
|
||||
}
|
||||
|
||||
if (vunit == CSS_UNIT_PCT) {
|
||||
y += (py1 - py0 - box->background->height * scale) *
|
||||
FIXTOFLT(vpos) / 100.;
|
||||
y += (py1 - py0 - content_get_height(box->background) *
|
||||
scale) * FIXTOFLT(vpos) / 100.;
|
||||
} else {
|
||||
y += (int) (FIXTOFLT(nscss_len2px(vpos, vunit,
|
||||
box->style)) * scale);
|
||||
@ -1843,35 +1848,29 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
|
||||
}
|
||||
/* and plot the image */
|
||||
if (plot_content) {
|
||||
int width = content_get_width(box->background);
|
||||
int height = content_get_height(box->background);
|
||||
|
||||
if (!repeat_x) {
|
||||
if (clip_x0 < x)
|
||||
clip_x0 = x;
|
||||
if (clip_x1 > x +
|
||||
box->background->width *
|
||||
scale)
|
||||
clip_x1 = x + box->background->
|
||||
width * scale;
|
||||
if (clip_x1 > x + width * scale)
|
||||
clip_x1 = x + width * scale;
|
||||
}
|
||||
if (!repeat_y) {
|
||||
if (clip_y0 < y)
|
||||
clip_y0 = y;
|
||||
if (clip_y1 > y +
|
||||
box->background->height *
|
||||
scale)
|
||||
clip_y1 = y + box->background->
|
||||
height * scale;
|
||||
if (clip_y1 > y + height * scale)
|
||||
clip_y1 = y + height * scale;
|
||||
}
|
||||
/* valid clipping rectangles only */
|
||||
if ((clip_x0 < clip_x1) && (clip_y0 < clip_y1)) {
|
||||
if (!plot.clip(clip_x0, clip_y0,
|
||||
clip_x1, clip_y1))
|
||||
return false;
|
||||
if (!content_redraw_tiled(box->
|
||||
background, x, y,
|
||||
ceilf(box->background->
|
||||
width * scale),
|
||||
ceilf(box->background->
|
||||
height * scale),
|
||||
if (!content_redraw_tiled(box->background, x, y,
|
||||
ceilf(width * scale),
|
||||
ceilf(height * scale),
|
||||
clip_x0, clip_y0,
|
||||
clip_x1, clip_y1,
|
||||
scale, *background_colour,
|
||||
|
@ -24,7 +24,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "render/box.h"
|
||||
#include "render/imagemap.h"
|
||||
#include "utils/log.h"
|
||||
@ -626,7 +627,7 @@ void imagemap_freelist(struct mapentry *list)
|
||||
/**
|
||||
* Retrieve url associated with imagemap entry
|
||||
*
|
||||
* \param c The containing content
|
||||
* \param h The containing content
|
||||
* \param key The map name to search for
|
||||
* \param x The left edge of the containing box
|
||||
* \param y The top edge of the containing box
|
||||
@ -635,11 +636,12 @@ void imagemap_freelist(struct mapentry *list)
|
||||
* \param target Pointer to location to receive target pointer (if any)
|
||||
* \return The url associated with this area, or NULL if not found
|
||||
*/
|
||||
const char *imagemap_get(struct content *c, const char *key,
|
||||
const char *imagemap_get(hlcache_handle *h, const char *key,
|
||||
unsigned long x, unsigned long y,
|
||||
unsigned long click_x, unsigned long click_y,
|
||||
const char **target)
|
||||
{
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
unsigned int slot = 0;
|
||||
struct imagemap *map;
|
||||
struct mapentry *entry;
|
||||
|
@ -22,11 +22,13 @@
|
||||
#include <libxml/HTMLtree.h>
|
||||
|
||||
struct content;
|
||||
struct hlcache_handle;
|
||||
|
||||
void imagemap_destroy(struct content *c);
|
||||
void imagemap_dump(struct content *c);
|
||||
bool imagemap_extract(xmlNode *node, struct content *c);
|
||||
const char *imagemap_get(struct content *c, const char *key,
|
||||
|
||||
const char *imagemap_get(struct hlcache_handle *h, const char *key,
|
||||
unsigned long x, unsigned long y,
|
||||
unsigned long click_x, unsigned long click_y,
|
||||
const char **target);
|
||||
|
110
render/layout.c
110
render/layout.c
@ -41,7 +41,7 @@
|
||||
#include <math.h>
|
||||
#include "css/css.h"
|
||||
#include "css/utils.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "desktop/gui.h"
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/scroll.h"
|
||||
@ -256,12 +256,14 @@ bool layout_block_context(struct box *block, int viewport_height,
|
||||
if (!layout_block_object(block))
|
||||
return false;
|
||||
if (block->height == AUTO) {
|
||||
if (block->object->width)
|
||||
block->height = block->object->height *
|
||||
if (content_get_width(block->object))
|
||||
block->height =
|
||||
content_get_height(block->object) *
|
||||
(float) block->width /
|
||||
block->object->width;
|
||||
content_get_width(block->object);
|
||||
else
|
||||
block->height = block->object->height;
|
||||
block->height =
|
||||
content_get_height(block->object);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -691,13 +693,13 @@ void layout_minmax_block(struct box *block,
|
||||
}
|
||||
|
||||
if (block->object) {
|
||||
if (block->object->type == CONTENT_HTML) {
|
||||
layout_minmax_block(block->object->data.html.layout,
|
||||
if (content_get_type(block->object) == CONTENT_HTML) {
|
||||
layout_minmax_block(html_get_box_tree(block->object),
|
||||
font_func);
|
||||
min = block->object->data.html.layout->min_width;
|
||||
max = block->object->data.html.layout->max_width;
|
||||
min = html_get_box_tree(block->object)->min_width;
|
||||
max = html_get_box_tree(block->object)->max_width;
|
||||
} else {
|
||||
min = max = block->object->width;
|
||||
min = max = content_get_width(block->object);
|
||||
}
|
||||
} else {
|
||||
/* recurse through children */
|
||||
@ -795,9 +797,9 @@ bool layout_block_object(struct box *block)
|
||||
LOG(("block %p, object %s, width %i", block, block->object->url,
|
||||
block->width));
|
||||
|
||||
if (block->object->type == CONTENT_HTML) {
|
||||
if (content_get_type(block->object) == CONTENT_HTML) {
|
||||
content_reformat(block->object, block->width, 1);
|
||||
block->height = block->object->height;
|
||||
block->height = content_get_height(block->object);
|
||||
} else {
|
||||
/* this case handled already in
|
||||
* layout_block_find_dimensions() */
|
||||
@ -837,25 +839,25 @@ void layout_block_find_dimensions(int available_width, int viewport_height,
|
||||
&width, &height, &max_width, &min_width,
|
||||
margin, padding, border);
|
||||
|
||||
if (box->object && box->object->type != CONTENT_HTML) {
|
||||
if (box->object && content_get_type(box->object) != CONTENT_HTML) {
|
||||
/* block-level replaced element, see 10.3.4 and 10.6.2 */
|
||||
if (width == AUTO && height == AUTO) {
|
||||
width = box->object->width;
|
||||
height = box->object->height;
|
||||
width = content_get_width(box->object);
|
||||
height = content_get_height(box->object);
|
||||
} else if (width == AUTO) {
|
||||
if (box->object->height)
|
||||
width = box->object->width *
|
||||
if (content_get_height(box->object))
|
||||
width = content_get_width(box->object) *
|
||||
(float) height /
|
||||
box->object->height;
|
||||
content_get_height(box->object);
|
||||
else
|
||||
width = box->object->width;
|
||||
width = content_get_width(box->object);
|
||||
} else if (height == AUTO) {
|
||||
if (box->object->width)
|
||||
height = box->object->height *
|
||||
if (content_get_width(box->object))
|
||||
height = content_get_height(box->object) *
|
||||
(float) width /
|
||||
box->object->width;
|
||||
content_get_width(box->object);
|
||||
else
|
||||
height = box->object->height;
|
||||
height = content_get_height(box->object);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1168,18 +1170,20 @@ void layout_float_find_dimensions(int available_width,
|
||||
padding[RIGHT] += scrollbar_width;
|
||||
padding[BOTTOM] += scrollbar_width;
|
||||
|
||||
if (box->object && box->object->type != CONTENT_HTML) {
|
||||
if (box->object && content_get_type(box->object) != CONTENT_HTML) {
|
||||
/* Floating replaced element, with intrinsic width or height.
|
||||
* See 10.3.6 and 10.6.2 */
|
||||
if (width == AUTO && height == AUTO) {
|
||||
width = box->object->width;
|
||||
height = box->object->height;
|
||||
width = content_get_width(box->object);
|
||||
height = content_get_height(box->object);
|
||||
} else if (width == AUTO)
|
||||
width = box->object->width * (float) height /
|
||||
box->object->height;
|
||||
width = content_get_width(box->object) *
|
||||
(float) height /
|
||||
content_get_height(box->object);
|
||||
else if (height == AUTO)
|
||||
height = box->object->height * (float) width /
|
||||
box->object->width;
|
||||
height = content_get_height(box->object) *
|
||||
(float) width /
|
||||
content_get_width(box->object);
|
||||
} else if (box->gadget && (box->gadget->type == GADGET_TEXTBOX ||
|
||||
box->gadget->type == GADGET_PASSWORD ||
|
||||
box->gadget->type == GADGET_FILE ||
|
||||
@ -2079,22 +2083,25 @@ bool layout_line(struct box *first, int *width, int *y,
|
||||
|
||||
if (b->object) {
|
||||
if (b->width == AUTO && b->height == AUTO) {
|
||||
b->width = b->object->width;
|
||||
b->height = b->object->height;
|
||||
b->width = content_get_width(b->object);
|
||||
b->height = content_get_height(b->object);
|
||||
} else if (b->width == AUTO) {
|
||||
if (b->object->height)
|
||||
b->width = b->object->width *
|
||||
if (content_get_height(b->object))
|
||||
b->width =
|
||||
content_get_width(b->object) *
|
||||
(float) b->height /
|
||||
b->object->height;
|
||||
content_get_height(b->object);
|
||||
else
|
||||
b->width = b->object->width;
|
||||
b->width = content_get_width(b->object);
|
||||
} else if (b->height == AUTO) {
|
||||
if (b->object->width)
|
||||
b->height = b->object->height *
|
||||
if (content_get_width(b->object))
|
||||
b->height =
|
||||
content_get_height(b->object) *
|
||||
(float) b->width /
|
||||
b->object->width;
|
||||
content_get_width(b->object);
|
||||
else
|
||||
b->height = b->object->height;
|
||||
b->height =
|
||||
content_get_height(b->object);
|
||||
}
|
||||
} else {
|
||||
/* form control with no object */
|
||||
@ -2106,14 +2113,15 @@ bool layout_line(struct box *first, int *width, int *y,
|
||||
CSS_UNIT_EM, b->style));
|
||||
}
|
||||
|
||||
if (b->object && b->object->type == CONTENT_HTML &&
|
||||
b->width != b->object->available_width) {
|
||||
if (b->object && content_get_type(b->object) == CONTENT_HTML &&
|
||||
b->width !=
|
||||
content_get_available_width(b->object)) {
|
||||
htype = css_computed_height(b->style, &value, &unit);
|
||||
|
||||
content_reformat(b->object, b->width, b->height);
|
||||
|
||||
if (htype == CSS_HEIGHT_AUTO)
|
||||
b->height = b->object->height;
|
||||
b->height = content_get_height(b->object);
|
||||
}
|
||||
|
||||
if (height < b->height)
|
||||
@ -2745,14 +2753,14 @@ struct box *layout_minmax_line(struct box *first,
|
||||
|
||||
if (b->object) {
|
||||
if (width == AUTO && height == AUTO) {
|
||||
width = b->object->width;
|
||||
width = content_get_width(b->object);
|
||||
} else if (width == AUTO) {
|
||||
if (b->object->height)
|
||||
width = b->object->width *
|
||||
if (content_get_height(b->object))
|
||||
width = content_get_width(b->object) *
|
||||
(float) height /
|
||||
b->object->height;
|
||||
content_get_height(b->object);
|
||||
else
|
||||
width = b->object->width;
|
||||
width = content_get_width(b->object);
|
||||
}
|
||||
fixed = frac = 0;
|
||||
calculate_mbp_width(b->style, LEFT, true, true, true,
|
||||
@ -3709,9 +3717,11 @@ void layout_lists(struct box *box,
|
||||
if (child->list_marker) {
|
||||
marker = child->list_marker;
|
||||
if (marker->object) {
|
||||
marker->width = marker->object->width;
|
||||
marker->width =
|
||||
content_get_width(marker->object);
|
||||
marker->x = -marker->width;
|
||||
marker->height = marker->object->height;
|
||||
marker->height =
|
||||
content_get_height(marker->object);
|
||||
marker->y = (line_height(marker->style) -
|
||||
marker->height) / 2;
|
||||
} else if (marker->text) {
|
||||
|
@ -28,7 +28,8 @@
|
||||
#include <strings.h>
|
||||
#include <math.h>
|
||||
#include <iconv.h>
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "css/css.h"
|
||||
#include "css/utils.h"
|
||||
#include "desktop/gui.h"
|
||||
@ -39,6 +40,7 @@
|
||||
#include "render/box.h"
|
||||
#include "render/font.h"
|
||||
#include "render/textplain.h"
|
||||
#include "utils/http.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/talloc.h"
|
||||
@ -72,14 +74,13 @@ static float textplain_line_height(void);
|
||||
* Create a CONTENT_TEXTPLAIN.
|
||||
*/
|
||||
|
||||
bool textplain_create(struct content *c, struct content *parent,
|
||||
const char *params[])
|
||||
bool textplain_create(struct content *c, const http_parameter *params)
|
||||
{
|
||||
unsigned int i;
|
||||
char *utf8_data;
|
||||
const char *encoding = "iso-8859-1";
|
||||
const char *encoding;
|
||||
iconv_t iconv_cd;
|
||||
union content_msg_data msg_data;
|
||||
nserror error;
|
||||
|
||||
textplain_style.size = (option_font_size * FONT_SIZE_SCALE) / 10;
|
||||
|
||||
@ -87,13 +88,9 @@ bool textplain_create(struct content *c, struct content *parent,
|
||||
if (!utf8_data)
|
||||
goto no_memory;
|
||||
|
||||
for (i = 0; params[i]; i += 2) {
|
||||
if (strcasecmp(params[i], "charset") == 0) {
|
||||
encoding = talloc_strdup(c, params[i + 1]);
|
||||
if (!encoding)
|
||||
goto no_memory;
|
||||
break;
|
||||
}
|
||||
error = http_parameter_list_find_item(params, "charset", &encoding);
|
||||
if (error != NSERROR_OK) {
|
||||
encoding = "Windows-1252";
|
||||
}
|
||||
|
||||
iconv_cd = iconv_open("utf-8", encoding);
|
||||
@ -141,18 +138,22 @@ bool textplain_process_data(struct content *c, char *data, unsigned int size)
|
||||
iconv_t iconv_cd = c->data.textplain.iconv_cd;
|
||||
size_t count;
|
||||
union content_msg_data msg_data;
|
||||
const char *source_data;
|
||||
unsigned long source_size;
|
||||
|
||||
source_data = content__get_source_data(c, &source_size);
|
||||
|
||||
do {
|
||||
char *inbuf = c->source_data + c->data.textplain.converted;
|
||||
size_t inbytesleft = c->source_size -
|
||||
char *inbuf = (char *) source_data +
|
||||
c->data.textplain.converted;
|
||||
size_t inbytesleft = source_size - c->data.textplain.converted;
|
||||
char *outbuf = c->data.textplain.utf8_data +
|
||||
c->data.textplain.utf8_data_size;
|
||||
size_t outbytesleft = c->data.textplain.utf8_data_allocated -
|
||||
c->data.textplain.utf8_data_size;
|
||||
count = iconv(iconv_cd, &inbuf, &inbytesleft,
|
||||
&outbuf, &outbytesleft);
|
||||
c->data.textplain.converted = inbuf - c->source_data;
|
||||
c->data.textplain.converted = inbuf - source_data;
|
||||
c->data.textplain.utf8_data_size = c->data.textplain.
|
||||
utf8_data_allocated - outbytesleft;
|
||||
|
||||
@ -180,7 +181,7 @@ bool textplain_process_data(struct content *c, char *data, unsigned int size)
|
||||
}
|
||||
|
||||
gui_multitask();
|
||||
} while (!(c->data.textplain.converted == c->source_size ||
|
||||
} while (!(c->data.textplain.converted == source_size ||
|
||||
(count == (size_t)(-1) && errno == EINVAL)));
|
||||
|
||||
return true;
|
||||
@ -466,6 +467,35 @@ bool textplain_redraw(struct content *c, int x, int y,
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve number of lines in content
|
||||
*
|
||||
* \param h Content to retrieve line count from
|
||||
* \return Number of lines
|
||||
*/
|
||||
unsigned long textplain_line_count(hlcache_handle *h)
|
||||
{
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
|
||||
assert(c != NULL);
|
||||
|
||||
return c->data.textplain.physical_line_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the size (in bytes) of text data
|
||||
*
|
||||
* \param h Content to retrieve size of
|
||||
* \return Size, in bytes, of data
|
||||
*/
|
||||
size_t textplain_size(hlcache_handle *h)
|
||||
{
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
|
||||
assert(c != NULL);
|
||||
|
||||
return c->data.textplain.utf8_data_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return byte offset within UTF8 textplain content, given the co-ordinates
|
||||
@ -473,15 +503,16 @@ bool textplain_redraw(struct content *c, int x, int y,
|
||||
* which to search (-1 = above-left, +1 = below-right) if the co-ordinates are not
|
||||
* contained within a line.
|
||||
*
|
||||
* \param c content of type CONTENT_TEXTPLAIN
|
||||
* \param h content of type CONTENT_TEXTPLAIN
|
||||
* \param x x ordinate of point
|
||||
* \param y y ordinate of point
|
||||
* \param dir direction of search if not within line
|
||||
* \return byte offset of character containing (or nearest to) point
|
||||
*/
|
||||
|
||||
size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir)
|
||||
size_t textplain_offset_from_coords(hlcache_handle *h, int x, int y, int dir)
|
||||
{
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
float line_height = textplain_line_height();
|
||||
struct textplain_line *line;
|
||||
const char *text;
|
||||
@ -489,6 +520,7 @@ size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir)
|
||||
size_t length;
|
||||
int idx;
|
||||
|
||||
assert(c != NULL);
|
||||
assert(c->type == CONTENT_TEXTPLAIN);
|
||||
|
||||
y = (int)((float)(y - MARGIN) / line_height);
|
||||
@ -552,19 +584,24 @@ size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir)
|
||||
* Given a byte offset within the text, return the line number
|
||||
* of the line containing that offset (or -1 if offset invalid)
|
||||
*
|
||||
* \param c content of type CONTENT_TEXTPLAIN
|
||||
* \param h content of type CONTENT_TEXTPLAIN
|
||||
* \param offset byte offset within textual representation
|
||||
* \return line number, or -1 if offset invalid (larger than size)
|
||||
*/
|
||||
|
||||
int textplain_find_line(struct content *c, unsigned offset)
|
||||
int textplain_find_line(hlcache_handle *h, unsigned offset)
|
||||
{
|
||||
struct textplain_line *line = c->data.textplain.physical_line;
|
||||
int nlines = c->data.textplain.physical_line_count;
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
struct textplain_line *line;
|
||||
int nlines;
|
||||
int lineno = 0;
|
||||
|
||||
assert(c != NULL);
|
||||
assert(c->type == CONTENT_TEXTPLAIN);
|
||||
|
||||
line = c->data.textplain.physical_line;
|
||||
nlines = c->data.textplain.physical_line_count;
|
||||
|
||||
if (offset > c->data.textplain.utf8_data_size)
|
||||
return -1;
|
||||
|
||||
@ -622,30 +659,33 @@ int textplain_coord_from_offset(const char *text, size_t offset, size_t length)
|
||||
* Given a range of byte offsets within a UTF8 textplain content,
|
||||
* return a box that fully encloses the text
|
||||
*
|
||||
* \param c content of type CONTENT_TEXTPLAIN
|
||||
* \param h content of type CONTENT_TEXTPLAIN
|
||||
* \param start byte offset of start of text range
|
||||
* \param end byte offset of end
|
||||
* \param r rectangle to be completed
|
||||
*/
|
||||
|
||||
void textplain_coords_from_range(struct content *c, unsigned start, unsigned end,
|
||||
struct rect *r)
|
||||
void textplain_coords_from_range(hlcache_handle *h, unsigned start,
|
||||
unsigned end, struct rect *r)
|
||||
{
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
float line_height = textplain_line_height();
|
||||
char *utf8_data = c->data.textplain.utf8_data;
|
||||
char *utf8_data;
|
||||
struct textplain_line *line;
|
||||
unsigned lineno = 0;
|
||||
unsigned nlines;
|
||||
|
||||
assert(c != NULL);
|
||||
assert(c->type == CONTENT_TEXTPLAIN);
|
||||
assert(start <= end);
|
||||
assert(end <= c->data.textplain.utf8_data_size);
|
||||
|
||||
utf8_data = c->data.textplain.utf8_data;
|
||||
nlines = c->data.textplain.physical_line_count;
|
||||
line = c->data.textplain.physical_line;
|
||||
|
||||
/* find start */
|
||||
lineno = textplain_find_line(c, start);
|
||||
lineno = textplain_find_line(h, start);
|
||||
|
||||
r->y0 = (int)(MARGIN + lineno * line_height);
|
||||
|
||||
@ -654,7 +694,7 @@ void textplain_coords_from_range(struct content *c, unsigned start, unsigned end
|
||||
forwards most of the time */
|
||||
|
||||
/* find end */
|
||||
lineno = textplain_find_line(c, end);
|
||||
lineno = textplain_find_line(h, end);
|
||||
|
||||
r->x0 = 0;
|
||||
r->x1 = c->data.textplain.formatted_width;
|
||||
@ -677,18 +717,20 @@ void textplain_coords_from_range(struct content *c, unsigned start, unsigned end
|
||||
/**
|
||||
* Return a pointer to the requested line of text.
|
||||
*
|
||||
* \param c content of type CONTENT_TEXTPLAIN
|
||||
* \param h content of type CONTENT_TEXTPLAIN
|
||||
* \param lineno line number
|
||||
* \param poffset receives byte offset of line start within text
|
||||
* \param plen receives length of returned line
|
||||
* \return pointer to text, or NULL if invalid line number
|
||||
*/
|
||||
|
||||
char *textplain_get_line(struct content *c, unsigned lineno,
|
||||
char *textplain_get_line(hlcache_handle *h, unsigned lineno,
|
||||
size_t *poffset, size_t *plen)
|
||||
{
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
struct textplain_line *line;
|
||||
|
||||
assert(c != NULL);
|
||||
assert(c->type == CONTENT_TEXTPLAIN);
|
||||
|
||||
if (lineno >= c->data.textplain.physical_line_count)
|
||||
@ -706,20 +748,24 @@ char *textplain_get_line(struct content *c, unsigned lineno,
|
||||
* text to fit the window width. Thus only hard newlines are preserved
|
||||
* in the saved/copied text of a selection.
|
||||
*
|
||||
* \param c content of type CONTENT_TEXTPLAIN
|
||||
* \param h content of type CONTENT_TEXTPLAIN
|
||||
* \param start starting byte offset within UTF-8 text
|
||||
* \param end ending byte offset
|
||||
* \param plen receives validated length
|
||||
* \return pointer to text, or NULL if no text
|
||||
*/
|
||||
|
||||
char *textplain_get_raw_data(struct content *c, unsigned start, unsigned end,
|
||||
char *textplain_get_raw_data(hlcache_handle *h, unsigned start, unsigned end,
|
||||
size_t *plen)
|
||||
{
|
||||
size_t utf8_size = c->data.textplain.utf8_data_size;
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
size_t utf8_size;
|
||||
|
||||
assert(c != NULL);
|
||||
assert(c->type == CONTENT_TEXTPLAIN);
|
||||
|
||||
utf8_size = c->data.textplain.utf8_data_size;
|
||||
|
||||
/* any text at all? */
|
||||
if (!utf8_size) return NULL;
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include <iconv.h>
|
||||
|
||||
struct content;
|
||||
struct hlcache_handle;
|
||||
struct http_parameter;
|
||||
|
||||
struct textplain_line {
|
||||
size_t start;
|
||||
@ -46,8 +48,7 @@ struct content_textplain_data {
|
||||
int formatted_width;
|
||||
};
|
||||
|
||||
bool textplain_create(struct content *c, struct content *parent,
|
||||
const char *params[]);
|
||||
bool textplain_create(struct content *c, const struct http_parameter *params);
|
||||
bool textplain_process_data(struct content *c, char *data, unsigned int size);
|
||||
bool textplain_convert(struct content *c, int width, int height);
|
||||
void textplain_reformat(struct content *c, int width, int height);
|
||||
@ -58,16 +59,17 @@ bool textplain_redraw(struct content *c, int x, int y,
|
||||
float scale, colour background_colour);
|
||||
|
||||
/* access to lines for text selection and searching */
|
||||
#define textplain_line_count(c) ((c)->data.textplain.physical_line_count)
|
||||
#define textplain_size(c) ((c)->data.textplain.utf8_data_size)
|
||||
unsigned long textplain_line_count(struct hlcache_handle *h);
|
||||
size_t textplain_size(struct hlcache_handle *h);
|
||||
|
||||
size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir);
|
||||
void textplain_coords_from_range(struct content *c,
|
||||
size_t textplain_offset_from_coords(struct hlcache_handle *h, int x, int y,
|
||||
int dir);
|
||||
void textplain_coords_from_range(struct hlcache_handle *h,
|
||||
unsigned start, unsigned end, struct rect *r);
|
||||
char *textplain_get_line(struct content *c, unsigned lineno,
|
||||
char *textplain_get_line(struct hlcache_handle *h, unsigned lineno,
|
||||
size_t *poffset, size_t *plen);
|
||||
int textplain_find_line(struct content *c, unsigned offset);
|
||||
char *textplain_get_raw_data(struct content *c,
|
||||
int textplain_find_line(struct hlcache_handle *h, unsigned offset);
|
||||
char *textplain_get_raw_data(struct hlcache_handle *h,
|
||||
unsigned start, unsigned end, size_t *plen);
|
||||
|
||||
#endif
|
||||
|
10
riscos/gui.c
10
riscos/gui.c
@ -279,7 +279,15 @@ static void *myrealloc(void *ptr, size_t len, void *pw)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
setbuf(stderr, NULL);
|
||||
return netsurf_main(argc, argv);
|
||||
|
||||
/* initialise netsurf */
|
||||
netsurf_init(argc, argv);
|
||||
|
||||
netsurf_main_loop();
|
||||
|
||||
netsurf_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1396,12 +1396,10 @@ bool gui_window_frame_resize_start(struct gui_window *g)
|
||||
* \param g gui_window containing the content
|
||||
* \param c the content to save
|
||||
*/
|
||||
|
||||
void gui_window_save_as_link(struct gui_window *g, struct content *c)
|
||||
void gui_window_save_link(struct gui_window *g, const char *url,
|
||||
const char *title)
|
||||
{
|
||||
if (!c)
|
||||
return;
|
||||
ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL, c->url, c->title);
|
||||
ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL, url, title);
|
||||
ro_gui_dialog_open_persistent(g->window, dialog_saveas, true);
|
||||
}
|
||||
|
||||
|
19
test/Makefile
Normal file
19
test/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
CFLAGS := -std=c99 -g -O0 -D_BSD_SOURCE -D_POSIX_C_SOURCE -I.. \
|
||||
`pkg-config --cflags libxml-2.0 libcurl libparserutils`
|
||||
LDFLAGS := `pkg-config --libs libxml-2.0 libcurl libparserutils`
|
||||
|
||||
llcache_SRCS := content/fetch.c content/fetchers/fetch_curl.c \
|
||||
content/fetchers/fetch_data.c content/llcache.c \
|
||||
content/urldb.c desktop/options.c desktop/version.c \
|
||||
utils/base64.c utils/hashtable.c utils/messages.c \
|
||||
utils/url.c utils/useragent.c utils/utf8.c utils/utils.c \
|
||||
test/llcache.c
|
||||
|
||||
llcache: $(addprefix ../,$(llcache_SRCS))
|
||||
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
$(RM) llcache
|
282
test/llcache.c
Normal file
282
test/llcache.c
Normal file
@ -0,0 +1,282 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "content/fetch.h"
|
||||
#include "content/llcache.h"
|
||||
#include "utils/ring.h"
|
||||
#include "utils/url.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Things that we'd reasonably expect to have to implement *
|
||||
******************************************************************************/
|
||||
|
||||
/* desktop/netsurf.h */
|
||||
bool verbose_log;
|
||||
|
||||
/* utils/utils.h */
|
||||
void die(const char * const error)
|
||||
{
|
||||
fprintf(stderr, "%s\n", error);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* utils/utils.h */
|
||||
void warn_user(const char *warning, const char *detail)
|
||||
{
|
||||
fprintf(stderr, "%s %s\n", warning, detail);
|
||||
}
|
||||
|
||||
/* content/fetch.h */
|
||||
const char *fetch_filetype(const char *unix_path)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* content/fetch.h */
|
||||
char *fetch_mimetype(const char *ro_path)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Things that are absolutely not reasonable, and should disappear *
|
||||
******************************************************************************/
|
||||
|
||||
#include "desktop/cookies.h"
|
||||
#include "desktop/tree.h"
|
||||
|
||||
/* desktop/cookies.h -- used by urldb
|
||||
*
|
||||
* URLdb should have a cookies update event + handler registration
|
||||
*/
|
||||
bool cookies_update(const char *domain, const struct cookie_data *data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* image/bitmap.h -- used by urldb
|
||||
*
|
||||
* URLdb shouldn't care about bitmaps.
|
||||
* This is because the legacy RO thumbnail stuff was hacked in and must die.
|
||||
*/
|
||||
void bitmap_destroy(void *bitmap)
|
||||
{
|
||||
}
|
||||
|
||||
/* desktop/tree.h -- used by options.c
|
||||
*
|
||||
* Why on earth is tree loading and saving in options.c?
|
||||
*/
|
||||
void tree_initialise(struct tree *tree)
|
||||
{
|
||||
}
|
||||
|
||||
/* desktop/tree.h */
|
||||
struct node *tree_create_folder_node(struct node *parent, const char *title)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* desktop/tree.h */
|
||||
struct node *tree_create_URL_node(struct node *parent, const char *url,
|
||||
const struct url_data *data, const char *title)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* desktop/tree.h */
|
||||
struct node_element *tree_find_element(struct node *node, node_element_data d)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* test: protocol handler *
|
||||
******************************************************************************/
|
||||
|
||||
typedef struct test_context {
|
||||
struct fetch *parent;
|
||||
|
||||
bool aborted;
|
||||
bool locked;
|
||||
|
||||
struct test_context *r_prev;
|
||||
struct test_context *r_next;
|
||||
} test_context;
|
||||
|
||||
static test_context *ring;
|
||||
|
||||
bool test_initialise(const char *scheme)
|
||||
{
|
||||
/* Nothing to do */
|
||||
return true;
|
||||
}
|
||||
|
||||
void test_finalise(const char *scheme)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
void *test_setup_fetch(struct fetch *parent, const char *url, bool only_2xx,
|
||||
const char *post_urlenc,
|
||||
struct fetch_multipart_data *post_multipart,
|
||||
const char **headers)
|
||||
{
|
||||
test_context *ctx = calloc(1, sizeof(test_context));
|
||||
|
||||
if (ctx == NULL)
|
||||
return NULL;
|
||||
|
||||
ctx->parent = parent;
|
||||
|
||||
RING_INSERT(ring, ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
bool test_start_fetch(void *handle)
|
||||
{
|
||||
/* Nothing to do */
|
||||
return true;
|
||||
}
|
||||
|
||||
void test_abort_fetch(void *handle)
|
||||
{
|
||||
test_context *ctx = handle;
|
||||
|
||||
ctx->aborted = true;
|
||||
}
|
||||
|
||||
void test_free_fetch(void *handle)
|
||||
{
|
||||
test_context *ctx = handle;
|
||||
|
||||
RING_REMOVE(ring, ctx);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void test_process(test_context *ctx)
|
||||
{
|
||||
/** \todo Implement */
|
||||
}
|
||||
|
||||
void test_poll(const char *scheme)
|
||||
{
|
||||
test_context *ctx, *next;
|
||||
|
||||
if (ring == NULL)
|
||||
return;
|
||||
|
||||
ctx = ring;
|
||||
do {
|
||||
next = ctx->r_next;
|
||||
|
||||
if (ctx->locked)
|
||||
continue;
|
||||
|
||||
if (ctx->aborted == false) {
|
||||
test_process(ctx);
|
||||
}
|
||||
|
||||
fetch_remove_from_queues(ctx->parent);
|
||||
fetch_free(ctx->parent);
|
||||
} while ((ctx = next) != ring && ring != NULL);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* The actual test code *
|
||||
******************************************************************************/
|
||||
|
||||
nserror query_handler(const llcache_query *query, void *pw,
|
||||
llcache_query_response cb, void *cbpw)
|
||||
{
|
||||
/* I'm too lazy to actually implement this. It should queue the query,
|
||||
* then deliver the response from main(). */
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
nserror event_handler(const llcache_handle *handle,
|
||||
const llcache_event *event, void *pw)
|
||||
{
|
||||
static char *event_names[] = {
|
||||
"HAD_HEADERS", "HAD_DATA", "DONE", "ERROR", "PROGRESS"
|
||||
};
|
||||
bool *done = pw;
|
||||
|
||||
if (event->type != LLCACHE_EVENT_PROGRESS)
|
||||
fprintf(stdout, "%p : %s\n", handle, event_names[event->type]);
|
||||
|
||||
/* Inform main() that the fetch completed */
|
||||
if (event->type == LLCACHE_EVENT_DONE)
|
||||
*done = true;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
nserror error;
|
||||
llcache_handle *handle;
|
||||
llcache_handle *handle2;
|
||||
bool done = false;
|
||||
|
||||
/* Initialise subsystems */
|
||||
url_init();
|
||||
fetch_init();
|
||||
fetch_add_fetcher("test", test_initialise, test_setup_fetch,
|
||||
test_start_fetch, test_abort_fetch, test_free_fetch,
|
||||
test_poll, test_finalise);
|
||||
|
||||
/* Initialise low-level cache */
|
||||
error = llcache_initialise(query_handler, NULL);
|
||||
if (error != NSERROR_OK) {
|
||||
fprintf(stderr, "llcache_initialise: %d\n", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Retrieve an URL from the low-level cache (may trigger fetch) */
|
||||
error = llcache_handle_retrieve("http://www.netsurf-browser.org/",
|
||||
LLCACHE_RETRIEVE_VERIFIABLE, NULL, NULL,
|
||||
event_handler, &done, &handle);
|
||||
if (error != NSERROR_OK) {
|
||||
fprintf(stderr, "llcache_handle_retrieve: %d\n", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Poll relevant components */
|
||||
while (done == false) {
|
||||
fetch_poll();
|
||||
llcache_poll();
|
||||
}
|
||||
|
||||
done = false;
|
||||
error = llcache_handle_retrieve("http://www.netsurf-browser.org/",
|
||||
LLCACHE_RETRIEVE_VERIFIABLE, NULL, NULL,
|
||||
event_handler, &done, &handle2);
|
||||
if (error != NSERROR_OK) {
|
||||
fprintf(stderr, "llcache_handle_retrieve: %d\n", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (done == false) {
|
||||
fetch_poll();
|
||||
llcache_poll();
|
||||
}
|
||||
|
||||
fprintf(stdout, "%p -> %p\n", handle,
|
||||
llcache_object_from_handle(handle));
|
||||
fprintf(stdout, "%p -> %p\n", handle2,
|
||||
llcache_object_from_handle(handle2));
|
||||
|
||||
/* Cleanup */
|
||||
llcache_handle_release(handle2);
|
||||
llcache_handle_release(handle);
|
||||
|
||||
fetch_quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
40
utils/errors.h
Normal file
40
utils/errors.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Error codes
|
||||
*/
|
||||
|
||||
#ifndef NETSURF_UTILS_ERRORS_H_
|
||||
#define NETSURF_UTILS_ERRORS_H_
|
||||
|
||||
/**
|
||||
* Enumeration of error codes
|
||||
*/
|
||||
typedef enum {
|
||||
NSERROR_OK, /**< No error */
|
||||
|
||||
NSERROR_NOMEM, /**< Memory exhaustion */
|
||||
|
||||
NSERROR_NO_FETCH_HANDLER, /**< No fetch handler for URL scheme */
|
||||
|
||||
NSERROR_NOT_FOUND, /**< Requested item not found */
|
||||
} nserror;
|
||||
|
||||
#endif
|
||||
|
390
utils/http.c
Normal file
390
utils/http.c
Normal file
@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright 2010 John-Mark Bell <jmb@netsurf-browser.org>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* HTTP header parsing functions
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils/http.h"
|
||||
|
||||
/**
|
||||
* Representation of an HTTP parameter
|
||||
*/
|
||||
struct http_parameter {
|
||||
struct http_parameter *next; /**< Next parameter in list, or NULL */
|
||||
|
||||
char *name; /**< Parameter name */
|
||||
char *value; /**< Parameter value */
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine if a character is valid for an HTTP token
|
||||
*
|
||||
* \param c Character to consider
|
||||
* \return True if character is valid, false otherwise
|
||||
*/
|
||||
static bool http_is_token_char(uint8_t c)
|
||||
{
|
||||
/* [ 32 - 126 ] except ()<>@,;:\"/[]?={} SP HT */
|
||||
|
||||
if (c <= ' ' || 126 < c)
|
||||
return false;
|
||||
|
||||
return (strchr("()<>@,;:\\\"/[]?={}", c) == NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an HTTP token
|
||||
*
|
||||
* \param input Pointer to current input byte. Updated on exit.
|
||||
* \param value Pointer to location to receive on-heap token value.
|
||||
* \return NSERROR_OK on success,
|
||||
* NSERROR_NOMEM on memory exhaustion
|
||||
*
|
||||
* The returned value is owned by the caller
|
||||
*/
|
||||
static nserror http_parse_token(const char **input, char **value)
|
||||
{
|
||||
const uint8_t *start = (const uint8_t *) *input;
|
||||
const uint8_t *end;
|
||||
char *token;
|
||||
|
||||
end = start;
|
||||
while (http_is_token_char(*end))
|
||||
end++;
|
||||
|
||||
token = malloc(end - start + 1);
|
||||
if (token == NULL)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
memcpy(token, start, end - start);
|
||||
token[end - start] = '\0';
|
||||
|
||||
*value = token;
|
||||
*input = (const char *) end;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an HTTP quoted-string
|
||||
*
|
||||
* \param input Pointer to current input byte. Updated on exit.
|
||||
* \param value Pointer to location to receive on-heap string value.
|
||||
* \return NSERROR_OK on success,
|
||||
* NSERROR_NOMEM on memory exhaustion
|
||||
*
|
||||
* The returned value is owned by the caller
|
||||
*/
|
||||
static nserror http_parse_quoted_string(const char **input, char **value)
|
||||
{
|
||||
const uint8_t *start = (const uint8_t *) *input;
|
||||
const uint8_t *end;
|
||||
uint8_t c;
|
||||
char *string_value;
|
||||
|
||||
/* <"> *( qdtext | quoted-pair ) <">
|
||||
* qdtext = any TEXT except <">
|
||||
* quoted-pair = "\" CHAR
|
||||
* TEXT = [ HT, CR, LF, 32-126, 128-255 ]
|
||||
* CHAR = [ 0 - 127 ]
|
||||
*
|
||||
* \todo TEXT may contain non 8859-1 chars encoded per RFC 2047
|
||||
* \todo Support quoted-pairs
|
||||
*/
|
||||
|
||||
if (*start == '"') {
|
||||
end = start = start + 1;
|
||||
|
||||
c = *end;
|
||||
while (c == '\t' || c == '\r' || c == '\n' ||
|
||||
c == ' ' || c == '!' ||
|
||||
('#' <= c && c <= 126) || c > 127) {
|
||||
end++;
|
||||
c = *end;
|
||||
}
|
||||
|
||||
if (*end != '"') {
|
||||
start--;
|
||||
end = start;
|
||||
}
|
||||
}
|
||||
|
||||
string_value = malloc(end - start + 1);
|
||||
if (string_value == NULL)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
memcpy(string_value, start, end - start);
|
||||
string_value[end - start] = '\0';
|
||||
|
||||
*value = string_value;
|
||||
|
||||
if (end != start)
|
||||
*input = (const char *) end + 1;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an HTTP parameter
|
||||
*
|
||||
* \param input Pointer to current input byte. Updated on exit.
|
||||
* \param parameter Pointer to location to receive on-heap parameter.
|
||||
* \return NSERROR_OK on success,
|
||||
* NSERROR_NOMEM on memory exhaustion
|
||||
*
|
||||
* The returned parameter is owned by the caller.
|
||||
*/
|
||||
static nserror http_parse_parameter(const char **input,
|
||||
http_parameter **parameter)
|
||||
{
|
||||
const char *pos = *input;
|
||||
char *name;
|
||||
char *value;
|
||||
http_parameter *param;
|
||||
nserror error;
|
||||
|
||||
/* token "=" ( token | quoted-string ) */
|
||||
|
||||
error = http_parse_token(&pos, &name);
|
||||
if (error != NSERROR_OK)
|
||||
return error;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
if (*pos != '=') {
|
||||
value = strdup("");
|
||||
if (value == NULL) {
|
||||
free(name);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
} else {
|
||||
pos++;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
if (*pos == '"')
|
||||
error = http_parse_quoted_string(&pos, &value);
|
||||
else
|
||||
error = http_parse_token(&pos, &value);
|
||||
|
||||
if (error != NSERROR_OK) {
|
||||
free(name);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
param = malloc(sizeof(*param));
|
||||
if (param == NULL) {
|
||||
free(value);
|
||||
free(name);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
param->next = NULL;
|
||||
param->name = name;
|
||||
param->value = value;
|
||||
|
||||
*parameter = param;
|
||||
*input = pos;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an HTTP parameter list
|
||||
*
|
||||
* \param input Pointer to current input byte. Updated on exit.
|
||||
* \param parameters Pointer to location to receive on-heap parameter list.
|
||||
* \return NSERROR_OK on success,
|
||||
* NSERROR_NOMEM on memory exhaustion
|
||||
*
|
||||
* The returned parameter list is owned by the caller
|
||||
*/
|
||||
static nserror http_parse_parameter_list(const char **input,
|
||||
http_parameter **parameters)
|
||||
{
|
||||
const char *pos = *input;
|
||||
http_parameter *param;
|
||||
http_parameter *list = NULL;
|
||||
nserror error;
|
||||
|
||||
/* 1*( ";" parameter ) */
|
||||
|
||||
while (*pos == ';') {
|
||||
pos++;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
error = http_parse_parameter(&pos, ¶m);
|
||||
if (error != NSERROR_OK) {
|
||||
while (list != NULL) {
|
||||
param = list;
|
||||
|
||||
list = param->next;
|
||||
|
||||
free(param->name);
|
||||
free(param->value);
|
||||
free(param);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
if (list != NULL)
|
||||
param->next = list;
|
||||
|
||||
list = param;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
}
|
||||
|
||||
*parameters = list;
|
||||
*input = pos;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/* See http.h for documentation */
|
||||
nserror http_parse_content_type(const char *header_value, char **media_type,
|
||||
http_parameter **parameters)
|
||||
{
|
||||
const char *pos = header_value;
|
||||
char *type;
|
||||
char *subtype = NULL;
|
||||
http_parameter *params = NULL;
|
||||
char *mime;
|
||||
size_t mime_len;
|
||||
nserror error;
|
||||
|
||||
/* type "/" subtype *( ";" parameter ) */
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
error = http_parse_token(&pos, &type);
|
||||
if (error != NSERROR_OK)
|
||||
return error;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
if (*pos == '/') {
|
||||
pos++;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
error = http_parse_token(&pos, &subtype);
|
||||
if (error != NSERROR_OK) {
|
||||
free(type);
|
||||
return error;
|
||||
}
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
if (*pos == ';') {
|
||||
pos++;
|
||||
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
|
||||
error = http_parse_parameter_list(&pos, ¶ms);
|
||||
if (error != NSERROR_OK) {
|
||||
free(subtype);
|
||||
free(type);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* <type> + <subtype> + '/' */
|
||||
mime_len = strlen(type) + (subtype != NULL ? strlen(subtype) : 0) + 1;
|
||||
|
||||
mime = malloc(mime_len + 1);
|
||||
if (mime == NULL) {
|
||||
http_parameter_list_destroy(params);
|
||||
free(subtype);
|
||||
free(type);
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
sprintf(mime, "%s/%s", type, subtype != NULL ? subtype : "");
|
||||
|
||||
free(subtype);
|
||||
free(type);
|
||||
|
||||
*media_type = mime;
|
||||
*parameters = params;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/* See http.h for documentation */
|
||||
nserror http_parameter_list_find_item(const http_parameter *list,
|
||||
const char *name, const char **value)
|
||||
{
|
||||
while (list != NULL && strcasecmp(name, list->name) != 0)
|
||||
list = list->next;
|
||||
|
||||
if (list == NULL)
|
||||
return NSERROR_NOT_FOUND;
|
||||
|
||||
*value = list->value;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/* See http.h for documentation */
|
||||
const http_parameter *http_parameter_list_iterate(const http_parameter *cur,
|
||||
const char **name, const char **value)
|
||||
{
|
||||
if (cur == NULL)
|
||||
return NULL;
|
||||
|
||||
*name = cur->name;
|
||||
*value = cur->value;
|
||||
|
||||
return cur->next;
|
||||
}
|
||||
|
||||
/* See http.h for documentation */
|
||||
void http_parameter_list_destroy(http_parameter *list)
|
||||
{
|
||||
while (list != NULL) {
|
||||
http_parameter *victim = list;
|
||||
|
||||
list = victim->next;
|
||||
|
||||
free(victim->name);
|
||||
free(victim->value);
|
||||
free(victim);
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user