Elinks currently only support GB2312 as Chinese encoding, but GBK and
[elinks.git] / src / document / refresh.c
blob4d815409b7cddf64b2aeca44ac75146435cf0c46
1 /** Document (meta) refresh.
2 * @file */
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
12 #include "elinks.h"
14 #include "config/options.h"
15 #include "document/document.h"
16 #include "document/refresh.h"
17 #include "document/view.h"
18 #include "main/select.h"
19 #include "main/timer.h"
20 #include "protocol/uri.h"
21 #include "session/download.h"
22 #include "session/session.h"
23 #include "session/task.h"
24 #include "util/error.h"
25 #include "util/memory.h"
26 #include "util/string.h"
29 struct document_refresh *
30 init_document_refresh(unsigned char *url, unsigned long seconds)
32 struct document_refresh *refresh;
34 refresh = mem_alloc(sizeof(*refresh));
35 if (!refresh) return NULL;
37 refresh->uri = get_uri(url, 0);
38 if (!refresh->uri) {
39 mem_free(refresh);
40 return NULL;
43 refresh->seconds = seconds;
44 refresh->timer = TIMER_ID_UNDEF;
45 refresh->restart = 1;
47 return refresh;
50 void
51 kill_document_refresh(struct document_refresh *refresh)
53 kill_timer(&refresh->timer);
56 void
57 done_document_refresh(struct document_refresh *refresh)
59 kill_document_refresh(refresh);
60 done_uri(refresh->uri);
61 mem_free(refresh);
64 /** Timer callback for document_refresh.timer. As explained in
65 * install_timer(), this function must erase the expired timer ID from
66 * all variables. */
67 static void
68 do_document_refresh(void *data)
70 struct document_view *doc_view = data;
71 struct document_refresh *refresh = doc_view->document->refresh;
72 struct type_query *type_query;
74 assert(refresh);
76 refresh->timer = TIMER_ID_UNDEF;
77 /* The expired timer ID has now been erased. */
79 /* When refreshing documents that will trigger a download (like
80 * sourceforge's download pages) make sure that we do not endlessly
81 * trigger the download (bug 289). */
82 foreach (type_query, doc_view->session->type_queries)
83 if (compare_uri(refresh->uri, type_query->uri, URI_BASE))
84 return;
86 if (compare_uri(refresh->uri, doc_view->document->uri, 0)) {
87 /* If the refreshing is for the current URI, force a reload. */
88 reload_frame(doc_view->session, doc_view->name,
89 CACHE_MODE_FORCE_RELOAD);
90 } else {
91 /* This makes sure that we send referer. */
92 goto_uri_frame(doc_view->session, refresh->uri, doc_view->name, CACHE_MODE_NORMAL);
93 /* XXX: A possible very wrong work-around for refreshing used when
94 * downloading files. */
95 refresh->restart = 0;
99 static void
100 start_document_refresh(struct document_refresh *refresh,
101 struct document_view *doc_view)
103 milliseconds_T minimum = (milliseconds_T) get_opt_int("document.browse.minimum_refresh_time", doc_view->session);
104 milliseconds_T refresh_delay = sec_to_ms(refresh->seconds);
105 milliseconds_T time = ms_max(refresh_delay, minimum);
106 struct type_query *type_query;
108 /* FIXME: This is just a work-around for stopping more than one timer
109 * from being started at anytime. The refresh timer should maybe belong
110 * to the session? The multiple refresh timers is triggered by
111 * http://ttforums.owenrudge.net/login.php when pressing 'Log in' and
112 * waiting for it to refresh. --jonas */
113 if (!refresh->restart
114 || refresh->timer != TIMER_ID_UNDEF)
115 return;
117 /* Like bug 289 another sourceforge download thingy this time with
118 * number 434. It should take care when refreshing to the same URI or
119 * what ever the cause is. */
120 foreach (type_query, doc_view->session->type_queries)
121 if (compare_uri(refresh->uri, type_query->uri, URI_BASE))
122 return;
124 if (time == 0) {
125 /* Use register_bottom_half() instead of install_timer()
126 * because the latter asserts that the delay is greater
127 * than 0. */
128 register_bottom_half(do_document_refresh, doc_view);
129 return;
132 install_timer(&refresh->timer, time, do_document_refresh, doc_view);
135 void
136 start_document_refreshes(struct session *ses)
139 assert(ses);
141 if (!ses->doc_view
142 || !ses->doc_view->document
143 || !get_opt_bool("document.browse.refresh", ses))
144 return;
146 if (document_has_frames(ses->doc_view->document)) {
147 struct document_view *doc_view;
149 foreach (doc_view, ses->scrn_frames) {
150 if (!doc_view->document
151 || !doc_view->document->refresh)
152 continue;
154 start_document_refresh(doc_view->document->refresh,
155 doc_view);
159 if (!ses->doc_view->document->refresh)
160 return;
162 start_document_refresh(ses->doc_view->document->refresh, ses->doc_view);