move-link-up-line: segfault when cursor was below last line.
[elinks.git] / src / document / refresh.c
blob2df897cee02fe3043559c0fd5c8d808170a8ad44
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/timer.h"
19 #include "protocol/uri.h"
20 #include "session/download.h"
21 #include "session/session.h"
22 #include "session/task.h"
23 #include "util/error.h"
24 #include "util/memory.h"
25 #include "util/string.h"
28 struct document_refresh *
29 init_document_refresh(unsigned char *url, unsigned long seconds)
31 struct document_refresh *refresh;
33 refresh = mem_alloc(sizeof(*refresh));
34 if (!refresh) return NULL;
36 refresh->uri = get_uri(url, 0);
37 if (!refresh->uri) {
38 mem_free(refresh);
39 return NULL;
42 refresh->seconds = seconds;
43 refresh->timer = TIMER_ID_UNDEF;
44 refresh->restart = 1;
46 return refresh;
49 void
50 kill_document_refresh(struct document_refresh *refresh)
52 kill_timer(&refresh->timer);
55 void
56 done_document_refresh(struct document_refresh *refresh)
58 kill_document_refresh(refresh);
59 done_uri(refresh->uri);
60 mem_free(refresh);
63 /** Timer callback for document_refresh.timer. As explained in
64 * install_timer(), this function must erase the expired timer ID from
65 * all variables. */
66 static void
67 do_document_refresh(void *data)
69 struct session *ses = data;
70 struct document_refresh *refresh = ses->doc_view->document->refresh;
71 struct type_query *type_query;
73 assert(refresh);
75 refresh->timer = TIMER_ID_UNDEF;
76 /* The expired timer ID has now been erased. */
78 /* When refreshing documents that will trigger a download (like
79 * sourceforge's download pages) make sure that we do not endlessly
80 * trigger the download (bug 289). */
81 foreach (type_query, ses->type_queries)
82 if (compare_uri(refresh->uri, type_query->uri, URI_BASE))
83 return;
85 if (compare_uri(refresh->uri, ses->doc_view->document->uri, 0)) {
86 /* If the refreshing is for the current URI, force a reload. */
87 reload(ses, CACHE_MODE_FORCE_RELOAD);
88 } else {
89 /* This makes sure that we send referer. */
90 goto_uri_frame(ses, refresh->uri, NULL, CACHE_MODE_NORMAL);
91 /* XXX: A possible very wrong work-around for refreshing used when
92 * downloading files. */
93 refresh->restart = 0;
97 static void
98 start_document_refresh(struct document_refresh *refresh, struct session *ses)
100 milliseconds_T minimum = (milliseconds_T) get_opt_int("document.browse.minimum_refresh_time");
101 milliseconds_T refresh_delay = sec_to_ms(refresh->seconds);
102 milliseconds_T time = ms_max(refresh_delay, minimum);
103 struct type_query *type_query;
105 /* FIXME: This is just a work-around for stopping more than one timer
106 * from being started at anytime. The refresh timer should maybe belong
107 * to the session? The multiple refresh timers is triggered by
108 * http://ttforums.owenrudge.net/login.php when pressing 'Log in' and
109 * waiting for it to refresh. --jonas */
110 if (!refresh->restart
111 || refresh->timer != TIMER_ID_UNDEF)
112 return;
114 /* Like bug 289 another sourceforge download thingy this time with
115 * number 434. It should take care when refreshing to the same URI or
116 * what ever the cause is. */
117 foreach (type_query, ses->type_queries)
118 if (compare_uri(refresh->uri, type_query->uri, URI_BASE))
119 return;
121 install_timer(&refresh->timer, time, do_document_refresh, ses);
124 void
125 start_document_refreshes(struct session *ses)
127 assert(ses);
129 if (!ses->doc_view
130 || !ses->doc_view->document
131 || !ses->doc_view->document->refresh
132 || !get_opt_bool("document.browse.refresh"))
133 return;
135 start_document_refresh(ses->doc_view->document->refresh, ses);