[wip] draw_images(): w, h, spos -> box screen_img; img_box -> pixel_box
[elinks/images.git] / src / viewer / action.c
blob402c4e123dab98bec8818f340b10fb7a4219b934
1 /* Sessions action management */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include <stdlib.h>
9 #include "elinks.h"
11 #include "bookmarks/dialogs.h"
12 #include "cache/dialogs.h"
13 #include "config/conf.h"
14 #include "config/dialogs.h"
15 #include "config/kbdbind.h"
16 #include "config/options.h"
17 #include "cookies/cookies.h"
18 #include "cookies/dialogs.h"
19 #include "dialogs/document.h"
20 #include "dialogs/download.h"
21 #include "dialogs/exmode.h"
22 #include "dialogs/info.h"
23 #include "dialogs/menu.h"
24 #include "dialogs/options.h"
25 #include "dialogs/status.h"
26 #include "document/document.h"
27 #include "document/view.h"
28 #include "formhist/dialogs.h"
29 #include "globhist/dialogs.h"
30 #include "main/main.h"
31 #include "network/connection.h"
32 #include "protocol/auth/auth.h"
33 #include "protocol/auth/dialogs.h"
34 #include "terminal/tab.h"
35 #include "terminal/terminal.h"
36 #include "terminal/window.h"
37 #include "session/history.h"
38 #include "session/session.h"
39 #include "session/task.h"
40 #include "viewer/action.h"
41 #include "viewer/text/draw.h"
42 #include "viewer/text/form.h"
43 #include "viewer/text/link.h"
44 #include "viewer/text/search.h"
45 #include "viewer/text/view.h"
48 static void
49 goto_url_action(struct session *ses,
50 unsigned char *(*get_url)(struct session *, unsigned char *, size_t))
52 unsigned char url[MAX_STR_LEN];
54 if (!get_url || !get_url(ses, url, sizeof(url)))
55 url[0] = 0;
57 dialog_goto_url(ses, url);
60 /* This could gradually become some multiplexor / switch noodle containing
61 * most if not all default handling of actions (for the main mapping) that
62 * frame_ev() and/or send_event() could use as a backend. */
63 /* Many execution paths may lead to this code so it needs to take appropriate
64 * precausions to stuff like doc_view and doc_view->vs being NULL. */
65 enum frame_event_status
66 do_action(struct session *ses, enum main_action action_id, int verbose)
68 enum frame_event_status status = FRAME_EVENT_OK;
69 struct terminal *term = ses->tab->term;
70 struct document_view *doc_view = current_frame(ses);
71 struct link *link = NULL;
73 if (action_id == -1) goto unknown_action;
75 if (doc_view && doc_view->vs) {
76 if (action_prefix_is_link_number(KEYMAP_MAIN, action_id)
77 && !try_jump_to_link_number(ses, doc_view))
78 goto ignore_action;
80 link = get_current_link(doc_view);
82 } else if (action_requires_view_state(KEYMAP_MAIN, action_id)) {
83 goto ignore_action;
86 if (action_requires_location(KEYMAP_MAIN, action_id)
87 && !have_location(ses))
88 return FRAME_EVENT_OK;
90 if (action_requires_link(KEYMAP_MAIN, action_id)
91 && !link)
92 goto ignore_action;
94 if (action_requires_form(KEYMAP_MAIN, action_id)
95 && (!link || !link_is_form(link)))
96 goto ignore_action;
98 if (!action_is_anonymous_safe(KEYMAP_MAIN, action_id)
99 && get_cmd_opt_bool("anonymous"))
100 goto ignore_action;
102 /* Please keep in alphabetical order for now. Later we can sort by most
103 * used or something. */
104 switch (action_id) {
105 case ACT_MAIN_ABORT_CONNECTION:
106 abort_loading(ses, 1);
107 print_screen_status(ses);
108 break;
110 case ACT_MAIN_ADD_BOOKMARK:
111 #ifdef CONFIG_BOOKMARKS
112 launch_bm_add_doc_dialog(term, NULL, ses);
113 #endif
114 break;
115 case ACT_MAIN_ADD_BOOKMARK_LINK:
116 #ifdef CONFIG_BOOKMARKS
117 launch_bm_add_link_dialog(term, NULL, ses);
118 #endif
119 break;
120 case ACT_MAIN_ADD_BOOKMARK_TABS:
121 #ifdef CONFIG_BOOKMARKS
122 bookmark_terminal_tabs_dialog(term);
123 #endif
124 break;
126 case ACT_MAIN_AUTH_MANAGER:
127 auth_manager(ses);
128 break;
130 case ACT_MAIN_BACKSPACE_PREFIX:
132 if (!ses->kbdprefix.repeat_count) break;
134 set_kbd_repeat_count(ses,
135 ses->kbdprefix.repeat_count / 10);
137 /* Keep send_event from resetting repeat_count. */
138 status = FRAME_EVENT_SESSION_DESTROYED;
140 break;
142 case ACT_MAIN_BOOKMARK_MANAGER:
143 #ifdef CONFIG_BOOKMARKS
144 bookmark_manager(ses);
145 #endif
146 break;
148 case ACT_MAIN_CACHE_MANAGER:
149 cache_manager(ses);
150 break;
152 case ACT_MAIN_CACHE_MINIMIZE:
153 shrink_memory(1);
154 break;
156 case ACT_MAIN_COOKIES_LOAD:
157 #ifdef CONFIG_COOKIES
158 if (!get_opt_bool("cookies.save", NULL)) break;
159 load_cookies();
160 #endif
161 break;
163 case ACT_MAIN_COOKIE_MANAGER:
164 #ifdef CONFIG_COOKIES
165 cookie_manager(ses);
166 #endif
167 break;
169 case ACT_MAIN_COPY_CLIPBOARD:
170 status = copy_current_link_to_clipboard(ses, doc_view, 0);
171 break;
173 case ACT_MAIN_DOCUMENT_INFO:
174 document_info_dialog(ses);
175 break;
177 case ACT_MAIN_DOWNLOAD_MANAGER:
178 download_manager(ses);
179 break;
181 case ACT_MAIN_EXMODE:
182 #ifdef CONFIG_EXMODE
183 exmode_start(ses);
184 #endif
185 break;
187 case ACT_MAIN_FILE_MENU:
188 activate_bfu_technology(ses, 0);
189 break;
191 case ACT_MAIN_FIND_NEXT:
192 status = find_next(ses, doc_view, 1);
193 break;
195 case ACT_MAIN_FIND_NEXT_BACK:
196 status = find_next(ses, doc_view, -1);
197 break;
199 case ACT_MAIN_FORGET_CREDENTIALS:
200 free_auth();
201 shrink_memory(1); /* flush caches */
202 break;
204 case ACT_MAIN_FORMHIST_MANAGER:
205 #ifdef CONFIG_FORMHIST
206 formhist_manager(ses);
207 #endif
208 break;
210 case ACT_MAIN_FRAME_EXTERNAL_COMMAND:
211 status = pass_uri_to_command(ses, doc_view,
212 PASS_URI_FRAME);
213 break;
215 case ACT_MAIN_FRAME_NEXT:
216 next_frame(ses, 1);
217 draw_formatted(ses, 0);
218 break;
220 case ACT_MAIN_FRAME_MAXIMIZE:
221 status = set_frame(ses, doc_view, 0);
222 break;
224 case ACT_MAIN_FRAME_PREV:
225 next_frame(ses, -1);
226 draw_formatted(ses, 0);
227 break;
229 case ACT_MAIN_GOTO_URL:
230 goto_url_action(ses, NULL);
231 break;
233 case ACT_MAIN_GOTO_URL_CURRENT:
234 goto_url_action(ses, get_current_url);
235 break;
237 case ACT_MAIN_GOTO_URL_CURRENT_LINK:
238 goto_url_action(ses, get_current_link_url);
239 break;
241 case ACT_MAIN_GOTO_URL_HOME:
242 goto_url_home(ses);
243 break;
245 case ACT_MAIN_HEADER_INFO:
246 protocol_header_dialog(ses);
247 break;
249 case ACT_MAIN_HISTORY_MANAGER:
250 #ifdef CONFIG_GLOBHIST
251 history_manager(ses);
252 #endif
253 break;
255 case ACT_MAIN_HISTORY_MOVE_BACK:
257 int count = int_max(1, eat_kbd_repeat_count(ses));
259 go_history_by_n(ses, -count);
260 break;
262 case ACT_MAIN_HISTORY_MOVE_FORWARD:
264 int count = int_max(1, eat_kbd_repeat_count(ses));
266 go_history_by_n(ses, count);
267 break;
269 case ACT_MAIN_JUMP_TO_LINK:
270 break;
272 case ACT_MAIN_KEYBINDING_MANAGER:
273 keybinding_manager(ses);
274 break;
276 case ACT_MAIN_KILL_BACKGROUNDED_CONNECTIONS:
277 abort_background_connections();
278 break;
280 case ACT_MAIN_LINK_DOWNLOAD:
281 case ACT_MAIN_LINK_DOWNLOAD_IMAGE:
282 case ACT_MAIN_LINK_DOWNLOAD_RESUME:
283 status = download_link(ses, doc_view, action_id);
284 break;
286 case ACT_MAIN_LINK_EXTERNAL_COMMAND:
287 status = pass_uri_to_command(ses, doc_view,
288 PASS_URI_LINK);
289 break;
291 case ACT_MAIN_LINK_FOLLOW:
292 status = enter(ses, doc_view, 0);
293 break;
295 case ACT_MAIN_LINK_FOLLOW_RELOAD:
296 status = enter(ses, doc_view, 1);
297 break;
299 case ACT_MAIN_LINK_INFO:
300 link_info_dialog(ses);
301 break;
303 case ACT_MAIN_LINK_MENU:
304 link_menu(term, NULL, ses);
305 break;
307 case ACT_MAIN_LINK_FORM_MENU:
308 link_form_menu(ses);
309 break;
311 case ACT_MAIN_LUA_CONSOLE:
312 #ifdef CONFIG_SCRIPTING_LUA
313 trigger_event_name("dialog-lua-console", ses);
314 #endif
315 break;
317 case ACT_MAIN_MARK_SET:
318 #ifdef CONFIG_MARKS
319 ses->kbdprefix.mark = KP_MARK_SET;
320 status = FRAME_EVENT_REFRESH;
321 #endif
322 break;
324 case ACT_MAIN_MARK_GOTO:
325 #ifdef CONFIG_MARKS
326 /* TODO: Show promptly a menu (or even listbox?)
327 * with all the marks. But the next letter must
328 * still choose a mark directly! --pasky */
329 ses->kbdprefix.mark = KP_MARK_GOTO;
330 status = FRAME_EVENT_REFRESH;
331 #endif
332 break;
334 case ACT_MAIN_MENU:
335 activate_bfu_technology(ses, -1);
336 break;
338 case ACT_MAIN_MOVE_CURSOR_UP:
339 status = move_cursor_up(ses, doc_view);
340 break;
342 case ACT_MAIN_MOVE_CURSOR_DOWN:
343 status = move_cursor_down(ses, doc_view);
344 break;
346 case ACT_MAIN_MOVE_CURSOR_LEFT:
347 status = move_cursor_left(ses, doc_view);
348 break;
350 case ACT_MAIN_MOVE_CURSOR_RIGHT:
351 status = move_cursor_right(ses, doc_view);
352 break;
354 case ACT_MAIN_MOVE_CURSOR_LINE_START:
355 status = move_cursor_line_start(ses, doc_view);
356 break;
358 case ACT_MAIN_MOVE_LINK_DOWN:
359 status = move_link_down(ses, doc_view);
360 break;
362 case ACT_MAIN_MOVE_LINK_DOWN_LINE:
363 status = move_link_down_line(ses, doc_view);
364 break;
366 case ACT_MAIN_MOVE_LINK_LEFT:
367 status = move_link_left(ses, doc_view);
368 break;
370 case ACT_MAIN_MOVE_LINK_LEFT_LINE:
371 status = move_link_prev_line(ses, doc_view);
372 break;
374 case ACT_MAIN_MOVE_LINK_NEXT:
375 status = move_link_next(ses, doc_view);
376 break;
378 case ACT_MAIN_MOVE_LINK_PREV:
379 status = move_link_prev(ses, doc_view);
380 break;
382 case ACT_MAIN_MOVE_LINK_RIGHT:
383 status = move_link_right(ses, doc_view);
384 break;
386 case ACT_MAIN_MOVE_LINK_RIGHT_LINE:
387 status = move_link_next_line(ses, doc_view);
388 break;
390 case ACT_MAIN_MOVE_LINK_UP:
391 status = move_link_up(ses, doc_view);
392 break;
394 case ACT_MAIN_MOVE_LINK_UP_LINE:
395 status = move_link_up_line(ses, doc_view);
396 break;
398 case ACT_MAIN_MOVE_PAGE_DOWN:
399 status = move_page_down(ses, doc_view);
400 break;
402 case ACT_MAIN_MOVE_HALF_PAGE_DOWN:
403 status = move_half_page_down(ses, doc_view);
404 break;
406 case ACT_MAIN_MOVE_PAGE_UP:
407 status = move_page_up(ses, doc_view);
408 break;
410 case ACT_MAIN_MOVE_HALF_PAGE_UP:
411 status = move_half_page_up(ses, doc_view);
412 break;
414 case ACT_MAIN_MOVE_DOCUMENT_START:
415 status = move_document_start(ses, doc_view);
416 break;
418 case ACT_MAIN_MOVE_DOCUMENT_END:
419 status = move_document_end(ses, doc_view);
420 break;
422 case ACT_MAIN_OPEN_LINK_IN_NEW_TAB:
423 open_current_link_in_new_tab(ses, 0);
424 break;
426 case ACT_MAIN_OPEN_LINK_IN_NEW_TAB_IN_BACKGROUND:
427 open_current_link_in_new_tab(ses, 1);
428 break;
430 case ACT_MAIN_OPEN_LINK_IN_NEW_WINDOW:
431 open_in_new_window(term, send_open_in_new_window, ses);
432 break;
434 case ACT_MAIN_OPEN_NEW_TAB:
435 open_uri_in_new_tab(ses, NULL, 0, 1);
436 break;
438 case ACT_MAIN_OPEN_NEW_TAB_IN_BACKGROUND:
439 open_uri_in_new_tab(ses, NULL, 1, 1);
440 break;
442 case ACT_MAIN_OPEN_NEW_WINDOW:
443 open_in_new_window(term, send_open_new_window, ses);
444 break;
446 case ACT_MAIN_OPEN_OS_SHELL:
447 exec_shell(term);
448 break;
450 case ACT_MAIN_OPTIONS_MANAGER:
451 options_manager(ses);
452 break;
454 case ACT_MAIN_QUIT:
455 exit_prog(ses, 1);
456 break;
458 case ACT_MAIN_REALLY_QUIT:
459 exit_prog(ses, 0);
460 break;
462 case ACT_MAIN_REDRAW:
463 redraw_terminal_cls(term);
464 break;
466 case ACT_MAIN_RELOAD:
467 reload(ses, CACHE_MODE_INCREMENT);
468 break;
470 case ACT_MAIN_RERENDER:
471 draw_formatted(ses, 2);
472 break;
474 case ACT_MAIN_RESET_FORM:
475 status = reset_form(ses, doc_view, 0);
476 break;
478 case ACT_MAIN_RESOURCE_INFO:
479 resource_info(term);
480 break;
482 case ACT_MAIN_SAVE_AS:
483 status = save_as(ses, doc_view, 0);
484 break;
486 case ACT_MAIN_SAVE_FORMATTED:
487 status = save_formatted_dlg(ses, doc_view, 0);
488 break;
490 case ACT_MAIN_SAVE_OPTIONS:
491 write_config(term);
492 break;
494 case ACT_MAIN_SAVE_URL_AS:
495 save_url_as(ses);
496 break;
498 case ACT_MAIN_SCROLL_DOWN:
499 status = scroll_down(ses, doc_view);
500 break;
502 case ACT_MAIN_SCROLL_LEFT:
503 status = scroll_left(ses, doc_view);
504 break;
506 case ACT_MAIN_SCROLL_RIGHT:
507 status = scroll_right(ses, doc_view);
508 break;
510 case ACT_MAIN_SCROLL_UP:
511 status = scroll_up(ses, doc_view);
512 break;
514 case ACT_MAIN_SEARCH:
515 status = search_dlg(ses, doc_view, 1);
516 break;
518 case ACT_MAIN_SEARCH_BACK:
519 status = search_dlg(ses, doc_view, -1);
520 break;
522 case ACT_MAIN_SEARCH_TYPEAHEAD:
523 case ACT_MAIN_SEARCH_TYPEAHEAD_LINK:
524 case ACT_MAIN_SEARCH_TYPEAHEAD_TEXT:
525 case ACT_MAIN_SEARCH_TYPEAHEAD_TEXT_BACK:
526 status = search_typeahead(ses, doc_view, action_id);
527 break;
529 case ACT_MAIN_SHOW_TERM_OPTIONS:
530 terminal_options(term, NULL, ses);
531 break;
533 case ACT_MAIN_SUBMIT_FORM:
534 status = submit_form(ses, doc_view, 0);
535 break;
537 case ACT_MAIN_SUBMIT_FORM_RELOAD:
538 status = submit_form(ses, doc_view, 1);
539 break;
541 case ACT_MAIN_TAB_CLOSE:
542 close_tab(term, ses);
543 status = FRAME_EVENT_SESSION_DESTROYED;
544 break;
546 case ACT_MAIN_TAB_CLOSE_ALL_BUT_CURRENT:
547 close_all_tabs_but_current(ses);
548 break;
550 case ACT_MAIN_TAB_EXTERNAL_COMMAND:
551 status = pass_uri_to_command(ses, doc_view,
552 PASS_URI_TAB);
553 break;
555 case ACT_MAIN_TAB_MOVE_LEFT:
556 move_current_tab(ses, -1);
557 break;
559 case ACT_MAIN_TAB_MOVE_RIGHT:
560 move_current_tab(ses, 1);
561 break;
563 case ACT_MAIN_TAB_MENU:
564 assert(ses->tab == get_current_tab(term));
566 if (ses->status.show_tabs_bar)
567 tab_menu(ses, ses->tab->xpos,
568 term->height - 1
569 - ses->status.show_status_bar,
571 else
572 tab_menu(ses, 0, 0, 0);
574 break;
576 case ACT_MAIN_TAB_NEXT:
577 switch_current_tab(ses, 1);
578 break;
580 case ACT_MAIN_TAB_PREV:
581 switch_current_tab(ses, -1);
582 break;
584 case ACT_MAIN_TERMINAL_RESIZE:
585 resize_terminal_dialog(term);
586 break;
588 case ACT_MAIN_TOGGLE_CSS:
589 #ifdef CONFIG_CSS
590 toggle_document_option(ses, "document.css.enable");
591 #endif
592 break;
594 case ACT_MAIN_TOGGLE_DISPLAY_IMAGES:
595 toggle_document_option(ses, "document.browse.images.show_as_links");
596 break;
598 case ACT_MAIN_TOGGLE_DISPLAY_TABLES:
599 toggle_document_option(ses, "document.html.display_tables");
600 break;
602 case ACT_MAIN_TOGGLE_DOCUMENT_COLORS:
603 toggle_document_option(ses, "document.colors.use_document_colors");
604 break;
606 case ACT_MAIN_TOGGLE_HTML_PLAIN:
607 toggle_plain_html(ses, ses->doc_view, 0);
608 break;
610 case ACT_MAIN_TOGGLE_MOUSE:
611 #ifdef CONFIG_MOUSE
612 toggle_mouse();
613 #endif
614 break;
616 case ACT_MAIN_TOGGLE_NUMBERED_LINKS:
617 toggle_document_option(ses, "document.browse.links.numbering");
618 break;
620 case ACT_MAIN_TOGGLE_PLAIN_COMPRESS_EMPTY_LINES:
621 toggle_document_option(ses, "document.plain.compress_empty_lines");
622 break;
624 case ACT_MAIN_TOGGLE_WRAP_TEXT:
625 toggle_wrap_text(ses, ses->doc_view, 0);
626 break;
628 case ACT_MAIN_VIEW_IMAGE:
629 status = view_image(ses, doc_view, 0);
630 break;
632 case ACT_MAIN_SCRIPTING_FUNCTION:
633 case ACT_MAIN_NONE:
634 case MAIN_ACTIONS:
635 default:
636 unknown_action:
637 if (verbose) {
638 INTERNAL("No action handling defined for '%s'.",
639 get_action_name(KEYMAP_MAIN, action_id));
642 status = FRAME_EVENT_IGNORED;
645 ignore_action:
646 /* XXX: At this point the session may have been destroyed */
648 if (status != FRAME_EVENT_SESSION_DESTROYED
649 && ses->insert_mode == INSERT_MODE_ON
650 && link != get_current_link(doc_view))
651 ses->insert_mode = INSERT_MODE_OFF;
653 if (status == FRAME_EVENT_REFRESH && doc_view)
654 refresh_view(ses, doc_view, 0);
656 return status;