netsurf: branch master updated. release/3.0-1127-g71cb700
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/71cb70065e6819c26f101...
...commit http://git.netsurf-browser.org/netsurf.git/commit/71cb70065e6819c26f101ff...
...tree http://git.netsurf-browser.org/netsurf.git/tree/71cb70065e6819c26f101ff11...
The branch, master has been updated
via 71cb70065e6819c26f101ff11e34c10383487b30 (commit)
from b99357616cebe750e523f123701f284d7ac0037f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=71cb70065e6819c26f1...
commit 71cb70065e6819c26f101ff11e34c10383487b30
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Gadgets can exisit outside forms, so now they store their own ref to the containing html content.
diff --git a/render/box_construct.c b/render/box_construct.c
index ce21b70..f5ef099 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -2391,6 +2391,7 @@ bool box_input(BOX_SPECIAL_PARAMS)
goto no_memory;
box->gadget = gadget;
gadget->box = box;
+ gadget->html = content;
if (type && dom_string_caseless_lwc_isequal(type,
corestring_lwc_password)) {
@@ -2526,6 +2527,7 @@ bool box_button(BOX_SPECIAL_PARAMS)
if (!gadget)
return false;
+ gadget->html = content;
box->gadget = gadget;
gadget->box = box;
@@ -2554,6 +2556,7 @@ bool box_select(BOX_SPECIAL_PARAMS)
if (gadget == NULL)
return false;
+ gadget->html = content;
err = dom_node_get_first_child(n, &c);
if (err != DOM_NO_ERR)
return false;
@@ -2761,6 +2764,7 @@ bool box_textarea(BOX_SPECIAL_PARAMS)
if (box->gadget == NULL)
return false;
+ box->gadget->html = content;
box->gadget->box = box;
if (!box_input_text(content, box, n))
diff --git a/render/box_textarea.c b/render/box_textarea.c
index 298406a..fe5a7ba 100644
--- a/render/box_textarea.c
+++ b/render/box_textarea.c
@@ -107,8 +107,8 @@ bool box_textarea_keypress(html_content *html, struct box *box, uint32_t key)
static void box_textarea_callback(void *data, struct textarea_msg *msg)
{
struct form_textarea_data *d = data;
- struct html_content *html = d->html;
struct form_control *gadget = d->gadget;
+ struct html_content *html = d->gadget->html;
struct box *box = gadget->box;
switch (msg->type) {
@@ -119,7 +119,7 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
union html_drag_owner drag_owner;
drag_owner.no_owner = true;
- html_set_drag_type(d->html, drag_type, drag_owner,
+ html_set_drag_type(html, drag_type, drag_owner,
NULL);
} else {
/* Textarea drag started */
@@ -146,7 +146,7 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
break;
}
- html_set_drag_type(d->html, drag_type, drag_owner,
+ html_set_drag_type(html, drag_type, drag_owner,
&rect);
}
break;
@@ -171,7 +171,7 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
union html_selection_owner sel_owner;
sel_owner.textarea = box;
- html_set_selection(d->html, HTML_SELECTION_TEXTAREA,
+ html_set_selection(html, HTML_SELECTION_TEXTAREA,
sel_owner,
msg->data.selection.read_only);
} else {
@@ -179,7 +179,7 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
union html_selection_owner sel_owner;
sel_owner.none = true;
- html_set_selection(d->html, HTML_SELECTION_NONE,
+ html_set_selection(html, HTML_SELECTION_NONE,
sel_owner, true);
}
break;
@@ -191,12 +191,12 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
if (msg->data.caret.type == TEXTAREA_CARET_HIDE) {
union html_focus_owner focus_owner;
focus_owner.textarea = box;
- html_set_focus(d->html, HTML_FOCUS_TEXTAREA,
+ html_set_focus(html, HTML_FOCUS_TEXTAREA,
focus_owner, true, 0, 0, 0, NULL);
} else {
union html_focus_owner focus_owner;
focus_owner.textarea = box;
- html_set_focus(d->html, HTML_FOCUS_TEXTAREA,
+ html_set_focus(html, HTML_FOCUS_TEXTAREA,
focus_owner, false,
msg->data.caret.pos.x,
msg->data.caret.pos.y,
@@ -277,7 +277,6 @@ bool box_textarea_create_textarea(html_content *html,
if (read_only)
ta_flags |= TEXTAREA_READONLY;
- gadget->data.text.data.html = html;
gadget->data.text.data.gadget = gadget;
font_plot_style_from_css(gadget->box->style, &fstyle);
diff --git a/render/form.c b/render/form.c
index d02240f..518d2f6 100644
--- a/render/form.c
+++ b/render/form.c
@@ -156,17 +156,6 @@ struct form *form_new(void *node, const char *action, const char *target,
/**
- * Set form's html content, so it can ask to redraw.
- *
- * \param form form to set html content for
- * \param html html content for form
- */
-void form_set_html_content(struct form *f, struct html_content *html)
-{
- f->html = html;
-}
-
-/**
* Free a form, and any controls it owns.
*
* \param form The form to free
@@ -1397,9 +1386,8 @@ static void form__select_process_selection(html_content *html,
void form_select_process_selection(struct form_control *control, int item)
{
assert(control != NULL);
- assert(control->form != NULL);
- form__select_process_selection(control->form->html, control, item);
+ form__select_process_selection(control->html, control, item);
}
/**
@@ -1650,13 +1638,13 @@ void form_radio_set(struct form_control *radio)
if (control->selected) {
control->selected = false;
dom_html_input_element_set_checked(control->node, false);
- html__redraw_a_box(radio->form->html, control->box);
+ html__redraw_a_box(radio->html, control->box);
}
}
radio->selected = true;
dom_html_input_element_set_checked(radio->node, true);
- html__redraw_a_box(radio->form->html, radio->box);
+ html__redraw_a_box(radio->html, radio->box);
}
diff --git a/render/form.h b/render/form.h
index 21829b9..f072b80 100644
--- a/render/form.h
+++ b/render/form.h
@@ -46,7 +46,6 @@ typedef enum {
/** HTML form. */
struct form {
- struct html_content *html; /**< HTML content containing form */
void *node; /**< Corresponding DOM node */
char *action; /**< Absolute URL to submit to. */
@@ -78,13 +77,13 @@ typedef enum {
/** Data for textarea */
struct form_textarea_data {
- struct html_content *html;
struct form_control *gadget;
};
/** Form control. */
struct form_control {
void *node; /**< Corresponding DOM node */
+ struct html_content *html; /**< HTML content containing control */
form_control_type type; /**< Type of control */
@@ -157,7 +156,6 @@ typedef void(*select_menu_redraw_callback)(void *client_data,
struct form *form_new(void *node, const char *action, const char *target,
form_method method, const char *charset,
const char *doc_charset);
-void form_set_html_content(struct form *f, struct html_content *html);
void form_free(struct form *form);
struct form_control *form_new_control(void *node, form_control_type type);
void form_add_control(struct form *form, struct form_control *control);
diff --git a/render/html.c b/render/html.c
index 8d3daf1..e375e62 100644
--- a/render/html.c
+++ b/render/html.c
@@ -1202,9 +1202,6 @@ html_begin_conversion(html_content *htmlc)
return false;
}
}
-
- /* Tell each form what content its in, so it can redraw */
- form_set_html_content(f, htmlc);
}
dom_node_unref(html);
-----------------------------------------------------------------------
Summary of changes:
render/box_construct.c | 4 ++++
render/box_textarea.c | 15 +++++++--------
render/form.c | 18 +++---------------
render/form.h | 4 +---
render/html.c | 3 ---
5 files changed, 15 insertions(+), 29 deletions(-)
diff --git a/render/box_construct.c b/render/box_construct.c
index ce21b70..f5ef099 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -2391,6 +2391,7 @@ bool box_input(BOX_SPECIAL_PARAMS)
goto no_memory;
box->gadget = gadget;
gadget->box = box;
+ gadget->html = content;
if (type && dom_string_caseless_lwc_isequal(type,
corestring_lwc_password)) {
@@ -2526,6 +2527,7 @@ bool box_button(BOX_SPECIAL_PARAMS)
if (!gadget)
return false;
+ gadget->html = content;
box->gadget = gadget;
gadget->box = box;
@@ -2554,6 +2556,7 @@ bool box_select(BOX_SPECIAL_PARAMS)
if (gadget == NULL)
return false;
+ gadget->html = content;
err = dom_node_get_first_child(n, &c);
if (err != DOM_NO_ERR)
return false;
@@ -2761,6 +2764,7 @@ bool box_textarea(BOX_SPECIAL_PARAMS)
if (box->gadget == NULL)
return false;
+ box->gadget->html = content;
box->gadget->box = box;
if (!box_input_text(content, box, n))
diff --git a/render/box_textarea.c b/render/box_textarea.c
index 298406a..fe5a7ba 100644
--- a/render/box_textarea.c
+++ b/render/box_textarea.c
@@ -107,8 +107,8 @@ bool box_textarea_keypress(html_content *html, struct box *box, uint32_t key)
static void box_textarea_callback(void *data, struct textarea_msg *msg)
{
struct form_textarea_data *d = data;
- struct html_content *html = d->html;
struct form_control *gadget = d->gadget;
+ struct html_content *html = d->gadget->html;
struct box *box = gadget->box;
switch (msg->type) {
@@ -119,7 +119,7 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
union html_drag_owner drag_owner;
drag_owner.no_owner = true;
- html_set_drag_type(d->html, drag_type, drag_owner,
+ html_set_drag_type(html, drag_type, drag_owner,
NULL);
} else {
/* Textarea drag started */
@@ -146,7 +146,7 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
break;
}
- html_set_drag_type(d->html, drag_type, drag_owner,
+ html_set_drag_type(html, drag_type, drag_owner,
&rect);
}
break;
@@ -171,7 +171,7 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
union html_selection_owner sel_owner;
sel_owner.textarea = box;
- html_set_selection(d->html, HTML_SELECTION_TEXTAREA,
+ html_set_selection(html, HTML_SELECTION_TEXTAREA,
sel_owner,
msg->data.selection.read_only);
} else {
@@ -179,7 +179,7 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
union html_selection_owner sel_owner;
sel_owner.none = true;
- html_set_selection(d->html, HTML_SELECTION_NONE,
+ html_set_selection(html, HTML_SELECTION_NONE,
sel_owner, true);
}
break;
@@ -191,12 +191,12 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
if (msg->data.caret.type == TEXTAREA_CARET_HIDE) {
union html_focus_owner focus_owner;
focus_owner.textarea = box;
- html_set_focus(d->html, HTML_FOCUS_TEXTAREA,
+ html_set_focus(html, HTML_FOCUS_TEXTAREA,
focus_owner, true, 0, 0, 0, NULL);
} else {
union html_focus_owner focus_owner;
focus_owner.textarea = box;
- html_set_focus(d->html, HTML_FOCUS_TEXTAREA,
+ html_set_focus(html, HTML_FOCUS_TEXTAREA,
focus_owner, false,
msg->data.caret.pos.x,
msg->data.caret.pos.y,
@@ -277,7 +277,6 @@ bool box_textarea_create_textarea(html_content *html,
if (read_only)
ta_flags |= TEXTAREA_READONLY;
- gadget->data.text.data.html = html;
gadget->data.text.data.gadget = gadget;
font_plot_style_from_css(gadget->box->style, &fstyle);
diff --git a/render/form.c b/render/form.c
index d02240f..518d2f6 100644
--- a/render/form.c
+++ b/render/form.c
@@ -156,17 +156,6 @@ struct form *form_new(void *node, const char *action, const char *target,
/**
- * Set form's html content, so it can ask to redraw.
- *
- * \param form form to set html content for
- * \param html html content for form
- */
-void form_set_html_content(struct form *f, struct html_content *html)
-{
- f->html = html;
-}
-
-/**
* Free a form, and any controls it owns.
*
* \param form The form to free
@@ -1397,9 +1386,8 @@ static void form__select_process_selection(html_content *html,
void form_select_process_selection(struct form_control *control, int item)
{
assert(control != NULL);
- assert(control->form != NULL);
- form__select_process_selection(control->form->html, control, item);
+ form__select_process_selection(control->html, control, item);
}
/**
@@ -1650,13 +1638,13 @@ void form_radio_set(struct form_control *radio)
if (control->selected) {
control->selected = false;
dom_html_input_element_set_checked(control->node, false);
- html__redraw_a_box(radio->form->html, control->box);
+ html__redraw_a_box(radio->html, control->box);
}
}
radio->selected = true;
dom_html_input_element_set_checked(radio->node, true);
- html__redraw_a_box(radio->form->html, radio->box);
+ html__redraw_a_box(radio->html, radio->box);
}
diff --git a/render/form.h b/render/form.h
index 21829b9..f072b80 100644
--- a/render/form.h
+++ b/render/form.h
@@ -46,7 +46,6 @@ typedef enum {
/** HTML form. */
struct form {
- struct html_content *html; /**< HTML content containing form */
void *node; /**< Corresponding DOM node */
char *action; /**< Absolute URL to submit to. */
@@ -78,13 +77,13 @@ typedef enum {
/** Data for textarea */
struct form_textarea_data {
- struct html_content *html;
struct form_control *gadget;
};
/** Form control. */
struct form_control {
void *node; /**< Corresponding DOM node */
+ struct html_content *html; /**< HTML content containing control */
form_control_type type; /**< Type of control */
@@ -157,7 +156,6 @@ typedef void(*select_menu_redraw_callback)(void *client_data,
struct form *form_new(void *node, const char *action, const char *target,
form_method method, const char *charset,
const char *doc_charset);
-void form_set_html_content(struct form *f, struct html_content *html);
void form_free(struct form *form);
struct form_control *form_new_control(void *node, form_control_type type);
void form_add_control(struct form *form, struct form_control *control);
diff --git a/render/html.c b/render/html.c
index 8d3daf1..e375e62 100644
--- a/render/html.c
+++ b/render/html.c
@@ -1202,9 +1202,6 @@ html_begin_conversion(html_content *htmlc)
return false;
}
}
-
- /* Tell each form what content its in, so it can redraw */
- form_set_html_content(f, htmlc);
}
dom_node_unref(html);
--
NetSurf Browser
9 years, 9 months
netsurf: branch master updated. release/3.0-1126-gb993576
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/b99357616cebe750e523f...
...commit http://git.netsurf-browser.org/netsurf.git/commit/b99357616cebe750e523f12...
...tree http://git.netsurf-browser.org/netsurf.git/tree/b99357616cebe750e523f1237...
The branch, master has been updated
via b99357616cebe750e523f123701f284d7ac0037f (commit)
from 143f28572af65aaabd084cc7b46dbfc5ab766b06 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=b99357616cebe750e52...
commit b99357616cebe750e523f123701f284d7ac0037f
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Fix unchecked return. Coverity #1175740.
diff --git a/desktop/browser_history.c b/desktop/browser_history.c
index c52f01c..ca551f7 100644
--- a/desktop/browser_history.c
+++ b/desktop/browser_history.c
@@ -712,9 +712,13 @@ void browser_window_history_go(struct browser_window *bw,
current = history->current;
history->current = entry;
- browser_window_create(BW_CREATE_CLONE,
+ error = browser_window_create(BW_CREATE_CLONE,
url, NULL, bw, NULL);
history->current = current;
+ if (error != NSERROR_OK) {
+ nsurl_unref(url);
+ return;
+ }
} else {
history->current = entry;
browser_window_navigate(bw, url, NULL,
-----------------------------------------------------------------------
Summary of changes:
desktop/browser_history.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/desktop/browser_history.c b/desktop/browser_history.c
index c52f01c..ca551f7 100644
--- a/desktop/browser_history.c
+++ b/desktop/browser_history.c
@@ -712,9 +712,13 @@ void browser_window_history_go(struct browser_window *bw,
current = history->current;
history->current = entry;
- browser_window_create(BW_CREATE_CLONE,
+ error = browser_window_create(BW_CREATE_CLONE,
url, NULL, bw, NULL);
history->current = current;
+ if (error != NSERROR_OK) {
+ nsurl_unref(url);
+ return;
+ }
} else {
history->current = entry;
browser_window_navigate(bw, url, NULL,
--
NetSurf Browser
9 years, 9 months
netsurf: branch master updated. release/3.0-1125-g143f285
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/143f28572af65aaabd084...
...commit http://git.netsurf-browser.org/netsurf.git/commit/143f28572af65aaabd084cc...
...tree http://git.netsurf-browser.org/netsurf.git/tree/143f28572af65aaabd084cc7b...
The branch, master has been updated
via 143f28572af65aaabd084cc7b46dbfc5ab766b06 (commit)
from b928095652a00bf579d8d724262b856f82a57a0f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=143f28572af65aaabd0...
commit 143f28572af65aaabd084cc7b46dbfc5ab766b06
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Fix redraw when selections are deleted.
diff --git a/desktop/textarea.c b/desktop/textarea.c
index fa0b2fd..584642d 100644
--- a/desktop/textarea.c
+++ b/desktop/textarea.c
@@ -202,6 +202,17 @@ static void textarea_normalise_text(struct textarea *ta,
/**
+ * Reset the selection (no redraw)
+ *
+ * \param ta Text area
+ */
+static inline void textarea_reset_selection(struct textarea *ta)
+{
+ ta->sel_start = ta->sel_end = -1;
+}
+
+
+/**
* Get the caret's position
*
* \param ta Text area
@@ -2400,8 +2411,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
length, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
if (!textarea_replace_text(ta, caret, caret,
utf8, length, false, &byte_delta, &r))
@@ -2431,8 +2443,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
"", 0, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else if (caret > 0) {
b_off = utf8_prev(ta->show->data, caret);
if (!textarea_replace_text(ta, b_off, caret,
@@ -2451,8 +2464,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
"", 0, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else if (caret < ta->show->len - 1) {
b_off = utf8_next(ta->show->data,
ta->show->len - 1, caret);
@@ -2476,8 +2490,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
&byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
if (!textarea_replace_text(ta, caret, caret,
"\n", 1, false,
@@ -2506,8 +2521,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
if (!textarea_replace_text(ta,
caret, caret,
@@ -2530,9 +2546,10 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
"", 0, true, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
caret += byte_delta;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
}
break;
case KEY_ESCAPE:
@@ -2704,8 +2721,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
ta->sel_start, ta->sel_end,
"", 0, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
if (ta->lines[line].b_length != 0) {
/* Delete line */
@@ -2736,8 +2754,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
ta->sel_start, ta->sel_end,
"", 0, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
b_len = ta->lines[line].b_length;
b_off = ta->lines[line].b_start + b_len;
@@ -2757,8 +2776,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
ta->sel_start, ta->sel_end,
"", 0, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
if (!textarea_replace_text(ta,
caret - ta->caret_pos.byte_off,
@@ -3043,7 +3063,7 @@ bool textarea_clear_selection(struct textarea *ta)
break;
/* Clear selection and redraw */
- ta->sel_start = ta->sel_end = -1;
+ textarea_reset_selection(ta);
msg.ta = ta;
msg.type = TEXTAREA_MSG_REDRAW_REQUEST;
-----------------------------------------------------------------------
Summary of changes:
desktop/textarea.c | 40 ++++++++++++++++++++++++++++++----------
1 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/desktop/textarea.c b/desktop/textarea.c
index fa0b2fd..584642d 100644
--- a/desktop/textarea.c
+++ b/desktop/textarea.c
@@ -202,6 +202,17 @@ static void textarea_normalise_text(struct textarea *ta,
/**
+ * Reset the selection (no redraw)
+ *
+ * \param ta Text area
+ */
+static inline void textarea_reset_selection(struct textarea *ta)
+{
+ ta->sel_start = ta->sel_end = -1;
+}
+
+
+/**
* Get the caret's position
*
* \param ta Text area
@@ -2400,8 +2411,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
length, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
if (!textarea_replace_text(ta, caret, caret,
utf8, length, false, &byte_delta, &r))
@@ -2431,8 +2443,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
"", 0, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else if (caret > 0) {
b_off = utf8_prev(ta->show->data, caret);
if (!textarea_replace_text(ta, b_off, caret,
@@ -2451,8 +2464,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
"", 0, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else if (caret < ta->show->len - 1) {
b_off = utf8_next(ta->show->data,
ta->show->len - 1, caret);
@@ -2476,8 +2490,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
&byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
if (!textarea_replace_text(ta, caret, caret,
"\n", 1, false,
@@ -2506,8 +2521,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
if (!textarea_replace_text(ta,
caret, caret,
@@ -2530,9 +2546,10 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
"", 0, true, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
caret += byte_delta;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
}
break;
case KEY_ESCAPE:
@@ -2704,8 +2721,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
ta->sel_start, ta->sel_end,
"", 0, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
if (ta->lines[line].b_length != 0) {
/* Delete line */
@@ -2736,8 +2754,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
ta->sel_start, ta->sel_end,
"", 0, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
b_len = ta->lines[line].b_length;
b_off = ta->lines[line].b_start + b_len;
@@ -2757,8 +2776,9 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
ta->sel_start, ta->sel_end,
"", 0, false, &byte_delta, &r))
return false;
+ redraw = true;
caret = ta->sel_end;
- textarea_clear_selection(ta);
+ textarea_reset_selection(ta);
} else {
if (!textarea_replace_text(ta,
caret - ta->caret_pos.byte_off,
@@ -3043,7 +3063,7 @@ bool textarea_clear_selection(struct textarea *ta)
break;
/* Clear selection and redraw */
- ta->sel_start = ta->sel_end = -1;
+ textarea_reset_selection(ta);
msg.ta = ta;
msg.type = TEXTAREA_MSG_REDRAW_REQUEST;
--
NetSurf Browser
9 years, 9 months
netsurf: branch vince/disccache updated. release/3.0-1128-gaa9d887
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/aa9d887887274224af73e...
...commit http://git.netsurf-browser.org/netsurf.git/commit/aa9d887887274224af73e0c...
...tree http://git.netsurf-browser.org/netsurf.git/tree/aa9d887887274224af73e0cf3...
The branch, vince/disccache has been updated
via aa9d887887274224af73e0cf3e5173c553d28d88 (commit)
from 0e952d5e6ebaefc9e9889d753895683396aeaa5f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=aa9d887887274224af7...
commit aa9d887887274224af73e0cf3e5173c553d28d88
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
add url check to metadata
diff --git a/content/llcache.c b/content/llcache.c
index 62faae6..b27bcf6 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -200,7 +200,6 @@ struct llcache_s {
/** low level cache state */
static struct llcache_s *llcache = NULL;
-
/* forward referenced callback function */
static void llcache_fetch_callback(const fetch_msg *msg, void *p);
@@ -1068,18 +1067,53 @@ llcache_persist_retrieve(llcache_object *object)
&object->source_len);
}
+uint8_t *crlf_line(uint8_t *data, uint8_t *end)
+{
+ uint8_t *nln = data;
+ while ((nln < end) && ((nln[0] != 13) || (nln[1] != 10) ))
+ nln++;
+ nln[0] = 0;
+ nln += 2;
+ return nln;
+}
+
static nserror
llcache_process_metadata(llcache_object *object, uint8_t *data, size_t datasize)
{
+ nserror res;
uint8_t *metadata = NULL;
size_t metadatalen = 0;
+ nsurl *metadataurl;
+ uint8_t *end;
+ uint8_t *ln;
+ uint8_t *nln;
/* attempt to retrieve object metadata from the cache */
error = guit->llcache->meta(object->url, &metadata, &metadatalen);
if (error != NSERROR_OK)
return error;
+ end = matadata + metadatalen;
+ ln = metadata;
+ nln = crlf_line(ln, end);
+
+ res = metadataurl(ln, &metadataurl);
+ if (res != NSERROR_OK) {
+ free(metadata);
+ return res;
+ }
+
+ if (nsurl_compare(object->url, metadataurl, NSURL_COMPLETE) != true) {
+ /* backing store returned the wrong object for the
+ * request. This may occour if the backing store had
+ * a collision in its stoage method. We cope with this
+ * buy simply skipping caching of this object.
+ */
+ free(metadata);
+
+ return NSERROR_NOT_FOUND;
+ }
free(metadata);
-----------------------------------------------------------------------
Summary of changes:
content/llcache.c | 36 +++++++++++++++++++++++++++++++++++-
1 files changed, 35 insertions(+), 1 deletions(-)
diff --git a/content/llcache.c b/content/llcache.c
index 62faae6..b27bcf6 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -200,7 +200,6 @@ struct llcache_s {
/** low level cache state */
static struct llcache_s *llcache = NULL;
-
/* forward referenced callback function */
static void llcache_fetch_callback(const fetch_msg *msg, void *p);
@@ -1068,18 +1067,53 @@ llcache_persist_retrieve(llcache_object *object)
&object->source_len);
}
+uint8_t *crlf_line(uint8_t *data, uint8_t *end)
+{
+ uint8_t *nln = data;
+ while ((nln < end) && ((nln[0] != 13) || (nln[1] != 10) ))
+ nln++;
+ nln[0] = 0;
+ nln += 2;
+ return nln;
+}
+
static nserror
llcache_process_metadata(llcache_object *object, uint8_t *data, size_t datasize)
{
+ nserror res;
uint8_t *metadata = NULL;
size_t metadatalen = 0;
+ nsurl *metadataurl;
+ uint8_t *end;
+ uint8_t *ln;
+ uint8_t *nln;
/* attempt to retrieve object metadata from the cache */
error = guit->llcache->meta(object->url, &metadata, &metadatalen);
if (error != NSERROR_OK)
return error;
+ end = matadata + metadatalen;
+ ln = metadata;
+ nln = crlf_line(ln, end);
+
+ res = metadataurl(ln, &metadataurl);
+ if (res != NSERROR_OK) {
+ free(metadata);
+ return res;
+ }
+
+ if (nsurl_compare(object->url, metadataurl, NSURL_COMPLETE) != true) {
+ /* backing store returned the wrong object for the
+ * request. This may occour if the backing store had
+ * a collision in its stoage method. We cope with this
+ * buy simply skipping caching of this object.
+ */
+ free(metadata);
+
+ return NSERROR_NOT_FOUND;
+ }
free(metadata);
--
NetSurf Browser
9 years, 9 months
netsurf: branch master updated. release/3.0-1124-gb928095
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/b928095652a00bf579d8d...
...commit http://git.netsurf-browser.org/netsurf.git/commit/b928095652a00bf579d8d72...
...tree http://git.netsurf-browser.org/netsurf.git/tree/b928095652a00bf579d8d7242...
The branch, master has been updated
via b928095652a00bf579d8d724262b856f82a57a0f (commit)
from c47a497bca10e2fce6fd2f458e9b5b9f6992062d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=b928095652a00bf579d...
commit b928095652a00bf579d8d724262b856f82a57a0f
Author: John-Mark Bell <jmb(a)netsurf-browser.org>
Commit: John-Mark Bell <jmb(a)netsurf-browser.org>
GTK: add some support for input methods.
We do not currently support pre-edit texts, or
retrieving/modifying text surrounding the caret.
This does, at least, finally allow the use of
dead keys during text input, but probably is
insufficient for useful input of CJKV &c.
diff --git a/gtk/treeview.c b/gtk/treeview.c
index 2a4732a..c99e9fd 100644
--- a/gtk/treeview.c
+++ b/gtk/treeview.c
@@ -35,12 +35,14 @@
#include "gtk/plotters.h"
#include "gtk/treeview.h"
#include "utils/log.h"
+#include "utils/utf8.h"
#include "utils/utils.h"
struct nsgtk_treeview {
GtkWindow *window;
GtkScrolledWindow *scrolled;
GtkDrawingArea *drawing_area;
+ GtkIMContext *input_method;
bool mouse_pressed;
int mouse_pressed_x;
int mouse_pressed_y;
@@ -52,6 +54,7 @@ struct nsgtk_treeview {
void nsgtk_treeview_destroy(struct nsgtk_treeview *tv)
{
tree_delete(tv->tree);
+ g_object_unref(tv->input_method);
gtk_widget_destroy(GTK_WIDGET(tv->window));
free(tv);
}
@@ -206,12 +209,14 @@ void nsgtk_tree_window_hide(GtkWidget *widget, gpointer g)
{
}
-gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget,
+static gboolean
+nsgtk_tree_window_button_press_event(GtkWidget *widget,
GdkEventButton *event, gpointer g)
{
struct nsgtk_treeview *tw = g;
struct tree *tree = tw->tree;
+ gtk_im_context_reset(tw->input_method);
gtk_widget_grab_focus(GTK_WIDGET(tw->drawing_area));
tw->mouse_pressed = true;
@@ -243,7 +248,8 @@ gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget,
return TRUE;
}
-gboolean nsgtk_tree_window_button_release_event(GtkWidget *widget,
+static gboolean
+nsgtk_tree_window_button_release_event(GtkWidget *widget,
GdkEventButton *event, gpointer g)
{
bool shift = event->state & GDK_SHIFT_MASK;
@@ -307,7 +313,8 @@ gboolean nsgtk_tree_window_button_release_event(GtkWidget *widget,
return TRUE;
}
-gboolean nsgtk_tree_window_motion_notify_event(GtkWidget *widget,
+static gboolean
+nsgtk_tree_window_motion_notify_event(GtkWidget *widget,
GdkEventMotion *event, gpointer g)
{
bool shift = event->state & GDK_SHIFT_MASK;
@@ -369,7 +376,8 @@ gboolean nsgtk_tree_window_motion_notify_event(GtkWidget *widget,
}
-gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
+static gboolean
+nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
gpointer g)
{
struct nsgtk_treeview *tw = (struct nsgtk_treeview *) g;
@@ -381,6 +389,9 @@ gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
GtkAdjustment *scroll = NULL;
gdouble hpage, vpage;
+ if (gtk_im_context_filter_keypress(tw->input_method, event))
+ return TRUE;
+
nskey = gtk_gui_gdkkey_to_nskey(event);
if (tree_keypress(tree, nskey) == true)
@@ -473,6 +484,32 @@ gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
return TRUE;
}
+static gboolean
+nsgtk_tree_window_keyrelease_event(GtkWidget *widget, GdkEventKey *event,
+ gpointer g)
+{
+ struct nsgtk_treeview *tw = (struct nsgtk_treeview *) g;
+
+ return gtk_im_context_filter_keypress(tw->input_method, event);
+}
+
+static void
+nsgtk_tree_window_input_method_commit(GtkIMContext *ctx,
+ const gchar *str, gpointer data)
+{
+ struct nsgtk_treeview *tw = (struct nsgtk_treeview *) data;
+ size_t len = strlen(str), offset = 0;
+
+ while (offset < len) {
+ uint32_t nskey = utf8_to_ucs4(str + offset, len - offset);
+
+ tree_keypress(tw->tree, nskey);
+
+ offset = utf8_next(str, len, offset);
+ }
+}
+
+
static const struct treeview_table nsgtk_tree_callbacks = {
.redraw_request = nsgtk_tree_redraw_request,
.resized = nsgtk_tree_resized,
@@ -498,6 +535,7 @@ struct nsgtk_treeview *nsgtk_treeview_create(unsigned int flags,
tv->window = window;
tv->scrolled = scrolled;
tv->drawing_area = drawing_area;
+ tv->input_method = gtk_im_multicontext_new();
tv->tree = tree_create(flags, &nsgtk_tree_callbacks, tv);
tv->mouse_state = 0;
tv->mouse_pressed = false;
@@ -510,17 +548,31 @@ struct nsgtk_treeview *nsgtk_treeview_create(unsigned int flags,
#define CONNECT(obj, sig, callback, ptr) \
g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
- CONNECT(drawing_area, "button_press_event",
+ CONNECT(drawing_area, "button-press-event",
nsgtk_tree_window_button_press_event,
tv);
- CONNECT(drawing_area, "button_release_event",
+ CONNECT(drawing_area, "button-release-event",
nsgtk_tree_window_button_release_event,
tv);
- CONNECT(drawing_area, "motion_notify_event",
+ CONNECT(drawing_area, "motion-notify-event",
nsgtk_tree_window_motion_notify_event,
tv);
- CONNECT(drawing_area, "key_press_event",
+ CONNECT(drawing_area, "key-press-event",
nsgtk_tree_window_keypress_event,
tv);
+ CONNECT(drawing_area, "key-release-event",
+ nsgtk_tree_window_keyrelease_event,
+ tv);
+
+
+ /* input method */
+ gtk_im_context_set_client_window(tv->input_method,
+ nsgtk_widget_get_window(GTK_WIDGET(tv->window)));
+ gtk_im_context_set_use_preedit(tv->input_method, FALSE);
+ /* input method signals */
+ CONNECT(tv->input_method, "commit",
+ nsgtk_tree_window_input_method_commit,
+ tv);
+
return tv;
}
diff --git a/gtk/treeview.h b/gtk/treeview.h
index a0acbd4..ad8180f 100644
--- a/gtk/treeview.h
+++ b/gtk/treeview.h
@@ -33,16 +33,6 @@ void nsgtk_treeview_destroy(struct nsgtk_treeview *tv);
struct tree *nsgtk_treeview_get_tree(struct nsgtk_treeview *tv);
-gboolean nsgtk_tree_window_expose_event(GtkWidget *, GdkEventExpose *,
- gpointer g);
void nsgtk_tree_window_hide(GtkWidget *widget, gpointer g);
-gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget,
- GdkEventButton *event, gpointer g);
-gboolean nsgtk_tree_window_button_release_event(GtkWidget *widget,
- GdkEventButton *event, gpointer g);
-gboolean nsgtk_tree_window_motion_notify_event(GtkWidget *widget,
- GdkEventMotion *event, gpointer g);
-gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
- gpointer g);
#endif /*__NSGTK_TREEVIEW_H__*/
diff --git a/gtk/window.c b/gtk/window.c
index 038622d..2da346b 100644
--- a/gtk/window.c
+++ b/gtk/window.c
@@ -27,6 +27,7 @@
#include <gdk-pixbuf/gdk-pixdata.h>
#include "utils/log.h"
+#include "utils/utf8.h"
#include "utils/utils.h"
#include "utils/nsoption.h"
#include "content/hlcache.h"
@@ -105,6 +106,9 @@ struct gui_window {
/** The icon this window should have */
GdkPixbuf *icon;
+ /** The input method to use with this window */
+ GtkIMContext *input_method;
+
/** list for cleanup */
struct gui_window *next, *prev;
};
@@ -315,6 +319,7 @@ static gboolean nsgtk_window_button_press_event(GtkWidget *widget,
{
struct gui_window *g = data;
+ gtk_im_context_reset(g->input_method);
gtk_widget_grab_focus(GTK_WIDGET(g->layout));
gtk_widget_hide(GTK_WIDGET(nsgtk_scaffolding_history_window(
g->scaffold)->window));
@@ -490,7 +495,12 @@ static gboolean nsgtk_window_keypress_event(GtkWidget *widget,
GdkEventKey *event, gpointer data)
{
struct gui_window *g = data;
- uint32_t nskey = gtk_gui_gdkkey_to_nskey(event);
+ uint32_t nskey;
+
+ if (gtk_im_context_filter_keypress(g->input_method, event))
+ return TRUE;
+
+ nskey = gtk_gui_gdkkey_to_nskey(event);
if (browser_window_key_press(g->bw, nskey))
return TRUE;
@@ -598,6 +608,31 @@ static gboolean nsgtk_window_keypress_event(GtkWidget *widget,
return TRUE;
}
+static gboolean nsgtk_window_keyrelease_event(GtkWidget *widget,
+ GdkEventKey *event, gpointer data)
+{
+ struct gui_window *g = data;
+
+ return gtk_im_context_filter_keypress(g->input_method, event);
+}
+
+
+static void nsgtk_window_input_method_commit(GtkIMContext *ctx,
+ const gchar *str, gpointer data)
+{
+ struct gui_window *g = data;
+ size_t len = strlen(str), offset = 0;
+
+ while (offset < len) {
+ uint32_t nskey = utf8_to_ucs4(str + offset, len - offset);
+
+ browser_window_key_press(g->bw, nskey);
+
+ offset = utf8_next(str, len, offset);
+ }
+}
+
+
static gboolean nsgtk_window_size_allocate_event(GtkWidget *widget,
GtkAllocation *allocation, gpointer data)
{
@@ -658,6 +693,8 @@ static void window_destroy(GtkWidget *widget, gpointer data)
struct gui_window *gw = data;
browser_window_destroy(gw->bw);
+
+ g_object_unref(gw->input_method);
}
/* Core interface documented in desktop/gui.h to create a gui_window */
@@ -720,6 +757,7 @@ gui_window_create(struct browser_window *bw,
g->layout = GTK_LAYOUT(gtk_builder_get_object(xml, "layout"));
g->status_bar = GTK_LABEL(gtk_builder_get_object(xml, "status_bar"));
g->paned = GTK_PANED(gtk_builder_get_object(xml, "hpaned1"));
+ g->input_method = gtk_im_multicontext_new();
/* add new gui window to global list (push_top) */
@@ -763,6 +801,8 @@ gui_window_create(struct browser_window *bw,
nsgtk_window_button_release_event, g);
CONNECT(g->layout, "key-press-event",
nsgtk_window_keypress_event, g);
+ CONNECT(g->layout, "key-release-event",
+ nsgtk_window_keyrelease_event, g);
CONNECT(g->layout, "size-allocate",
nsgtk_window_size_allocate_event, g);
CONNECT(g->layout, "scroll-event",
@@ -779,6 +819,14 @@ gui_window_create(struct browser_window *bw,
CONNECT(g->container, "destroy",
window_destroy, g);
+ /* input method */
+ gtk_im_context_set_client_window(g->input_method,
+ nsgtk_layout_get_bin_window(g->layout));
+ gtk_im_context_set_use_preedit(g->input_method, FALSE);
+ /* input method signals */
+ CONNECT(g->input_method, "commit",
+ nsgtk_window_input_method_commit, g);
+
/* add the tab container to the scaffold notebook */
switch (temp_open_background) {
case -1:
-----------------------------------------------------------------------
Summary of changes:
gtk/treeview.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++------
gtk/treeview.h | 10 --------
gtk/window.c | 50 ++++++++++++++++++++++++++++++++++++++++-
3 files changed, 109 insertions(+), 19 deletions(-)
diff --git a/gtk/treeview.c b/gtk/treeview.c
index 2a4732a..c99e9fd 100644
--- a/gtk/treeview.c
+++ b/gtk/treeview.c
@@ -35,12 +35,14 @@
#include "gtk/plotters.h"
#include "gtk/treeview.h"
#include "utils/log.h"
+#include "utils/utf8.h"
#include "utils/utils.h"
struct nsgtk_treeview {
GtkWindow *window;
GtkScrolledWindow *scrolled;
GtkDrawingArea *drawing_area;
+ GtkIMContext *input_method;
bool mouse_pressed;
int mouse_pressed_x;
int mouse_pressed_y;
@@ -52,6 +54,7 @@ struct nsgtk_treeview {
void nsgtk_treeview_destroy(struct nsgtk_treeview *tv)
{
tree_delete(tv->tree);
+ g_object_unref(tv->input_method);
gtk_widget_destroy(GTK_WIDGET(tv->window));
free(tv);
}
@@ -206,12 +209,14 @@ void nsgtk_tree_window_hide(GtkWidget *widget, gpointer g)
{
}
-gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget,
+static gboolean
+nsgtk_tree_window_button_press_event(GtkWidget *widget,
GdkEventButton *event, gpointer g)
{
struct nsgtk_treeview *tw = g;
struct tree *tree = tw->tree;
+ gtk_im_context_reset(tw->input_method);
gtk_widget_grab_focus(GTK_WIDGET(tw->drawing_area));
tw->mouse_pressed = true;
@@ -243,7 +248,8 @@ gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget,
return TRUE;
}
-gboolean nsgtk_tree_window_button_release_event(GtkWidget *widget,
+static gboolean
+nsgtk_tree_window_button_release_event(GtkWidget *widget,
GdkEventButton *event, gpointer g)
{
bool shift = event->state & GDK_SHIFT_MASK;
@@ -307,7 +313,8 @@ gboolean nsgtk_tree_window_button_release_event(GtkWidget *widget,
return TRUE;
}
-gboolean nsgtk_tree_window_motion_notify_event(GtkWidget *widget,
+static gboolean
+nsgtk_tree_window_motion_notify_event(GtkWidget *widget,
GdkEventMotion *event, gpointer g)
{
bool shift = event->state & GDK_SHIFT_MASK;
@@ -369,7 +376,8 @@ gboolean nsgtk_tree_window_motion_notify_event(GtkWidget *widget,
}
-gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
+static gboolean
+nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
gpointer g)
{
struct nsgtk_treeview *tw = (struct nsgtk_treeview *) g;
@@ -381,6 +389,9 @@ gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
GtkAdjustment *scroll = NULL;
gdouble hpage, vpage;
+ if (gtk_im_context_filter_keypress(tw->input_method, event))
+ return TRUE;
+
nskey = gtk_gui_gdkkey_to_nskey(event);
if (tree_keypress(tree, nskey) == true)
@@ -473,6 +484,32 @@ gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
return TRUE;
}
+static gboolean
+nsgtk_tree_window_keyrelease_event(GtkWidget *widget, GdkEventKey *event,
+ gpointer g)
+{
+ struct nsgtk_treeview *tw = (struct nsgtk_treeview *) g;
+
+ return gtk_im_context_filter_keypress(tw->input_method, event);
+}
+
+static void
+nsgtk_tree_window_input_method_commit(GtkIMContext *ctx,
+ const gchar *str, gpointer data)
+{
+ struct nsgtk_treeview *tw = (struct nsgtk_treeview *) data;
+ size_t len = strlen(str), offset = 0;
+
+ while (offset < len) {
+ uint32_t nskey = utf8_to_ucs4(str + offset, len - offset);
+
+ tree_keypress(tw->tree, nskey);
+
+ offset = utf8_next(str, len, offset);
+ }
+}
+
+
static const struct treeview_table nsgtk_tree_callbacks = {
.redraw_request = nsgtk_tree_redraw_request,
.resized = nsgtk_tree_resized,
@@ -498,6 +535,7 @@ struct nsgtk_treeview *nsgtk_treeview_create(unsigned int flags,
tv->window = window;
tv->scrolled = scrolled;
tv->drawing_area = drawing_area;
+ tv->input_method = gtk_im_multicontext_new();
tv->tree = tree_create(flags, &nsgtk_tree_callbacks, tv);
tv->mouse_state = 0;
tv->mouse_pressed = false;
@@ -510,17 +548,31 @@ struct nsgtk_treeview *nsgtk_treeview_create(unsigned int flags,
#define CONNECT(obj, sig, callback, ptr) \
g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
- CONNECT(drawing_area, "button_press_event",
+ CONNECT(drawing_area, "button-press-event",
nsgtk_tree_window_button_press_event,
tv);
- CONNECT(drawing_area, "button_release_event",
+ CONNECT(drawing_area, "button-release-event",
nsgtk_tree_window_button_release_event,
tv);
- CONNECT(drawing_area, "motion_notify_event",
+ CONNECT(drawing_area, "motion-notify-event",
nsgtk_tree_window_motion_notify_event,
tv);
- CONNECT(drawing_area, "key_press_event",
+ CONNECT(drawing_area, "key-press-event",
nsgtk_tree_window_keypress_event,
tv);
+ CONNECT(drawing_area, "key-release-event",
+ nsgtk_tree_window_keyrelease_event,
+ tv);
+
+
+ /* input method */
+ gtk_im_context_set_client_window(tv->input_method,
+ nsgtk_widget_get_window(GTK_WIDGET(tv->window)));
+ gtk_im_context_set_use_preedit(tv->input_method, FALSE);
+ /* input method signals */
+ CONNECT(tv->input_method, "commit",
+ nsgtk_tree_window_input_method_commit,
+ tv);
+
return tv;
}
diff --git a/gtk/treeview.h b/gtk/treeview.h
index a0acbd4..ad8180f 100644
--- a/gtk/treeview.h
+++ b/gtk/treeview.h
@@ -33,16 +33,6 @@ void nsgtk_treeview_destroy(struct nsgtk_treeview *tv);
struct tree *nsgtk_treeview_get_tree(struct nsgtk_treeview *tv);
-gboolean nsgtk_tree_window_expose_event(GtkWidget *, GdkEventExpose *,
- gpointer g);
void nsgtk_tree_window_hide(GtkWidget *widget, gpointer g);
-gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget,
- GdkEventButton *event, gpointer g);
-gboolean nsgtk_tree_window_button_release_event(GtkWidget *widget,
- GdkEventButton *event, gpointer g);
-gboolean nsgtk_tree_window_motion_notify_event(GtkWidget *widget,
- GdkEventMotion *event, gpointer g);
-gboolean nsgtk_tree_window_keypress_event(GtkWidget *widget, GdkEventKey *event,
- gpointer g);
#endif /*__NSGTK_TREEVIEW_H__*/
diff --git a/gtk/window.c b/gtk/window.c
index 038622d..2da346b 100644
--- a/gtk/window.c
+++ b/gtk/window.c
@@ -27,6 +27,7 @@
#include <gdk-pixbuf/gdk-pixdata.h>
#include "utils/log.h"
+#include "utils/utf8.h"
#include "utils/utils.h"
#include "utils/nsoption.h"
#include "content/hlcache.h"
@@ -105,6 +106,9 @@ struct gui_window {
/** The icon this window should have */
GdkPixbuf *icon;
+ /** The input method to use with this window */
+ GtkIMContext *input_method;
+
/** list for cleanup */
struct gui_window *next, *prev;
};
@@ -315,6 +319,7 @@ static gboolean nsgtk_window_button_press_event(GtkWidget *widget,
{
struct gui_window *g = data;
+ gtk_im_context_reset(g->input_method);
gtk_widget_grab_focus(GTK_WIDGET(g->layout));
gtk_widget_hide(GTK_WIDGET(nsgtk_scaffolding_history_window(
g->scaffold)->window));
@@ -490,7 +495,12 @@ static gboolean nsgtk_window_keypress_event(GtkWidget *widget,
GdkEventKey *event, gpointer data)
{
struct gui_window *g = data;
- uint32_t nskey = gtk_gui_gdkkey_to_nskey(event);
+ uint32_t nskey;
+
+ if (gtk_im_context_filter_keypress(g->input_method, event))
+ return TRUE;
+
+ nskey = gtk_gui_gdkkey_to_nskey(event);
if (browser_window_key_press(g->bw, nskey))
return TRUE;
@@ -598,6 +608,31 @@ static gboolean nsgtk_window_keypress_event(GtkWidget *widget,
return TRUE;
}
+static gboolean nsgtk_window_keyrelease_event(GtkWidget *widget,
+ GdkEventKey *event, gpointer data)
+{
+ struct gui_window *g = data;
+
+ return gtk_im_context_filter_keypress(g->input_method, event);
+}
+
+
+static void nsgtk_window_input_method_commit(GtkIMContext *ctx,
+ const gchar *str, gpointer data)
+{
+ struct gui_window *g = data;
+ size_t len = strlen(str), offset = 0;
+
+ while (offset < len) {
+ uint32_t nskey = utf8_to_ucs4(str + offset, len - offset);
+
+ browser_window_key_press(g->bw, nskey);
+
+ offset = utf8_next(str, len, offset);
+ }
+}
+
+
static gboolean nsgtk_window_size_allocate_event(GtkWidget *widget,
GtkAllocation *allocation, gpointer data)
{
@@ -658,6 +693,8 @@ static void window_destroy(GtkWidget *widget, gpointer data)
struct gui_window *gw = data;
browser_window_destroy(gw->bw);
+
+ g_object_unref(gw->input_method);
}
/* Core interface documented in desktop/gui.h to create a gui_window */
@@ -720,6 +757,7 @@ gui_window_create(struct browser_window *bw,
g->layout = GTK_LAYOUT(gtk_builder_get_object(xml, "layout"));
g->status_bar = GTK_LABEL(gtk_builder_get_object(xml, "status_bar"));
g->paned = GTK_PANED(gtk_builder_get_object(xml, "hpaned1"));
+ g->input_method = gtk_im_multicontext_new();
/* add new gui window to global list (push_top) */
@@ -763,6 +801,8 @@ gui_window_create(struct browser_window *bw,
nsgtk_window_button_release_event, g);
CONNECT(g->layout, "key-press-event",
nsgtk_window_keypress_event, g);
+ CONNECT(g->layout, "key-release-event",
+ nsgtk_window_keyrelease_event, g);
CONNECT(g->layout, "size-allocate",
nsgtk_window_size_allocate_event, g);
CONNECT(g->layout, "scroll-event",
@@ -779,6 +819,14 @@ gui_window_create(struct browser_window *bw,
CONNECT(g->container, "destroy",
window_destroy, g);
+ /* input method */
+ gtk_im_context_set_client_window(g->input_method,
+ nsgtk_layout_get_bin_window(g->layout));
+ gtk_im_context_set_use_preedit(g->input_method, FALSE);
+ /* input method signals */
+ CONNECT(g->input_method, "commit",
+ nsgtk_window_input_method_commit, g);
+
/* add the tab container to the scaffold notebook */
switch (temp_open_background) {
case -1:
--
NetSurf Browser
9 years, 9 months
netsurf: branch vince/disccache updated. release/3.0-1127-g0e952d5
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/0e952d5e6ebaefc9e9889...
...commit http://git.netsurf-browser.org/netsurf.git/commit/0e952d5e6ebaefc9e9889d7...
...tree http://git.netsurf-browser.org/netsurf.git/tree/0e952d5e6ebaefc9e9889d753...
The branch, vince/disccache has been updated
via 0e952d5e6ebaefc9e9889d753895683396aeaa5f (commit)
from 5b625b4479a813c4284e40d5011769204f66a19e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=0e952d5e6ebaefc9e98...
commit 0e952d5e6ebaefc9e9889d753895683396aeaa5f
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
restructure slightly to be more obvious
diff --git a/content/llcache.c b/content/llcache.c
index 6731a28..62faae6 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -1071,6 +1071,23 @@ llcache_persist_retrieve(llcache_object *object)
static nserror
llcache_process_metadata(llcache_object *object, uint8_t *data, size_t datasize)
{
+ uint8_t *metadata = NULL;
+ size_t metadatalen = 0;
+
+ /* attempt to retrieve object metadata from the cache */
+ error = guit->llcache->meta(object->url, &metadata, &metadatalen);
+ if (error != NSERROR_OK)
+ return error;
+
+
+
+ free(metadata);
+
+ object->source_alloc = object->source_len;
+
+ /* metadata says object stored in backing store */
+ object->store_state = LLCACHE_STORE_DISC;
+
return NSERROR_NOT_FOUND;
}
@@ -1079,19 +1096,20 @@ llcache_process_metadata(llcache_object *object, uint8_t *data, size_t datasize)
*/
static nserror
llcache_object_fetch_persistant(llcache_object *object,
- uint32_t flags,
- nsurl *referer,
- const llcache_post_data *post,
- uint32_t redirect_count)
+ uint32_t flags,
+ nsurl *referer,
+ const llcache_post_data *post,
+ uint32_t redirect_count)
{
nserror error;
nsurl *referer_clone = NULL;
llcache_post_data *post_clone = NULL;
- uint8_t *metadata = NULL;
- size_t metadatalen = 0;
- /* attempt to retrieve object metadata from the cache */
- error = guit->llcache->meta(object->url, &metadata, &metadatalen);
+ object->cache.req_time = time(NULL);
+ object->cache.fin_time = object->cache.req_time;
+
+ /* retrieve and process metadata */
+ error = llcache_process_metadata(object);
if (error != NSERROR_OK)
return error;
@@ -1105,27 +1123,15 @@ llcache_object_fetch_persistant(llcache_object *object,
if (referer != NULL)
referer_clone = nsurl_ref(referer);
- object->cache.req_time = time(NULL);
- object->cache.fin_time = object->cache.req_time;
-
object->fetch.flags = flags;
object->fetch.referer = referer_clone;
object->fetch.post = post_clone;
object->fetch.redirect_count = redirect_count;
- /* process the metadata */
- error = llcache_process_metadata(object, metadata, metadatalen);
- free(metadata);
- if (error != NSERROR_OK)
- return error;
-
/* fetch is "finished" */
object->fetch.state = LLCACHE_FETCH_COMPLETE;
object->fetch.fetch = NULL;
- object->store_state = LLCACHE_STORE_DISC;
- object->source_alloc = object->source_len;
-
return NSERROR_OK;
}
-----------------------------------------------------------------------
Summary of changes:
content/llcache.c | 46 ++++++++++++++++++++++++++--------------------
1 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/content/llcache.c b/content/llcache.c
index 6731a28..62faae6 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -1071,6 +1071,23 @@ llcache_persist_retrieve(llcache_object *object)
static nserror
llcache_process_metadata(llcache_object *object, uint8_t *data, size_t datasize)
{
+ uint8_t *metadata = NULL;
+ size_t metadatalen = 0;
+
+ /* attempt to retrieve object metadata from the cache */
+ error = guit->llcache->meta(object->url, &metadata, &metadatalen);
+ if (error != NSERROR_OK)
+ return error;
+
+
+
+ free(metadata);
+
+ object->source_alloc = object->source_len;
+
+ /* metadata says object stored in backing store */
+ object->store_state = LLCACHE_STORE_DISC;
+
return NSERROR_NOT_FOUND;
}
@@ -1079,19 +1096,20 @@ llcache_process_metadata(llcache_object *object, uint8_t *data, size_t datasize)
*/
static nserror
llcache_object_fetch_persistant(llcache_object *object,
- uint32_t flags,
- nsurl *referer,
- const llcache_post_data *post,
- uint32_t redirect_count)
+ uint32_t flags,
+ nsurl *referer,
+ const llcache_post_data *post,
+ uint32_t redirect_count)
{
nserror error;
nsurl *referer_clone = NULL;
llcache_post_data *post_clone = NULL;
- uint8_t *metadata = NULL;
- size_t metadatalen = 0;
- /* attempt to retrieve object metadata from the cache */
- error = guit->llcache->meta(object->url, &metadata, &metadatalen);
+ object->cache.req_time = time(NULL);
+ object->cache.fin_time = object->cache.req_time;
+
+ /* retrieve and process metadata */
+ error = llcache_process_metadata(object);
if (error != NSERROR_OK)
return error;
@@ -1105,27 +1123,15 @@ llcache_object_fetch_persistant(llcache_object *object,
if (referer != NULL)
referer_clone = nsurl_ref(referer);
- object->cache.req_time = time(NULL);
- object->cache.fin_time = object->cache.req_time;
-
object->fetch.flags = flags;
object->fetch.referer = referer_clone;
object->fetch.post = post_clone;
object->fetch.redirect_count = redirect_count;
- /* process the metadata */
- error = llcache_process_metadata(object, metadata, metadatalen);
- free(metadata);
- if (error != NSERROR_OK)
- return error;
-
/* fetch is "finished" */
object->fetch.state = LLCACHE_FETCH_COMPLETE;
object->fetch.fetch = NULL;
- object->store_state = LLCACHE_STORE_DISC;
- object->source_alloc = object->source_len;
-
return NSERROR_OK;
}
--
NetSurf Browser
9 years, 9 months
netsurf: branch vince/disccache updated. release/3.0-1126-g5b625b4
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/5b625b4479a813c4284e4...
...commit http://git.netsurf-browser.org/netsurf.git/commit/5b625b4479a813c4284e40d...
...tree http://git.netsurf-browser.org/netsurf.git/tree/5b625b4479a813c4284e40d50...
The branch, vince/disccache has been updated
via 5b625b4479a813c4284e40d5011769204f66a19e (commit)
via cc69c29fcd44a56d2af310cb3c98a7365c0ae1d0 (commit)
from b16f63dc42635c5dfc10c67ae7f39f39663edb2b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=5b625b4479a813c4284...
commit 5b625b4479a813c4284e40d5011769204f66a19e
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
change metadata handling and cleanup header processing
diff --git a/content/llcache.c b/content/llcache.c
index 44224fe..6731a28 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -17,7 +17,11 @@
*/
/** \file
- * Low-level resource cache (implementation)
+ * Low-level resource cache implementation
+ *
+ * This is the implementation of the low level cache. This cache
+ * stores source objects in memory and may use a persistant backing
+ * store to extend their lifetime.
*/
#include <stdlib.h>
@@ -47,6 +51,9 @@
#define LLCACHE_LOG(x)
#endif
+#define LLCACHE_MIN_DISC_LIFETIME 3600
+#define LLCACHE_MAX_DISC_BANDWIDTH (512*1024)
+
/** State of a low-level cache object fetch */
typedef enum {
LLCACHE_FETCH_INIT, /**< Initial state, before fetch */
@@ -105,6 +112,30 @@ typedef struct {
char *value; /**< Header value */
} llcache_header;
+/** validation control */
+typedef enum {
+ LLCACHE_VALIDATE_FRESH, /**< Only revalidate if not fresh */
+ LLCACHE_VALIDATE_ALWAYS, /**< Always revalidate */
+ LLCACHE_VALIDATE_ONCE /**< Revalidate once only */
+} llcache_validate;
+
+/** cache control value for invalid age */
+#define INVALID_AGE -1
+
+/** Cache control data */
+typedef struct {
+ time_t req_time; /**< Time of request */
+ time_t res_time; /**< Time of response */
+ time_t fin_time; /**< Time of request completion */
+ time_t date; /**< Date: response header */
+ time_t expires; /**< Expires: response header */
+ int age; /**< Age: response header */
+ int max_age; /**< Max-Age Cache-control parameter */
+ llcache_validate no_cache; /**< No-Cache Cache-control parameter */
+ char *etag; /**< Etag: response header */
+ time_t last_modified; /**< Last-Modified: response header */
+} llcache_cache_control;
+
/** Current status of objects data */
typedef enum {
LLCACHE_STORE_RAM = 0, /**< sourec data is stored in RAM only */
@@ -399,7 +430,15 @@ static nserror llcache_fetch_split_header(const uint8_t *data, size_t len,
colon = (const uint8_t *) strchr((const char *) data, ':');
if (colon == NULL) {
/* Failed, assume a key with no value */
- n = strdup((const char *) data);
+ colon = data + strlen((const char *)data);
+
+ /* Strip trailing whitespace from name */
+ while ((colon > data) &&
+ (colon[-1] == ' ' || colon[-1] == '\t' ||
+ colon[-1] == '\r' || colon[-1] == '\n')) {
+ colon--;
+ }
+ n = strndup((const char *) data, colon - data);
if (n == NULL)
return NSERROR_NOMEM;
@@ -620,6 +659,13 @@ static nserror llcache_fetch_process_header(llcache_object *object,
return error;
}
+ /* deal with empty header */
+ if (name[0] == 0) {
+ free(name);
+ free(value);
+ return NSERROR_OK;
+ }
+
/* Append header data to the object's headers array */
temp = realloc(object->headers, (object->num_headers + 1) *
sizeof(llcache_header));
@@ -1017,14 +1063,19 @@ llcache_persist_retrieve(llcache_object *object)
}
/* Source data for the object may be in the persiatant store */
- return guit->llcache->retrieve(object->url,
- NULL,
- &object->source_data,
- &object->source_len);
+ return guit->llcache->fetch(object->url,
+ &object->source_data,
+ &object->source_len);
+}
+
+static nserror
+llcache_process_metadata(llcache_object *object, uint8_t *data, size_t datasize)
+{
+ return NSERROR_NOT_FOUND;
}
/**
- * attempt to retrieve an object from persistant storage
+ * attempt to retrieve an object from persistant storage.
*/
static nserror
llcache_object_fetch_persistant(llcache_object *object,
@@ -1036,12 +1087,11 @@ llcache_object_fetch_persistant(llcache_object *object,
nserror error;
nsurl *referer_clone = NULL;
llcache_post_data *post_clone = NULL;
+ uint8_t *metadata = NULL;
+ size_t metadatalen = 0;
- /* attempt to retrieve object from the cache */
- error = guit->llcache->retrieve(object->url,
- &object->cache,
- &object->source_data,
- &object->source_len);
+ /* attempt to retrieve object metadata from the cache */
+ error = guit->llcache->meta(object->url, &metadata, &metadatalen);
if (error != NSERROR_OK)
return error;
@@ -1055,11 +1105,20 @@ llcache_object_fetch_persistant(llcache_object *object,
if (referer != NULL)
referer_clone = nsurl_ref(referer);
+ object->cache.req_time = time(NULL);
+ object->cache.fin_time = object->cache.req_time;
+
object->fetch.flags = flags;
object->fetch.referer = referer_clone;
object->fetch.post = post_clone;
object->fetch.redirect_count = redirect_count;
+ /* process the metadata */
+ error = llcache_process_metadata(object, metadata, metadatalen);
+ free(metadata);
+ if (error != NSERROR_OK)
+ return error;
+
/* fetch is "finished" */
object->fetch.state = LLCACHE_FETCH_COMPLETE;
object->fetch.fetch = NULL;
@@ -1772,9 +1831,89 @@ static nserror llcache_fetch_ssl_error(llcache_object *object)
return error;
}
-#define LLCACHE_MIN_DISC_LIFETIME 3600
-#define LLCACHE_MAX_DISC_BANDWIDTH (512*1024)
+/**
+ * Generate a serialised version of an objects metadata
+ *
+ * metadata includes object headers
+ */
+static nserror
+llcache_serialise_metadata(llcache_object *object,
+ uint8_t **data_out,
+ size_t *datasize_out)
+{
+ size_t allocsize;
+ int datasize;
+ uint8_t *data;
+ char *op;
+ unsigned int hloop;
+ int use;
+
+ allocsize = 10 + 2; /* object length */
+
+ allocsize += 10 + 2; /* space for number of header entries */
+
+ allocsize += nsurl_length(object->url) + 2;
+
+ for (hloop = 0 ; hloop < object->num_headers ; hloop++) {
+ allocsize += strlen(object->headers[hloop].name) + 1;
+ allocsize += strlen(object->headers[hloop].value) + 2;
+ }
+
+ data = malloc(allocsize);
+ if (data == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ op = (char *)data;
+ datasize = allocsize;
+
+ /* the url, used for checking for collisions */
+ use = snprintf(op, datasize, "%s%c%c", nsurl_access(object->url) ,13, 10);
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+
+ /* object size */
+ use = snprintf(op, datasize, "%d%c%c", (unsigned int)object->source_len, 13, 10);
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+
+ /* number of headers */
+ use = snprintf(op, datasize, "%d%c%c", (unsigned int)object->num_headers, 13, 10);
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+
+ /* headers */
+ for (hloop = 0 ; hloop < object->num_headers ; hloop++) {
+ use = snprintf(op, datasize,
+ "%s:%s%c%c",
+ object->headers[hloop].name,
+ object->headers[hloop].value,
+ 13, 10);
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+ }
+
+ LOG(("Filled buffer with %d spare", datasize));
+
+ *data_out = data;
+ *datasize_out = allocsize - datasize;
+ return NSERROR_OK;
+
+overflow:
+ /* somehow we overflowed the buffer - hth? */
+ LOG(("Overflowed metadata buffer"));
+ free(data);
+ return NSERROR_INVALID;
+}
/**
* possibly push objects data to persiatant storage.
@@ -1800,11 +1939,25 @@ static void llcache_persist(void *p)
(object->fetch.outstanding_query == false) &&
(object->store_state == LLCACHE_STORE_RAM) &&
(remaining_lifetime > LLCACHE_MIN_DISC_LIFETIME)) {
+ uint8_t *metadata;
+ size_t metadatasize;
+
+ ret = llcache_serialise_metadata(object, &metadata, &metadatasize);
+ if (ret != NSERROR_OK) {
+ /* as there has been a serialisation
+ * error, give up on making any more
+ * objects persistant for now.
+ */
+ return;
+ }
+
/* ok found an object to write */
- ret = guit->llcache->persist(object->url,
- &object->cache,
- object->source_data,
- object->source_len);
+ ret = guit->llcache->store(object->url,
+ metadata,
+ metadatasize,
+ object->source_data,
+ object->source_len);
+ free(metadata);
if (ret != NSERROR_OK) {
/* as there has been a serialisation
* error, give up on making any more
@@ -1813,7 +1966,7 @@ static void llcache_persist(void *p)
return;
}
object->store_state = LLCACHE_STORE_DISC;
- size_written += object->source_len;
+ size_written += object->source_len + metadatasize;
if (size_written > LLCACHE_MAX_DISC_BANDWIDTH) {
break;
diff --git a/content/llcache_private.h b/content/llcache_private.h
index 926773b..f038c9d 100644
--- a/content/llcache_private.h
+++ b/content/llcache_private.h
@@ -25,34 +25,31 @@
#include "content/llcache.h"
-/** validation control */
-typedef enum {
- LLCACHE_VALIDATE_FRESH, /**< Only revalidate if not fresh */
- LLCACHE_VALIDATE_ALWAYS, /**< Always revalidate */
- LLCACHE_VALIDATE_ONCE /**< Revalidate once only */
-} llcache_validate;
-
-/** cache control value for invalid age */
-#define INVALID_AGE -1
-
-/** Cache control data */
-typedef struct {
- time_t req_time; /**< Time of request */
- time_t res_time; /**< Time of response */
- time_t fin_time; /**< Time of request completion */
- time_t date; /**< Date: response header */
- time_t expires; /**< Expires: response header */
- int age; /**< Age: response header */
- int max_age; /**< Max-Age Cache-control parameter */
- llcache_validate no_cache; /**< No-Cache Cache-control parameter */
- char *etag; /**< Etag: response header */
- time_t last_modified; /**< Last-Modified: response header */
-} llcache_cache_control;
-
-/** operation table */
+/** low level cache operation table
+ *
+ * The low level cache (source objects) has the capability to make
+ * objects and their metadata (headers etc) persistant by writing to a
+ * backing store using these operations.
+ */
struct gui_llcache_table {
- nserror (*persist)(struct nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen);
- nserror (*retrieve)(struct nsurl *url, llcache_cache_control *cache_control, uint8_t **data, size_t *datalen);
+ /** Place a source object and its metadata in the backing store. */
+ nserror (*store)(struct nsurl *url,
+ const uint8_t *metadata, const size_t metadatalen,
+ const uint8_t *data, const size_t datalen);
+
+ /** retrive source object data from backing store. */
+ nserror (*fetch)(struct nsurl *url, uint8_t **data, size_t *datalen);
+
+ /** retrive source object metadata from backing store. */
+ nserror (*meta)(struct nsurl *url, uint8_t **data, size_t *datalen);
+
+ /**
+ * invalidate a source object from the backing store.
+ *
+ * The entry (if present in the backing store) must no longer
+ * be returned as a result to the fetch or meta operations.
+ */
+ nserror (*invalidate)(struct nsurl *url);
};
#endif
diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c
index 37fee39..71fb226 100644
--- a/desktop/gui_factory.c
+++ b/desktop/gui_factory.c
@@ -345,19 +345,38 @@ static nserror verify_utf8_register(struct gui_utf8_table *gut)
return NSERROR_OK;
}
-static nserror gui_default_persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen)
+static nserror
+gui_default_store(nsurl *url,
+ const uint8_t *metadata, const size_t metadatalen,
+ const uint8_t *data, const size_t datalen)
{
return NSERROR_SAVE_FAILED;
}
-static nserror gui_default_retrieve(nsurl *url, llcache_cache_control *cache_control, uint8_t **data_out, size_t *datalen_out)
+static nserror
+gui_default_fetch(nsurl *url, uint8_t **data_out, size_t *datalen_out)
{
return NSERROR_NOT_FOUND;
}
+static nserror
+gui_default_meta(nsurl *url, uint8_t **data_out, size_t *datalen_out)
+{
+ return NSERROR_NOT_FOUND;
+}
+
+static nserror
+gui_default_invalidate(nsurl *url)
+{
+ return NSERROR_NOT_FOUND;
+}
+
+
static struct gui_llcache_table default_llcache_table = {
- .persist = gui_default_persist,
- .retrieve = gui_default_retrieve,
+ .store = gui_default_store,
+ .fetch = gui_default_fetch,
+ .meta = gui_default_meta,
+ .invalidate = gui_default_invalidate,
};
/** verify clipboard table is valid */
@@ -369,10 +388,16 @@ static nserror verify_llcache_register(struct gui_llcache_table *glt)
}
/* mandantory operations */
- if (glt->persist == NULL) {
+ if (glt->store == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+ if (glt->fetch == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+ if (glt->meta == NULL) {
return NSERROR_BAD_PARAMETER;
}
- if (glt->retrieve == NULL) {
+ if (glt->invalidate == NULL) {
return NSERROR_BAD_PARAMETER;
}
return NSERROR_OK;
diff --git a/gtk/llcache.c b/gtk/llcache.c
index a2c27e5..4fa4e1e 100644
--- a/gtk/llcache.c
+++ b/gtk/llcache.c
@@ -41,9 +41,10 @@ static uint8_t encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
static unsigned int mod_table[] = {0, 2, 1};
-static uint8_t *base64url_encode(const char *data,
- size_t input_length,
- size_t *output_length)
+static uint8_t *
+base64url_encode(const char *data,
+ size_t input_length,
+ size_t *output_length)
{
uint8_t *encoded_data;
size_t i;
@@ -79,7 +80,9 @@ static uint8_t *base64url_encode(const char *data,
}
static nserror
-persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen)
+store(nsurl *url,
+ const uint8_t *metadata, const size_t metadatalen,
+ const uint8_t *data, const size_t datalen)
{
uint8_t *b64u;
size_t b64ulen;
@@ -101,7 +104,7 @@ persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, c
return NSERROR_SAVE_FAILED;
}
- LOG(("Writing %d bytes at %p to file", datalen, data));
+ LOG(("Writing %d bytes from %p", datalen, data));
if (fwrite(data, datalen, 1, file) != 1) {
LOG(("did not return 1"));
fclose(file);
@@ -123,27 +126,14 @@ persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, c
return NSERROR_SAVE_FAILED;
}
- fprintf(file,
- "req_time:%lld\n"
- "res_time:%lld\n"
- "fin_time:%lld\n"
- "date:%lld\n"
- "expires:%lld\n"
- "age:%d\n"
- "max_age:%d\n"
- "no_cache:%d\n"
- "last_modified:%lld\n"
- "etag:%s\n",
- (long long)cache_control->req_time,
- (long long)cache_control->res_time,
- (long long)cache_control->fin_time,
- (long long)cache_control->date,
- (long long)cache_control->expires,
- cache_control->age,
- cache_control->max_age,
- cache_control->no_cache,
- (long long)cache_control->last_modified,
- cache_control->etag == NULL?"":cache_control->etag);
+ LOG(("Writing %d bytes from %p", metadatalen, metadata));
+ if (fwrite(metadata, metadatalen, 1, file) != 1) {
+ LOG(("did not return 1"));
+ fclose(file);
+ free(fname);
+ free(b64u);
+ return NSERROR_SAVE_FAILED;
+ }
fclose(file);
@@ -154,10 +144,7 @@ persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, c
}
static nserror
-retrieve(nsurl *url,
- llcache_cache_control *cache_control,
- uint8_t **data_out,
- size_t *datalen_out)
+fetch(nsurl *url, uint8_t **data_out, size_t *datalen_out)
{
uint8_t *b64u;
size_t b64ulen;
@@ -166,7 +153,6 @@ retrieve(nsurl *url,
uint8_t *data;
size_t datalen;
-
data = *data_out;
datalen = *datalen_out;
@@ -176,51 +162,73 @@ retrieve(nsurl *url,
&b64ulen);
fname = malloc(SLEN("/tmp/ns/d/") + b64ulen + 1);
+ snprintf(fname, SLEN("/tmp/ns/d/") + b64ulen + 1, "/tmp/ns/d/%s", b64u);
- /* retrive cache control info if necessary */
- if (cache_control != NULL) {
- int cnt;
- snprintf(fname, SLEN("/tmp/ns/i/") + b64ulen + 1, "/tmp/ns/i/%s", b64u);
+ LOG(("Opening file %s",fname));
+ file = fopen(fname, "rb");
+ free(fname);
+ if (file == NULL) {
+ free(b64u);
+ return NSERROR_NOT_FOUND;
+ }
- file = fopen(fname, "rb");
- if (file == NULL) {
- LOG(("Unable to open %s", fname));
- free(fname);
- free(b64u);
- return NSERROR_NOT_FOUND;
+ /* need to deal with buffers */
+ if (data == NULL) {
+ if (datalen == 0) {
+ /* caller did not know the files length */
+ fseek(file, 0L, SEEK_END);
+ datalen = ftell(file);
+ fseek(file, 0L, SEEK_SET);
}
- LOG(("Opening info file %s", fname));
-
- cnt = fscanf(file,
- "req_time:%lld\n"
- "res_time:%lld\n"
- "fin_time:%lld\n"
- "date:%lld\n"
- "expires:%lld\n"
- "age:%d\n"
- "max_age:%d\n"
- "no_cache:%d\n"
- "last_modified:%lld\n"
- "etag:%ms\n",
- (long long*)&cache_control->req_time,
- (long long*)&cache_control->res_time,
- (long long*)&cache_control->fin_time,
- (long long*)&cache_control->date,
- (long long*)&cache_control->expires,
- &cache_control->age,
- &cache_control->max_age,
- (int *)&cache_control->no_cache,
- (long long*)&cache_control->last_modified,
- &cache_control->etag);
-
- LOG(("Read %d items from cache constrol", cnt));
+ data = malloc(datalen);
+ if (data == NULL) {
+ fclose(file);
+ free(b64u);
+ return NSERROR_NOMEM;
+ }
+ }
+ LOG(("Reading %d bytes into %p from file", datalen, data));
+ if (fread(data, datalen, 1, file) != 1) {
+ LOG(("did not return 1"));
fclose(file);
-
+ free(b64u);
+ if ((*data_out) == NULL) {
+ free(data);
+ }
+ return NSERROR_NOT_FOUND;
}
- snprintf(fname, SLEN("/tmp/ns/d/") + b64ulen + 1, "/tmp/ns/d/%s", b64u);
+ fclose(file);
+ free(b64u);
+
+ *data_out = data;
+ *datalen_out = datalen;
+
+ return NSERROR_OK;
+}
+
+static nserror
+fetchmeta(nsurl *url, uint8_t **metadata_out, size_t *metadatalen_out)
+{
+ uint8_t *b64u;
+ size_t b64ulen;
+ char *fname;
+ FILE *file;
+ uint8_t *data;
+ size_t datalen;
+
+ data = *metadata_out;
+ datalen = *metadatalen_out;
+
+ LOG(("retriving cache file for url:%s", nsurl_access(url)));
+ b64u = base64url_encode(nsurl_access(url),
+ strlen(nsurl_access(url)),
+ &b64ulen);
+
+ fname = malloc(SLEN("/tmp/ns/i/") + b64ulen + 1);
+ snprintf(fname, SLEN("/tmp/ns/i/") + b64ulen + 1, "/tmp/ns/i/%s", b64u);
LOG(("Opening file %s",fname));
file = fopen(fname, "rb");
@@ -230,7 +238,7 @@ retrieve(nsurl *url,
return NSERROR_NOT_FOUND;
}
- /* need to deal with buffers */
+ /* need to deal with allocating buffers */
if (data == NULL) {
if (datalen == 0) {
/* caller did not know the files length */
@@ -252,7 +260,7 @@ retrieve(nsurl *url,
LOG(("did not return 1"));
fclose(file);
free(b64u);
- if ((*data_out) == NULL) {
+ if ((*metadata_out) == NULL) {
free(data);
}
return NSERROR_NOT_FOUND;
@@ -261,15 +269,24 @@ retrieve(nsurl *url,
fclose(file);
free(b64u);
- *data_out = data;
- *datalen_out = datalen;
+ *metadata_out = data;
+ *metadatalen_out = datalen;
return NSERROR_OK;
}
+static nserror
+invalidate(nsurl *url)
+{
+ return NSERROR_OK;
+}
+
+
static struct gui_llcache_table llcache_table = {
- .persist = persist,
- .retrieve = retrieve,
+ .store = store,
+ .fetch = fetch,
+ .meta = fetchmeta,
+ .invalidate = invalidate,
};
struct gui_llcache_table *nsgtk_llcache_table = &llcache_table;
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=cc69c29fcd44a56d2af...
commit cc69c29fcd44a56d2af310cb3c98a7365c0ae1d0
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
header names should have whitespace stripped regardless
diff --git a/content/llcache.c b/content/llcache.c
index a4bc9b4..44224fe 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -389,6 +389,12 @@ static nserror llcache_fetch_split_header(const uint8_t *data, size_t len,
char *n, *v;
const uint8_t *colon;
+ /* Strip leading whitespace from name */
+ while (data[0] == ' ' || data[0] == '\t' ||
+ data[0] == '\r' || data[0] == '\n') {
+ data++;
+ }
+
/* Find colon */
colon = (const uint8_t *) strchr((const char *) data, ':');
if (colon == NULL) {
@@ -405,12 +411,6 @@ static nserror llcache_fetch_split_header(const uint8_t *data, size_t len,
} else {
/* Split header into name & value */
- /* Strip leading whitespace from name */
- while (data[0] == ' ' || data[0] == '\t' ||
- data[0] == '\r' || data[0] == '\n') {
- data++;
- }
-
/* Strip trailing whitespace from name */
while (colon > data && (colon[-1] == ' ' ||
colon[-1] == '\t' || colon[-1] == '\r' ||
@@ -1023,8 +1023,11 @@ llcache_persist_retrieve(llcache_object *object)
&object->source_len);
}
+/**
+ * attempt to retrieve an object from persistant storage
+ */
static nserror
-llcache_object_persist_fetch(llcache_object *object,
+llcache_object_fetch_persistant(llcache_object *object,
uint32_t flags,
nsurl *referer,
const llcache_post_data *post,
@@ -1114,7 +1117,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
return error;
/* attempt to retrieve object from persistant store */
- error = llcache_object_persist_fetch(obj, flags, referer, post, redirect_count);
+ error = llcache_object_fetch_persistant(obj, flags, referer, post, redirect_count);
if (error == NSERROR_OK) {
/* set object from persistant store as newest */
newest = obj;
-----------------------------------------------------------------------
Summary of changes:
content/llcache.c | 208 +++++++++++++++++++++++++++++++++++++++------
content/llcache_private.h | 51 +++++------
desktop/gui_factory.c | 37 +++++++--
gtk/llcache.c | 165 ++++++++++++++++++++----------------
4 files changed, 328 insertions(+), 133 deletions(-)
diff --git a/content/llcache.c b/content/llcache.c
index a4bc9b4..6731a28 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -17,7 +17,11 @@
*/
/** \file
- * Low-level resource cache (implementation)
+ * Low-level resource cache implementation
+ *
+ * This is the implementation of the low level cache. This cache
+ * stores source objects in memory and may use a persistant backing
+ * store to extend their lifetime.
*/
#include <stdlib.h>
@@ -47,6 +51,9 @@
#define LLCACHE_LOG(x)
#endif
+#define LLCACHE_MIN_DISC_LIFETIME 3600
+#define LLCACHE_MAX_DISC_BANDWIDTH (512*1024)
+
/** State of a low-level cache object fetch */
typedef enum {
LLCACHE_FETCH_INIT, /**< Initial state, before fetch */
@@ -105,6 +112,30 @@ typedef struct {
char *value; /**< Header value */
} llcache_header;
+/** validation control */
+typedef enum {
+ LLCACHE_VALIDATE_FRESH, /**< Only revalidate if not fresh */
+ LLCACHE_VALIDATE_ALWAYS, /**< Always revalidate */
+ LLCACHE_VALIDATE_ONCE /**< Revalidate once only */
+} llcache_validate;
+
+/** cache control value for invalid age */
+#define INVALID_AGE -1
+
+/** Cache control data */
+typedef struct {
+ time_t req_time; /**< Time of request */
+ time_t res_time; /**< Time of response */
+ time_t fin_time; /**< Time of request completion */
+ time_t date; /**< Date: response header */
+ time_t expires; /**< Expires: response header */
+ int age; /**< Age: response header */
+ int max_age; /**< Max-Age Cache-control parameter */
+ llcache_validate no_cache; /**< No-Cache Cache-control parameter */
+ char *etag; /**< Etag: response header */
+ time_t last_modified; /**< Last-Modified: response header */
+} llcache_cache_control;
+
/** Current status of objects data */
typedef enum {
LLCACHE_STORE_RAM = 0, /**< sourec data is stored in RAM only */
@@ -389,11 +420,25 @@ static nserror llcache_fetch_split_header(const uint8_t *data, size_t len,
char *n, *v;
const uint8_t *colon;
+ /* Strip leading whitespace from name */
+ while (data[0] == ' ' || data[0] == '\t' ||
+ data[0] == '\r' || data[0] == '\n') {
+ data++;
+ }
+
/* Find colon */
colon = (const uint8_t *) strchr((const char *) data, ':');
if (colon == NULL) {
/* Failed, assume a key with no value */
- n = strdup((const char *) data);
+ colon = data + strlen((const char *)data);
+
+ /* Strip trailing whitespace from name */
+ while ((colon > data) &&
+ (colon[-1] == ' ' || colon[-1] == '\t' ||
+ colon[-1] == '\r' || colon[-1] == '\n')) {
+ colon--;
+ }
+ n = strndup((const char *) data, colon - data);
if (n == NULL)
return NSERROR_NOMEM;
@@ -405,12 +450,6 @@ static nserror llcache_fetch_split_header(const uint8_t *data, size_t len,
} else {
/* Split header into name & value */
- /* Strip leading whitespace from name */
- while (data[0] == ' ' || data[0] == '\t' ||
- data[0] == '\r' || data[0] == '\n') {
- data++;
- }
-
/* Strip trailing whitespace from name */
while (colon > data && (colon[-1] == ' ' ||
colon[-1] == '\t' || colon[-1] == '\r' ||
@@ -620,6 +659,13 @@ static nserror llcache_fetch_process_header(llcache_object *object,
return error;
}
+ /* deal with empty header */
+ if (name[0] == 0) {
+ free(name);
+ free(value);
+ return NSERROR_OK;
+ }
+
/* Append header data to the object's headers array */
temp = realloc(object->headers, (object->num_headers + 1) *
sizeof(llcache_header));
@@ -1017,14 +1063,22 @@ llcache_persist_retrieve(llcache_object *object)
}
/* Source data for the object may be in the persiatant store */
- return guit->llcache->retrieve(object->url,
- NULL,
- &object->source_data,
- &object->source_len);
+ return guit->llcache->fetch(object->url,
+ &object->source_data,
+ &object->source_len);
+}
+
+static nserror
+llcache_process_metadata(llcache_object *object, uint8_t *data, size_t datasize)
+{
+ return NSERROR_NOT_FOUND;
}
+/**
+ * attempt to retrieve an object from persistant storage.
+ */
static nserror
-llcache_object_persist_fetch(llcache_object *object,
+llcache_object_fetch_persistant(llcache_object *object,
uint32_t flags,
nsurl *referer,
const llcache_post_data *post,
@@ -1033,12 +1087,11 @@ llcache_object_persist_fetch(llcache_object *object,
nserror error;
nsurl *referer_clone = NULL;
llcache_post_data *post_clone = NULL;
+ uint8_t *metadata = NULL;
+ size_t metadatalen = 0;
- /* attempt to retrieve object from the cache */
- error = guit->llcache->retrieve(object->url,
- &object->cache,
- &object->source_data,
- &object->source_len);
+ /* attempt to retrieve object metadata from the cache */
+ error = guit->llcache->meta(object->url, &metadata, &metadatalen);
if (error != NSERROR_OK)
return error;
@@ -1052,11 +1105,20 @@ llcache_object_persist_fetch(llcache_object *object,
if (referer != NULL)
referer_clone = nsurl_ref(referer);
+ object->cache.req_time = time(NULL);
+ object->cache.fin_time = object->cache.req_time;
+
object->fetch.flags = flags;
object->fetch.referer = referer_clone;
object->fetch.post = post_clone;
object->fetch.redirect_count = redirect_count;
+ /* process the metadata */
+ error = llcache_process_metadata(object, metadata, metadatalen);
+ free(metadata);
+ if (error != NSERROR_OK)
+ return error;
+
/* fetch is "finished" */
object->fetch.state = LLCACHE_FETCH_COMPLETE;
object->fetch.fetch = NULL;
@@ -1114,7 +1176,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
return error;
/* attempt to retrieve object from persistant store */
- error = llcache_object_persist_fetch(obj, flags, referer, post, redirect_count);
+ error = llcache_object_fetch_persistant(obj, flags, referer, post, redirect_count);
if (error == NSERROR_OK) {
/* set object from persistant store as newest */
newest = obj;
@@ -1769,9 +1831,89 @@ static nserror llcache_fetch_ssl_error(llcache_object *object)
return error;
}
-#define LLCACHE_MIN_DISC_LIFETIME 3600
-#define LLCACHE_MAX_DISC_BANDWIDTH (512*1024)
+/**
+ * Generate a serialised version of an objects metadata
+ *
+ * metadata includes object headers
+ */
+static nserror
+llcache_serialise_metadata(llcache_object *object,
+ uint8_t **data_out,
+ size_t *datasize_out)
+{
+ size_t allocsize;
+ int datasize;
+ uint8_t *data;
+ char *op;
+ unsigned int hloop;
+ int use;
+
+ allocsize = 10 + 2; /* object length */
+
+ allocsize += 10 + 2; /* space for number of header entries */
+ allocsize += nsurl_length(object->url) + 2;
+
+ for (hloop = 0 ; hloop < object->num_headers ; hloop++) {
+ allocsize += strlen(object->headers[hloop].name) + 1;
+ allocsize += strlen(object->headers[hloop].value) + 2;
+ }
+
+ data = malloc(allocsize);
+ if (data == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ op = (char *)data;
+ datasize = allocsize;
+
+ /* the url, used for checking for collisions */
+ use = snprintf(op, datasize, "%s%c%c", nsurl_access(object->url) ,13, 10);
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+
+ /* object size */
+ use = snprintf(op, datasize, "%d%c%c", (unsigned int)object->source_len, 13, 10);
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+
+ /* number of headers */
+ use = snprintf(op, datasize, "%d%c%c", (unsigned int)object->num_headers, 13, 10);
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+
+ /* headers */
+ for (hloop = 0 ; hloop < object->num_headers ; hloop++) {
+ use = snprintf(op, datasize,
+ "%s:%s%c%c",
+ object->headers[hloop].name,
+ object->headers[hloop].value,
+ 13, 10);
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+ }
+
+ LOG(("Filled buffer with %d spare", datasize));
+
+ *data_out = data;
+ *datasize_out = allocsize - datasize;
+
+ return NSERROR_OK;
+
+overflow:
+ /* somehow we overflowed the buffer - hth? */
+ LOG(("Overflowed metadata buffer"));
+ free(data);
+ return NSERROR_INVALID;
+}
/**
* possibly push objects data to persiatant storage.
@@ -1797,11 +1939,25 @@ static void llcache_persist(void *p)
(object->fetch.outstanding_query == false) &&
(object->store_state == LLCACHE_STORE_RAM) &&
(remaining_lifetime > LLCACHE_MIN_DISC_LIFETIME)) {
+ uint8_t *metadata;
+ size_t metadatasize;
+
+ ret = llcache_serialise_metadata(object, &metadata, &metadatasize);
+ if (ret != NSERROR_OK) {
+ /* as there has been a serialisation
+ * error, give up on making any more
+ * objects persistant for now.
+ */
+ return;
+ }
+
/* ok found an object to write */
- ret = guit->llcache->persist(object->url,
- &object->cache,
- object->source_data,
- object->source_len);
+ ret = guit->llcache->store(object->url,
+ metadata,
+ metadatasize,
+ object->source_data,
+ object->source_len);
+ free(metadata);
if (ret != NSERROR_OK) {
/* as there has been a serialisation
* error, give up on making any more
@@ -1810,7 +1966,7 @@ static void llcache_persist(void *p)
return;
}
object->store_state = LLCACHE_STORE_DISC;
- size_written += object->source_len;
+ size_written += object->source_len + metadatasize;
if (size_written > LLCACHE_MAX_DISC_BANDWIDTH) {
break;
diff --git a/content/llcache_private.h b/content/llcache_private.h
index 926773b..f038c9d 100644
--- a/content/llcache_private.h
+++ b/content/llcache_private.h
@@ -25,34 +25,31 @@
#include "content/llcache.h"
-/** validation control */
-typedef enum {
- LLCACHE_VALIDATE_FRESH, /**< Only revalidate if not fresh */
- LLCACHE_VALIDATE_ALWAYS, /**< Always revalidate */
- LLCACHE_VALIDATE_ONCE /**< Revalidate once only */
-} llcache_validate;
-
-/** cache control value for invalid age */
-#define INVALID_AGE -1
-
-/** Cache control data */
-typedef struct {
- time_t req_time; /**< Time of request */
- time_t res_time; /**< Time of response */
- time_t fin_time; /**< Time of request completion */
- time_t date; /**< Date: response header */
- time_t expires; /**< Expires: response header */
- int age; /**< Age: response header */
- int max_age; /**< Max-Age Cache-control parameter */
- llcache_validate no_cache; /**< No-Cache Cache-control parameter */
- char *etag; /**< Etag: response header */
- time_t last_modified; /**< Last-Modified: response header */
-} llcache_cache_control;
-
-/** operation table */
+/** low level cache operation table
+ *
+ * The low level cache (source objects) has the capability to make
+ * objects and their metadata (headers etc) persistant by writing to a
+ * backing store using these operations.
+ */
struct gui_llcache_table {
- nserror (*persist)(struct nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen);
- nserror (*retrieve)(struct nsurl *url, llcache_cache_control *cache_control, uint8_t **data, size_t *datalen);
+ /** Place a source object and its metadata in the backing store. */
+ nserror (*store)(struct nsurl *url,
+ const uint8_t *metadata, const size_t metadatalen,
+ const uint8_t *data, const size_t datalen);
+
+ /** retrive source object data from backing store. */
+ nserror (*fetch)(struct nsurl *url, uint8_t **data, size_t *datalen);
+
+ /** retrive source object metadata from backing store. */
+ nserror (*meta)(struct nsurl *url, uint8_t **data, size_t *datalen);
+
+ /**
+ * invalidate a source object from the backing store.
+ *
+ * The entry (if present in the backing store) must no longer
+ * be returned as a result to the fetch or meta operations.
+ */
+ nserror (*invalidate)(struct nsurl *url);
};
#endif
diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c
index 37fee39..71fb226 100644
--- a/desktop/gui_factory.c
+++ b/desktop/gui_factory.c
@@ -345,19 +345,38 @@ static nserror verify_utf8_register(struct gui_utf8_table *gut)
return NSERROR_OK;
}
-static nserror gui_default_persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen)
+static nserror
+gui_default_store(nsurl *url,
+ const uint8_t *metadata, const size_t metadatalen,
+ const uint8_t *data, const size_t datalen)
{
return NSERROR_SAVE_FAILED;
}
-static nserror gui_default_retrieve(nsurl *url, llcache_cache_control *cache_control, uint8_t **data_out, size_t *datalen_out)
+static nserror
+gui_default_fetch(nsurl *url, uint8_t **data_out, size_t *datalen_out)
{
return NSERROR_NOT_FOUND;
}
+static nserror
+gui_default_meta(nsurl *url, uint8_t **data_out, size_t *datalen_out)
+{
+ return NSERROR_NOT_FOUND;
+}
+
+static nserror
+gui_default_invalidate(nsurl *url)
+{
+ return NSERROR_NOT_FOUND;
+}
+
+
static struct gui_llcache_table default_llcache_table = {
- .persist = gui_default_persist,
- .retrieve = gui_default_retrieve,
+ .store = gui_default_store,
+ .fetch = gui_default_fetch,
+ .meta = gui_default_meta,
+ .invalidate = gui_default_invalidate,
};
/** verify clipboard table is valid */
@@ -369,10 +388,16 @@ static nserror verify_llcache_register(struct gui_llcache_table *glt)
}
/* mandantory operations */
- if (glt->persist == NULL) {
+ if (glt->store == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+ if (glt->fetch == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+ if (glt->meta == NULL) {
return NSERROR_BAD_PARAMETER;
}
- if (glt->retrieve == NULL) {
+ if (glt->invalidate == NULL) {
return NSERROR_BAD_PARAMETER;
}
return NSERROR_OK;
diff --git a/gtk/llcache.c b/gtk/llcache.c
index a2c27e5..4fa4e1e 100644
--- a/gtk/llcache.c
+++ b/gtk/llcache.c
@@ -41,9 +41,10 @@ static uint8_t encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
static unsigned int mod_table[] = {0, 2, 1};
-static uint8_t *base64url_encode(const char *data,
- size_t input_length,
- size_t *output_length)
+static uint8_t *
+base64url_encode(const char *data,
+ size_t input_length,
+ size_t *output_length)
{
uint8_t *encoded_data;
size_t i;
@@ -79,7 +80,9 @@ static uint8_t *base64url_encode(const char *data,
}
static nserror
-persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen)
+store(nsurl *url,
+ const uint8_t *metadata, const size_t metadatalen,
+ const uint8_t *data, const size_t datalen)
{
uint8_t *b64u;
size_t b64ulen;
@@ -101,7 +104,7 @@ persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, c
return NSERROR_SAVE_FAILED;
}
- LOG(("Writing %d bytes at %p to file", datalen, data));
+ LOG(("Writing %d bytes from %p", datalen, data));
if (fwrite(data, datalen, 1, file) != 1) {
LOG(("did not return 1"));
fclose(file);
@@ -123,27 +126,14 @@ persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, c
return NSERROR_SAVE_FAILED;
}
- fprintf(file,
- "req_time:%lld\n"
- "res_time:%lld\n"
- "fin_time:%lld\n"
- "date:%lld\n"
- "expires:%lld\n"
- "age:%d\n"
- "max_age:%d\n"
- "no_cache:%d\n"
- "last_modified:%lld\n"
- "etag:%s\n",
- (long long)cache_control->req_time,
- (long long)cache_control->res_time,
- (long long)cache_control->fin_time,
- (long long)cache_control->date,
- (long long)cache_control->expires,
- cache_control->age,
- cache_control->max_age,
- cache_control->no_cache,
- (long long)cache_control->last_modified,
- cache_control->etag == NULL?"":cache_control->etag);
+ LOG(("Writing %d bytes from %p", metadatalen, metadata));
+ if (fwrite(metadata, metadatalen, 1, file) != 1) {
+ LOG(("did not return 1"));
+ fclose(file);
+ free(fname);
+ free(b64u);
+ return NSERROR_SAVE_FAILED;
+ }
fclose(file);
@@ -154,10 +144,7 @@ persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, c
}
static nserror
-retrieve(nsurl *url,
- llcache_cache_control *cache_control,
- uint8_t **data_out,
- size_t *datalen_out)
+fetch(nsurl *url, uint8_t **data_out, size_t *datalen_out)
{
uint8_t *b64u;
size_t b64ulen;
@@ -166,7 +153,6 @@ retrieve(nsurl *url,
uint8_t *data;
size_t datalen;
-
data = *data_out;
datalen = *datalen_out;
@@ -176,51 +162,73 @@ retrieve(nsurl *url,
&b64ulen);
fname = malloc(SLEN("/tmp/ns/d/") + b64ulen + 1);
+ snprintf(fname, SLEN("/tmp/ns/d/") + b64ulen + 1, "/tmp/ns/d/%s", b64u);
- /* retrive cache control info if necessary */
- if (cache_control != NULL) {
- int cnt;
- snprintf(fname, SLEN("/tmp/ns/i/") + b64ulen + 1, "/tmp/ns/i/%s", b64u);
+ LOG(("Opening file %s",fname));
+ file = fopen(fname, "rb");
+ free(fname);
+ if (file == NULL) {
+ free(b64u);
+ return NSERROR_NOT_FOUND;
+ }
- file = fopen(fname, "rb");
- if (file == NULL) {
- LOG(("Unable to open %s", fname));
- free(fname);
- free(b64u);
- return NSERROR_NOT_FOUND;
+ /* need to deal with buffers */
+ if (data == NULL) {
+ if (datalen == 0) {
+ /* caller did not know the files length */
+ fseek(file, 0L, SEEK_END);
+ datalen = ftell(file);
+ fseek(file, 0L, SEEK_SET);
}
- LOG(("Opening info file %s", fname));
-
- cnt = fscanf(file,
- "req_time:%lld\n"
- "res_time:%lld\n"
- "fin_time:%lld\n"
- "date:%lld\n"
- "expires:%lld\n"
- "age:%d\n"
- "max_age:%d\n"
- "no_cache:%d\n"
- "last_modified:%lld\n"
- "etag:%ms\n",
- (long long*)&cache_control->req_time,
- (long long*)&cache_control->res_time,
- (long long*)&cache_control->fin_time,
- (long long*)&cache_control->date,
- (long long*)&cache_control->expires,
- &cache_control->age,
- &cache_control->max_age,
- (int *)&cache_control->no_cache,
- (long long*)&cache_control->last_modified,
- &cache_control->etag);
-
- LOG(("Read %d items from cache constrol", cnt));
+ data = malloc(datalen);
+ if (data == NULL) {
+ fclose(file);
+ free(b64u);
+ return NSERROR_NOMEM;
+ }
+ }
+ LOG(("Reading %d bytes into %p from file", datalen, data));
+ if (fread(data, datalen, 1, file) != 1) {
+ LOG(("did not return 1"));
fclose(file);
-
+ free(b64u);
+ if ((*data_out) == NULL) {
+ free(data);
+ }
+ return NSERROR_NOT_FOUND;
}
- snprintf(fname, SLEN("/tmp/ns/d/") + b64ulen + 1, "/tmp/ns/d/%s", b64u);
+ fclose(file);
+ free(b64u);
+
+ *data_out = data;
+ *datalen_out = datalen;
+
+ return NSERROR_OK;
+}
+
+static nserror
+fetchmeta(nsurl *url, uint8_t **metadata_out, size_t *metadatalen_out)
+{
+ uint8_t *b64u;
+ size_t b64ulen;
+ char *fname;
+ FILE *file;
+ uint8_t *data;
+ size_t datalen;
+
+ data = *metadata_out;
+ datalen = *metadatalen_out;
+
+ LOG(("retriving cache file for url:%s", nsurl_access(url)));
+ b64u = base64url_encode(nsurl_access(url),
+ strlen(nsurl_access(url)),
+ &b64ulen);
+
+ fname = malloc(SLEN("/tmp/ns/i/") + b64ulen + 1);
+ snprintf(fname, SLEN("/tmp/ns/i/") + b64ulen + 1, "/tmp/ns/i/%s", b64u);
LOG(("Opening file %s",fname));
file = fopen(fname, "rb");
@@ -230,7 +238,7 @@ retrieve(nsurl *url,
return NSERROR_NOT_FOUND;
}
- /* need to deal with buffers */
+ /* need to deal with allocating buffers */
if (data == NULL) {
if (datalen == 0) {
/* caller did not know the files length */
@@ -252,7 +260,7 @@ retrieve(nsurl *url,
LOG(("did not return 1"));
fclose(file);
free(b64u);
- if ((*data_out) == NULL) {
+ if ((*metadata_out) == NULL) {
free(data);
}
return NSERROR_NOT_FOUND;
@@ -261,15 +269,24 @@ retrieve(nsurl *url,
fclose(file);
free(b64u);
- *data_out = data;
- *datalen_out = datalen;
+ *metadata_out = data;
+ *metadatalen_out = datalen;
return NSERROR_OK;
}
+static nserror
+invalidate(nsurl *url)
+{
+ return NSERROR_OK;
+}
+
+
static struct gui_llcache_table llcache_table = {
- .persist = persist,
- .retrieve = retrieve,
+ .store = store,
+ .fetch = fetch,
+ .meta = fetchmeta,
+ .invalidate = invalidate,
};
struct gui_llcache_table *nsgtk_llcache_table = &llcache_table;
--
NetSurf Browser
9 years, 9 months
netsurf: branch master updated. release/3.0-1123-gc47a497
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/c47a497bca10e2fce6fd2...
...commit http://git.netsurf-browser.org/netsurf.git/commit/c47a497bca10e2fce6fd2f4...
...tree http://git.netsurf-browser.org/netsurf.git/tree/c47a497bca10e2fce6fd2f458...
The branch, master has been updated
via c47a497bca10e2fce6fd2f458e9b5b9f6992062d (commit)
from 1511a742031342944d7aae38b35854fe62eaaf91 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=c47a497bca10e2fce6f...
commit c47a497bca10e2fce6fd2f458e9b5b9f6992062d
Author: John-Mark Bell <jmb(a)netsurf-browser.org>
Commit: John-Mark Bell <jmb(a)netsurf-browser.org>
GTK: more endian fixes for bitmap conversion.
diff --git a/gtk/bitmap.c b/gtk/bitmap.c
index 4b14c28..3ae2114 100644
--- a/gtk/bitmap.c
+++ b/gtk/bitmap.c
@@ -204,20 +204,42 @@ unsigned char *bitmap_get_buffer(void *vbitmap)
cairo_image_surface_get_height(gbitmap->surface);
if (fmt == CAIRO_FORMAT_RGB24) {
- /* Opaque image: simply swap R & B channels */
+ /* Opaque image */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
+ /* Cairo surface is ARGB, written in native endian */
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
b = pixels[4 * pixel_loop + 0];
+ g = pixels[4 * pixel_loop + 1];
r = pixels[4 * pixel_loop + 2];
+ t = pixels[4 * pixel_loop + 3];
+#else
+ t = pixels[4 * pixel_loop + 0];
+ r = pixels[4 * pixel_loop + 1];
+ g = pixels[4 * pixel_loop + 2];
+ b = pixels[4 * pixel_loop + 3];
+#endif
+
+ /* Core bitmaps always have a component order of rgba,
+ * regardless of system endianness */
pixels[4 * pixel_loop + 0] = r;
+ pixels[4 * pixel_loop + 1] = g;
pixels[4 * pixel_loop + 2] = b;
+ pixels[4 * pixel_loop + 3] = t;
}
} else {
- /* Alpha image: swap R & B channels, and de-multiply alpha */
+ /* Alpha image: de-multiply alpha */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
b = pixels[4 * pixel_loop + 0];
g = pixels[4 * pixel_loop + 1];
r = pixels[4 * pixel_loop + 2];
t = pixels[4 * pixel_loop + 3];
+#else
+ t = pixels[4 * pixel_loop + 0];
+ r = pixels[4 * pixel_loop + 1];
+ g = pixels[4 * pixel_loop + 2];
+ b = pixels[4 * pixel_loop + 3];
+#endif
if (t != 0) {
r = (r << 8) / t;
@@ -343,15 +365,30 @@ void bitmap_modified(void *vbitmap) {
}
if (fmt == CAIRO_FORMAT_RGB24) {
- /* Opaque image: simply swap R & B channels */
+ /* Opaque image */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
+ /* Core bitmaps always have a component order of rgba,
+ * regardless of system endianness */
r = pixels[4 * pixel_loop + 0];
+ g = pixels[4 * pixel_loop + 1];
b = pixels[4 * pixel_loop + 2];
+ t = pixels[4 * pixel_loop + 3];
+
+ /* Cairo surface is ARGB, written in native endian */
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
pixels[4 * pixel_loop + 0] = b;
+ pixels[4 * pixel_loop + 1] = g;
pixels[4 * pixel_loop + 2] = r;
+ pixels[4 * pixel_loop + 3] = t;
+#else
+ pixels[4 * pixel_loop + 0] = t;
+ pixels[4 * pixel_loop + 1] = r;
+ pixels[4 * pixel_loop + 2] = g;
+ pixels[4 * pixel_loop + 3] = b;
+#endif
}
} else {
- /* Alpha image: swap R & B channels, and pre-multiply alpha */
+ /* Alpha image: pre-multiply alpha */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
r = pixels[4 * pixel_loop + 0];
g = pixels[4 * pixel_loop + 1];
@@ -366,10 +403,17 @@ void bitmap_modified(void *vbitmap) {
r = g = b = 0;
}
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
pixels[4 * pixel_loop + 0] = b;
pixels[4 * pixel_loop + 1] = g;
pixels[4 * pixel_loop + 2] = r;
pixels[4 * pixel_loop + 3] = t;
+#else
+ pixels[4 * pixel_loop + 0] = t;
+ pixels[4 * pixel_loop + 1] = r;
+ pixels[4 * pixel_loop + 2] = g;
+ pixels[4 * pixel_loop + 3] = b;
+#endif
}
}
-----------------------------------------------------------------------
Summary of changes:
gtk/bitmap.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/gtk/bitmap.c b/gtk/bitmap.c
index 4b14c28..3ae2114 100644
--- a/gtk/bitmap.c
+++ b/gtk/bitmap.c
@@ -204,20 +204,42 @@ unsigned char *bitmap_get_buffer(void *vbitmap)
cairo_image_surface_get_height(gbitmap->surface);
if (fmt == CAIRO_FORMAT_RGB24) {
- /* Opaque image: simply swap R & B channels */
+ /* Opaque image */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
+ /* Cairo surface is ARGB, written in native endian */
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
b = pixels[4 * pixel_loop + 0];
+ g = pixels[4 * pixel_loop + 1];
r = pixels[4 * pixel_loop + 2];
+ t = pixels[4 * pixel_loop + 3];
+#else
+ t = pixels[4 * pixel_loop + 0];
+ r = pixels[4 * pixel_loop + 1];
+ g = pixels[4 * pixel_loop + 2];
+ b = pixels[4 * pixel_loop + 3];
+#endif
+
+ /* Core bitmaps always have a component order of rgba,
+ * regardless of system endianness */
pixels[4 * pixel_loop + 0] = r;
+ pixels[4 * pixel_loop + 1] = g;
pixels[4 * pixel_loop + 2] = b;
+ pixels[4 * pixel_loop + 3] = t;
}
} else {
- /* Alpha image: swap R & B channels, and de-multiply alpha */
+ /* Alpha image: de-multiply alpha */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
b = pixels[4 * pixel_loop + 0];
g = pixels[4 * pixel_loop + 1];
r = pixels[4 * pixel_loop + 2];
t = pixels[4 * pixel_loop + 3];
+#else
+ t = pixels[4 * pixel_loop + 0];
+ r = pixels[4 * pixel_loop + 1];
+ g = pixels[4 * pixel_loop + 2];
+ b = pixels[4 * pixel_loop + 3];
+#endif
if (t != 0) {
r = (r << 8) / t;
@@ -343,15 +365,30 @@ void bitmap_modified(void *vbitmap) {
}
if (fmt == CAIRO_FORMAT_RGB24) {
- /* Opaque image: simply swap R & B channels */
+ /* Opaque image */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
+ /* Core bitmaps always have a component order of rgba,
+ * regardless of system endianness */
r = pixels[4 * pixel_loop + 0];
+ g = pixels[4 * pixel_loop + 1];
b = pixels[4 * pixel_loop + 2];
+ t = pixels[4 * pixel_loop + 3];
+
+ /* Cairo surface is ARGB, written in native endian */
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
pixels[4 * pixel_loop + 0] = b;
+ pixels[4 * pixel_loop + 1] = g;
pixels[4 * pixel_loop + 2] = r;
+ pixels[4 * pixel_loop + 3] = t;
+#else
+ pixels[4 * pixel_loop + 0] = t;
+ pixels[4 * pixel_loop + 1] = r;
+ pixels[4 * pixel_loop + 2] = g;
+ pixels[4 * pixel_loop + 3] = b;
+#endif
}
} else {
- /* Alpha image: swap R & B channels, and pre-multiply alpha */
+ /* Alpha image: pre-multiply alpha */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
r = pixels[4 * pixel_loop + 0];
g = pixels[4 * pixel_loop + 1];
@@ -366,10 +403,17 @@ void bitmap_modified(void *vbitmap) {
r = g = b = 0;
}
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
pixels[4 * pixel_loop + 0] = b;
pixels[4 * pixel_loop + 1] = g;
pixels[4 * pixel_loop + 2] = r;
pixels[4 * pixel_loop + 3] = t;
+#else
+ pixels[4 * pixel_loop + 0] = t;
+ pixels[4 * pixel_loop + 1] = r;
+ pixels[4 * pixel_loop + 2] = g;
+ pixels[4 * pixel_loop + 3] = b;
+#endif
}
}
--
NetSurf Browser
9 years, 9 months
netsurf: branch master updated. release/3.0-1122-g1511a74
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/1511a742031342944d7aa...
...commit http://git.netsurf-browser.org/netsurf.git/commit/1511a742031342944d7aae3...
...tree http://git.netsurf-browser.org/netsurf.git/tree/1511a742031342944d7aae38b...
The branch, master has been updated
via 1511a742031342944d7aae38b35854fe62eaaf91 (commit)
from 5e0efcbd6c8792b0b9287f2b85c9ca63e55188e7 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=1511a742031342944d7...
commit 1511a742031342944d7aae38b35854fe62eaaf91
Author: John-Mark Bell <jmb(a)netsurf-browser.org>
Commit: John-Mark Bell <jmb(a)netsurf-browser.org>
GTK: fix pre-multiplication of alpha.
diff --git a/gtk/bitmap.c b/gtk/bitmap.c
index 4474b07..4b14c28 100644
--- a/gtk/bitmap.c
+++ b/gtk/bitmap.c
@@ -359,9 +359,9 @@ void bitmap_modified(void *vbitmap) {
t = pixels[4 * pixel_loop + 3];
if (t != 0) {
- r = ((r * t) >> 8) & 0xff;
- g = ((g * t) >> 8) & 0xff;
- b = ((b * t) >> 8) & 0xff;
+ r = ((r * (t + 1)) >> 8) & 0xff;
+ g = ((g * (t + 1)) >> 8) & 0xff;
+ b = ((b * (t + 1)) >> 8) & 0xff;
} else {
r = g = b = 0;
}
-----------------------------------------------------------------------
Summary of changes:
gtk/bitmap.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/gtk/bitmap.c b/gtk/bitmap.c
index 4474b07..4b14c28 100644
--- a/gtk/bitmap.c
+++ b/gtk/bitmap.c
@@ -359,9 +359,9 @@ void bitmap_modified(void *vbitmap) {
t = pixels[4 * pixel_loop + 3];
if (t != 0) {
- r = ((r * t) >> 8) & 0xff;
- g = ((g * t) >> 8) & 0xff;
- b = ((b * t) >> 8) & 0xff;
+ r = ((r * (t + 1)) >> 8) & 0xff;
+ g = ((g * (t + 1)) >> 8) & 0xff;
+ b = ((b * (t + 1)) >> 8) & 0xff;
} else {
r = g = b = 0;
}
--
NetSurf Browser
9 years, 9 months
netsurf: branch master updated. release/3.0-1121-g5e0efcb
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/5e0efcbd6c8792b0b9287...
...commit http://git.netsurf-browser.org/netsurf.git/commit/5e0efcbd6c8792b0b9287f2...
...tree http://git.netsurf-browser.org/netsurf.git/tree/5e0efcbd6c8792b0b9287f2b8...
The branch, master has been updated
via 5e0efcbd6c8792b0b9287f2b85c9ca63e55188e7 (commit)
from d9002dc71c3e08c3222cf3e64f2d09c4ec9d87de (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=5e0efcbd6c8792b0b92...
commit 5e0efcbd6c8792b0b9287f2b85c9ca63e55188e7
Author: John-Mark Bell <jmb(a)netsurf-browser.org>
Commit: John-Mark Bell <jmb(a)netsurf-browser.org>
GTK: make image component manipulation endian-safe.
diff --git a/gtk/bitmap.c b/gtk/bitmap.c
index 96e9eda..4474b07 100644
--- a/gtk/bitmap.c
+++ b/gtk/bitmap.c
@@ -187,48 +187,54 @@ unsigned char *bitmap_get_buffer(void *vbitmap)
struct bitmap *gbitmap = (struct bitmap *)vbitmap;
int pixel_loop;
int pixel_count;
- uint32_t *pixels;
- uint32_t pixel;
+ uint8_t *pixels;
+ uint32_t t, r, g, b;
cairo_format_t fmt;
assert(gbitmap);
cairo_surface_flush(gbitmap->surface);
- pixels = (uint32_t *)cairo_image_surface_get_data(gbitmap->surface);
+ pixels = cairo_image_surface_get_data(gbitmap->surface);
if (!gbitmap->converted)
- return (unsigned char *) pixels;
+ return pixels;
fmt = cairo_image_surface_get_format(gbitmap->surface);
pixel_count = cairo_image_surface_get_width(gbitmap->surface) *
cairo_image_surface_get_height(gbitmap->surface);
if (fmt == CAIRO_FORMAT_RGB24) {
+ /* Opaque image: simply swap R & B channels */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- pixels[pixel_loop] = (pixel & 0xff00ff00) |
- ((pixel & 0xff) << 16) |
- ((pixel & 0xff0000) >> 16);
+ b = pixels[4 * pixel_loop + 0];
+ r = pixels[4 * pixel_loop + 2];
+ pixels[4 * pixel_loop + 0] = r;
+ pixels[4 * pixel_loop + 2] = b;
}
} else {
- uint32_t t, r, g, b;
+ /* Alpha image: swap R & B channels, and de-multiply alpha */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- t = (pixel & 0xff000000) >> 24;
- if (t == 0) {
- pixels[pixel_loop] = 0;
- } else {
- r = ((pixel & 0xff0000) >> 8) / t;
- g = ((pixel & 0xff00)) / t;
- b = ((pixel & 0xff) << 8) / t;
+ b = pixels[4 * pixel_loop + 0];
+ g = pixels[4 * pixel_loop + 1];
+ r = pixels[4 * pixel_loop + 2];
+ t = pixels[4 * pixel_loop + 3];
+
+ if (t != 0) {
+ r = (r << 8) / t;
+ g = (g << 8) / t;
+ b = (b << 8) / t;
r = (r > 255) ? 255 : r;
g = (g > 255) ? 255 : g;
b = (b > 255) ? 255 : b;
-
- pixels[pixel_loop] = (t << 24) |
- (r) | (g << 8) | (b << 16);
+ } else {
+ r = g = b = 0;
}
+
+ pixels[4 * pixel_loop + 0] = r;
+ pixels[4 * pixel_loop + 1] = g;
+ pixels[4 * pixel_loop + 2] = b;
+ pixels[4 * pixel_loop + 3] = t;
}
}
@@ -319,8 +325,8 @@ void bitmap_modified(void *vbitmap) {
struct bitmap *gbitmap = (struct bitmap *)vbitmap;
int pixel_loop;
int pixel_count;
- uint32_t *pixels;
- uint32_t pixel;
+ uint8_t *pixels;
+ uint32_t t, r, g, b;
cairo_format_t fmt;
assert(gbitmap);
@@ -329,7 +335,7 @@ void bitmap_modified(void *vbitmap) {
pixel_count = cairo_image_surface_get_width(gbitmap->surface) *
cairo_image_surface_get_height(gbitmap->surface);
- pixels = (uint32_t *)cairo_image_surface_get_data(gbitmap->surface);
+ pixels = cairo_image_surface_get_data(gbitmap->surface);
if (gbitmap->converted) {
cairo_surface_mark_dirty(gbitmap->surface);
@@ -337,30 +343,33 @@ void bitmap_modified(void *vbitmap) {
}
if (fmt == CAIRO_FORMAT_RGB24) {
+ /* Opaque image: simply swap R & B channels */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- pixels[pixel_loop] = (pixel & 0xff00ff00) |
- ((pixel & 0xff) << 16) |
- ((pixel & 0xff0000) >> 16);
+ r = pixels[4 * pixel_loop + 0];
+ b = pixels[4 * pixel_loop + 2];
+ pixels[4 * pixel_loop + 0] = b;
+ pixels[4 * pixel_loop + 2] = r;
}
} else {
- uint8_t t, r, g, b;
+ /* Alpha image: swap R & B channels, and pre-multiply alpha */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- t = (pixel & 0xff000000) >> 24;
- if (t == 0) {
- pixels[pixel_loop] = 0;
+ r = pixels[4 * pixel_loop + 0];
+ g = pixels[4 * pixel_loop + 1];
+ b = pixels[4 * pixel_loop + 2];
+ t = pixels[4 * pixel_loop + 3];
+
+ if (t != 0) {
+ r = ((r * t) >> 8) & 0xff;
+ g = ((g * t) >> 8) & 0xff;
+ b = ((b * t) >> 8) & 0xff;
} else {
- r = (pixel & 0xff0000) >> 16;
- g = (pixel & 0xff00) >> 8;
- b = pixel & 0xff;
-
- pixels[pixel_loop] = (t << 24) |
- ((r * t) >> 8) |
- ((g * t) >> 8) << 8 |
- ((b * t) >> 8) << 16;
-
+ r = g = b = 0;
}
+
+ pixels[4 * pixel_loop + 0] = b;
+ pixels[4 * pixel_loop + 1] = g;
+ pixels[4 * pixel_loop + 2] = r;
+ pixels[4 * pixel_loop + 3] = t;
}
}
-----------------------------------------------------------------------
Summary of changes:
gtk/bitmap.c | 91 ++++++++++++++++++++++++++++++++--------------------------
1 files changed, 50 insertions(+), 41 deletions(-)
diff --git a/gtk/bitmap.c b/gtk/bitmap.c
index 96e9eda..4474b07 100644
--- a/gtk/bitmap.c
+++ b/gtk/bitmap.c
@@ -187,48 +187,54 @@ unsigned char *bitmap_get_buffer(void *vbitmap)
struct bitmap *gbitmap = (struct bitmap *)vbitmap;
int pixel_loop;
int pixel_count;
- uint32_t *pixels;
- uint32_t pixel;
+ uint8_t *pixels;
+ uint32_t t, r, g, b;
cairo_format_t fmt;
assert(gbitmap);
cairo_surface_flush(gbitmap->surface);
- pixels = (uint32_t *)cairo_image_surface_get_data(gbitmap->surface);
+ pixels = cairo_image_surface_get_data(gbitmap->surface);
if (!gbitmap->converted)
- return (unsigned char *) pixels;
+ return pixels;
fmt = cairo_image_surface_get_format(gbitmap->surface);
pixel_count = cairo_image_surface_get_width(gbitmap->surface) *
cairo_image_surface_get_height(gbitmap->surface);
if (fmt == CAIRO_FORMAT_RGB24) {
+ /* Opaque image: simply swap R & B channels */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- pixels[pixel_loop] = (pixel & 0xff00ff00) |
- ((pixel & 0xff) << 16) |
- ((pixel & 0xff0000) >> 16);
+ b = pixels[4 * pixel_loop + 0];
+ r = pixels[4 * pixel_loop + 2];
+ pixels[4 * pixel_loop + 0] = r;
+ pixels[4 * pixel_loop + 2] = b;
}
} else {
- uint32_t t, r, g, b;
+ /* Alpha image: swap R & B channels, and de-multiply alpha */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- t = (pixel & 0xff000000) >> 24;
- if (t == 0) {
- pixels[pixel_loop] = 0;
- } else {
- r = ((pixel & 0xff0000) >> 8) / t;
- g = ((pixel & 0xff00)) / t;
- b = ((pixel & 0xff) << 8) / t;
+ b = pixels[4 * pixel_loop + 0];
+ g = pixels[4 * pixel_loop + 1];
+ r = pixels[4 * pixel_loop + 2];
+ t = pixels[4 * pixel_loop + 3];
+
+ if (t != 0) {
+ r = (r << 8) / t;
+ g = (g << 8) / t;
+ b = (b << 8) / t;
r = (r > 255) ? 255 : r;
g = (g > 255) ? 255 : g;
b = (b > 255) ? 255 : b;
-
- pixels[pixel_loop] = (t << 24) |
- (r) | (g << 8) | (b << 16);
+ } else {
+ r = g = b = 0;
}
+
+ pixels[4 * pixel_loop + 0] = r;
+ pixels[4 * pixel_loop + 1] = g;
+ pixels[4 * pixel_loop + 2] = b;
+ pixels[4 * pixel_loop + 3] = t;
}
}
@@ -319,8 +325,8 @@ void bitmap_modified(void *vbitmap) {
struct bitmap *gbitmap = (struct bitmap *)vbitmap;
int pixel_loop;
int pixel_count;
- uint32_t *pixels;
- uint32_t pixel;
+ uint8_t *pixels;
+ uint32_t t, r, g, b;
cairo_format_t fmt;
assert(gbitmap);
@@ -329,7 +335,7 @@ void bitmap_modified(void *vbitmap) {
pixel_count = cairo_image_surface_get_width(gbitmap->surface) *
cairo_image_surface_get_height(gbitmap->surface);
- pixels = (uint32_t *)cairo_image_surface_get_data(gbitmap->surface);
+ pixels = cairo_image_surface_get_data(gbitmap->surface);
if (gbitmap->converted) {
cairo_surface_mark_dirty(gbitmap->surface);
@@ -337,30 +343,33 @@ void bitmap_modified(void *vbitmap) {
}
if (fmt == CAIRO_FORMAT_RGB24) {
+ /* Opaque image: simply swap R & B channels */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- pixels[pixel_loop] = (pixel & 0xff00ff00) |
- ((pixel & 0xff) << 16) |
- ((pixel & 0xff0000) >> 16);
+ r = pixels[4 * pixel_loop + 0];
+ b = pixels[4 * pixel_loop + 2];
+ pixels[4 * pixel_loop + 0] = b;
+ pixels[4 * pixel_loop + 2] = r;
}
} else {
- uint8_t t, r, g, b;
+ /* Alpha image: swap R & B channels, and pre-multiply alpha */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- t = (pixel & 0xff000000) >> 24;
- if (t == 0) {
- pixels[pixel_loop] = 0;
+ r = pixels[4 * pixel_loop + 0];
+ g = pixels[4 * pixel_loop + 1];
+ b = pixels[4 * pixel_loop + 2];
+ t = pixels[4 * pixel_loop + 3];
+
+ if (t != 0) {
+ r = ((r * t) >> 8) & 0xff;
+ g = ((g * t) >> 8) & 0xff;
+ b = ((b * t) >> 8) & 0xff;
} else {
- r = (pixel & 0xff0000) >> 16;
- g = (pixel & 0xff00) >> 8;
- b = pixel & 0xff;
-
- pixels[pixel_loop] = (t << 24) |
- ((r * t) >> 8) |
- ((g * t) >> 8) << 8 |
- ((b * t) >> 8) << 16;
-
+ r = g = b = 0;
}
+
+ pixels[4 * pixel_loop + 0] = b;
+ pixels[4 * pixel_loop + 1] = g;
+ pixels[4 * pixel_loop + 2] = r;
+ pixels[4 * pixel_loop + 3] = t;
}
}
--
NetSurf Browser
9 years, 9 months