Dillo v3.2.0-88-g47ab7c70
Loading...
Searching...
No Matches
uicmd.cc
Go to the documentation of this file.
1/*
2 * File: uicmd.cc
3 *
4 * Copyright (C) 2005-2011 Jorge Arellano Cid <jcid@dillo.org>
5 * Copyright (C) 2024-2025 Rodrigo Arias Mallo <rodarima@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 */
12
18#include <string.h>
19#include <stdio.h>
20#include <stdarg.h>
21#include <stdlib.h> /* for qsort */
22#include <math.h> /* for rint */
23#include <limits.h> /* for UINT_MAX */
24#include <sys/stat.h>
25
26#include <FL/Fl.H>
27#include <FL/Fl_Widget.H>
28#include <FL/Fl_Double_Window.H>
29#include <FL/Fl_Wizard.H>
30#include <FL/Fl_Box.H>
31#include <FL/Fl_Pack.H>
32#include <FL/Fl_Scroll.H>
33#include <FL/names.h>
34
35#include "paths.hh"
36#include "keys.hh"
37#include "ui.hh"
38#include "uicmd.hh"
39#include "timeout.hh"
40#include "utf8.hh"
41#include "menu.hh"
42#include "dialog.hh"
43#include "xembed.hh"
44#include "bookmark.h"
45#include "history.h"
46#include "msg.h"
47#include "prefs.h"
48#include "misc.h"
49#include "dlib/dlib.h"
50
51#include "dw/fltkviewport.hh"
52
53#include "nav.h"
54
55//#define DEFAULT_TAB_LABEL "-.untitled.-"
56#define DEFAULT_TAB_LABEL "-.new.-"
57
58// Handy macro
59#define BW2UI(bw) ((UI*)((bw)->ui))
60
61// Platform independent part
62using namespace dw::core;
63// FLTK related
64using namespace dw::fltk;
65
66
67/*
68 * Local data
69 */
70static const char *save_dir = "";
71
72struct Tabgroup {
73 CustTabs *tabs;
74 struct Tabgroup *next;
75};
76
77/* An stack of CustTabs groups, each maps to one FLTK window. Points to
78 * the last one created. */
79static struct Tabgroup *tabgroups = NULL;
80
81/*
82 * Forward declarations
83 */
84static BrowserWindow *UIcmd_tab_new(CustTabs *tabs, UI *old_ui, int focus);
85static void close_tab_btn_cb (Fl_Widget *w, void *cb_data);
86static char *UIcmd_make_search_str(const char *str);
87static void UIcmd_set_window_labels(Fl_Window *win, const char *str);
88
89//----------------------------------------------------------------------------
90
91/*
92 * CustTabs ---------------------------------------------------------------
93 */
94
98class CustTabButton : public Fl_Button {
99 UI *ui_;
100 uint_t focus_num_; // Used to choose which tab to focus when closing the
101 // active one (the highest numbered gets focus).
102public:
103 CustTabButton (int x,int y,int w,int h, const char* label = 0) :
104 Fl_Button (x,y,w,h,label) { ui_ = NULL; focus_num_ = 0; };
105 void ui(UI *pui) { ui_ = pui; }
106 UI *ui(void) { return ui_; }
107 void focus_num(uint_t fn) { focus_num_ = fn; }
108 uint_t focus_num(void) { return focus_num_; }
109};
110
111static int btn_cmp(const void *p1, const void *p2)
112{
113 return ((*(CustTabButton * const *)p1)->focus_num() -
114 (*(CustTabButton * const *)p2)->focus_num() );
115}
116
120class CustTabs : public Fl_Group {
121 uint_t focus_counter; // An increasing counter
122 int tab_w, tab_h, ctab_h, btn_w, ctl_w;
123 Fl_Wizard *Wizard;
124 Fl_Scroll *Scroll;
125 Fl_Pack *Pack;
126 Fl_Group *Control;
127 CustButton *CloseBtn;
128
129 void update_pack_offset(void);
130 void resize(int x, int y, int w, int h)
131 { Fl_Group::resize(x,y,w,h); update_pack_offset(); }
132 int get_btn_idx(UI *ui);
133 void increase_focus_counter() {
134 if (focus_counter < UINT_MAX) /* check for overflow */
135 ++focus_counter;
136 else {
137 /* wrap & normalize old numbers here */
138 CustTabButton **btns = dNew(CustTabButton*, num_tabs());
139 for (int i = 0; i < num_tabs(); ++i)
140 btns[i] = (CustTabButton*)Pack->child(i);
141 qsort(btns, num_tabs(), sizeof(CustTabButton *), btn_cmp);
142 focus_counter = 0;
143 for (int i = 0; i < num_tabs(); ++i)
144 btns[i]->focus_num(focus_counter++);
145 dFree(btns);
146 }
147 }
148
149public:
150 CustTabs (int ww, int wh, int th, const char *lbl=0) :
151 Fl_Group(0,0,ww,th,lbl) {
152 Pack = NULL;
153 focus_counter = 0;
154 tab_w = 50, tab_h = th, ctab_h = 1, btn_w = 20, ctl_w = 1*btn_w+2;
155 resize(0,0,ww,ctab_h);
156 /* tab buttons go inside a pack within a scroll */
157 Scroll = new Fl_Scroll(0,0,ww-ctl_w,ctab_h);
158 Scroll->type(0); /* no scrollbars */
159 Scroll->box(FL_NO_BOX);
160 Pack = new Fl_Pack(0,0,ww-ctl_w,tab_h);
161 Pack->type(Fl_Pack::HORIZONTAL);
162 Pack->box(FL_NO_BOX); //FL_THIN_DOWN_FRAME
163 Pack->end();
164 Scroll->end();
165 resizable(Scroll);
166
167 /* control buttons go inside a group */
168 Control = new Fl_Group(ww-ctl_w,0,ctl_w,ctab_h);
169 CloseBtn = new CustButton(ww-ctl_w+2,0,btn_w,ctab_h, "X");
170 CloseBtn->box(FL_THIN_UP_BOX);
171 CloseBtn->clear_visible_focus();
173 "Close current tab.\nor Right-click tab label to close." :
174 "Close current tab.\nor Middle-click tab label to close.");
175 CloseBtn->callback(close_tab_btn_cb, this);
176 CloseBtn->hide();
177 Control->end();
178
179 box(FL_FLAT_BOX);
180 end();
181
182 Wizard = new Fl_Wizard(0,ctab_h,ww,wh-ctab_h);
183 Wizard->box(FL_NO_BOX);
184 Wizard->end();
185 };
186 int handle(int e);
187 UI *add_new_tab(UI *old_ui, int focus);
188 void remove_tab(UI *ui);
189 Fl_Wizard *wizard(void) { return Wizard; }
190 int num_tabs() { return (Pack ? Pack->children() : 0); }
191 void switch_tab(CustTabButton *cbtn);
192 void switch_tab(int index);
193 void prev_tab(void);
194 void next_tab(void);
195 void set_tab_label(UI *ui, const char *title);
196};
197
201static void tab_btn_cb (Fl_Widget *w, void *cb_data)
202{
203 CustTabButton *btn = (CustTabButton*) w;
204 CustTabs *tabs = (CustTabs*) cb_data;
205 int b = Fl::event_button();
206
207 if (b == FL_LEFT_MOUSE) {
208 tabs->switch_tab(btn);
209 } else if ((b == FL_RIGHT_MOUSE && prefs.right_click_closes_tab) ||
210 (b == FL_MIDDLE_MOUSE && !prefs.right_click_closes_tab)) {
211 // TODO: just an example, not necessarily final
213 }
214}
215
219static void close_tab_btn_cb (Fl_Widget *, void *cb_data)
220{
221 CustTabs *tabs = (CustTabs*) cb_data;
222 int b = Fl::event_button();
223
224 if (b == FL_LEFT_MOUSE) {
225 a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(tabs->wizard()->value()));
226 }
227}
228
229int CustTabs::handle(int e)
230{
231 int ret = 0;
232
233 _MSG("CustTabs::handle e=%s\n", fl_eventnames[e]);
234 if (e == FL_KEYBOARD) {
235 return 0; // Receive as shortcut
236 } else if (e == FL_SHORTCUT) {
237 UI *ui = (UI*)wizard()->value();
240 if (cmd == KEYS_NOP) {
241 // Do nothing
242 _MSG("CustTabs::handle KEYS_NOP\n");
243 } else if (cmd == KEYS_NEW_TAB) {
244 a_UIcmd_open_url_nt(bw, NULL, 1);
245 ret = 1;
246 } else if (cmd == KEYS_CLOSE_TAB) {
248 ret = 1;
249 } else if (cmd == KEYS_LEFT_TAB) {
250 prev_tab();
251 ret = 1;
252 } else if (cmd == KEYS_RIGHT_TAB) {
253 next_tab();
254 ret = 1;
255 } else if (cmd == KEYS_NEW_WINDOW) {
256 a_UIcmd_open_url_nw(bw, NULL);
257 ret = 1;
258 } else if (cmd == KEYS_CLOSE_ALL) {
260 ret = 1;
261 }
262 } else if (e == FL_MOUSEWHEEL && prefs.scroll_switches_tabs) {
263 /* Move to the next or previous tab using the mouse wheel */
264 int dx = Fl::event_dx();
265 int dy = Fl::event_dy();
266 int dir = dy ? dy : dx;
267
269 dir = -dir;
270
271 if (dir > 0)
272 next_tab();
273 else if (dir < 0)
274 prev_tab();
275
276 ret = 1;
277 }
278
279 return (ret) ? ret : Fl_Group::handle(e);
280}
281
285UI *CustTabs::add_new_tab(UI *old_ui, int focus)
286{
287 if (num_tabs() == 1) {
288 // Show tabbar
289 ctab_h = tab_h;
290 Wizard->resize(0,ctab_h,Wizard->w(),window()->h()-ctab_h);
291 resize(0,0,window()->w(),ctab_h); // tabbar
292 CloseBtn->show();
293 {int w = 0, h; Pack->child(0)->measure_label(w, h);
294 Pack->child(0)->size(w+14,ctab_h);}
295 Pack->child(0)->show(); // first tab button
296 window()->init_sizes();
297 }
298
299 /* The UI is constructed in a comfortable fitting size, and then resized
300 * so FLTK doesn't get confused later with even smaller dimensions! */
301 current(0);
302 UI *new_ui = new UI(0,0,UI_MIN_W,UI_MIN_H,"Dillo:",old_ui);
303 new_ui->resize(0,ctab_h,Wizard->w(),Wizard->h());
304 new_ui->tabs(this);
305 Wizard->add(new_ui);
306 new_ui->show();
307
308 CustTabButton *btn = new CustTabButton(num_tabs()*tab_w,0,tab_w,ctab_h);
309 btn->align(FL_ALIGN_INSIDE);
310 btn->labelsize(btn->labelsize()-2);
311 btn->copy_label(DEFAULT_TAB_LABEL);
312 btn->clear_visible_focus();
313 btn->box(FL_GTK_THIN_UP_BOX);
316 btn->ui(new_ui);
317 btn->callback(tab_btn_cb, this);
318 Pack->add(btn); // append
319
320 if (focus) {
321 switch_tab(btn);
322 } else { // no focus
323 // set focus counter
324 increase_focus_counter();
325 btn->focus_num(focus_counter);
326
327 if (num_tabs() == 2) {
328 // tabbar added: redraw current page
329 Wizard->redraw();
330 }
331 }
332 if (num_tabs() == 1)
333 btn->hide();
334 update_pack_offset();
335
336 return new_ui;
337}
338
342void CustTabs::remove_tab(UI *ui)
343{
344 CustTabButton *btn;
345
346 // get active tab idx
347 int act_idx = get_btn_idx((UI*)Wizard->value());
348 // get to-be-removed tab idx
349 int rm_idx = get_btn_idx(ui);
350 btn = (CustTabButton*)Pack->child(rm_idx);
351
352 if (act_idx == rm_idx) {
353 // Active tab is being closed, switch to the "previous" one
354 CustTabButton *fbtn = NULL;
355 for (int i = 0; i < num_tabs(); ++i) {
356 if (i != rm_idx) {
357 if (!fbtn)
358 fbtn = (CustTabButton*)Pack->child(i);
359 CustTabButton *btn = (CustTabButton*)Pack->child(i);
360 if (btn->focus_num() > fbtn->focus_num())
361 fbtn = btn;
362 }
363 }
364 switch_tab(fbtn);
365 }
366 Pack->remove(rm_idx);
367 update_pack_offset();
368 delete btn;
369
370 Wizard->remove(ui);
371 delete(ui);
372
373 if (num_tabs() == 1) {
374 // hide tabbar
375 ctab_h = 1;
376 CloseBtn->hide();
377 Pack->child(0)->size(0,0);
378 Pack->child(0)->hide(); // first tab button
379 resize(0,0,window()->w(),ctab_h); // tabbar
380 Wizard->resize(0,ctab_h,Wizard->w(),window()->h()-ctab_h);
381 window()->init_sizes();
382 window()->redraw();
383 }
384}
385
386int CustTabs::get_btn_idx(UI *ui)
387{
388 for (int i = 0; i < num_tabs(); ++i) {
389 CustTabButton *btn = (CustTabButton*)Pack->child(i);
390 if (btn->ui() == ui)
391 return i;
392 }
393 return -1;
394}
395
400void CustTabs::update_pack_offset()
401{
402 dReturn_if (num_tabs() == 0);
403
404 // get active tab button
405 int act_idx = get_btn_idx((UI*)Wizard->value());
406 CustTabButton *cbtn = (CustTabButton*)Pack->child(act_idx);
407
408 // calculate tab button's x() coordinates
409 int x_i = 0, x_f;
410 for (int j=0; j < act_idx; ++j)
411 x_i += Pack->child(j)->w();
412 x_f = x_i + cbtn->w();
413
414 int scr_x = Scroll->xposition(), scr_y = Scroll->yposition();
415 int px_i = x_i - scr_x;
416 int px_f = px_i + cbtn->w();
417 int pw = Scroll->window()->w() - ctl_w;
418 _MSG(" scr_x=%d btn_x=%d px_i=%d btn_w=%d px_f=%d pw=%d",
419 Scroll->xposition(),cbtn->x(),px_i,cbtn->w(),px_f,pw);
420 if (px_i < 0) {
421 Scroll->scroll_to(x_i, scr_y);
422 } else if (px_i > pw || (px_i > 0 && px_f > pw)) {
423 Scroll->scroll_to(MIN(x_i, x_f-pw), scr_y);
424 }
425 Scroll->redraw();
426 _MSG(" >>scr_x=%d btn0_x=%d\n", scr_x, Pack->child(0)->x());
427}
428
432void CustTabs::switch_tab(CustTabButton *cbtn)
433{
434 int idx;
435 CustTabButton *btn;
436 BrowserWindow *bw;
437 UI *old_ui = (UI*)Wizard->value();
438
439 if (cbtn && cbtn->ui() != old_ui) {
440 // Set old tab label to normal color
441 if ((idx = get_btn_idx(old_ui)) != -1) {
442 btn = (CustTabButton*)Pack->child(idx);
443 btn->color(PREFS_UI_TAB_BG_COLOR);
444 btn->labelcolor(PREFS_UI_TAB_FG_COLOR);
445 btn->redraw();
446 }
447 /* We make a point of calling show() before value() is changed because
448 * the wizard may hide the old one before showing the new one. In that
449 * case, the new UI gets focus with Fl::e_keysym set to whatever
450 * triggered the switch, and this is a problem when it's Tab/Left/Right/
451 * Up/Down because some widgets (notably Fl_Group and Fl_Input) exhibit
452 * unwelcome behaviour in that case. If the new widgets are already
453 * shown, fl_fix_focus will fix everything with Fl::e_keysym temporarily
454 * cleared.
455 */
456 cbtn->ui()->show();
457 Wizard->value(cbtn->ui());
458 cbtn->color(PREFS_UI_TAB_ACTIVE_BG_COLOR);
459 cbtn->labelcolor(PREFS_UI_TAB_ACTIVE_FG_COLOR);
460 cbtn->redraw();
461 update_pack_offset();
462
463 // Update window title
464 if ((bw = a_UIcmd_get_bw_by_widget(cbtn->ui()))) {
465 const char *title = (cbtn->ui())->label();
466 UIcmd_set_window_labels(cbtn->window(), title ? title : "");
467 }
468 // Update focus priority
469 increase_focus_counter();
470 cbtn->focus_num(focus_counter);
471 }
472}
473
474void CustTabs::prev_tab()
475{
476 int idx;
477
478 if ((idx = get_btn_idx((UI*)Wizard->value())) != -1)
479 switch_tab((CustTabButton*)Pack->child(idx>0 ? idx-1 : num_tabs()-1));
480}
481
482void CustTabs::next_tab()
483{
484 int idx;
485
486 if ((idx = get_btn_idx((UI*)Wizard->value())) != -1)
487 switch_tab((CustTabButton*)Pack->child((idx+1<num_tabs()) ? idx+1 : 0));
488}
489
493void CustTabs::switch_tab(int index)
494{
495 if (index >= 0 && index < num_tabs())
496 switch_tab((CustTabButton*)Pack->child(index));
497}
498
502void CustTabs::set_tab_label(UI *ui, const char *label)
503{
504 char title[128];
505 int idx = get_btn_idx(ui);
506
507 if (idx != -1) {
508 // Make a label for this tab
509 size_t tab_chars = 15, label_len = strlen(label);
510
511 if (label_len > tab_chars)
512 tab_chars = a_Utf8_end_of_char(label, tab_chars - 1) + 1;
513 snprintf(title, tab_chars + 1, "%s", label);
514 if (label_len > tab_chars)
515 snprintf(title + tab_chars, 4, "...");
516
517 // Avoid unnecessary redraws
518 if (strcmp(Pack->child(idx)->label(), title)) {
519 int w = 0, h;
520 Pack->child(idx)->copy_label(title);
521 Pack->child(idx)->measure_label(w, h);
522 Pack->child(idx)->size(w+14,ctab_h);
523 update_pack_offset();
524 }
525 }
526}
527
528
529//----------------------------------------------------------------------------
530
531static void win_cb (Fl_Widget *w, void *cb_data) {
532 CustTabs *tabs = (CustTabs*) cb_data;
533 int choice = 1, ntabs = tabs->num_tabs();
534
535 if (Fl::event_key() == FL_Escape) {
536 // Don't let FLTK close a browser window due to unhandled Escape
537 // (most likely with modifiers).
538 return;
539 }
540
541 if (prefs.show_quit_dialog && ntabs > 1)
542 choice = a_Dialog_choice("Dillo: Close window?",
543 "Window contains more than one tab.",
544 "Close", "Cancel", NULL);
545 if (choice == 1)
546 while (ntabs-- > 0)
547 a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(tabs->wizard()->value()));
548}
549
550/*
551 * Given a UI or UI child widget, return its bw.
552 */
554{
555 BrowserWindow *bw;
556 for (int i = 0; i < a_Bw_num(); ++i) {
557 bw = a_Bw_get(i);
558 if (((UI*)bw->ui)->contains((Fl_Widget*)v_wid)) {
559 return bw;
560 }
561 }
562 return NULL;
563}
564
565/*
566 * Create a new UI and its associated BrowserWindow data structure.
567 * Use style from v_ui. If non-NULL it must be of type UI*.
568 */
570 uint32_t xid, const void *vbw)
571{
572 BrowserWindow *old_bw = (BrowserWindow*)vbw;
573 BrowserWindow *new_bw = NULL;
574 UI *old_ui = old_bw ? BW2UI(old_bw) : NULL;
575 Fl_Window *win;
576
577 if (ww <= 0 || wh <= 0) {
578 // Set default geometry from dillorc.
579 ww = prefs.width;
580 wh = prefs.height;
581 }
582
583 if (xid)
584 win = new Xembed(xid, ww, wh);
585 else if (prefs.buffered_drawing != 2)
586 win = new Fl_Window(ww, wh);
587 else
588 win = new Fl_Double_Window(ww, wh);
589
590 win->box(FL_NO_BOX);
591 CustTabs *DilloTabs = new CustTabs(ww, wh, prefs.ui_tab_height);
592
593 struct Tabgroup *tg = new Tabgroup;
594 tg->tabs = DilloTabs;
595 tg->next = tabgroups;
596 tabgroups = tg;
597 _MSG("new: tabgroups=%p\n", (void *) tg);
598
599 win->end();
600 win->resizable(DilloTabs->wizard());
601
602 int focus = 1;
603 new_bw = UIcmd_tab_new(DilloTabs, old_ui, focus);
604 win->show();
605
606 if (old_bw == NULL) {
607 new_bw->zoom = prefs.zoom_factor;
608
609 if (prefs.xpos >= 0 && prefs.ypos >= 0) {
610 // position the first window according to preferences
611 DilloTabs->window()->position(prefs.xpos, prefs.ypos);
612 }
613 }
614
615 win->callback(win_cb, DilloTabs);
616
617 return new_bw;
618}
619
620/*
621 * Set the window name and icon name.
622 */
623static void UIcmd_set_window_labels(Fl_Window *win, const char *str)
624{
625 const char *copy;
626
627 win->Fl_Widget::copy_label(str);
628 copy = win->label();
629 win->label(copy, copy);
630}
631
632/*
633 * Create a new Tab button, UI and its associated BrowserWindow data
634 * structure.
635 */
636static BrowserWindow *UIcmd_tab_new(CustTabs *tabs, UI *old_ui, int focus)
637{
638 _MSG(" UIcmd_tab_new\n");
639
640 // Create and set the UI
641 UI *new_ui = tabs->add_new_tab(old_ui, focus);
642
643 // Now create the Dw render layout and viewport
645 Layout *layout = new Layout (platform);
647 layout->setBgColor (bgColor);
651
652 // set_render_layout() sets the proper viewport size
653 FltkViewport *viewport = new FltkViewport (0, 0, 0, 1);
654 viewport->box(FL_NO_BOX);
663
664 // Now, create a new browser window structure
665 BrowserWindow *new_bw = a_Bw_new();
666
667 // Reference the UI from the bw
668 new_bw->ui = (void *)new_ui;
669 // Copy the layout pointer into the bw data
670 new_bw->render_layout = (void*)layout;
671
672 // Clear the window title
673 if (focus)
674 UIcmd_set_window_labels(new_ui->window(), new_ui->label());
675
676 // WORKAROUND: see findbar_toggle()
677 new_ui->findbar_toggle(0);
678
679 return new_bw;
680}
681
682/*
683 * Close one browser window
684 */
685void a_UIcmd_close_bw(void *vbw)
686{
687 BrowserWindow *bw = (BrowserWindow *)vbw;
688 UI *ui = BW2UI(bw);
689 CustTabs *tabs = ui->tabs();
691
692 _MSG("a_UIcmd_close_bw\n");
694 delete(layout);
695 if (tabs) {
696 tabs->remove_tab(ui);
697 if (tabs->num_tabs() == 0) {
698 /* No more tabs, remove tabgroup */
699 struct Tabgroup *tmp = tabgroups;
700 struct Tabgroup *prev = NULL;
701 for (tmp = tabgroups; tmp; tmp = tmp->next) {
702 if (tmp->tabs == tabs) {
703 if (prev)
704 prev->next = tmp->next;
705 else
706 tabgroups = tmp->next;
707 break;
708 }
709 prev = tmp;
710 }
711 if (tmp) {
712 _MSG("gone: tmp=%p tabgroups=%p\n", (void *) tmp, (void *) tabgroups);
713 delete tmp;
714 }
715 delete tabs->window();
716 }
717 }
718 a_Bw_free(bw);
719}
720
721/*
722 * Close all the browser windows
723 */
725{
726 BrowserWindow *bw;
727 int choice = 1;
728
729 if (prefs.show_quit_dialog && a_Bw_num() > 1)
730 choice = a_Dialog_choice("Dillo: Quit?",
731 "More than one open tab or window.",
732 "Quit", "Cancel", NULL);
733 if (choice == 1)
734 while ((bw = a_Bw_get(0)))
735 a_UIcmd_close_bw((void*)bw);
736}
737
738/*
739 * Return a search string of the suffix if str starts with a
740 * prefix of a search engine name and a blank
741 */
742static char *UIcmd_find_search_str(const char *str)
743{
744 int p;
745 char *url = NULL;
746 int len = strcspn(str, " ");
747
748 if (len > 0 && str[len] != '\0') {
749 /* we found a ' ' in str, check whether the first part of str
750 * is a prefix of a search_url label
751 */
752 for (p = 0; p < dList_length(prefs.search_urls); p++) {
753 const char *search =
754 (const char *)dList_nth_data(prefs.search_urls, p);
755 if (search && dStrnAsciiCasecmp(str, search, len) == 0) {
757 url = UIcmd_make_search_str(str + len + 1);
758 break;
759 }
760 }
761 }
762 return url;
763}
764
765/*
766 * Open a new URL in the given browser window.
767 *
768 * our custom "file:" URIs are normalized here too.
769 */
770void a_UIcmd_open_urlstr(void *vbw, const char *urlstr)
771{
772 char *new_urlstr;
773 char *search_urlstr = NULL;
774 DilloUrl *url;
775 int ch;
776 BrowserWindow *bw = (BrowserWindow*)vbw;
777
778 if ((search_urlstr = UIcmd_find_search_str(urlstr))) {
779 urlstr = search_urlstr;
780 }
781 if (urlstr && *urlstr) {
782 /* Filter URL string */
783 new_urlstr = a_Url_string_strip_delimiters(urlstr);
784
785 if (!dStrnAsciiCasecmp(new_urlstr, "file:", 5)) {
786 /* file URI */
787 ch = new_urlstr[5];
788 if (!ch || ch == '.') {
789 url = a_Url_new(Paths::getOldWorkingDir(), "file:");
790 } else {
791 url = a_Url_new(new_urlstr, "file:");
792 }
793
794 } else {
795 /* common case */
796 url = a_Url_new(new_urlstr, NULL);
797 }
798 dFree(new_urlstr);
799
800 if (url) {
801 a_UIcmd_open_url(bw, url);
802 a_Url_free(url);
803 }
804 }
805 dFree(search_urlstr);
806}
807
808/*
809 * Open a new URL in the given browser window
810 */
812{
813 if (url) {
814 a_Nav_push(bw, url, NULL);
815 BW2UI(bw)->focus_main();
816 } else {
817 // Used to start a bw with a blank screen
818 BW2UI(bw)->focus_location();
820 }
821}
822
823static void UIcmd_open_url_nbw(BrowserWindow *new_bw, const DilloUrl *url)
824{
825 if (!url && prefs.new_tab_page) {
826 if (strcmp(URL_STR(prefs.new_tab_page), "about:blank") != 0)
827 url = prefs.new_tab_page;
828 }
829
830 /* When opening a new BrowserWindow (tab or real window) we focus
831 * Location if we don't yet have an URL, main otherwise.
832 */
833 if (url) {
834 a_Nav_push(new_bw, url, NULL);
836 BW2UI(new_bw)->focus_main();
837 } else {
838 BW2UI(new_bw)->focus_location();
840 }
841}
842
843/*
844 * Open a new URL in a new browser window
845 */
847{
848 int w, h;
849 BrowserWindow *new_bw;
850
851 a_UIcmd_get_wh(bw, &w, &h);
852 new_bw = a_UIcmd_browser_window_new(w, h, 0, bw);
853
854 /* Preserve same zoom factor in new window */
855 new_bw->zoom = bw->zoom;
856 UIcmd_open_url_nbw(new_bw, url);
857}
858
859/*
860 * Open a new URL in a new tab in the same browser window
861 */
862void a_UIcmd_open_url_nt(void *vbw, const DilloUrl *url, int focus)
863{
864 BrowserWindow *bw = (BrowserWindow *)vbw;
865 BrowserWindow *new_bw = UIcmd_tab_new(BW2UI(bw)->tabs(),
866 bw ? BW2UI(bw) : NULL, focus);
867 /* Preserve same zoom factor in new tab */
868 new_bw->zoom = bw->zoom;
869 UIcmd_open_url_nbw(new_bw, url);
870}
871
872/*
873 * Send the browser back to previous page
874 */
875void a_UIcmd_back(void *vbw)
876{
878}
879
880/*
881 * Send the browser back to previous page in a new tab
882 */
883void a_UIcmd_back_nt(void *vbw)
884{
886}
887
888/*
889 * Popup the navigation menu of the Back button
890 */
891void a_UIcmd_back_popup(void *vbw, int x, int y)
892{
893 a_Menu_history_popup((BrowserWindow*)vbw, x, y, -1);
894}
895
896/*
897 * Send the browser to next page in the history list
898 */
899void a_UIcmd_forw(void *vbw)
900{
902}
903
904/*
905 * Send the browser to next page in the history list in new tab
906 */
907void a_UIcmd_forw_nt(void *vbw)
908{
910}
911
912/*
913 * Popup the navigation menu of the Forward button
914 */
915void a_UIcmd_forw_popup(void *vbw, int x, int y)
916{
917 a_Menu_history_popup((BrowserWindow*)vbw, x, y, 1);
918}
919
920/*
921 * Send the browser to home URL
922 */
923void a_UIcmd_home(void *vbw, int nt)
924{
925 if (nt)
927 else
929}
930
931/*
932 * Reload current URL
933 */
934void a_UIcmd_reload(void *vbw)
935{
937}
938
939/*
940 * Reload all active tabs
941 */
943{
944 struct Tabgroup *tg = tabgroups;
945 for (tg = tabgroups; tg; tg = tg->next) {
946 BrowserWindow *bw = a_UIcmd_get_bw_by_widget(tg->tabs->wizard()->value());
947 if (bw)
948 a_UIcmd_reload(bw);
949 }
950}
951
952/*
953 * Repush current URL
954 */
955void a_UIcmd_repush(void *vbw)
956{
958}
959
960/*
961 * Zero-delay URL redirection.
962 */
963void a_UIcmd_redirection0(void *vbw, const DilloUrl *url)
964{
966}
967
968/*
969 * Copy selection to clipboard
970 */
971void a_UIcmd_copy(void *vbw)
972{
973 BrowserWindow *bw = (BrowserWindow*) vbw;
976}
977
978/*
979 * Zoom in
980 */
981void a_UIcmd_zoom_in(void *vbw)
982{
983 BrowserWindow *bw = (BrowserWindow*) vbw;
984 bw->zoom += 0.10;
985
986 if (bw->zoom > 10.0)
987 bw->zoom = 10.0;
988
989 a_UIcmd_set_msg(bw, "Zoom set to %.0f%%", bw->zoom * 100.0);
990
992}
993
994/*
995 * Zoom out
996 */
997void a_UIcmd_zoom_out(void *vbw)
998{
999 BrowserWindow *bw = (BrowserWindow*) vbw;
1000 bw->zoom -= 0.10;
1001
1002 if (bw->zoom < 0.10)
1003 bw->zoom = 0.10;
1004
1005 a_UIcmd_set_msg(bw, "Zoom set to %.0f%%", bw->zoom * 100.0);
1006
1008}
1009
1010/*
1011 * Zoom reset
1012 */
1013void a_UIcmd_zoom_reset(void *vbw)
1014{
1015 BrowserWindow *bw = (BrowserWindow*) vbw;
1016 bw->zoom = 1.0;
1017
1018 a_UIcmd_set_msg(bw, "Zoom set to %.0f%%", bw->zoom * 100.0);
1019
1021}
1022
1023/*
1024 * Return a suitable filename for a given URL path.
1025 */
1026static char *UIcmd_make_save_filename(const DilloUrl *url)
1027{
1028 size_t MaxLen = 64;
1029 const char *dir = save_dir, *path, *path2, *query;
1030 char *name, *free1, *free2, *n1, *n2;
1031
1032 free1 = free2 = NULL;
1033
1034 /* get the last component of the path */
1035 path = URL_PATH(url);
1036 path2 = strrchr(path, '/');
1037 path = path2 ? path2 + 1 : path;
1038
1039 /* truncate the path if necessary */
1040 if (strlen(path) > MaxLen) {
1041 path = free1 = dStrndup(path, MaxLen);
1042 }
1043
1044 /* is there a query? */
1045 query = URL_QUERY(url);
1046 if (*query) {
1047 /* truncate the query if necessary */
1048 if (strlen(query) > MaxLen) {
1049 query = free2 = dStrndup(query, MaxLen);
1050 }
1051 name = dStrconcat(dir, path, "?", query, NULL);
1052 } else {
1053 name = dStrconcat(dir, path, NULL);
1054 }
1055
1056 dFree(free1);
1057 dFree(free2);
1058
1059 /* Replace %20 and ' ' with '_' */
1060 for (n1 = n2 = name; *n1; n1++, n2++) {
1061 *n2 =
1062 (n1[0] == ' ')
1063 ? '_' :
1064 (n1[0] == '%' && n1[1] == '2' && n1[2] == '0')
1065 ? (n1 += 2, '_') :
1066 n1[0];
1067 }
1068 *n2 = 0;
1069
1070 return name;
1071}
1072
1073/*
1074 * Set the default directory for saving files.
1075 */
1077{
1078 const char *dir = prefs.save_dir;
1079
1080 if (dir && *dir) {
1081 // assert a trailing '/'
1082 save_dir =
1083 (dir[strlen(dir)-1] == '/')
1084 ? dStrdup(dir)
1085 : dStrconcat(dir, "/", NULL);
1086 }
1087}
1088
1089/*
1090 * Check a file to save to.
1091 */
1092static int UIcmd_save_file_check(const char *name)
1093{
1094 struct stat ss;
1095 if (stat(name, &ss) == 0) {
1096 Dstr *ds;
1097 int ch;
1098 ds = dStr_sized_new(128);
1099 dStr_sprintf(ds,
1100 "The file: %s (%d Bytes) already exists. What do we do?",
1101 name, (int)ss.st_size);
1102 ch = a_Dialog_choice("Dillo Save: File exists!", ds->str,
1103 "Abort", "Continue", "Rename", NULL);
1104 dStr_free(ds, 1);
1105 return ch;
1106 } else {
1107 return 2; /* assume the file does not exist, so Continue */
1108 }
1109}
1110
1111/*
1112 * Save a URL
1113 */
1114static void UIcmd_save(BrowserWindow *bw, const DilloUrl *url, char *filename,
1115 const char *title)
1116{
1117 char *SuggestedName = filename ? filename : UIcmd_make_save_filename(url);
1118
1119 while (1) {
1120 const char *name = a_Dialog_save_file(title, NULL, SuggestedName);
1121 dFree(SuggestedName);
1122
1123 if (name) {
1124 switch (UIcmd_save_file_check(name)) {
1125 case 0:
1126 case 1:
1127 /* Abort */
1128 return;
1129 case 2:
1130 /* Continue */
1131 MSG("UIcmd_save: %s\n", name);
1132 a_Nav_save_url(bw, url, name);
1133 return;
1134 default:
1135 /* Rename */
1136 break; /* prompt again */
1137 }
1138 } else {
1139 return; /* no name, so Abort */
1140 }
1141
1142 SuggestedName = dStrdup(name);
1143 }
1144}
1145
1146/*
1147 * Save current URL
1148 */
1149void a_UIcmd_save(void *vbw)
1150{
1151 BrowserWindow *bw = (BrowserWindow *)vbw;
1152 const DilloUrl *url = a_History_get_url(NAV_TOP_UIDX(bw));
1153
1154 if (url) {
1155 UIcmd_save(bw, url, NULL, "Save Page as File");
1156 }
1157}
1158
1159/*
1160 * Select a file
1161 */
1163{
1164 return a_Dialog_select_file("Dillo: Select a File", NULL, NULL);
1165}
1166
1167/*
1168 * Stop network activity on this bw.
1169 * The stop button was pressed: stop page (and images) downloads.
1170 */
1171void a_UIcmd_stop(void *vbw)
1172{
1173 BrowserWindow *bw = (BrowserWindow *)vbw;
1174
1175 MSG("a_UIcmd_stop()\n");
1179}
1180
1181/*
1182 * Popup the tools menu
1183 */
1184void a_UIcmd_tools(void *vbw, int x, int y)
1185{
1186 a_Menu_tools_popup((BrowserWindow*)vbw, x, y);
1187}
1188
1189/*
1190 * Open URL with dialog chooser
1191 */
1192void a_UIcmd_open_file(void *vbw)
1193{
1194 char *name;
1195 DilloUrl *url;
1196
1197 name = a_Dialog_open_file("Dillo: Open File", NULL, "");
1198
1199 if (name) {
1200 url = a_Url_new(name, "file:");
1201 a_UIcmd_open_url((BrowserWindow*)vbw, url);
1202 a_Url_free(url);
1203 dFree(name);
1204 }
1205}
1206
1207/*
1208 * Returns a newly allocated string holding a search url generated from
1209 * a string of keywords (separated by blanks) and the current search_url.
1210 * The search string is urlencoded.
1211 */
1212static char *UIcmd_make_search_str(const char *str)
1213{
1214 char *search_url, *l, *u, *c;
1215 char *keys = a_Url_encode_hex_str(str),
1217 Dstr *ds = dStr_sized_new(128);
1218
1219 /* parse search_url into label and url */
1220 if (a_Misc_parse_search_url(src, &l, &u) == 0) {
1221 for (c = u; *c; c++) {
1222 if (*c == '%')
1223 switch(*++c) {
1224 case 's':
1225 dStr_append(ds, keys); break;
1226 case '%':
1227 dStr_append_c(ds, '%'); break;
1228 case 0:
1229 MSG_WARN("search_url ends with '%%'\n"); c--; break;
1230 default:
1231 MSG_WARN("illegal specifier '%%%c' in search_url\n", *c);
1232 }
1233 else
1234 dStr_append_c(ds, *c);
1235 }
1236 }
1237 dFree(keys);
1238
1239 search_url = ds->str;
1240 dStr_free(ds, 0);
1241 return search_url;
1242}
1243
1244/*
1245 * Get a query from a dialog and open it
1246 */
1248{
1249 const char *query;
1250
1251 if ((query = a_Dialog_input("Dillo: Search", "Search the Web:"))) {
1252 char *url_str = UIcmd_make_search_str(query);
1253 a_UIcmd_open_urlstr(vbw, url_str);
1254 dFree(url_str);
1255 }
1256}
1257
1258/*
1259 * Get password for user
1260 */
1261const char *a_UIcmd_get_passwd(const char *user)
1262{
1263 const char *passwd;
1264 const char *title = "Dillo: Password";
1265 char *msg = dStrconcat("Password for user \"", user, "\"", NULL);
1266 passwd = a_Dialog_passwd(title, msg);
1267 dFree(msg);
1268 return passwd;
1269}
1270
1271/*
1272 * Save link URL
1273 */
1274void a_UIcmd_save_link(BrowserWindow *bw, const DilloUrl *url, char *filename)
1275{
1276 UIcmd_save(bw, url, filename, "Dillo: Save Link as File");
1277}
1278
1279/*
1280 * Request the bookmarks page
1281 */
1282void a_UIcmd_book(void *vbw, int nt)
1283{
1284 DilloUrl *url = a_Url_new("dpi:/bm/", NULL);
1285
1286 if (nt)
1287 a_UIcmd_open_url_nt((BrowserWindow*)vbw, url, 1);
1288 else
1289 a_UIcmd_open_url((BrowserWindow*)vbw, url);
1290
1291 a_Url_free(url);
1292}
1293
1294/*
1295 * Add a bookmark for a certain URL
1296 */
1298{
1299 a_Bookmarks_add(bw, url);
1300}
1301
1302
1303/*
1304 * Popup the page menu
1305 */
1306void a_UIcmd_page_popup(void *vbw, bool_t has_bugs, void *v_cssUrls)
1307{
1308 BrowserWindow *bw = (BrowserWindow*)vbw;
1309 const DilloUrl *url = a_History_get_url(NAV_TOP_UIDX(bw));
1310 a_Menu_page_popup(bw, url, has_bugs, v_cssUrls);
1311}
1312
1313/*
1314 * Popup the link menu
1315 */
1316void a_UIcmd_link_popup(void *vbw, const DilloUrl *url, const DilloUrl *page_url)
1317{
1318 a_Menu_link_popup((BrowserWindow*)vbw, url, page_url);
1319}
1320
1321/*
1322 * Pop up the image menu
1323 */
1324void a_UIcmd_image_popup(void *vbw, const DilloUrl *url, bool_t loaded_img,
1325 DilloUrl *page_url, DilloUrl *link_url)
1326{
1327 a_Menu_image_popup((BrowserWindow*)vbw, url, loaded_img, page_url,link_url);
1328}
1329
1330/*
1331 * Pop up the form menu
1332 */
1333void a_UIcmd_form_popup(void *vbw, const DilloUrl *url, void *vform,
1334 bool_t showing_hiddens)
1335{
1336 a_Menu_form_popup((BrowserWindow*)vbw, url, vform, showing_hiddens);
1337}
1338
1339/*
1340 * Pop up the file menu
1341 */
1342void a_UIcmd_file_popup(void *vbw, void *v_wid)
1343{
1344 a_Menu_file_popup((BrowserWindow*)vbw, v_wid);
1345}
1346
1347/*
1348 * Copy url string to paste buffer.
1349 *
1350 * For destination use: 0=primary, 1=clipboard, 2=both
1351 */
1352void a_UIcmd_copy_urlstr(BrowserWindow *bw, const char *urlstr, int destination)
1353{
1355 layout->copySelection(urlstr, destination);
1356}
1357
1358/*
1359 * Ask the vsource dpi to show this URL's source
1360 */
1362{
1363 char *buf, *major;
1364 int buf_size;
1365 Dstr *dstr_url;
1366 DilloUrl *vs_url;
1367 static int post_id = 0;
1368 char tag[16];
1369 const char *content_type = a_Nav_get_content_type(url);
1370
1371 a_Misc_parse_content_type(content_type, &major, NULL, NULL);
1372
1373 if (major && dStrAsciiCasecmp(major, "image") &&
1374 a_Nav_get_buf(url, &buf, &buf_size)) {
1376 dstr_url = dStr_new("dpi:/vsource/:");
1377 dStr_append(dstr_url, URL_STR(url));
1378 if (URL_FLAGS(url) & URL_Post) {
1379 /* append a custom string to differentiate POST URLs */
1380 post_id = (post_id < 9999) ? post_id + 1 : 0;
1381 snprintf(tag, 16, "_%.4d", post_id);
1382 dStr_append(dstr_url, tag);
1383 }
1384 vs_url = a_Url_new(dstr_url->str, NULL);
1385 a_UIcmd_open_url_nt(bw, vs_url, 1);
1386 a_Url_free(vs_url);
1387 dStr_free(dstr_url, 1);
1388 a_Nav_unref_buf(url);
1389 }
1390 dFree(major);
1391}
1392
1393/*
1394 * Show the browser window's HTML errors in a text window
1395 */
1397{
1398 BrowserWindow *bw = (BrowserWindow*)vbw;
1399
1400 if (bw->num_page_bugs > 0) {
1401 a_Dialog_text_window("Dillo: Detected HTML errors", bw->page_bugs->str);
1402 } else {
1403 a_Dialog_msg("Dillo: Good HTML!", "No HTML errors found while parsing!");
1404 }
1405}
1406
1407/*
1408 * Popup the bug meter menu
1409 */
1411{
1412 BrowserWindow *bw = (BrowserWindow*)vbw;
1413
1415}
1416
1417/*
1418 * Make a list of URL indexes for the history popup
1419 * based on direction (-1 = back, 1 = forward)
1420 */
1421int *a_UIcmd_get_history(BrowserWindow *bw, int direction)
1422{
1423 int i, j, n;
1424 int *hlist;
1425
1426 // Count the number of URLs
1427 i = a_Nav_stack_ptr(bw) + direction;
1428 for (n = 0 ; i >= 0 && i < a_Nav_stack_size(bw); i+=direction)
1429 ++n;
1430 hlist = dNew(int, n + 1);
1431
1432 // Fill the list
1433 i = a_Nav_stack_ptr(bw) + direction;
1434 for (j = 0 ; i >= 0 && i < a_Nav_stack_size(bw); i+=direction, j += 1) {
1435 hlist[j] = NAV_UIDX(bw,i);
1436 }
1437 hlist[j] = -1;
1438
1439 return hlist;
1440}
1441
1442/*
1443 * Jump to a certain URL in the navigation stack.
1444 */
1445void a_UIcmd_nav_jump(BrowserWindow *bw, int offset, int new_bw)
1446{
1447 a_Nav_jump(bw, offset, new_bw);
1448}
1449
1450// UI binding functions -------------------------------------------------------
1451
1452/*
1453 * Return browser window width and height
1454 */
1455void a_UIcmd_get_wh(BrowserWindow *bw, int *w, int *h)
1456{
1457 *w = BW2UI(bw)->w();
1458 *h = BW2UI(bw)->h();
1459 _MSG("a_UIcmd_wh: w=%d, h=%d\n", *w, *h);
1460}
1461
1462/*
1463 * Get the scroll position (x, y offset pair)
1464 */
1465void a_UIcmd_get_scroll_xy(BrowserWindow *bw, int *x, int *y)
1466{
1468
1469 if (layout) {
1470 *x = layout->getScrollPosX();
1471 *y = layout->getScrollPosY();
1472 }
1473}
1474
1475/*
1476 * Set the scroll position ({x, y} offset pair)
1477 */
1479{
1481
1482 if (layout) {
1483 layout->scrollTo(HPOS_LEFT, VPOS_TOP, x, y, 0, 0);
1484 }
1485}
1486
1487/*
1488 * Set the scroll position by fragment (from URL)
1489 */
1491{
1493
1494 if (layout && f) {
1495 layout->setAnchor(f);
1496 }
1497}
1498
1499/*
1500 * Pass scrolling command to dw.
1501 */
1503{
1505
1506 if (layout) {
1507 typedef struct {
1508 KeysCommand_t keys_cmd;
1509 ScrollCommand dw_cmd;
1510 } mapping_t;
1511
1512 const mapping_t map[] = {
1521 {KEYS_TOP, TOP_CMD},
1523 };
1524 KeysCommand_t keycmd = (KeysCommand_t)icmd;
1525
1526 for (uint_t i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
1527 if (keycmd == map[i].keys_cmd) {
1528 layout->scroll(map[i].dw_cmd);
1529 break;
1530 }
1531 }
1532 }
1533}
1534
1535/*
1536 * Get location's text
1537 */
1539{
1540 return dStrdup(BW2UI(bw)->get_location());
1541}
1542
1543/*
1544 * Set location's text
1545 */
1546void a_UIcmd_set_location_text(void *vbw, const char *text)
1547{
1548 BrowserWindow *bw = (BrowserWindow*)vbw;
1549 BW2UI(bw)->set_location(text);
1550}
1551
1552/*
1553 * Set the page progress bar
1554 * cmd: 0 Deactivate, 1 Update, 2 Clear
1555 */
1556void a_UIcmd_set_page_prog(BrowserWindow *bw, size_t nbytes, int cmd)
1557{
1558 BW2UI(bw)->set_page_prog(nbytes, cmd);
1559}
1560
1561/*
1562 * Set the images progress bar
1563 * cmd: 0 Deactivate, 1 Update, 2 Clear
1564 */
1565void a_UIcmd_set_img_prog(BrowserWindow *bw, int n_img, int t_img, int cmd)
1566{
1567 BW2UI(bw)->set_img_prog(n_img, t_img, cmd);
1568#if 0
1569 if (!cmd)
1570 a_UIcmd_close_bw(bw);
1571#endif
1572}
1573
1574/*
1575 * Set the bug meter progress label
1576 */
1578{
1579 BW2UI(bw)->set_bug_prog(n_bug);
1580}
1581
1582/*
1583 * Set the page title in the tab label and window titlebar.
1584 * (Update window titlebar for the current tab only)
1585 */
1586void a_UIcmd_set_page_title(BrowserWindow *bw, const char *label)
1587{
1588 const int size = 128;
1589 char title[size];
1590
1591 if (snprintf(title, size, "Dillo: %s", label ? label : "") >= size) {
1592 uint_t i = MIN(size - 4, 1 + a_Utf8_end_of_char(title, size - 8));
1593 snprintf(title + i, 4, "...");
1594 }
1595 BW2UI(bw)->copy_label(title);
1596 BW2UI(bw)->tabs()->set_tab_label(BW2UI(bw), label ? label : "");
1597
1598 if (a_UIcmd_get_bw_by_widget(BW2UI(bw)->tabs()->wizard()->value()) == bw) {
1599 // This is the focused bw, set window title
1600 UIcmd_set_window_labels(BW2UI(bw)->window(), title);
1601 }
1602}
1603
1604/*
1605 * Set a printf-like status string on the bottom of the dillo window.
1606 * Beware: The safe way to set an arbitrary string is
1607 * a_UIcmd_set_msg(bw, "%s", str)
1608 */
1609void a_UIcmd_set_msg(BrowserWindow *bw, const char *format, ...)
1610{
1611 va_list argp;
1612 Dstr *ds = dStr_sized_new(128);
1613 va_start(argp, format);
1614 dStr_vsprintf(ds, format, argp);
1615 va_end(argp);
1616 BW2UI(bw)->set_status(ds->str);
1617 dStr_free(ds, 1);
1618}
1619
1620/*
1621 * Set the sensitivity of back/forw/stop buttons.
1622 */
1624{
1625 int sens;
1626
1627 // Stop
1628 sens = (dList_length(bw->ImageClients) || dList_length(bw->RootClients));
1629 BW2UI(bw)->button_set_sens(UI_STOP, sens);
1630 // Back
1631 sens = (a_Nav_stack_ptr(bw) > 0);
1632 BW2UI(bw)->button_set_sens(UI_BACK, sens);
1633 // Forward
1634 sens = (a_Nav_stack_ptr(bw) < a_Nav_stack_size(bw) - 1 &&
1635 !a_Bw_expecting(bw));
1636 BW2UI(bw)->button_set_sens(UI_FORW, sens);
1637}
1638
1639/*
1640 * Toggle control panel
1641 */
1643{
1644 BW2UI(bw)->panels_toggle();
1645}
1646
1647/*
1648 * Search for next/previous occurrence of key.
1649 */
1650void a_UIcmd_findtext_search(BrowserWindow *bw, const char *key,
1651 int case_sens, int backward)
1652{
1653 Layout *l = (Layout *)bw->render_layout;
1654
1655 switch (l->search(key, case_sens, backward)) {
1657 a_UIcmd_set_msg(bw, backward?"Top reached; restarting from the bottom."
1658 :"Bottom reached; restarting from the top.");
1659 break;
1661 a_UIcmd_set_msg(bw, "\"%s\" not found.", key);
1662 break;
1664 default:
1665 a_UIcmd_set_msg(bw, "");
1666 }
1667}
1668
1669/*
1670 * Reset text search state.
1671 */
1673{
1674 Layout *l = (Layout *)bw->render_layout;
1675 l->resetSearch();
1676
1677 a_UIcmd_set_msg(bw, "");
1678}
1679
1680/*
1681 * Tell the UI to hide/show the findbar
1682 */
1684{
1685 BW2UI(bw)->findbar_toggle(on);
1686}
1687
1688/*
1689 * Focus the rendered area.
1690 */
1692{
1693 BW2UI(bw)->focus_main();
1694}
1695
1696/*
1697 * Focus the location bar.
1698 */
1700{
1701 BrowserWindow *bw = (BrowserWindow*)vbw;
1702 BW2UI(bw)->focus_location();
1703}
1704
1705/*
1706 * Focus the tab at index, starting from 0.
1707 */
1708void a_UIcmd_focus_tab(void *vbw, int index)
1709{
1710 BrowserWindow *bw = (BrowserWindow*)vbw;
1711 UI *ui = BW2UI(bw);
1712 CustTabs *tabs = ui->tabs();
1713 if (tabs)
1714 tabs->switch_tab(index);
1715}
void a_Bookmarks_add(BrowserWindow *bw, const DilloUrl *url)
Add the new bookmark through the bookmarks server.
Definition bookmark.c:71
#define _MSG(...)
Definition bookmarks.c:45
#define MSG(...)
Definition bookmarks.c:46
bool_t a_Bw_expecting(BrowserWindow *bw)
Definition bw.c:334
void a_Bw_free(BrowserWindow *bw)
Free resources associated to a bw.
Definition bw.c:89
BrowserWindow * a_Bw_get(int i)
Return a bw by index.
Definition bw.c:313
void a_Bw_stop_clients(BrowserWindow *bw, int flags)
Stop the active clients of this bw's top page.
Definition bw.c:182
int a_Bw_num(void)
Definition bw.c:305
BrowserWindow * a_Bw_new(void)
Create a new browser window and return it.
Definition bw.c:47
#define BW_Img
Definition bw.h:22
#define BW_Force
Definition bw.h:23
#define BW_Root
Definition bw.h:21
A button that highlights on mouse over.
Definition tipwin.hh:49
static KeysCommand_t getKeyCmd(void)
Look if the just pressed key is bound to a command.
Definition keys.cc:213
static char * getOldWorkingDir(void)
Return the initial current working directory in a string.
Definition paths.cc:64
void set_tooltip(const char *s)
Definition tipwin.cc:162
Definition ui.hh:123
void findbar_toggle(bool add)
Adjust space for the findbar (if necessary) and show or remove it.
Definition ui.cc:1074
void set_render_layout(Fl_Group *nw)
Set 'nw' as the main render area widget.
Definition ui.cc:1031
CustTabs * tabs()
Definition ui.hh:179
@ SUCCESS
The next occurrence of the pattern has been found.
Definition findtext.hh:18
@ NOT_FOUND
The pattern does not at all occur in the text.
Definition findtext.hh:27
@ RESTART
There is no further occurrence of the pattern, instead, the first occurrence has been selected.
Definition findtext.hh:24
The central class for managing and drawing a widget tree.
Definition layout.hh:37
void copyCurrentSelection(int destination)
Definition layout.hh:441
void attachView(View *view)
Attach a view to the layout.
Definition layout.cc:459
int getScrollPosY()
Definition layout.hh:309
FindtextState::Result search(const char *str, bool caseSens, int backwards)
See dw::core::FindtextState::search.
Definition layout.hh:455
void resetSearch()
See dw::core::FindtextState::resetSearch.
Definition layout.hh:460
void setBgColor(style::Color *color)
Definition layout.cc:826
void setBgImage(style::StyleImage *bgImage, style::BackgroundRepeat bgRepeat, style::BackgroundAttachment bgAttachment, style::Length bgPositionX, style::Length bgPositionY)
Definition layout.cc:839
int getScrollPosX()
Definition layout.hh:308
void copySelection(const char *text, int destination)
Definition layout.hh:436
void scrollTo(HPosition hpos, VPosition vpos, int x, int y, int width, int height)
Scrolls all viewports, so that the region [x, y, width, height] is seen, according to hpos and vpos.
Definition layout.cc:539
void scroll(ScrollCommand)
Definition layout.cc:529
void setAnchor(const char *anchor)
Sets the anchor to scroll to.
Definition layout.cc:738
static Color * create(Layout *layout, int color)
Definition style.cc:529
void setBufferedDrawing(bool b)
void setPageOverlap(int overlap)
void setScrollbarPageMode(bool enable)
void setDragScroll(bool enable)
void setScrollStep(int step)
void setScrollbarOnLeft(bool enable)
unsigned int uint_t
Definition d_size.h:20
unsigned char bool_t
Definition d_size.h:21
char * a_Dialog_open_file(const char *title, const char *pattern, const char *fname)
Show the open file dialog.
Definition dialog.cc:272
int a_Dialog_choice(const char *title, const char *msg,...)
Make a question-dialog with a question and alternatives.
Definition dialog.cc:342
void a_Dialog_msg(const char *title, const char *msg)
Display a message in a popup window.
Definition dialog.cc:127
const char * a_Dialog_save_file(const char *title, const char *pattern, const char *fname)
Show the save file dialog.
Definition dialog.cc:246
const char * a_Dialog_passwd(const char *title, const char *msg)
Dialog for password.
Definition dialog.cc:233
void a_Dialog_text_window(const char *title, const char *txt)
Show a new window with the provided text.
Definition dialog.cc:296
const char * a_Dialog_select_file(const char *title, const char *pattern, const char *fname)
Show the select file dialog.
Definition dialog.cc:257
const char * a_Dialog_input(const char *title, const char *msg)
Dialog for one line of Input with a message.
Definition dialog.cc:151
char * dStrconcat(const char *s1,...)
Concatenate a NULL-terminated list of strings.
Definition dlib.c:102
void dFree(void *mem)
Definition dlib.c:68
int dStrAsciiCasecmp(const char *s1, const char *s2)
Definition dlib.c:203
void dStr_append(Dstr *ds, const char *s)
Append a C string to a Dstr.
Definition dlib.c:316
char * dStrdup(const char *s)
Definition dlib.c:77
Dstr * dStr_sized_new(int sz)
Create a new string with a given size.
Definition dlib.c:254
int dStrnAsciiCasecmp(const char *s1, const char *s2, size_t n)
Definition dlib.c:215
int dList_length(Dlist *lp)
For completing the ADT.
Definition dlib.c:641
void * dList_nth_data(Dlist *lp, int n0)
Return the nth data item, NULL when not found or 'n0' is out of range.
Definition dlib.c:690
void dStr_free(Dstr *ds, int all)
Free a dillo string.
Definition dlib.c:337
void dStr_append_c(Dstr *ds, int c)
Append one character.
Definition dlib.c:349
char * dStrndup(const char *s, size_t sz)
Definition dlib.c:88
void dStr_sprintf(Dstr *ds, const char *format,...)
Printf-like function.
Definition dlib.c:450
Dstr * dStr_new(const char *s)
Create a new string.
Definition dlib.c:325
void dStr_vsprintf(Dstr *ds, const char *format, va_list argp)
vsprintf-like function.
Definition dlib.c:439
#define MIN(a, b)
Definition dlib.h:42
#define dReturn_if(expr)
Definition dlib.h:76
#define dNew(type, count)
Definition dlib.h:61
static Fl_Window * window
static Layout * layout
static FltkPlatform * platform
static FltkViewport * viewport
const DilloUrl * a_History_get_url(int idx)
Return the DilloUrl field (by index)
Definition history.c:80
KeysCommand_t
Definition keys.hh:17
@ KEYS_SCREEN_RIGHT
Definition keys.hh:45
@ KEYS_BOTTOM
Definition keys.hh:51
@ KEYS_LEFT
Definition keys.hh:48
@ KEYS_RIGHT
Definition keys.hh:49
@ KEYS_NOP
Definition keys.hh:19
@ KEYS_LEFT_TAB
Definition keys.hh:23
@ KEYS_RIGHT_TAB
Definition keys.hh:24
@ KEYS_CLOSE_ALL
Definition keys.hh:36
@ KEYS_LINE_UP
Definition keys.hh:46
@ KEYS_SCREEN_DOWN
Definition keys.hh:43
@ KEYS_TOP
Definition keys.hh:50
@ KEYS_LINE_DOWN
Definition keys.hh:47
@ KEYS_NEW_WINDOW
Definition keys.hh:21
@ KEYS_NEW_TAB
Definition keys.hh:22
@ KEYS_SCREEN_LEFT
Definition keys.hh:44
@ KEYS_SCREEN_UP
Definition keys.hh:42
@ KEYS_CLOSE_TAB
Definition keys.hh:25
#define MSG_WARN(...)
Definition msg.h:26
void a_Menu_page_popup(BrowserWindow *bw, const DilloUrl *url, bool_t has_bugs, void *v_cssUrls)
Page popup menu (construction & popup)
Definition menu.cc:355
void a_Menu_file_popup(BrowserWindow *bw, void *v_wid)
File popup menu (construction & popup)
Definition menu.cc:658
void a_Menu_tools_popup(BrowserWindow *bw, int x, int y)
Tools popup menu (construction & popup).
Definition menu.cc:830
void a_Menu_link_popup(BrowserWindow *bw, const DilloUrl *url, const DilloUrl *page_url)
Link popup menu (construction & popup)
Definition menu.cc:550
void a_Menu_image_popup(BrowserWindow *bw, const DilloUrl *url, bool_t loaded_img, DilloUrl *page_url, DilloUrl *link_url)
Image popup menu (construction & popup)
Definition menu.cc:571
void a_Menu_bugmeter_popup(BrowserWindow *bw, const DilloUrl *url)
Bugmeter popup menu (construction & popup)
Definition menu.cc:691
void a_Menu_history_popup(BrowserWindow *bw, int x, int y, int direction)
Navigation History popup menu (construction & popup).
Definition menu.cc:717
void a_Menu_form_popup(BrowserWindow *bw, const DilloUrl *page_url, void *formptr, bool_t hidvis)
Form popup menu (construction & popup)
Definition menu.cc:630
int a_Misc_parse_search_url(char *source, char **label, char **urlstr)
Parse dillorc's search_url string ([<label> ]<url>) Return value: -1 on error, 0 on success (and labe...
Definition misc.c:391
void a_Misc_parse_content_type(const char *type, char **major, char **minor, char **charset)
Parse Content-Type string, e.g., "text/html; charset=utf-8".
Definition misc.c:210
@ BACKGROUND_ATTACHMENT_SCROLL
Definition style.hh:245
Length createPerLength(double v)
Returns a percentage, v is relative to 1, not to 100.
Definition style.hh:435
The core of Dw is defined in this namespace.
Definition core.hh:23
@ VPOS_TOP
Definition types.hh:27
@ HPOS_LEFT
Definition types.hh:17
ScrollCommand
Definition types.hh:35
@ LINE_UP_CMD
Definition types.hh:36
@ BOTTOM_CMD
Definition types.hh:37
@ RIGHT_CMD
Definition types.hh:37
@ SCREEN_LEFT_CMD
Definition types.hh:35
@ LEFT_CMD
Definition types.hh:37
@ SCREEN_DOWN_CMD
Definition types.hh:35
@ LINE_DOWN_CMD
Definition types.hh:36
@ SCREEN_UP_CMD
Definition types.hh:35
@ SCREEN_RIGHT_CMD
Definition types.hh:36
@ TOP_CMD
Definition types.hh:37
This namespace contains FLTK implementations of Dw interfaces.
int a_Nav_stack_ptr(BrowserWindow *bw)
Definition nav.c:55
void a_Nav_redirection0(BrowserWindow *bw, const DilloUrl *new_url)
Definition nav.c:422
void a_Nav_forw(BrowserWindow *bw)
Definition nav.c:465
const char * a_Nav_get_content_type(const DilloUrl *url)
Definition nav.c:622
void a_Nav_cancel_expect(BrowserWindow *bw)
Definition nav.c:247
void a_Nav_jump(BrowserWindow *bw, int offset, int new_bw)
Definition nav.c:551
void a_Nav_back(BrowserWindow *bw)
Definition nav.c:438
void a_Nav_reload(BrowserWindow *bw)
Definition nav.c:542
void a_Nav_repush(BrowserWindow *bw)
Definition nav.c:393
void a_Nav_back_nt(BrowserWindow *bw)
Definition nav.c:452
void a_Nav_forw_nt(BrowserWindow *bw)
Definition nav.c:479
void a_Nav_unref_buf(const DilloUrl *Url)
Definition nav.c:614
int a_Nav_stack_size(BrowserWindow *bw)
Definition nav.c:98
void a_Nav_set_vsource_url(const DilloUrl *Url)
Definition nav.c:630
void a_Nav_save_url(BrowserWindow *bw, const DilloUrl *url, const char *filename)
Definition nav.c:593
int a_Nav_get_buf(const DilloUrl *Url, char **PBuf, int *BufSize)
Definition nav.c:606
void a_Nav_push(BrowserWindow *bw, const DilloUrl *url, const DilloUrl *requester)
Definition nav.c:342
#define NAV_UIDX(bw, i)
Definition nav.h:9
#define NAV_TOP_UIDX(bw)
Definition nav.h:10
DilloPrefs prefs
Global Data.
Definition prefs.c:33
#define PREFS_UI_TAB_ACTIVE_BG_COLOR
Definition prefs.h:29
#define PREFS_UI_TAB_ACTIVE_FG_COLOR
Definition prefs.h:30
#define PREFS_UI_TAB_FG_COLOR
Definition prefs.h:32
#define PREFS_UI_TAB_BG_COLOR
Definition prefs.h:31
#define UI_MIN_H
Definition ui.hh:38
@ UI_FORW
Definition ui.hh:19
@ UI_BACK
Definition ui.hh:18
@ UI_STOP
Definition ui.hh:23
#define UI_MIN_W
Definition ui.hh:37
Contains the specific data for a single window.
Definition bw.h:27
Dlist * ImageClients
Image Keys for all active connections in the window.
Definition bw.h:42
Dstr * page_bugs
Definition bw.h:71
Dlist * RootClients
A list of active cache clients in the window (The primary Key)
Definition bw.h:40
void * render_layout
All the rendering is done by this.
Definition bw.h:34
float zoom
Definition bw.h:74
void * ui
Pointer to the UI object this bw belongs to.
Definition bw.h:29
int num_page_bugs
HTML-bugs detected at parse time.
Definition bw.h:70
int xpos
Definition prefs.h:40
int width
Definition prefs.h:38
int ypos
Definition prefs.h:41
int32_t bg_color
Definition prefs.h:54
int32_t buffered_drawing
Definition prefs.h:107
bool_t middle_click_drags_page
Definition prefs.h:123
bool_t right_click_closes_tab
Definition prefs.h:115
bool_t show_quit_dialog
Definition prefs.h:97
bool_t scrollbar_on_left
Definition prefs.h:81
bool_t scrollbar_page_mode
Definition prefs.h:82
int32_t scroll_page_overlap
Definition prefs.h:80
int32_t scroll_step
Definition prefs.h:79
DilloUrl * new_tab_page
Definition prefs.h:51
bool_t scroll_switches_tabs
Definition prefs.h:116
bool_t scroll_switches_tabs_reverse
Definition prefs.h:117
double zoom_factor
Definition prefs.h:76
Dlist * search_urls
Definition prefs.h:119
char * save_dir
Definition prefs.h:120
int32_t ui_tab_height
Definition prefs.h:63
int height
Definition prefs.h:39
DilloUrl * home
Definition prefs.h:50
bool_t search_url_idx
Definition prefs.h:118
Definition url.h:88
Definition dlib.h:114
Dstr_char_t * str
Definition dlib.h:117
static void path()
Definition cookies.c:859
void a_Timeout_add(float t, TimeoutCb_t cb, void *cbdata)
Hook a one-time timeout function 'cb' after 't' seconds with 'cbdata" as its data.
Definition timeout.cc:25
void a_UIcmd_tools(void *vbw, int x, int y)
Definition uicmd.cc:1184
void a_UIcmd_link_popup(void *vbw, const DilloUrl *url, const DilloUrl *page_url)
Definition uicmd.cc:1316
void a_UIcmd_book(void *vbw, int nt)
Definition uicmd.cc:1282
const char * a_UIcmd_get_passwd(const char *user)
Definition uicmd.cc:1261
static void UIcmd_open_url_nbw(BrowserWindow *new_bw, const DilloUrl *url)
Definition uicmd.cc:823
#define BW2UI(bw)
Definition uicmd.cc:59
static BrowserWindow * UIcmd_tab_new(CustTabs *tabs, UI *old_ui, int focus)
Definition uicmd.cc:636
void a_UIcmd_set_bug_prog(BrowserWindow *bw, int n_bug)
Definition uicmd.cc:1577
void a_UIcmd_set_scroll_xy(BrowserWindow *bw, int x, int y)
Definition uicmd.cc:1478
void a_UIcmd_page_popup(void *vbw, bool_t has_bugs, void *v_cssUrls)
Definition uicmd.cc:1306
void a_UIcmd_bugmeter_popup(void *vbw)
Definition uicmd.cc:1410
void a_UIcmd_forw_nt(void *vbw)
Definition uicmd.cc:907
void a_UIcmd_set_msg(BrowserWindow *bw, const char *format,...)
Definition uicmd.cc:1609
static char * UIcmd_find_search_str(const char *str)
Definition uicmd.cc:742
void a_UIcmd_form_popup(void *vbw, const DilloUrl *url, void *vform, bool_t showing_hiddens)
Definition uicmd.cc:1333
void a_UIcmd_close_bw(void *vbw)
Definition uicmd.cc:685
void a_UIcmd_home(void *vbw, int nt)
Definition uicmd.cc:923
static char * UIcmd_make_search_str(const char *str)
Definition uicmd.cc:1212
void a_UIcmd_image_popup(void *vbw, const DilloUrl *url, bool_t loaded_img, DilloUrl *page_url, DilloUrl *link_url)
Definition uicmd.cc:1324
int * a_UIcmd_get_history(BrowserWindow *bw, int direction)
Definition uicmd.cc:1421
static void win_cb(Fl_Widget *w, void *cb_data)
Definition uicmd.cc:531
void a_UIcmd_reload_all_active()
Definition uicmd.cc:942
void a_UIcmd_copy_urlstr(BrowserWindow *bw, const char *urlstr, int destination)
Definition uicmd.cc:1352
void a_UIcmd_open_file(void *vbw)
Definition uicmd.cc:1192
BrowserWindow * a_UIcmd_browser_window_new(int ww, int wh, uint32_t xid, const void *vbw)
Definition uicmd.cc:569
void a_UIcmd_focus_location(void *vbw)
Definition uicmd.cc:1699
void a_UIcmd_zoom_reset(void *vbw)
Definition uicmd.cc:1013
void a_UIcmd_focus_tab(void *vbw, int index)
Definition uicmd.cc:1708
void a_UIcmd_zoom_in(void *vbw)
Definition uicmd.cc:981
void a_UIcmd_zoom_out(void *vbw)
Definition uicmd.cc:997
void a_UIcmd_set_page_title(BrowserWindow *bw, const char *label)
Definition uicmd.cc:1586
void a_UIcmd_focus_main_area(BrowserWindow *bw)
Definition uicmd.cc:1691
void a_UIcmd_findtext_search(BrowserWindow *bw, const char *key, int case_sens, int backward)
Definition uicmd.cc:1650
void a_UIcmd_reload(void *vbw)
Definition uicmd.cc:934
static void UIcmd_save(BrowserWindow *bw, const DilloUrl *url, char *filename, const char *title)
Definition uicmd.cc:1114
static void tab_btn_cb(Fl_Widget *w, void *cb_data)
Callback for mouse click.
Definition uicmd.cc:201
#define DEFAULT_TAB_LABEL
Definition uicmd.cc:56
BrowserWindow * a_UIcmd_get_bw_by_widget(void *v_wid)
Definition uicmd.cc:553
void a_UIcmd_file_popup(void *vbw, void *v_wid)
Definition uicmd.cc:1342
void a_UIcmd_open_url_nw(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:846
static void close_tab_btn_cb(Fl_Widget *w, void *cb_data)
Callback for the close-tab button.
Definition uicmd.cc:219
void a_UIcmd_view_page_source(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:1361
void a_UIcmd_search_dialog(void *vbw)
Definition uicmd.cc:1247
void a_UIcmd_view_page_bugs(void *vbw)
Definition uicmd.cc:1396
void a_UIcmd_nav_jump(BrowserWindow *bw, int offset, int new_bw)
Definition uicmd.cc:1445
static char * UIcmd_make_save_filename(const DilloUrl *url)
Definition uicmd.cc:1026
void a_UIcmd_findbar_toggle(BrowserWindow *bw, int on)
Definition uicmd.cc:1683
static int btn_cmp(const void *p1, const void *p2)
Definition uicmd.cc:111
void a_UIcmd_get_wh(BrowserWindow *bw, int *w, int *h)
Definition uicmd.cc:1455
void a_UIcmd_open_urlstr(void *vbw, const char *urlstr)
Definition uicmd.cc:770
void a_UIcmd_set_buttons_sens(BrowserWindow *bw)
Definition uicmd.cc:1623
static struct Tabgroup * tabgroups
Definition uicmd.cc:79
void a_UIcmd_panels_toggle(BrowserWindow *bw)
Definition uicmd.cc:1642
const char * a_UIcmd_select_file()
Definition uicmd.cc:1162
void a_UIcmd_forw_popup(void *vbw, int x, int y)
Definition uicmd.cc:915
void a_UIcmd_save(void *vbw)
Definition uicmd.cc:1149
void a_UIcmd_back(void *vbw)
Definition uicmd.cc:875
void a_UIcmd_get_scroll_xy(BrowserWindow *bw, int *x, int *y)
Definition uicmd.cc:1465
void a_UIcmd_forw(void *vbw)
Definition uicmd.cc:899
void a_UIcmd_copy(void *vbw)
Definition uicmd.cc:971
void a_UIcmd_repush(void *vbw)
Definition uicmd.cc:955
void a_UIcmd_back_popup(void *vbw, int x, int y)
Definition uicmd.cc:891
char * a_UIcmd_get_location_text(BrowserWindow *bw)
Definition uicmd.cc:1538
void a_UIcmd_close_all_bw(void *)
Definition uicmd.cc:724
static const char * save_dir
Definition uicmd.cc:70
void a_UIcmd_add_bookmark(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:1297
void a_UIcmd_open_url(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:811
void a_UIcmd_set_page_prog(BrowserWindow *bw, size_t nbytes, int cmd)
Definition uicmd.cc:1556
void a_UIcmd_stop(void *vbw)
Definition uicmd.cc:1171
void a_UIcmd_findtext_reset(BrowserWindow *bw)
Definition uicmd.cc:1672
void a_UIcmd_save_link(BrowserWindow *bw, const DilloUrl *url, char *filename)
Definition uicmd.cc:1274
void a_UIcmd_scroll(BrowserWindow *bw, int icmd)
Definition uicmd.cc:1502
static void UIcmd_set_window_labels(Fl_Window *win, const char *str)
Definition uicmd.cc:623
void a_UIcmd_set_scroll_by_fragment(BrowserWindow *bw, const char *f)
Definition uicmd.cc:1490
void a_UIcmd_set_img_prog(BrowserWindow *bw, int n_img, int t_img, int cmd)
Definition uicmd.cc:1565
static int UIcmd_save_file_check(const char *name)
Definition uicmd.cc:1092
void a_UIcmd_back_nt(void *vbw)
Definition uicmd.cc:883
void a_UIcmd_redirection0(void *vbw, const DilloUrl *url)
Definition uicmd.cc:963
void a_UIcmd_set_location_text(void *vbw, const char *text)
Definition uicmd.cc:1546
void a_UIcmd_open_url_nt(void *vbw, const DilloUrl *url, int focus)
Definition uicmd.cc:862
void a_UIcmd_init(void)
Definition uicmd.cc:1076
char * a_Url_string_strip_delimiters(const char *str)
RFC-3986 suggests this stripping when "importing" URLs from other media.
Definition url.c:658
char * a_Url_encode_hex_str(const char *str)
Urlencode 'str'.
Definition url.c:620
void a_Url_free(DilloUrl *url)
Free a DilloUrl.
Definition url.c:208
DilloUrl * a_Url_new(const char *url_str, const char *base_url)
Transform (and resolve) an URL string into the respective DilloURL.
Definition url.c:371
#define URL_PATH(u)
Definition url.h:72
#define URL_FLAGS(u)
Definition url.h:79
#define URL_STR(u)
Definition url.h:76
#define URL_QUERY(u)
Definition url.h:73
#define URL_Post
Definition url.h:33
uint_t a_Utf8_end_of_char(const char *str, uint_t i)
Return index of the last byte of the UTF-8-encoded character that str + i points to or into.
Definition utf8.cc:23