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