Dillo v3.1.1-91-g6d5b3ee3
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);
637
638 // Now, create a new browser window structure
639 BrowserWindow *new_bw = a_Bw_new();
640
641 // Reference the UI from the bw
642 new_bw->ui = (void *)new_ui;
643 // Copy the layout pointer into the bw data
644 new_bw->render_layout = (void*)layout;
645
646 // Clear the window title
647 if (focus)
648 UIcmd_set_window_labels(new_ui->window(), new_ui->label());
649
650 // WORKAROUND: see findbar_toggle()
651 new_ui->findbar_toggle(0);
652
653 return new_bw;
654}
655
656/*
657 * Close one browser window
658 */
659void a_UIcmd_close_bw(void *vbw)
660{
661 BrowserWindow *bw = (BrowserWindow *)vbw;
662 UI *ui = BW2UI(bw);
663 CustTabs *tabs = ui->tabs();
665
666 _MSG("a_UIcmd_close_bw\n");
668 delete(layout);
669 if (tabs) {
670 tabs->remove_tab(ui);
671 if (tabs->num_tabs() == 0)
672 delete tabs->window();
673 }
674 a_Bw_free(bw);
675}
676
677/*
678 * Close all the browser windows
679 */
681{
682 BrowserWindow *bw;
683 int choice = 1;
684
685 if (prefs.show_quit_dialog && a_Bw_num() > 1)
686 choice = a_Dialog_choice("Dillo: Quit?",
687 "More than one open tab or window.",
688 "Quit", "Cancel", NULL);
689 if (choice == 1)
690 while ((bw = a_Bw_get(0)))
691 a_UIcmd_close_bw((void*)bw);
692}
693
694/*
695 * Return a search string of the suffix if str starts with a
696 * prefix of a search engine name and a blank
697 */
698static char *UIcmd_find_search_str(const char *str)
699{
700 int p;
701 char *url = NULL;
702 int len = strcspn(str, " ");
703
704 if (len > 0 && str[len] != '\0') {
705 /* we found a ' ' in str, check whether the first part of str
706 * is a prefix of a search_url label
707 */
708 for (p = 0; p < dList_length(prefs.search_urls); p++) {
709 const char *search =
710 (const char *)dList_nth_data(prefs.search_urls, p);
711 if (search && dStrnAsciiCasecmp(str, search, len) == 0) {
713 url = UIcmd_make_search_str(str + len + 1);
714 break;
715 }
716 }
717 }
718 return url;
719}
720
721/*
722 * Open a new URL in the given browser window.
723 *
724 * our custom "file:" URIs are normalized here too.
725 */
726void a_UIcmd_open_urlstr(void *vbw, const char *urlstr)
727{
728 char *new_urlstr;
729 char *search_urlstr = NULL;
730 DilloUrl *url;
731 int ch;
732 BrowserWindow *bw = (BrowserWindow*)vbw;
733
734 if ((search_urlstr = UIcmd_find_search_str(urlstr))) {
735 urlstr = search_urlstr;
736 }
737 if (urlstr && *urlstr) {
738 /* Filter URL string */
739 new_urlstr = a_Url_string_strip_delimiters(urlstr);
740
741 if (!dStrnAsciiCasecmp(new_urlstr, "file:", 5)) {
742 /* file URI */
743 ch = new_urlstr[5];
744 if (!ch || ch == '.') {
745 url = a_Url_new(Paths::getOldWorkingDir(), "file:");
746 } else {
747 url = a_Url_new(new_urlstr, "file:");
748 }
749
750 } else {
751 /* common case */
752 url = a_Url_new(new_urlstr, NULL);
753 }
754 dFree(new_urlstr);
755
756 if (url) {
757 a_UIcmd_open_url(bw, url);
758 a_Url_free(url);
759 }
760 }
761 dFree(search_urlstr);
762}
763
764/*
765 * Open a new URL in the given browser window
766 */
768{
769 if (url) {
770 a_Nav_push(bw, url, NULL);
771 BW2UI(bw)->focus_main();
772 } else {
773 // Used to start a bw with a blank screen
774 BW2UI(bw)->focus_location();
776 }
777}
778
779static void UIcmd_open_url_nbw(BrowserWindow *new_bw, const DilloUrl *url)
780{
781 if (!url && prefs.new_tab_page) {
782 if (strcmp(URL_STR(prefs.new_tab_page), "about:blank") != 0)
783 url = prefs.new_tab_page;
784 }
785
786 /* When opening a new BrowserWindow (tab or real window) we focus
787 * Location if we don't yet have an URL, main otherwise.
788 */
789 if (url) {
790 a_Nav_push(new_bw, url, NULL);
792 BW2UI(new_bw)->focus_main();
793 } else {
794 BW2UI(new_bw)->focus_location();
796 }
797}
798
799/*
800 * Open a new URL in a new browser window
801 */
803{
804 int w, h;
805 BrowserWindow *new_bw;
806
807 a_UIcmd_get_wh(bw, &w, &h);
808 new_bw = a_UIcmd_browser_window_new(w, h, 0, bw);
809
810 /* Preserve same zoom factor in new window */
811 new_bw->zoom = bw->zoom;
812 UIcmd_open_url_nbw(new_bw, url);
813}
814
815/*
816 * Open a new URL in a new tab in the same browser window
817 */
818void a_UIcmd_open_url_nt(void *vbw, const DilloUrl *url, int focus)
819{
820 BrowserWindow *bw = (BrowserWindow *)vbw;
821 BrowserWindow *new_bw = UIcmd_tab_new(BW2UI(bw)->tabs(),
822 bw ? BW2UI(bw) : NULL, focus);
823 /* Preserve same zoom factor in new tab */
824 new_bw->zoom = bw->zoom;
825 UIcmd_open_url_nbw(new_bw, url);
826}
827
828/*
829 * Send the browser back to previous page
830 */
831void a_UIcmd_back(void *vbw)
832{
834}
835
836/*
837 * Popup the navigation menu of the Back button
838 */
839void a_UIcmd_back_popup(void *vbw, int x, int y)
840{
841 a_Menu_history_popup((BrowserWindow*)vbw, x, y, -1);
842}
843
844/*
845 * Send the browser to next page in the history list
846 */
847void a_UIcmd_forw(void *vbw)
848{
850}
851
852/*
853 * Popup the navigation menu of the Forward button
854 */
855void a_UIcmd_forw_popup(void *vbw, int x, int y)
856{
857 a_Menu_history_popup((BrowserWindow*)vbw, x, y, 1);
858}
859
860/*
861 * Send the browser to home URL
862 */
863void a_UIcmd_home(void *vbw)
864{
866}
867
868/*
869 * Reload current URL
870 */
871void a_UIcmd_reload(void *vbw)
872{
874}
875
876/*
877 * Repush current URL
878 */
879void a_UIcmd_repush(void *vbw)
880{
882}
883
884/*
885 * Zero-delay URL redirection.
886 */
887void a_UIcmd_redirection0(void *vbw, const DilloUrl *url)
888{
890}
891
892/*
893 * Zoom in
894 */
895void a_UIcmd_zoom_in(void *vbw)
896{
897 BrowserWindow *bw = (BrowserWindow*) vbw;
898 bw->zoom += 0.10;
899
900 if (bw->zoom > 10.0)
901 bw->zoom = 10.0;
902
903 a_UIcmd_set_msg(bw, "Zoom set to %.0f%%", bw->zoom * 100.0);
904
906}
907
908/*
909 * Zoom out
910 */
911void a_UIcmd_zoom_out(void *vbw)
912{
913 BrowserWindow *bw = (BrowserWindow*) vbw;
914 bw->zoom -= 0.10;
915
916 if (bw->zoom < 0.10)
917 bw->zoom = 0.10;
918
919 a_UIcmd_set_msg(bw, "Zoom set to %.0f%%", bw->zoom * 100.0);
920
922}
923
924/*
925 * Zoom reset
926 */
927void a_UIcmd_zoom_reset(void *vbw)
928{
929 BrowserWindow *bw = (BrowserWindow*) vbw;
930 bw->zoom = 1.0;
931
932 a_UIcmd_set_msg(bw, "Zoom set to %.0f%%", bw->zoom * 100.0);
933
935}
936
937/*
938 * Return a suitable filename for a given URL path.
939 */
940static char *UIcmd_make_save_filename(const DilloUrl *url)
941{
942 size_t MaxLen = 64;
943 const char *dir = save_dir, *path, *path2, *query;
944 char *name, *free1, *free2, *n1, *n2;
945
946 free1 = free2 = NULL;
947
948 /* get the last component of the path */
949 path = URL_PATH(url);
950 path2 = strrchr(path, '/');
951 path = path2 ? path2 + 1 : path;
952
953 /* truncate the path if necessary */
954 if (strlen(path) > MaxLen) {
955 path = free1 = dStrndup(path, MaxLen);
956 }
957
958 /* is there a query? */
959 query = URL_QUERY(url);
960 if (*query) {
961 /* truncate the query if necessary */
962 if (strlen(query) > MaxLen) {
963 query = free2 = dStrndup(query, MaxLen);
964 }
965 name = dStrconcat(dir, path, "?", query, NULL);
966 } else {
967 name = dStrconcat(dir, path, NULL);
968 }
969
970 dFree(free1);
971 dFree(free2);
972
973 /* Replace %20 and ' ' with '_' */
974 for (n1 = n2 = name; *n1; n1++, n2++) {
975 *n2 =
976 (n1[0] == ' ')
977 ? '_' :
978 (n1[0] == '%' && n1[1] == '2' && n1[2] == '0')
979 ? (n1 += 2, '_') :
980 n1[0];
981 }
982 *n2 = 0;
983
984 return name;
985}
986
987/*
988 * Set the default directory for saving files.
989 */
990void a_UIcmd_init(void)
991{
992 const char *dir = prefs.save_dir;
993
994 if (dir && *dir) {
995 // assert a trailing '/'
996 save_dir =
997 (dir[strlen(dir)-1] == '/')
998 ? dStrdup(dir)
999 : dStrconcat(dir, "/", NULL);
1000 }
1001}
1002
1003/*
1004 * Check a file to save to.
1005 */
1006static int UIcmd_save_file_check(const char *name)
1007{
1008 struct stat ss;
1009 if (stat(name, &ss) == 0) {
1010 Dstr *ds;
1011 int ch;
1012 ds = dStr_sized_new(128);
1013 dStr_sprintf(ds,
1014 "The file: %s (%d Bytes) already exists. What do we do?",
1015 name, (int)ss.st_size);
1016 ch = a_Dialog_choice("Dillo Save: File exists!", ds->str,
1017 "Abort", "Continue", "Rename", NULL);
1018 dStr_free(ds, 1);
1019 return ch;
1020 } else {
1021 return 2; /* assume the file does not exist, so Continue */
1022 }
1023}
1024
1025/*
1026 * Save a URL
1027 */
1028static void UIcmd_save(BrowserWindow *bw, const DilloUrl *url,
1029 const char *title)
1030{
1031 char *SuggestedName = UIcmd_make_save_filename(url);
1032
1033 while (1) {
1034 const char *name = a_Dialog_save_file(title, NULL, SuggestedName);
1035 dFree(SuggestedName);
1036
1037 if (name) {
1038 switch (UIcmd_save_file_check(name)) {
1039 case 0:
1040 case 1:
1041 /* Abort */
1042 return;
1043 case 2:
1044 /* Continue */
1045 MSG("UIcmd_save: %s\n", name);
1046 a_Nav_save_url(bw, url, name);
1047 return;
1048 default:
1049 /* Rename */
1050 break; /* prompt again */
1051 }
1052 } else {
1053 return; /* no name, so Abort */
1054 }
1055
1056 SuggestedName = dStrdup(name);
1057 }
1058}
1059
1060/*
1061 * Save current URL
1062 */
1063void a_UIcmd_save(void *vbw)
1064{
1065 BrowserWindow *bw = (BrowserWindow *)vbw;
1066 const DilloUrl *url = a_History_get_url(NAV_TOP_UIDX(bw));
1067
1068 if (url) {
1069 UIcmd_save(bw, url, "Save Page as File");
1070 }
1071}
1072
1073/*
1074 * Select a file
1075 */
1077{
1078 return a_Dialog_select_file("Dillo: Select a File", NULL, NULL);
1079}
1080
1081/*
1082 * Stop network activity on this bw.
1083 * The stop button was pressed: stop page (and images) downloads.
1084 */
1085void a_UIcmd_stop(void *vbw)
1086{
1087 BrowserWindow *bw = (BrowserWindow *)vbw;
1088
1089 MSG("a_UIcmd_stop()\n");
1093}
1094
1095/*
1096 * Popup the tools menu
1097 */
1098void a_UIcmd_tools(void *vbw, int x, int y)
1099{
1100 a_Menu_tools_popup((BrowserWindow*)vbw, x, y);
1101}
1102
1103/*
1104 * Open URL with dialog chooser
1105 */
1106void a_UIcmd_open_file(void *vbw)
1107{
1108 char *name;
1109 DilloUrl *url;
1110
1111 name = a_Dialog_open_file("Dillo: Open File", NULL, "");
1112
1113 if (name) {
1114 url = a_Url_new(name, "file:");
1115 a_UIcmd_open_url((BrowserWindow*)vbw, url);
1116 a_Url_free(url);
1117 dFree(name);
1118 }
1119}
1120
1121/*
1122 * Returns a newly allocated string holding a search url generated from
1123 * a string of keywords (separated by blanks) and the current search_url.
1124 * The search string is urlencoded.
1125 */
1126static char *UIcmd_make_search_str(const char *str)
1127{
1128 char *search_url, *l, *u, *c;
1129 char *keys = a_Url_encode_hex_str(str),
1131 Dstr *ds = dStr_sized_new(128);
1132
1133 /* parse search_url into label and url */
1134 if (a_Misc_parse_search_url(src, &l, &u) == 0) {
1135 for (c = u; *c; c++) {
1136 if (*c == '%')
1137 switch(*++c) {
1138 case 's':
1139 dStr_append(ds, keys); break;
1140 case '%':
1141 dStr_append_c(ds, '%'); break;
1142 case 0:
1143 MSG_WARN("search_url ends with '%%'\n"); c--; break;
1144 default:
1145 MSG_WARN("illegal specifier '%%%c' in search_url\n", *c);
1146 }
1147 else
1148 dStr_append_c(ds, *c);
1149 }
1150 }
1151 dFree(keys);
1152
1153 search_url = ds->str;
1154 dStr_free(ds, 0);
1155 return search_url;
1156}
1157
1158/*
1159 * Get a query from a dialog and open it
1160 */
1162{
1163 const char *query;
1164
1165 if ((query = a_Dialog_input("Dillo: Search", "Search the Web:"))) {
1166 char *url_str = UIcmd_make_search_str(query);
1167 a_UIcmd_open_urlstr(vbw, url_str);
1168 dFree(url_str);
1169 }
1170}
1171
1172/*
1173 * Get password for user
1174 */
1175const char *a_UIcmd_get_passwd(const char *user)
1176{
1177 const char *passwd;
1178 const char *title = "Dillo: Password";
1179 char *msg = dStrconcat("Password for user \"", user, "\"", NULL);
1180 passwd = a_Dialog_passwd(title, msg);
1181 dFree(msg);
1182 return passwd;
1183}
1184
1185/*
1186 * Save link URL
1187 */
1189{
1190 UIcmd_save(bw, url, "Dillo: Save Link as File");
1191}
1192
1193/*
1194 * Request the bookmarks page
1195 */
1196void a_UIcmd_book(void *vbw)
1197{
1198 DilloUrl *url = a_Url_new("dpi:/bm/", NULL);
1199 a_UIcmd_open_url((BrowserWindow*)vbw, url);
1200 a_Url_free(url);
1201}
1202
1203/*
1204 * Add a bookmark for a certain URL
1205 */
1207{
1208 a_Bookmarks_add(bw, url);
1209}
1210
1211
1212/*
1213 * Popup the page menu
1214 */
1215void a_UIcmd_page_popup(void *vbw, bool_t has_bugs, void *v_cssUrls)
1216{
1217 BrowserWindow *bw = (BrowserWindow*)vbw;
1218 const DilloUrl *url = a_History_get_url(NAV_TOP_UIDX(bw));
1219 a_Menu_page_popup(bw, url, has_bugs, v_cssUrls);
1220}
1221
1222/*
1223 * Popup the link menu
1224 */
1225void a_UIcmd_link_popup(void *vbw, const DilloUrl *url)
1226{
1227 a_Menu_link_popup((BrowserWindow*)vbw, url);
1228}
1229
1230/*
1231 * Pop up the image menu
1232 */
1233void a_UIcmd_image_popup(void *vbw, const DilloUrl *url, bool_t loaded_img,
1234 DilloUrl *page_url, DilloUrl *link_url)
1235{
1236 a_Menu_image_popup((BrowserWindow*)vbw, url, loaded_img, page_url,link_url);
1237}
1238
1239/*
1240 * Pop up the form menu
1241 */
1242void a_UIcmd_form_popup(void *vbw, const DilloUrl *url, void *vform,
1243 bool_t showing_hiddens)
1244{
1245 a_Menu_form_popup((BrowserWindow*)vbw, url, vform, showing_hiddens);
1246}
1247
1248/*
1249 * Pop up the file menu
1250 */
1251void a_UIcmd_file_popup(void *vbw, void *v_wid)
1252{
1253 a_Menu_file_popup((BrowserWindow*)vbw, v_wid);
1254}
1255
1256/*
1257 * Copy url string to paste buffer
1258 */
1259void a_UIcmd_copy_urlstr(BrowserWindow *bw, const char *urlstr)
1260{
1262 layout->copySelection(urlstr);
1263}
1264
1265/*
1266 * Ask the vsource dpi to show this URL's source
1267 */
1269{
1270 char *buf, *major;
1271 int buf_size;
1272 Dstr *dstr_url;
1273 DilloUrl *vs_url;
1274 static int post_id = 0;
1275 char tag[16];
1276 const char *content_type = a_Nav_get_content_type(url);
1277
1278 a_Misc_parse_content_type(content_type, &major, NULL, NULL);
1279
1280 if (major && dStrAsciiCasecmp(major, "image") &&
1281 a_Nav_get_buf(url, &buf, &buf_size)) {
1283 dstr_url = dStr_new("dpi:/vsource/:");
1284 dStr_append(dstr_url, URL_STR(url));
1285 if (URL_FLAGS(url) & URL_Post) {
1286 /* append a custom string to differentiate POST URLs */
1287 post_id = (post_id < 9999) ? post_id + 1 : 0;
1288 snprintf(tag, 16, "_%.4d", post_id);
1289 dStr_append(dstr_url, tag);
1290 }
1291 vs_url = a_Url_new(dstr_url->str, NULL);
1292 a_UIcmd_open_url_nt(bw, vs_url, 1);
1293 a_Url_free(vs_url);
1294 dStr_free(dstr_url, 1);
1295 a_Nav_unref_buf(url);
1296 }
1297 dFree(major);
1298}
1299
1300/*
1301 * Show the browser window's HTML errors in a text window
1302 */
1304{
1305 BrowserWindow *bw = (BrowserWindow*)vbw;
1306
1307 if (bw->num_page_bugs > 0) {
1308 a_Dialog_text_window("Dillo: Detected HTML errors", bw->page_bugs->str);
1309 } else {
1310 a_Dialog_msg("Dillo: Good HTML!", "No HTML errors found while parsing!");
1311 }
1312}
1313
1314/*
1315 * Popup the bug meter menu
1316 */
1318{
1319 BrowserWindow *bw = (BrowserWindow*)vbw;
1320
1322}
1323
1324/*
1325 * Make a list of URL indexes for the history popup
1326 * based on direction (-1 = back, 1 = forward)
1327 */
1328int *a_UIcmd_get_history(BrowserWindow *bw, int direction)
1329{
1330 int i, j, n;
1331 int *hlist;
1332
1333 // Count the number of URLs
1334 i = a_Nav_stack_ptr(bw) + direction;
1335 for (n = 0 ; i >= 0 && i < a_Nav_stack_size(bw); i+=direction)
1336 ++n;
1337 hlist = dNew(int, n + 1);
1338
1339 // Fill the list
1340 i = a_Nav_stack_ptr(bw) + direction;
1341 for (j = 0 ; i >= 0 && i < a_Nav_stack_size(bw); i+=direction, j += 1) {
1342 hlist[j] = NAV_UIDX(bw,i);
1343 }
1344 hlist[j] = -1;
1345
1346 return hlist;
1347}
1348
1349/*
1350 * Jump to a certain URL in the navigation stack.
1351 */
1352void a_UIcmd_nav_jump(BrowserWindow *bw, int offset, int new_bw)
1353{
1354 a_Nav_jump(bw, offset, new_bw);
1355}
1356
1357// UI binding functions -------------------------------------------------------
1358
1359/*
1360 * Return browser window width and height
1361 */
1362void a_UIcmd_get_wh(BrowserWindow *bw, int *w, int *h)
1363{
1364 *w = BW2UI(bw)->w();
1365 *h = BW2UI(bw)->h();
1366 _MSG("a_UIcmd_wh: w=%d, h=%d\n", *w, *h);
1367}
1368
1369/*
1370 * Get the scroll position (x, y offset pair)
1371 */
1372void a_UIcmd_get_scroll_xy(BrowserWindow *bw, int *x, int *y)
1373{
1375
1376 if (layout) {
1377 *x = layout->getScrollPosX();
1378 *y = layout->getScrollPosY();
1379 }
1380}
1381
1382/*
1383 * Set the scroll position ({x, y} offset pair)
1384 */
1386{
1388
1389 if (layout) {
1390 layout->scrollTo(HPOS_LEFT, VPOS_TOP, x, y, 0, 0);
1391 }
1392}
1393
1394/*
1395 * Set the scroll position by fragment (from URL)
1396 */
1398{
1400
1401 if (layout && f) {
1402 layout->setAnchor(f);
1403 }
1404}
1405
1406/*
1407 * Pass scrolling command to dw.
1408 */
1410{
1412
1413 if (layout) {
1414 typedef struct {
1415 KeysCommand_t keys_cmd;
1416 ScrollCommand dw_cmd;
1417 } mapping_t;
1418
1419 const mapping_t map[] = {
1428 {KEYS_TOP, TOP_CMD},
1430 };
1431 KeysCommand_t keycmd = (KeysCommand_t)icmd;
1432
1433 for (uint_t i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
1434 if (keycmd == map[i].keys_cmd) {
1435 layout->scroll(map[i].dw_cmd);
1436 break;
1437 }
1438 }
1439 }
1440}
1441
1442/*
1443 * Get location's text
1444 */
1446{
1447 return dStrdup(BW2UI(bw)->get_location());
1448}
1449
1450/*
1451 * Set location's text
1452 */
1453void a_UIcmd_set_location_text(void *vbw, const char *text)
1454{
1455 BrowserWindow *bw = (BrowserWindow*)vbw;
1456 BW2UI(bw)->set_location(text);
1457}
1458
1459/*
1460 * Set the page progress bar
1461 * cmd: 0 Deactivate, 1 Update, 2 Clear
1462 */
1463void a_UIcmd_set_page_prog(BrowserWindow *bw, size_t nbytes, int cmd)
1464{
1465 BW2UI(bw)->set_page_prog(nbytes, cmd);
1466}
1467
1468/*
1469 * Set the images progress bar
1470 * cmd: 0 Deactivate, 1 Update, 2 Clear
1471 */
1472void a_UIcmd_set_img_prog(BrowserWindow *bw, int n_img, int t_img, int cmd)
1473{
1474 BW2UI(bw)->set_img_prog(n_img, t_img, cmd);
1475#if 0
1476 if (!cmd)
1477 a_UIcmd_close_bw(bw);
1478#endif
1479}
1480
1481/*
1482 * Set the bug meter progress label
1483 */
1485{
1486 BW2UI(bw)->set_bug_prog(n_bug);
1487}
1488
1489/*
1490 * Set the page title in the tab label and window titlebar.
1491 * (Update window titlebar for the current tab only)
1492 */
1493void a_UIcmd_set_page_title(BrowserWindow *bw, const char *label)
1494{
1495 const int size = 128;
1496 char title[size];
1497
1498 if (snprintf(title, size, "Dillo: %s", label ? label : "") >= size) {
1499 uint_t i = MIN(size - 4, 1 + a_Utf8_end_of_char(title, size - 8));
1500 snprintf(title + i, 4, "...");
1501 }
1502 BW2UI(bw)->copy_label(title);
1503 BW2UI(bw)->tabs()->set_tab_label(BW2UI(bw), label ? label : "");
1504
1505 if (a_UIcmd_get_bw_by_widget(BW2UI(bw)->tabs()->wizard()->value()) == bw) {
1506 // This is the focused bw, set window title
1507 UIcmd_set_window_labels(BW2UI(bw)->window(), title);
1508 }
1509}
1510
1511/*
1512 * Set a printf-like status string on the bottom of the dillo window.
1513 * Beware: The safe way to set an arbitrary string is
1514 * a_UIcmd_set_msg(bw, "%s", str)
1515 */
1516void a_UIcmd_set_msg(BrowserWindow *bw, const char *format, ...)
1517{
1518 va_list argp;
1519 Dstr *ds = dStr_sized_new(128);
1520 va_start(argp, format);
1521 dStr_vsprintf(ds, format, argp);
1522 va_end(argp);
1523 BW2UI(bw)->set_status(ds->str);
1524 dStr_free(ds, 1);
1525}
1526
1527/*
1528 * Set the sensitivity of back/forw/stop buttons.
1529 */
1531{
1532 int sens;
1533
1534 // Stop
1535 sens = (dList_length(bw->ImageClients) || dList_length(bw->RootClients));
1536 BW2UI(bw)->button_set_sens(UI_STOP, sens);
1537 // Back
1538 sens = (a_Nav_stack_ptr(bw) > 0);
1539 BW2UI(bw)->button_set_sens(UI_BACK, sens);
1540 // Forward
1541 sens = (a_Nav_stack_ptr(bw) < a_Nav_stack_size(bw) - 1 &&
1542 !a_Bw_expecting(bw));
1543 BW2UI(bw)->button_set_sens(UI_FORW, sens);
1544}
1545
1546/*
1547 * Toggle control panel
1548 */
1550{
1551 BW2UI(bw)->panels_toggle();
1552}
1553
1554/*
1555 * Search for next/previous occurrence of key.
1556 */
1557void a_UIcmd_findtext_search(BrowserWindow *bw, const char *key,
1558 int case_sens, int backward)
1559{
1560 Layout *l = (Layout *)bw->render_layout;
1561
1562 switch (l->search(key, case_sens, backward)) {
1564 a_UIcmd_set_msg(bw, backward?"Top reached; restarting from the bottom."
1565 :"Bottom reached; restarting from the top.");
1566 break;
1568 a_UIcmd_set_msg(bw, "\"%s\" not found.", key);
1569 break;
1571 default:
1572 a_UIcmd_set_msg(bw, "");
1573 }
1574}
1575
1576/*
1577 * Reset text search state.
1578 */
1580{
1581 Layout *l = (Layout *)bw->render_layout;
1582 l->resetSearch();
1583
1584 a_UIcmd_set_msg(bw, "");
1585}
1586
1587/*
1588 * Tell the UI to hide/show the findbar
1589 */
1591{
1592 BW2UI(bw)->findbar_toggle(on);
1593}
1594
1595/*
1596 * Focus the rendered area.
1597 */
1599{
1600 BW2UI(bw)->focus_main();
1601}
1602
1603/*
1604 * Focus the location bar.
1605 */
1607{
1608 BrowserWindow *bw = (BrowserWindow*)vbw;
1609 BW2UI(bw)->focus_location();
1610}
1611
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 setPageOverlap(int overlap)
void setScrollbarPageMode(bool enable)
void setDragScroll(bool enable)
void setScrollStep(int step)
void setScrollbarOnLeft(bool enable)
unsigned int uint_t
Definition d_size.h:20
unsigned char bool_t
Definition d_size.h:21
char * a_Dialog_open_file(const char *title, const char *pattern, const char *fname)
Show the open file dialog.
Definition dialog.cc:272
int a_Dialog_choice(const char *title, const char *msg,...)
Make a question-dialog with a question and alternatives.
Definition dialog.cc:342
void a_Dialog_msg(const char *title, const char *msg)
Display a message in a popup window.
Definition dialog.cc:127
const char * a_Dialog_save_file(const char *title, const char *pattern, const char *fname)
Show the save file dialog.
Definition dialog.cc:246
const char * a_Dialog_passwd(const char *title, const char *msg)
Dialog for password.
Definition dialog.cc:233
void a_Dialog_text_window(const char *title, const char *txt)
Show a new window with the provided text.
Definition dialog.cc:296
const char * a_Dialog_select_file(const char *title, const char *pattern, const char *fname)
Show the select file dialog.
Definition dialog.cc:257
const char * a_Dialog_input(const char *title, const char *msg)
Dialog for one line of Input with a message.
Definition dialog.cc:151
char * dStrconcat(const char *s1,...)
Concatenate a NULL-terminated list of strings.
Definition dlib.c:102
void dFree(void *mem)
Definition dlib.c:68
int dStrAsciiCasecmp(const char *s1, const char *s2)
Definition dlib.c:203
void dStr_append(Dstr *ds, const char *s)
Append a C string to a Dstr.
Definition dlib.c:316
char * dStrdup(const char *s)
Definition dlib.c:77
Dstr * dStr_sized_new(int sz)
Create a new string with a given size.
Definition dlib.c:254
int dStrnAsciiCasecmp(const char *s1, const char *s2, size_t n)
Definition dlib.c:215
int dList_length(Dlist *lp)
For completing the ADT.
Definition dlib.c: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:245
Length createPerLength(double v)
Returns a percentage, v is relative to 1, not to 100.
Definition style.hh:435
The core of Dw is defined in this namespace.
Definition core.hh:23
@ VPOS_TOP
Definition types.hh:27
@ HPOS_LEFT
Definition types.hh:17
ScrollCommand
Definition types.hh:35
@ LINE_UP_CMD
Definition types.hh:36
@ BOTTOM_CMD
Definition types.hh:37
@ RIGHT_CMD
Definition types.hh:37
@ SCREEN_LEFT_CMD
Definition types.hh:35
@ LEFT_CMD
Definition types.hh:37
@ SCREEN_DOWN_CMD
Definition types.hh:35
@ LINE_DOWN_CMD
Definition types.hh:36
@ SCREEN_UP_CMD
Definition types.hh:35
@ SCREEN_RIGHT_CMD
Definition types.hh:36
@ TOP_CMD
Definition types.hh:37
This namespace contains FLTK implementations of Dw interfaces.
int a_Nav_stack_ptr(BrowserWindow *bw)
Definition nav.c:55
void a_Nav_redirection0(BrowserWindow *bw, const DilloUrl *new_url)
Definition nav.c:422
void a_Nav_forw(BrowserWindow *bw)
Definition nav.c: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:106
bool_t middle_click_drags_page
Definition prefs.h:122
bool_t right_click_closes_tab
Definition prefs.h:114
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:115
bool_t scroll_switches_tabs_reverse
Definition prefs.h:116
double zoom_factor
Definition prefs.h:76
Dlist * search_urls
Definition prefs.h:118
char * save_dir
Definition prefs.h:119
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:117
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:1098
void a_UIcmd_link_popup(void *vbw, const DilloUrl *url)
Definition uicmd.cc:1225
const char * a_UIcmd_get_passwd(const char *user)
Definition uicmd.cc:1175
static void UIcmd_open_url_nbw(BrowserWindow *new_bw, const DilloUrl *url)
Definition uicmd.cc:779
#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:1484
void a_UIcmd_set_scroll_xy(BrowserWindow *bw, int x, int y)
Definition uicmd.cc:1385
void a_UIcmd_page_popup(void *vbw, bool_t has_bugs, void *v_cssUrls)
Definition uicmd.cc:1215
void a_UIcmd_bugmeter_popup(void *vbw)
Definition uicmd.cc:1317
void a_UIcmd_set_msg(BrowserWindow *bw, const char *format,...)
Definition uicmd.cc:1516
static char * UIcmd_find_search_str(const char *str)
Definition uicmd.cc:698
void a_UIcmd_home(void *vbw)
Definition uicmd.cc:863
void a_UIcmd_copy_urlstr(BrowserWindow *bw, const char *urlstr)
Definition uicmd.cc:1259
void a_UIcmd_form_popup(void *vbw, const DilloUrl *url, void *vform, bool_t showing_hiddens)
Definition uicmd.cc:1242
void a_UIcmd_close_bw(void *vbw)
Definition uicmd.cc:659
static char * UIcmd_make_search_str(const char *str)
Definition uicmd.cc:1126
void a_UIcmd_image_popup(void *vbw, const DilloUrl *url, bool_t loaded_img, DilloUrl *page_url, DilloUrl *link_url)
Definition uicmd.cc:1233
int * a_UIcmd_get_history(BrowserWindow *bw, int direction)
Definition uicmd.cc:1328
static void win_cb(Fl_Widget *w, void *cb_data)
Definition uicmd.cc:512
void a_UIcmd_open_file(void *vbw)
Definition uicmd.cc:1106
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:1606
void a_UIcmd_zoom_reset(void *vbw)
Definition uicmd.cc:927
void a_UIcmd_zoom_in(void *vbw)
Definition uicmd.cc:895
void a_UIcmd_zoom_out(void *vbw)
Definition uicmd.cc:911
void a_UIcmd_set_page_title(BrowserWindow *bw, const char *label)
Definition uicmd.cc:1493
void a_UIcmd_focus_main_area(BrowserWindow *bw)
Definition uicmd.cc:1598
void a_UIcmd_findtext_search(BrowserWindow *bw, const char *key, int case_sens, int backward)
Definition uicmd.cc:1557
void a_UIcmd_reload(void *vbw)
Definition uicmd.cc:871
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:1251
void a_UIcmd_open_url_nw(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:802
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:1268
void a_UIcmd_book(void *vbw)
Definition uicmd.cc:1196
void a_UIcmd_search_dialog(void *vbw)
Definition uicmd.cc:1161
void a_UIcmd_view_page_bugs(void *vbw)
Definition uicmd.cc:1303
void a_UIcmd_nav_jump(BrowserWindow *bw, int offset, int new_bw)
Definition uicmd.cc:1352
static char * UIcmd_make_save_filename(const DilloUrl *url)
Definition uicmd.cc:940
void a_UIcmd_findbar_toggle(BrowserWindow *bw, int on)
Definition uicmd.cc:1590
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:1362
void a_UIcmd_open_urlstr(void *vbw, const char *urlstr)
Definition uicmd.cc:726
void a_UIcmd_set_buttons_sens(BrowserWindow *bw)
Definition uicmd.cc:1530
void a_UIcmd_panels_toggle(BrowserWindow *bw)
Definition uicmd.cc:1549
const char * a_UIcmd_select_file()
Definition uicmd.cc:1076
void a_UIcmd_forw_popup(void *vbw, int x, int y)
Definition uicmd.cc:855
void a_UIcmd_save(void *vbw)
Definition uicmd.cc:1063
void a_UIcmd_back(void *vbw)
Definition uicmd.cc:831
void a_UIcmd_get_scroll_xy(BrowserWindow *bw, int *x, int *y)
Definition uicmd.cc:1372
void a_UIcmd_forw(void *vbw)
Definition uicmd.cc:847
void a_UIcmd_save_link(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:1188
static void UIcmd_save(BrowserWindow *bw, const DilloUrl *url, const char *title)
Definition uicmd.cc:1028
void a_UIcmd_repush(void *vbw)
Definition uicmd.cc:879
void a_UIcmd_back_popup(void *vbw, int x, int y)
Definition uicmd.cc:839
char * a_UIcmd_get_location_text(BrowserWindow *bw)
Definition uicmd.cc:1445
void a_UIcmd_close_all_bw(void *)
Definition uicmd.cc:680
static const char * save_dir
Definition uicmd.cc:70
void a_UIcmd_add_bookmark(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:1206
void a_UIcmd_open_url(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:767
void a_UIcmd_set_page_prog(BrowserWindow *bw, size_t nbytes, int cmd)
Definition uicmd.cc:1463
void a_UIcmd_stop(void *vbw)
Definition uicmd.cc:1085
void a_UIcmd_findtext_reset(BrowserWindow *bw)
Definition uicmd.cc:1579
void a_UIcmd_scroll(BrowserWindow *bw, int icmd)
Definition uicmd.cc:1409
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:1397
void a_UIcmd_set_img_prog(BrowserWindow *bw, int n_img, int t_img, int cmd)
Definition uicmd.cc:1472
static int UIcmd_save_file_check(const char *name)
Definition uicmd.cc:1006
void a_UIcmd_redirection0(void *vbw, const DilloUrl *url)
Definition uicmd.cc:887
void a_UIcmd_set_location_text(void *vbw, const char *text)
Definition uicmd.cc:1453
void a_UIcmd_open_url_nt(void *vbw, const DilloUrl *url, int focus)
Definition uicmd.cc:818
void a_UIcmd_init(void)
Definition uicmd.cc:990
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