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