NetSurf
gui.c
Go to the documentation of this file.
1/*
2 * Copyright 2008-2025 Chris Young <chris@unsatisfactorysoftware.co.uk>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
20#ifdef __amigaos4__
21/* Custom StringView class */
24#endif
25
26/* AmigaOS libraries */
27#ifdef __amigaos4__
28#include <proto/application.h>
29#endif
30#include <proto/asl.h>
31#include <proto/datatypes.h>
32#include <proto/diskfont.h>
33#include <proto/dos.h>
34#include <proto/exec.h>
35#include <proto/graphics.h>
36#include <proto/icon.h>
37#include <proto/intuition.h>
38#include <proto/keymap.h>
39#include <proto/layers.h>
40#include <proto/locale.h>
41#include <proto/utility.h>
42#include <proto/wb.h>
43
44#ifdef WITH_AMISSL
45/* AmiSSL needs everything to use bsdsocket.library directly to avoid problems */
46#include <proto/bsdsocket.h>
47#define waitselect WaitSelect
48#endif
49
50/* Other OS includes */
51#include <datatypes/textclass.h>
52#include <devices/inputevent.h>
53#include <graphics/gfxbase.h>
54#include <graphics/rpattr.h>
55#ifdef __amigaos4__
56#include <diskfont/diskfonttag.h>
57#include <graphics/blitattr.h>
58#include <intuition/gui.h>
59#include <libraries/application.h>
60#include <libraries/keymap.h>
61#endif
62#include <intuition/icclass.h>
63#include <intuition/screens.h>
64#include <libraries/gadtools.h>
65#include <workbench/workbench.h>
66
67/* ReAction libraries */
68#include <proto/bevel.h>
69#include <proto/bitmap.h>
70#include <proto/button.h>
71#include <proto/chooser.h>
72#include <proto/clicktab.h>
73#include <proto/label.h>
74#include <proto/layout.h>
75#include <proto/listbrowser.h>
76#include <proto/scroller.h>
77#include <proto/space.h>
78#include <proto/speedbar.h>
79#include <proto/string.h>
80#include <proto/window.h>
81
82#include <classes/window.h>
83#include <gadgets/button.h>
84#include <gadgets/chooser.h>
85#include <gadgets/clicktab.h>
86#include <gadgets/layout.h>
87#include <gadgets/listbrowser.h>
88#include <gadgets/scroller.h>
89#include <gadgets/space.h>
90#include <gadgets/speedbar.h>
91#include <gadgets/string.h>
92#include <images/bevel.h>
93#include <images/bitmap.h>
94#include <images/label.h>
95
96#include <reaction/reaction_macros.h>
97
98/* newlib includes */
99#include <math.h>
100#include <string.h>
101#include <stdlib.h>
102#include <limits.h>
103
104/* NetSurf core includes */
105#include "utils/log.h"
106#include "utils/messages.h"
107#include "utils/nsoption.h"
108#include "utils/utf8.h"
109#include "utils/utils.h"
110#include "utils/nsurl.h"
111#include "utils/file.h"
112#include "netsurf/window.h"
113#include "netsurf/fetch.h"
114#include "netsurf/misc.h"
115#include "netsurf/mouse.h"
116#include "netsurf/netsurf.h"
117#include "netsurf/content.h"
119#include "netsurf/cookie_db.h"
120#include "netsurf/url_db.h"
121#include "netsurf/keypress.h"
123#include "content/fetch.h"
125#include "desktop/hotlist.h"
126#include "desktop/version.h"
128#include "desktop/searchweb.h"
129
130/* NetSurf Amiga platform includes */
131#include "amiga/gui.h"
132#include "amiga/arexx.h"
133#include "amiga/bitmap.h"
134#include "amiga/clipboard.h"
135#include "amiga/cookies.h"
136#include "amiga/ctxmenu.h"
137#include "amiga/datatypes.h"
138#include "amiga/download.h"
139#include "amiga/drag.h"
140#include "amiga/file.h"
141#include "amiga/filetype.h"
142#include "amiga/font.h"
143#include "amiga/gui_options.h"
144#include "amiga/help.h"
145#include "amiga/history.h"
146#include "amiga/history_local.h"
147#include "amiga/hotlist.h"
148#include "amiga/icon.h"
149#include "amiga/launch.h"
150#include "amiga/libs.h"
151#include "amiga/memory.h"
152#include "amiga/menu.h"
153#include "amiga/misc.h"
154#include "amiga/nsoption.h"
155#include "amiga/pageinfo.h"
156#include "amiga/plotters.h"
157#include "amiga/plugin_hack.h"
158#include "amiga/print.h"
159#include "amiga/schedule.h"
160#include "amiga/search.h"
161#include "amiga/selectmenu.h"
162#include "amiga/theme.h"
163#include "amiga/utf8.h"
164#include "amiga/corewindow.h"
165
166#define AMINS_SCROLLERPEN NUMDRIPENS
167#define NSA_KBD_SCROLL_PX 10
168#define NSA_MAX_HOTLIST_BUTTON_LEN 20
169
170#define SCROLL_TOP INT_MIN
171#define SCROLL_PAGE_UP (INT_MIN + 1)
172#define SCROLL_PAGE_DOWN (INT_MAX - 1)
173#define SCROLL_BOTTOM (INT_MAX)
174
175/* Extra mouse button defines to match those in intuition/intuition.h */
176#define SIDEDOWN (IECODE_4TH_BUTTON)
177#define SIDEUP (IECODE_4TH_BUTTON | IECODE_UP_PREFIX)
178#define EXTRADOWN (IECODE_5TH_BUTTON)
179#define EXTRAUP (IECODE_5TH_BUTTON | IECODE_UP_PREFIX)
180
181/* Left OR Right Shift/Alt keys */
182#define NSA_QUAL_SHIFT (IEQUALIFIER_RSHIFT | IEQUALIFIER_LSHIFT)
183#define NSA_QUAL_ALT (IEQUALIFIER_RALT | IEQUALIFIER_LALT)
184
185#ifdef __amigaos4__
186#define NSA_STATUS_TEXT GA_Text
187#else
188#define NSA_STATUS_TEXT STRINGA_TextVal
189#endif
190
191#ifdef __amigaos4__
192#define BOOL_MISMATCH(a,b) ((a == FALSE) && (b != FALSE)) || ((a != FALSE) && (b == FALSE))
193#else
194#define BOOL_MISMATCH(a,b) (1)
195#endif
196
197extern struct gui_utf8_table *amiga_utf8_table;
198
199enum
200{
245
248 struct Window *win;
249 Object *restrict objects[GID_LAST];
250 struct gui_window *gw; /* currently-displayed gui_window */
253 struct List tab_list;
254 ULONG tabs;
255 ULONG next_tab;
256 struct Node *last_new_tab;
257 struct Hook scrollerhook;
262 ULONG oldh;
263 ULONG oldv;
264 int temp;
267 struct ami_menu_data *menu_data[AMI_MENU_AREXX_MAX + 1]; /* only for GadTools menus */
271 struct List *web_search_list;
272 Object *search_bm;
273 char *restrict svbuffer;
274 char *restrict status;
275 char *restrict wintitle;
276 char icontitle[24];
277 char *restrict helphints[GID_LAST];
279 struct timeval lastclick;
280 struct AppIcon *appicon; /* iconify appicon */
281 struct DiskObject *dobj; /* iconify appicon */
282 struct Hook favicon_hook;
283 struct Hook throbber_hook;
284 struct Hook browser_hook;
285 struct Hook *ctxmenu_hook;
286 Object *restrict history_ctxmenu[2];
289 struct IBox *ptr_lock;
290 struct AppWindow *appwin;
291 struct MinList *shared_pens;
293 struct Menu *imenu; /* Intuition menu */
294 bool closed; /* Window has been closed (via menu) */
295};
296
298{
300 int tab;
301 struct Node *tab_node;
302 int c_x; /* Caret X posn */
303 int c_y; /* Caret Y posn */
304 int c_w; /* Caret width */
305 int c_h; /* Caret height */
310 struct List dllist;
313 char *tabtitle;
315 struct MinList *deferred_rects;
317 struct ColumnInfo *logcolumns;
318 struct List loglist;
319};
320
322 struct List *sblist;
324 int items;
325};
326
327static struct MinList *window_list = NULL;
328static struct Screen *scrn = NULL;
329static struct MsgPort *sport = NULL;
330static struct gui_window *cur_gw = NULL;
331
332static bool ami_quit = false;
333
334static struct MsgPort *schedulermsgport = NULL;
335static struct MsgPort *appport;
336#ifdef __amigaos4__
337static Class *urlStringClass;
338#endif
339
340static BOOL locked_screen = FALSE;
341static int screen_signal = -1;
342static bool win_destroyed;
343static STRPTR nsscreentitle;
344static struct gui_globals *browserglob = NULL;
345
346static struct MsgPort *applibport = NULL;
347static uint32 ami_appid = 0;
348static ULONG applibsig = 0;
349static ULONG rxsig = 0;
350static struct Hook newprefs_hook;
351
352static STRPTR temp_homepage_url = NULL;
353static bool cli_force = false;
354
355#define USERS_DIR "PROGDIR:Users"
356static char *users_dir = NULL;
357static char *current_user_dir;
359
360static const __attribute__((used)) char *stack_cookie = "\0$STACK:196608\0";
361
362const char * const versvn;
363
364static void ami_switch_tab(struct gui_window_2 *gwin, bool redraw);
365static void ami_change_tab(struct gui_window_2 *gwin, int direction);
366static void ami_get_hscroll_pos(struct gui_window_2 *gwin, ULONG *xs);
367static void ami_get_vscroll_pos(struct gui_window_2 *gwin, ULONG *ys);
368static void ami_quit_netsurf_delayed(void);
369static Object *ami_gui_splash_open(void);
370static void ami_gui_splash_close(Object *win_obj);
371static bool ami_gui_map_filename(char **remapped, const char *restrict path,
372 const char *restrict file, const char *restrict map);
373static void ami_gui_window_update_box_deferred(struct gui_window *g, bool draw);
374static void ami_do_redraw(struct gui_window_2 *g);
375static void ami_schedule_redraw_remove(struct gui_window_2 *gwin);
376
377static bool gui_window_get_scroll(struct gui_window *g, int *restrict sx, int *restrict sy);
378static nserror gui_window_set_scroll(struct gui_window *g, const struct rect *rect);
379static void gui_window_remove_caret(struct gui_window *g);
380static void gui_window_place_caret(struct gui_window *g, int x, int y, int height, const struct rect *clip);
381
382HOOKF(uint32, ami_set_favicon_render_hook, APTR, space, struct gpRender *);
383HOOKF(uint32, ami_set_throbber_render_hook, APTR, space, struct gpRender *);
384HOOKF(uint32, ami_gui_browser_render_hook, APTR, space, struct gpRender *);
385
386/* accessors for default options - user option is updated if it is set as per default */
387#define nsoption_default_set_int(OPTION, VALUE) \
388 if (nsoptions_default[NSOPTION_##OPTION].value.i == nsoptions[NSOPTION_##OPTION].value.i) \
389 nsoptions[NSOPTION_##OPTION].value.i = VALUE; \
390 nsoptions_default[NSOPTION_##OPTION].value.i = VALUE
391
392/* Functions documented in gui.h */
393struct MsgPort *ami_gui_get_shared_msgport(void)
394{
395 assert(sport != NULL);
396 return sport;
397}
398
400{
401 return cur_gw;
402}
403
404struct Screen *ami_gui_get_screen(void)
405{
406 return scrn;
407}
408
409struct MinList *ami_gui_get_window_list(void)
410{
411 assert(window_list != NULL);
412 return window_list;
413}
414
415void ami_gui_beep(void)
416{
417 DisplayBeep(scrn);
418}
419
421{
422 assert(gw != NULL);
423 return gw->bw;
424}
425
427{
428 assert(gwin != NULL);
429 return ami_gui_get_browser_window(gwin->gw);
430}
431
432struct List *ami_gui_get_download_list(struct gui_window *gw)
433{
434 assert(gw != NULL);
435 return &gw->dllist;
436}
437
439{
440 assert(gw != NULL);
441 return gw->shared;
442}
443
445{
446 assert(gwin != NULL);
447 return gwin->gw;
448}
449
450const char *ami_gui_get_win_title(struct gui_window *gw)
451{
452 assert(gw != NULL);
453 assert(gw->shared != NULL);
454 return (const char *)gw->shared->wintitle;
455}
456
457const char *ami_gui_get_tab_title(struct gui_window *gw)
458{
459 assert(gw != NULL);
460 return (const char *)gw->tabtitle;
461}
462
463struct Node *ami_gui_get_tab_node(struct gui_window *gw)
464{
465 assert(gw != NULL);
466 return gw->tab_node;
467}
468
470{
471 assert(gwin != NULL);
472 return gwin->tabs;
473}
474
475struct List *ami_gui2_get_tab_list(struct gui_window_2 *gwin)
476{
477 assert(gwin != NULL);
478 return &gwin->tab_list;
479}
480
482{
483 assert(gw != NULL);
484 return gw->favicon;
485}
486
488{
489 assert(gw != NULL);
490 return gw->hw;
491}
492
494{
495 assert(gw != NULL);
496 gw->hw = hw;
497}
498
500{
501 /* This needs to be in gui_window_2 as it is shared amongst tabs (I think),
502 * it just happens that the find code only knows of the gui_window
503 */
504 assert(gw != NULL);
505 assert(gw->shared != NULL);
506 gw->shared->searchwin = fw;
507}
508
510{
511 assert(gw != NULL);
512 return gw->throbbing;
513}
514
515void ami_gui_set_throbbing(struct gui_window *gw, bool throbbing)
516{
517 assert(gw != NULL);
518 gw->throbbing = throbbing;
519}
520
522{
523 assert(gw != NULL);
524 assert(gw->shared != NULL);
525 return gw->shared->throbber_frame;
526}
527
529{
530 assert(gw != NULL);
531 assert(gw->shared != NULL);
532 gw->shared->throbber_frame = frame;
533}
534
535Object *ami_gui2_get_object(struct gui_window_2 *gwin, int object_type)
536{
537 ULONG obj = 0;
538
539 assert(gwin != NULL);
540
541 switch(object_type) {
542 case AMI_WIN_MAIN:
543 obj = OID_MAIN;
544 break;
545
546 case AMI_GAD_THROBBER:
547 obj = GID_THROBBER;
548 break;
549
550 case AMI_GAD_TABS:
551 obj = GID_TABS;
552 break;
553
554 case AMI_GAD_URL:
555 obj = GID_URL;
556 break;
557
558 case AMI_GAD_SEARCH:
559 obj = GID_SEARCHSTRING;
560 break;
561
562 default:
563 return NULL;
564 break;
565 }
566
567 return gwin->objects[obj];
568}
569
570
571struct Window *ami_gui2_get_window(struct gui_window_2 *gwin)
572{
573 assert(gwin != NULL);
574 return gwin->win;
575}
576
577struct Window *ami_gui_get_window(struct gui_window *gw)
578{
579 assert(gw != NULL);
580 return ami_gui2_get_window(gw->shared);
581}
582
583struct Menu *ami_gui_get_menu(struct gui_window *gw)
584{
585 assert(gw != NULL);
586 assert(gw->shared != NULL);
587 return gw->shared->imenu;
588}
589
590void ami_gui2_set_menu(struct gui_window_2 *gwin, struct Menu *menu)
591{
592 if(menu != NULL) {
593 gwin->imenu = menu;
594 } else {
596 }
597}
598
600{
601 assert(gwin != NULL);
602 return gwin->menu_data;
603}
604
606{
607 assert(gwin != NULL);
608 gwin->temp = temp;
609}
610
612{
613 assert(gwin != NULL);
614 return gwin->temp;
615}
616
617Object *ami_gui2_get_ctxmenu_history(struct gui_window_2 *gwin, ULONG direction)
618{
619 assert(gwin != NULL);
620 return gwin->history_ctxmenu[direction];
621}
622
623void ami_gui2_set_ctxmenu_history(struct gui_window_2 *gwin, ULONG direction, Object *ctx_hist)
624{
625 assert(gwin != NULL);
626 gwin->history_ctxmenu[direction] = ctx_hist;
627}
628
629void ami_gui2_set_closed(struct gui_window_2 *gwin, bool closed)
630{
631 assert(gwin != NULL);
632 gwin->closed = closed;
633}
634
635void ami_gui2_set_new_content(struct gui_window_2 *gwin, bool new_content)
636{
637 assert(gwin != NULL);
638 gwin->new_content = new_content;
639}
640
641/** undocumented, or internal, or documented elsewhere **/
642
643#ifdef __amigaos4__
644static void *ami_find_gwin_by_id(struct Window *win, uint32 type)
645{
646 struct nsObject *node, *nnode;
647 struct gui_window_2 *gwin;
648
650 {
651 node = (struct nsObject *)GetHead((struct List *)window_list);
652
653 do
654 {
655 nnode=(struct nsObject *)GetSucc((struct Node *)node);
656
657 if(node->Type == type)
658 {
659 gwin = node->objstruct;
660 if(win == ami_gui2_get_window(gwin)) return gwin;
661 }
662 } while((node = nnode));
663 }
664 return NULL;
665}
666
668{
669 struct Layer *layer;
670 struct Screen *scrn = ami_gui_get_screen();
671
672 LockLayerInfo(&scrn->LayerInfo);
673
674 layer = WhichLayer(&scrn->LayerInfo, scrn->MouseX, scrn->MouseY);
675
676 UnlockLayerInfo(&scrn->LayerInfo);
677
678 if(layer) return ami_find_gwin_by_id(layer->Window, type);
679 else return NULL;
680}
681#else
682/**\todo check if OS4 version of this function will build on OS3, even if it isn't called */
684{
685 return NULL;
686}
687#endif
688
689void ami_set_pointer(struct gui_window_2 *gwin, gui_pointer_shape shape, bool update)
690{
691 if(gwin->mouse_pointer == shape) return;
693 if(update == true) gwin->mouse_pointer = shape;
694}
695
696/* reset the mouse pointer back to what NetSurf last set it as */
698{
700}
701
702
703STRPTR ami_locale_langs(int *codeset)
704{
705 struct Locale *locale;
706 STRPTR acceptlangs = NULL;
707 char *remapped = NULL;
708
709 if((locale = OpenLocale(NULL)))
710 {
711 if(codeset != NULL) *codeset = locale->loc_CodeSet;
712
713 for(int i = 0; i < 10; i++)
714 {
715 if(locale->loc_PrefLanguages[i])
716 {
717 if(ami_gui_map_filename(&remapped, "PROGDIR:Resources",
718 locale->loc_PrefLanguages[i], "LangNames"))
719 {
720 if(acceptlangs)
721 {
722 STRPTR acceptlangs2 = acceptlangs;
723 acceptlangs = ASPrintf("%s, %s",acceptlangs2, remapped);
724 FreeVec(acceptlangs2);
725 acceptlangs2 = NULL;
726 }
727 else
728 {
729 acceptlangs = ASPrintf("%s", remapped);
730 }
731 }
732 if(remapped != NULL) free(remapped);
733 }
734 else
735 {
736 continue;
737 }
738 }
739 CloseLocale(locale);
740 }
741 return acceptlangs;
742}
743
744static bool ami_gui_map_filename(char **remapped, const char *restrict path,
745 const char *restrict file, const char *restrict map)
746{
747 BPTR fh = 0;
748 char *mapfile = NULL;
749 size_t mapfile_size = 0;
750 char buffer[1024];
751 char *restrict realfname;
752 bool found = false;
753
754 netsurf_mkpath(&mapfile, &mapfile_size, 2, path, map);
755
756 if(mapfile == NULL) return false;
757
758 fh = FOpen(mapfile, MODE_OLDFILE, 0);
759 if(fh)
760 {
761 while(FGets(fh, buffer, 1024) != 0)
762 {
763 if((buffer[0] == '#') ||
764 (buffer[0] == '\n') ||
765 (buffer[0] == '\0')) continue;
766
767 realfname = strchr(buffer, ':');
768 if(realfname)
769 {
770 if(strncmp(buffer, file, strlen(file)) == 0)
771 {
772 if(realfname[strlen(realfname)-1] == '\n')
773 realfname[strlen(realfname)-1] = '\0';
774 *remapped = strdup(realfname + 1);
775 found = true;
776 break;
777 }
778 }
779 }
780 FClose(fh);
781 }
782
783 if(found == false) *remapped = strdup(file);
784 else NSLOG(netsurf, INFO,
785 "Remapped %s to %s in path %s using %s", file,
786 *remapped, path, map);
787
788 free(mapfile);
789
790 return found;
791}
792
793static bool ami_gui_check_resource(char *fullpath, const char *file)
794{
795 bool found = false;
796 char *remapped;
797 BPTR lock = 0;
798 size_t fullpath_len = 1024;
799
800 ami_gui_map_filename(&remapped, fullpath, file, "Resource.map");
801 netsurf_mkpath(&fullpath, &fullpath_len, 2, fullpath, remapped);
802
803 lock = Lock(fullpath, ACCESS_READ);
804 if(lock) {
805 UnLock(lock);
806 found = true;
807 }
808
809 if(found) NSLOG(netsurf, INFO, "Found %s", fullpath);
810 free(remapped);
811
812 return found;
813}
814
815bool ami_locate_resource(char *fullpath, const char *file)
816{
817 struct Locale *locale;
818 int i;
819 bool found = false;
820 char *remapped = NULL;
821 size_t fullpath_len = 1024;
822
823 /* Check NetSurf user data area first */
824
825 if(current_user_dir != NULL) {
826 strcpy(fullpath, current_user_dir);
827 found = ami_gui_check_resource(fullpath, file);
828 if(found) return true;
829 }
830
831 /* Check current theme directory */
832 if(nsoption_charp(theme)) {
833 strcpy(fullpath, nsoption_charp(theme));
834 found = ami_gui_check_resource(fullpath, file);
835 if(found) return true;
836 }
837
838 /* If not found, start on the user's preferred languages */
839
840 locale = OpenLocale(NULL);
841
842 for(i=0;i<10;i++) {
843 strcpy(fullpath, "PROGDIR:Resources/");
844
845 if(locale->loc_PrefLanguages[i]) {
846 if(ami_gui_map_filename(&remapped, "PROGDIR:Resources",
847 locale->loc_PrefLanguages[i], "LangNames") == true) {
848 netsurf_mkpath(&fullpath, &fullpath_len, 2, fullpath, remapped);
849 found = ami_gui_check_resource(fullpath, file);
850 free(remapped);
851 }
852 } else {
853 continue;
854 }
855
856 if(found) break;
857 }
858
859 if(!found) {
860 /* If not found yet, check in PROGDIR:Resources/en,
861 * might not be in user's preferred languages */
862
863 strcpy(fullpath, "PROGDIR:Resources/en/");
864 found = ami_gui_check_resource(fullpath, file);
865 }
866
867 CloseLocale(locale);
868
869 if(!found) {
870 /* Lastly check directly in PROGDIR:Resources */
871
872 strcpy(fullpath, "PROGDIR:Resources/");
873 found = ami_gui_check_resource(fullpath, file);
874 }
875
876 return found;
877}
878
879static void ami_gui_resources_free(void)
880{
883
887}
888
889static bool ami_gui_resources_open(void)
890{
891#ifdef __amigaos4__
892 urlStringClass = MakeStringClass();
893#endif
894
896 ASO_NoTrack, FALSE,
897 TAG_DONE))) return false;
898
900 ASO_NoTrack, FALSE,
901 TAG_DONE))) return false;
902
904 ASO_NoTrack, FALSE,
905 TAG_DONE))) return false;
906
908 ami_misc_fatal_error("Failed to initialise scheduler");
909 return false;
910 }
911
913
914 return true;
915}
916
917static UWORD ami_system_colour_scrollbar_fgpen(struct DrawInfo *drinfo)
918{
919 LONG scrollerfillpen = FALSE;
920#ifdef __amigaos4__
921 GetGUIAttrs(NULL, drinfo, GUIA_PropKnobColor, &scrollerfillpen, TAG_DONE);
922
923 if(scrollerfillpen) return FILLPEN;
924 else return FOREGROUNDPEN;
925#else
926 return FILLPEN;
927#endif
928
929}
930
931#ifdef __amigaos4__
932
933/**
934 * convert an amiga pen to a netsurf colour
935 */
936static colour
937nscolour_from_pen(struct Screen *screen, UWORD pen, colour sel_colour)
938{
939 ULONG colr[3];
940 struct DrawInfo *drinfo;
941
942 drinfo = GetScreenDrawInfo(screen);
943
944 if (drinfo != NULL) {
945 if (pen == AMINS_SCROLLERPEN) {
947 }
948
949 /* Get the colour of the pen being used for "pen" */
950 GetRGB32(screen->ViewPort.ColorMap,
951 drinfo->dri_Pens[pen],
952 1,
953 (ULONG *)&colr);
954
955 /* convert it to a color */
956 sel_colour = ((colr[0] & 0xff000000) >> 24) |
957 ((colr[1] & 0xff000000) >> 16) |
958 ((colr[2] & 0xff000000) >> 8);
959
960 FreeScreenDrawInfo(screen, drinfo);
961 }
962 return sel_colour;
963}
964
965
966/**
967 * set system colour options from amiga pen
968 */
969static nserror system_colours_from_pen(struct Screen *screen)
970{
971 #define MAP_SIZE (19)
972 int mapidx;
973 colour sel_colour;
974 struct pcm {
975 enum nsoption_e option;
976 UWORD pen;
977 colour def_colour;
978 };
979 struct pcm pen_colour_map[MAP_SIZE] = {
980 {NSOPTION_sys_colour_AccentColor, FILLPEN, 0x00000000},
981 {NSOPTION_sys_colour_AccentColorText, TEXTPEN, 0x00000000},
982 {NSOPTION_sys_colour_ActiveText, TEXTPEN, 0x00000000},
983 {NSOPTION_sys_colour_ButtonBorder, FILLPEN, 0x00000000},
984 {NSOPTION_sys_colour_ButtonFace, FOREGROUNDPEN, 0x00aaaaaa},
985 {NSOPTION_sys_colour_ButtonText, TEXTPEN, 0x00000000},
986 {NSOPTION_sys_colour_Canvas, BACKGROUNDPEN, 0x00aaaaaa},
987 {NSOPTION_sys_colour_CanvasText, TEXTPEN, 0x00000000},
988 {NSOPTION_sys_colour_Field, BACKGROUNDPEN, 0x00aaaaaa},
989 {NSOPTION_sys_colour_FieldText, TEXTPEN, 0x00000000},
990 {NSOPTION_sys_colour_GrayText, DISABLEDTEXTPEN, 0x00777777},
991 {NSOPTION_sys_colour_Highlight, SELECTPEN, 0x00ee0000},
992 {NSOPTION_sys_colour_HighlightText, SELECTTEXTPEN, 0x00000000},
993 {NSOPTION_sys_colour_LinkText, TEXTPEN, 0x00000000},
994 {NSOPTION_sys_colour_Mark, FILLPEN, 0x00000000},
995 {NSOPTION_sys_colour_MarkText, TEXTPEN, 0x00000000},
996 {NSOPTION_sys_colour_SelectedItem, FILLPEN, 0x00000000},
997 {NSOPTION_sys_colour_SelectedItemText, TEXTPEN, 0x00000000},
998 {NSOPTION_sys_colour_VisitedText, TEXTPEN, 0x00000000},
999 };
1000 struct pcm *entry;
1001
1002 for (mapidx=0; mapidx < MAP_SIZE; mapidx++) {
1003 entry = &pen_colour_map[mapidx];
1004 sel_colour = nscolour_from_pen(screen, entry->pen, entry->def_colour);
1005
1006 if (nsoptions_default[entry->option].value.c == nsoptions[entry->option].value.c) {
1007 nsoptions[entry->option].value.c = sel_colour;
1008 }
1009 nsoptions_default[entry->option].value.c = sel_colour;
1010 }
1011
1012 return NSERROR_OK;
1013}
1014
1015#endif /* __amigaos4__ */
1016
1017/* exported interface documented in amiga/gui.h */
1019{
1020 if(nsscreentitle == NULL) {
1021 nsscreentitle = ASPrintf("NetSurf %s", netsurf_version);
1022 /* If this fails it will be NULL, which means we'll get the screen's
1023 * default titlebar text instead - so no need to check for error. */
1024 }
1025
1026 return nsscreentitle;
1027}
1028
1029static void ami_set_screen_defaults(struct Screen *screen)
1030{
1031 nsoption_default_set_int(redraw_tile_size_x, screen->Width);
1032 nsoption_default_set_int(redraw_tile_size_y, screen->Height);
1033
1034#ifdef __amigaos4__
1035 /* set system colours for amiga ui */
1036 system_colours_from_pen(screen);
1037#endif
1038}
1039
1040
1041/**
1042 * Set option defaults for amiga frontend
1043 *
1044 * @param defaults The option table to update.
1045 * @return error status.
1046 */
1048{
1049 STRPTR tempacceptlangs;
1050 char temp[1024];
1051 int codeset = 0;
1052
1053 /* The following line disables the popupmenu.class select menu.
1054 ** It's not recommended to use it!
1055 */
1056 nsoption_set_bool(core_select_menu, true);
1057
1058 /* ClickTab < 53 doesn't work with the auto show/hide tab-bar (for reasons forgotten) */
1059 if(ClickTabBase->lib_Version < 53)
1060 nsoption_set_bool(tab_always_show, true);
1061
1062 if((!nsoption_charp(accept_language)) ||
1063 (nsoption_charp(accept_language)[0] == '\0') ||
1064 (nsoption_bool(accept_lang_locale) == true))
1065 {
1066 if((tempacceptlangs = ami_locale_langs(&codeset)))
1067 {
1068 nsoption_set_charp(accept_language,
1069 (char *)strdup(tempacceptlangs));
1070 FreeVec(tempacceptlangs);
1071 }
1072 }
1073
1074 /* Some OS-specific overrides */
1075#ifdef __amigaos4__
1076 if(!LIB_IS_AT_LEAST((struct Library *)SysBase, 53, 89)) {
1077 /* Disable ExtMem usage pre-OS4.1FEU1 */
1078 nsoption_set_bool(use_extmem, false);
1079 }
1080
1081 if(codeset == 0) codeset = 4; /* ISO-8859-1 */
1082 const char *encname = (const char *)ObtainCharsetInfo(DFCS_NUMBER, codeset,
1083 DFCS_MIMENAME);
1084 nsoption_set_charp(local_charset, strdup(encname));
1085 nsoption_set_int(local_codeset, codeset);
1086#else
1087 nsoption_set_bool(download_notify, false);
1088 nsoption_set_bool(font_antialiasing, false);
1089 nsoption_set_bool(truecolour_mouse_pointers, false);
1090 nsoption_set_bool(use_openurl_lib, true);
1091 nsoption_set_bool(bitmap_fonts, true);
1092#endif
1093
1094 sprintf(temp, "%s/Cookies", current_user_dir);
1095 nsoption_setnull_charp(cookie_file,
1096 (char *)strdup(temp));
1097
1098 sprintf(temp, "%s/Hotlist", current_user_dir);
1099 nsoption_setnull_charp(hotlist_file,
1100 (char *)strdup(temp));
1101
1102 sprintf(temp, "%s/URLdb", current_user_dir);
1103 nsoption_setnull_charp(url_file,
1104 (char *)strdup(temp));
1105
1106 sprintf(temp, "%s/FontGlyphCache", current_user_dir);
1107 nsoption_setnull_charp(font_unicode_file,
1108 (char *)strdup(temp));
1109
1110 nsoption_setnull_charp(ca_bundle,
1111 (char *)strdup("PROGDIR:Resources/ca-bundle"));
1112
1113 /* font defaults */
1114#ifdef __amigaos4__
1115 nsoption_setnull_charp(font_sans, (char *)strdup("DejaVu Sans"));
1116 nsoption_setnull_charp(font_serif, (char *)strdup("DejaVu Serif"));
1117 nsoption_setnull_charp(font_mono, (char *)strdup("DejaVu Sans Mono"));
1118 nsoption_setnull_charp(font_cursive, (char *)strdup("DejaVu Sans"));
1119 nsoption_setnull_charp(font_fantasy, (char *)strdup("DejaVu Serif"));
1120#else
1121 nsoption_setnull_charp(font_sans, (char *)strdup("helvetica"));
1122 nsoption_setnull_charp(font_serif, (char *)strdup("times"));
1123 nsoption_setnull_charp(font_mono, (char *)strdup("topaz"));
1124 nsoption_setnull_charp(font_cursive, (char *)strdup("garnet"));
1125 nsoption_setnull_charp(font_fantasy, (char *)strdup("emerald"));
1126/* Default CG fonts for OS3 - these work with use_diskfont both on and off,
1127 however they are slow in both cases. The bitmap fonts don't work when
1128 use_diskfont is off. The bitmap fonts performance on 68k is far superior,
1129 so default to those for now whilst testing.
1130 \todo maybe add some buttons to the prefs GUI to toggle?
1131 nsoption_setnull_charp(font_sans, (char *)strdup("CGTriumvirate"));
1132 nsoption_setnull_charp(font_serif, (char *)strdup("CGTimes"));
1133 nsoption_setnull_charp(font_mono, (char *)strdup("LetterGothic"));
1134 nsoption_setnull_charp(font_cursive, (char *)strdup("CGTriumvirate"));
1135 nsoption_setnull_charp(font_fantasy, (char *)strdup("CGTimes"));
1136*/
1137#endif
1138
1139 if (nsoption_charp(font_unicode) == NULL)
1140 {
1141 BPTR lock = 0;
1142 /* Search for some likely candidates */
1143
1144 if((lock = Lock("FONTS:Code2000.otag", ACCESS_READ)))
1145 {
1146 UnLock(lock);
1147 nsoption_set_charp(font_unicode,
1148 (char *)strdup("Code2000"));
1149 }
1150 else if((lock = Lock("FONTS:Bitstream Cyberbit.otag", ACCESS_READ)))
1151 {
1152 UnLock(lock);
1153 nsoption_set_charp(font_unicode,
1154 (char *)strdup("Bitstream Cyberbit"));
1155 }
1156 }
1157
1158 if (nsoption_charp(font_surrogate) == NULL) {
1159 BPTR lock = 0;
1160 /* Search for some likely candidates -
1161 * Ideally we should pick a font during the scan process which announces it
1162 * contains UCR_SURROGATES, but nothing appears to have the tag.
1163 */
1164 if((lock = Lock("FONTS:Symbola.otag", ACCESS_READ))) {
1165 UnLock(lock);
1166 nsoption_set_charp(font_surrogate,
1167 (char *)strdup("Symbola"));
1168 }
1169 }
1170
1171 return NSERROR_OK;
1172}
1173
1174static void ami_amiupdate(void)
1175{
1176 /* Create AppPath location for AmiUpdate use */
1177
1178 BPTR lock = 0;
1179
1180 if(((lock = Lock("ENVARC:AppPaths",SHARED_LOCK)) == 0))
1181 {
1182 lock = CreateDir("ENVARC:AppPaths");
1183 }
1184
1185 UnLock(lock);
1186
1187 if((lock = Lock("PROGDIR:", ACCESS_READ)))
1188 {
1189 char filename[1024];
1190 BPTR amiupdatefh;
1191
1192 DevNameFromLock(lock, (STRPTR)&filename, 1024L, DN_FULLPATH);
1193
1194 if((amiupdatefh = FOpen("ENVARC:AppPaths/NetSurf", MODE_NEWFILE, 0))) {
1195 FPuts(amiupdatefh, (CONST_STRPTR)&filename);
1196 FClose(amiupdatefh);
1197 }
1198
1199 UnLock(lock);
1200 }
1201}
1202
1203static nsurl *gui_get_resource_url(const char *path)
1204{
1205 char buf[1024];
1206 nsurl *url = NULL;
1207
1208 if(ami_locate_resource(buf, path) == false)
1209 return NULL;
1210
1211 netsurf_path_to_nsurl(buf, &url);
1212
1213 return url;
1214}
1215
1216HOOKF(void, ami_gui_newprefs_hook, APTR, window, APTR)
1217{
1219}
1220
1221static void ami_openscreen(void)
1222{
1223 ULONG id = 0;
1224 ULONG compositing;
1225
1226 if (nsoption_int(screen_compositing) == -1)
1227 compositing = ~0UL;
1228 else compositing = nsoption_int(screen_compositing);
1229
1230 if (nsoption_charp(pubscreen_name) == NULL)
1231 {
1232 if((nsoption_charp(screen_modeid)) &&
1233 (strncmp(nsoption_charp(screen_modeid), "0x", 2) == 0))
1234 {
1235 id = strtoul(nsoption_charp(screen_modeid), NULL, 0);
1236 }
1237 else
1238 {
1239 struct ScreenModeRequester *screenmodereq = NULL;
1240
1241 if((screenmodereq = AllocAslRequest(ASL_ScreenModeRequest,NULL))) {
1242 if(AslRequestTags(screenmodereq,
1243 ASLSM_MinDepth, 0,
1244 ASLSM_MaxDepth, 32,
1245 TAG_DONE))
1246 {
1247 char *modeid = malloc(20);
1248 id = screenmodereq->sm_DisplayID;
1249 sprintf(modeid, "0x%lx", id);
1250 nsoption_set_charp(screen_modeid, modeid);
1252 }
1253 FreeAslRequest(screenmodereq);
1254 }
1255 }
1256
1257 if(screen_signal == -1) screen_signal = AllocSignal(-1);
1258 NSLOG(netsurf, INFO, "Screen signal %d", screen_signal);
1259 scrn = OpenScreenTags(NULL,
1260 /**\todo specify screen depth */
1261 SA_DisplayID, id,
1262 SA_Title, ami_gui_get_screen_title(),
1263 SA_Type, PUBLICSCREEN,
1264 SA_PubName, "NetSurf",
1265 SA_PubSig, screen_signal,
1266 SA_PubTask, FindTask(0),
1267 SA_LikeWorkbench, TRUE,
1268 SA_Compositing, compositing,
1269 TAG_DONE);
1270
1271 if(scrn)
1272 {
1273 PubScreenStatus(scrn,0);
1274 }
1275 else
1276 {
1277 FreeSignal(screen_signal);
1278 screen_signal = -1;
1279
1280 if((scrn = LockPubScreen("NetSurf")))
1281 {
1282 locked_screen = TRUE;
1283 }
1284 else
1285 {
1286 nsoption_set_charp(pubscreen_name,
1287 strdup("Workbench"));
1288 }
1289 }
1290 }
1291
1292 if (nsoption_charp(pubscreen_name) != NULL)
1293 {
1294 scrn = LockPubScreen(nsoption_charp(pubscreen_name));
1295
1296 if(scrn == NULL)
1297 {
1298 scrn = LockPubScreen("Workbench");
1299 }
1300 locked_screen = TRUE;
1301 }
1302
1306}
1307
1308static void ami_openscreenfirst(void)
1309{
1311 if(browserglob == NULL) browserglob = ami_plot_ra_alloc(0, 0, false, false);
1313}
1314
1315static struct RDArgs *ami_gui_commandline(int *restrict argc, char ** argv,
1316 int *restrict nargc, char ** nargv)
1317{
1318 struct RDArgs *args;
1319 CONST_STRPTR template = "-v/S,NSOPTS/M,URL/K,USERSDIR/K,FORCE/S";
1320 long rarray[] = {0,0,0,0,0};
1321 enum
1322 {
1323 A_VERBOSE, /* ignored */
1324 A_NSOPTS, /* ignored */
1325 A_URL,
1326 A_USERSDIR,
1327 A_FORCE
1328 };
1329
1330 if(*argc == 0) return NULL; // argc==0 is started from wb
1331
1332 if((args = ReadArgs(template, rarray, NULL))) {
1333 if(rarray[A_URL]) {
1334 NSLOG(netsurf, INFO,
1335 "URL %s specified on command line",
1336 (char *)rarray[A_URL]);
1337 temp_homepage_url = strdup((char *)rarray[A_URL]); /**\todo allow IDNs */
1338 }
1339
1340 if(rarray[A_USERSDIR]) {
1341 NSLOG(netsurf, INFO,
1342 "USERSDIR %s specified on command line",
1343 (char *)rarray[A_USERSDIR]);
1344 users_dir = ASPrintf("%s", rarray[A_USERSDIR]);
1345 }
1346
1347 if(rarray[A_FORCE]) {
1348 NSLOG(netsurf, INFO,
1349 "FORCE specified on command line");
1350 cli_force = true;
1351 }
1352
1353 if(rarray[A_NSOPTS]) {
1354 /* The NSOPTS/M parameter specified in the ReadArgs template is
1355 * special. The /M means it collects all arguments that can't
1356 * be assigned to any other parameter, and stores them in an
1357 * array. We collect these and pass them as a fake argc/argv
1358 * to nsoption_commandline().
1359 * This trickery is necessary because if ReadArgs() is called
1360 * first, nsoption_commandline() can no longer parse (fetch?)
1361 * the arguments. If nsoption_commandline() is called first,
1362 * then ReadArgs cannot fetch the arguments.
1363 *\todo this was totally broken so to stop startup crashing
1364 * has been temporarily removed (core cli not called when func
1365 * returns NULL).
1366 */
1367 }
1368 } else {
1369 NSLOG(netsurf, INFO, "ReadArgs failed to parse command line");
1370 }
1371
1372 FreeArgs(args);
1373 return NULL;
1374}
1375
1376static char *ami_gui_read_tooltypes(struct WBArg *wbarg)
1377{
1378 struct DiskObject *dobj;
1379 STRPTR *toolarray;
1380 char *s;
1381 char *current_user = NULL;
1382
1383 if((*wbarg->wa_Name) && (dobj = GetDiskObject(wbarg->wa_Name))) {
1384 toolarray = (STRPTR *)dobj->do_ToolTypes;
1385
1386 if((s = (char *)FindToolType(toolarray,"USERSDIR"))) users_dir = ASPrintf("%s", s);
1387 if((s = (char *)FindToolType(toolarray,"USER"))) current_user = ASPrintf("%s", s);
1388
1389 FreeDiskObject(dobj);
1390 }
1391 return current_user;
1392}
1393
1394static STRPTR ami_gui_read_all_tooltypes(int argc, char **argv)
1395{
1396 struct WBStartup *WBenchMsg;
1397 struct WBArg *wbarg;
1398 char i = 0;
1399 char *current_user = NULL;
1400 char *cur_user = NULL;
1401
1402 if(argc == 0) { /* Started from WB */
1403 WBenchMsg = (struct WBStartup *)argv;
1404 for(i = 0, wbarg = WBenchMsg->sm_ArgList; i < WBenchMsg->sm_NumArgs; i++,wbarg++) {
1405 LONG olddir =-1;
1406 if((wbarg->wa_Lock) && (*wbarg->wa_Name))
1407 olddir = SetCurrentDir(wbarg->wa_Lock);
1408
1409 cur_user = ami_gui_read_tooltypes(wbarg);
1410 if(cur_user != NULL) {
1411 if(current_user != NULL) FreeVec(current_user);
1412 current_user = cur_user;
1413 }
1414
1415 if(olddir !=-1) SetCurrentDir(olddir);
1416 }
1417 }
1418
1419 return current_user;
1420}
1421
1422static void gui_init2(int argc, char** argv)
1423{
1424 struct Screen *screen;
1425 BOOL notalreadyrunning;
1426 nsurl *url;
1427 nserror error;
1428 struct browser_window *bw = NULL;
1429
1430 notalreadyrunning = ami_arexx_init(&rxsig);
1431
1432 /* ...and this ensures the treeview at least gets the WB colour palette to work with */
1433 if(scrn == NULL) {
1434 if((screen = LockPubScreen("Workbench"))) {
1436 UnlockPubScreen(NULL, screen);
1437 }
1438 } else {
1440 }
1441 /**/
1442
1443 hotlist_init(nsoption_charp(hotlist_file),
1444 nsoption_charp(hotlist_file));
1445 search_web_select_provider(nsoption_charp(search_web_provider));
1446
1447 if (notalreadyrunning &&
1448 (nsoption_bool(startup_no_window) == false))
1450
1451 if(cli_force == true) {
1452 notalreadyrunning = TRUE;
1453 }
1454
1455 if(temp_homepage_url && notalreadyrunning) {
1456 error = nsurl_create(temp_homepage_url, &url);
1457 if (error == NSERROR_OK) {
1459 url,
1460 NULL,
1461 NULL,
1462 &bw);
1463 nsurl_unref(url);
1464 }
1465 if (error != NSERROR_OK) {
1467 }
1468 free(temp_homepage_url);
1469 temp_homepage_url = NULL;
1470 }
1471
1472 if(argc == 0) { // WB
1473 struct WBStartup *WBenchMsg = (struct WBStartup *)argv;
1474 struct WBArg *wbarg;
1475 int first=0,i=0;
1476 char fullpath[1024];
1477
1478 for(i=0,wbarg=WBenchMsg->sm_ArgList;i<WBenchMsg->sm_NumArgs;i++,wbarg++)
1479 {
1480 if(i==0) continue;
1481 if((wbarg->wa_Lock)&&(*wbarg->wa_Name))
1482 {
1483 DevNameFromLock(wbarg->wa_Lock,fullpath,1024,DN_FULLPATH);
1484 AddPart(fullpath,wbarg->wa_Name,1024);
1485
1486 if(!temp_homepage_url) {
1487 nsurl *temp_url;
1488 if (netsurf_path_to_nsurl(fullpath, &temp_url) == NSERROR_OK) {
1489 temp_homepage_url = strdup(nsurl_access(temp_url));
1490 nsurl_unref(temp_url);
1491 }
1492 }
1493
1494 if(notalreadyrunning)
1495 {
1496 error = nsurl_create(temp_homepage_url, &url);
1497
1498 if (error == NSERROR_OK) {
1499 if(!first)
1500 {
1502 url,
1503 NULL,
1504 NULL,
1505 &bw);
1506
1507 first=1;
1508 }
1509 else
1510 {
1512 url,
1513 NULL,
1514 bw,
1515 &bw);
1516
1517 }
1518 nsurl_unref(url);
1519
1520 }
1521 if (error != NSERROR_OK) {
1523 }
1524 free(temp_homepage_url);
1525 temp_homepage_url = NULL;
1526 }
1527 }
1528 /* this should be where we read tooltypes, but it's too late for that now */
1529 }
1530 }
1531
1532 nsoption_setnull_charp(homepage_url, (char *)strdup(NETSURF_HOMEPAGE));
1533
1534 if(!notalreadyrunning)
1535 {
1536 STRPTR sendcmd = NULL;
1537 char newtab[11] = "\0";
1538
1539 if(nsoption_bool(tab_new_session) == true) {
1540 strcpy(newtab, "TAB ACTIVE");
1541 }
1542
1543 if(temp_homepage_url) {
1544 sendcmd = ASPrintf("OPEN \"%s\" NEW%s", temp_homepage_url, newtab);
1545 free(temp_homepage_url);
1546 temp_homepage_url = NULL;
1547 } else {
1548 sendcmd = ASPrintf("OPEN \"%s\" NEW%s", nsoption_charp(homepage_url), newtab);
1549 }
1550 ami_arexx_self(sendcmd);
1551 FreeVec(sendcmd);
1552
1553 /* Bring the screen to the front. Intuition may have already done this, but it doesn't hurt. */
1554 ami_arexx_self("TOFRONT");
1555
1556 ami_quit=true;
1557 return;
1558 }
1559#ifdef __amigaos4__
1560 if(IApplication)
1561 {
1562 if(argc == 0)
1563 {
1564 ULONG noicon = TAG_IGNORE;
1565
1566 if (nsoption_bool(hide_docky_icon))
1567 noicon = REGAPP_NoIcon;
1568
1569 ami_appid = RegisterApplication(messages_get("NetSurf"),
1570 REGAPP_URLIdentifier, "netsurf-browser.org",
1571 REGAPP_WBStartup, (struct WBStartup *)argv,
1572 noicon, TRUE,
1573 REGAPP_HasPrefsWindow, TRUE,
1574 REGAPP_CanCreateNewDocs, TRUE,
1575 REGAPP_UniqueApplication, TRUE,
1576 REGAPP_Description, messages_get("NetSurfDesc"),
1577 TAG_DONE);
1578 }
1579 else
1580 {
1581/* TODO: Specify icon when run from Shell */
1582 ami_appid = RegisterApplication(messages_get("NetSurf"),
1583 REGAPP_URLIdentifier, "netsurf-browser.org",
1584 REGAPP_FileName, argv[0],
1585 REGAPP_NoIcon, TRUE,
1586 REGAPP_HasPrefsWindow, TRUE,
1587 REGAPP_CanCreateNewDocs, TRUE,
1588 REGAPP_UniqueApplication, TRUE,
1589 REGAPP_Description, messages_get("NetSurfDesc"),
1590 TAG_DONE);
1591 }
1592
1593 GetApplicationAttrs(ami_appid, APPATTR_Port, (ULONG)&applibport, TAG_DONE);
1594 if(applibport) applibsig = (1L << applibport->mp_SigBit);
1595 }
1596#endif
1597 if(!bw && (nsoption_bool(startup_no_window) == false)) {
1598 error = nsurl_create(nsoption_charp(homepage_url), &url);
1599 if (error == NSERROR_OK) {
1601 url,
1602 NULL,
1603 NULL,
1604 NULL);
1605 nsurl_unref(url);
1606 }
1607 if (error != NSERROR_OK) {
1609 }
1610 }
1611}
1612
1613static void ami_update_buttons(struct gui_window_2 *gwin)
1614{
1615 long back=FALSE, forward=FALSE, tabclose=FALSE, stop=FALSE, reload=FALSE;
1616 long s_back, s_forward, s_tabclose, s_stop, s_reload;
1617
1619 back=TRUE;
1620
1622 forward=TRUE;
1623
1625 stop=TRUE;
1626
1628 reload=TRUE;
1629
1630 if(nsoption_bool(kiosk_mode) == false) {
1631 if(gwin->tabs <= 1) {
1632 tabclose=TRUE;
1633 ami_gui_menu_set_disabled(gwin->win, gwin->imenu, M_CLOSETAB, true);
1634 } else {
1635 ami_gui_menu_set_disabled(gwin->win, gwin->imenu, M_CLOSETAB, false);
1636 }
1637 }
1638
1639 GetAttr(GA_Disabled, gwin->objects[GID_BACK], (uint32 *)&s_back);
1640 GetAttr(GA_Disabled, gwin->objects[GID_FORWARD], (uint32 *)&s_forward);
1641 GetAttr(GA_Disabled, gwin->objects[GID_RELOAD], (uint32 *)&s_reload);
1642 GetAttr(GA_Disabled, gwin->objects[GID_STOP], (uint32 *)&s_stop);
1643
1644 if(BOOL_MISMATCH(s_back, back))
1645 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_BACK],
1646 gwin->win, NULL, GA_Disabled, back, TAG_DONE);
1647
1648 if(BOOL_MISMATCH(s_forward, forward))
1649 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_FORWARD],
1650 gwin->win, NULL, GA_Disabled, forward, TAG_DONE);
1651
1652 if(BOOL_MISMATCH(s_reload, reload))
1653 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_RELOAD],
1654 gwin->win, NULL, GA_Disabled, reload, TAG_DONE);
1655
1656 if(BOOL_MISMATCH(s_stop, stop))
1657 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_STOP],
1658 gwin->win, NULL, GA_Disabled, stop, TAG_DONE);
1659
1660 if(ClickTabBase->lib_Version < 53) {
1661 if(gwin->tabs <= 1) tabclose = TRUE;
1662
1663 GetAttr(GA_Disabled, gwin->objects[GID_CLOSETAB], (uint32 *)&s_tabclose);
1664
1665 if(BOOL_MISMATCH(s_tabclose, tabclose))
1666 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_CLOSETAB],
1667 gwin->win, NULL, GA_Disabled, tabclose, TAG_DONE);
1668 }
1669
1670 /* Update the back/forward buttons history context menu */
1673}
1674
1675void ami_gui_history(struct gui_window_2 *gwin, bool back)
1676{
1677 if(back == true)
1678 {
1680 browser_window_history_back(gwin->gw->bw, false);
1681 }
1682 else
1683 {
1685 browser_window_history_forward(gwin->gw->bw, false);
1686 }
1687
1688 ami_update_buttons(gwin);
1689}
1690
1691int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie)
1692{
1693 int nskey = 0, chars;
1694 char buffer[20];
1695 char *utf8 = NULL;
1696
1697 if(keycode >= IECODE_UP_PREFIX) return 0;
1698
1699 switch(keycode)
1700 {
1701 case RAWKEY_CRSRUP:
1702 if(ie->ie_Qualifier & NSA_QUAL_SHIFT) {
1703 nskey = NS_KEY_PAGE_UP;
1704 } else if(ie->ie_Qualifier & NSA_QUAL_ALT) {
1705 nskey = NS_KEY_TEXT_START;
1706 }
1707 else nskey = NS_KEY_UP;
1708 break;
1709 case RAWKEY_CRSRDOWN:
1710 if(ie->ie_Qualifier & NSA_QUAL_SHIFT) {
1711 nskey = NS_KEY_PAGE_DOWN;
1712 } else if(ie->ie_Qualifier & NSA_QUAL_ALT) {
1713 nskey = NS_KEY_TEXT_END;
1714 }
1715 else nskey = NS_KEY_DOWN;
1716 break;
1717 case RAWKEY_CRSRLEFT:
1718 if(ie->ie_Qualifier & NSA_QUAL_SHIFT) {
1719 nskey = NS_KEY_LINE_START;
1720 }else if(ie->ie_Qualifier & NSA_QUAL_ALT) {
1721 nskey = NS_KEY_WORD_LEFT;
1722 }
1723 else nskey = NS_KEY_LEFT;
1724 break;
1725 case RAWKEY_CRSRRIGHT:
1726 if(ie->ie_Qualifier & NSA_QUAL_SHIFT) {
1727 nskey = NS_KEY_LINE_END;
1728 }else if(ie->ie_Qualifier & NSA_QUAL_ALT) {
1729 nskey = NS_KEY_WORD_RIGHT;
1730 }
1731 else nskey = NS_KEY_RIGHT;
1732 break;
1733 case RAWKEY_ESC:
1734 nskey = NS_KEY_ESCAPE;
1735 break;
1736 case RAWKEY_PAGEUP:
1737 nskey = NS_KEY_PAGE_UP;
1738 break;
1739 case RAWKEY_PAGEDOWN:
1740 nskey = NS_KEY_PAGE_DOWN;
1741 break;
1742 case RAWKEY_HOME:
1743 nskey = NS_KEY_TEXT_START;
1744 break;
1745 case RAWKEY_END:
1746 nskey = NS_KEY_TEXT_END;
1747 break;
1748 case RAWKEY_BACKSPACE:
1749 if(ie->ie_Qualifier & NSA_QUAL_SHIFT) {
1751 } else {
1752 nskey = NS_KEY_DELETE_LEFT;
1753 }
1754 break;
1755 case RAWKEY_DEL:
1756 if(ie->ie_Qualifier & NSA_QUAL_SHIFT) {
1757 nskey = NS_KEY_DELETE_LINE_END;
1758 } else {
1759 nskey = NS_KEY_DELETE_RIGHT;
1760 }
1761 break;
1762 case RAWKEY_TAB:
1763 if(ie->ie_Qualifier & NSA_QUAL_SHIFT) {
1764 nskey = NS_KEY_SHIFT_TAB;
1765 } else {
1766 nskey = NS_KEY_TAB;
1767 }
1768 break;
1769 case RAWKEY_F5:
1770 case RAWKEY_F8:
1771 case RAWKEY_F9:
1772 case RAWKEY_F10:
1773 case RAWKEY_F12:
1774 case RAWKEY_HELP:
1775 // don't translate
1776 nskey = keycode;
1777 break;
1778 default:
1779 if((chars = MapRawKey(ie,buffer,20,NULL)) > 0) {
1780 if(utf8_from_local_encoding(buffer, chars, &utf8) != NSERROR_OK) return 0;
1781 nskey = utf8_to_ucs4(utf8, utf8_char_byte_length(utf8));
1782 free(utf8);
1783
1784 if(ie->ie_Qualifier & IEQUALIFIER_RCOMMAND) {
1785 switch(nskey) {
1786 case 'a':
1787 nskey = NS_KEY_SELECT_ALL;
1788 break;
1789 case 'c':
1790 nskey = NS_KEY_COPY_SELECTION;
1791 break;
1792 case 'v':
1793 nskey = NS_KEY_PASTE;
1794 break;
1795 case 'x':
1796 nskey = NS_KEY_CUT_SELECTION;
1797 break;
1798 case 'y':
1799 nskey = NS_KEY_REDO;
1800 break;
1801 case 'z':
1802 nskey = NS_KEY_UNDO;
1803 break;
1804 }
1805 }
1806 }
1807 break;
1808 }
1809
1810 return nskey;
1811}
1812
1813int ami_gui_get_quals(Object *win_obj)
1814{
1815 uint32 quals = 0;
1816 int key_state = 0;
1817#ifdef __amigaos4__
1818 GetAttr(WINDOW_Qualifier, win_obj, (uint32 *)&quals);
1819#else
1820#warning qualifier needs fixing for OS3
1821#endif
1822
1823 if(quals & NSA_QUAL_SHIFT) {
1824 key_state |= BROWSER_MOUSE_MOD_1;
1825 }
1826
1827 if(quals & IEQUALIFIER_CONTROL) {
1828 key_state |= BROWSER_MOUSE_MOD_2;
1829 }
1830
1831 if(quals & NSA_QUAL_ALT) {
1832 key_state |= BROWSER_MOUSE_MOD_3;
1833 }
1834
1835 return key_state;
1836}
1837
1838static void ami_update_quals(struct gui_window_2 *gwin)
1839{
1841}
1842
1843/* exported interface documented in amiga/gui.h */
1844nserror ami_gui_get_space_box(Object *obj, struct IBox **bbox)
1845{
1846 struct IBox *ib = AllocVec(sizeof(struct IBox), MEMF_PRIVATE);
1847 if(ib == NULL) return NSERROR_NOMEM;
1848#ifdef __amigaos4__
1849 if(LIB_IS_AT_LEAST((struct Library *)SpaceBase, 53, 6)) {
1850 GetAttr(SPACE_RenderBox, obj, (ULONG *)ib);
1851 } else
1852#endif
1853 {
1854 struct IBox *t_ib;
1855 GetAttr(SPACE_AreaBox, obj, (ULONG *)&t_ib);
1856 if(t_ib == NULL) {
1857 FreeVec(ib);
1858 return NSERROR_NOMEM;
1859 } else {
1860 /* Create a copy so this works the same as the newer SPACE_RenderBox */
1861 CopyMem(t_ib, ib, sizeof(struct IBox));
1862 }
1863 }
1864
1865 *bbox = ib;
1866 return NSERROR_OK;
1867}
1868
1869/* exported interface documented in amiga/gui.h */
1870void ami_gui_free_space_box(struct IBox *bbox)
1871{
1872 if(bbox != NULL) FreeVec(bbox);
1873}
1874
1876 int *restrict x, int *restrict y, int space_x, int space_y)
1877{
1878 int ns_x = space_x;
1879 int ns_y = space_y;
1880
1881 ns_x += gwin->gw->scrollx;
1882 ns_y += gwin->gw->scrolly;
1883
1884 *x = ns_x;
1885 *y = ns_y;
1886
1887 return true;
1888}
1889
1890bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *restrict x, int *restrict y,
1891 int mouse_x, int mouse_y)
1892{
1893 int ns_x, ns_y;
1894 struct IBox *bbox;
1895
1896 if(mouse_x == -1) mouse_x = gwin->win->MouseX;
1897 if(mouse_y == -1) mouse_y = gwin->win->MouseY;
1898
1899 if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) == NSERROR_OK) {
1900 ns_x = (ULONG)(mouse_x - bbox->Left);
1901 ns_y = (ULONG)(mouse_y - bbox->Top);
1902
1903 if((ns_x < 0) || (ns_x > bbox->Width) || (ns_y < 0) || (ns_y > bbox->Height)) {
1905 return false;
1906 }
1907
1909 } else {
1910 amiga_warn_user("NoMemory", "");
1911 return false;
1912 }
1913
1914 return ami_spacebox_to_ns_coords(gwin, x, y, ns_x, ns_y);
1915}
1916
1917static void ami_gui_scroll_internal(struct gui_window_2 *gwin, int xs, int ys)
1918{
1919 struct IBox *bbox;
1920 int x, y;
1921 struct rect rect;
1922
1923 if(ami_mouse_to_ns_coords(gwin, &x, &y, -1, -1) == true)
1924 {
1925 if(browser_window_scroll_at_point(gwin->gw->bw, x, y, xs, ys) == false)
1926 {
1927 int width, height;
1928
1930 &gwin->gw->scrollx,
1931 &gwin->gw->scrolly);
1932
1933 if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
1934 amiga_warn_user("NoMemory", "");
1935 return;
1936 }
1937
1938 browser_window_get_extents(gwin->gw->bw, false, &width, &height);
1939
1940 switch(xs)
1941 {
1942 case SCROLL_PAGE_UP:
1943 xs = gwin->gw->scrollx - bbox->Width;
1944 break;
1945
1946 case SCROLL_PAGE_DOWN:
1947 xs = gwin->gw->scrollx + bbox->Width;
1948 break;
1949
1950 case SCROLL_TOP:
1951 xs = 0;
1952 break;
1953
1954 case SCROLL_BOTTOM:
1955 xs = width;
1956 break;
1957
1958 default:
1959 xs += gwin->gw->scrollx;
1960 break;
1961 }
1962
1963 switch(ys)
1964 {
1965 case SCROLL_PAGE_UP:
1966 ys = gwin->gw->scrolly - bbox->Height;
1967 break;
1968
1969 case SCROLL_PAGE_DOWN:
1970 ys = gwin->gw->scrolly + bbox->Height;
1971 break;
1972
1973 case SCROLL_TOP:
1974 ys = 0;
1975 break;
1976
1977 case SCROLL_BOTTOM:
1978 ys = height;
1979 break;
1980
1981 default:
1982 ys += gwin->gw->scrolly;
1983 break;
1984 }
1985
1987 rect.x0 = rect.x1 = xs;
1988 rect.y0 = rect.y1 = ys;
1989 gui_window_set_scroll(gwin->gw, &rect);
1990 }
1991 }
1992}
1993
1994static struct IBox *ami_ns_rect_to_ibox(struct gui_window_2 *gwin, const struct rect *rect)
1995{
1996 struct IBox *bbox, *ibox;
1997
1998 ibox = malloc(sizeof(struct IBox));
1999 if(ibox == NULL) return NULL;
2000
2001 if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
2002 free(ibox);
2003 amiga_warn_user("NoMemory", "");
2004 return NULL;
2005 }
2006
2007 ibox->Left = gwin->win->MouseX + (rect->x0);
2008 ibox->Top = gwin->win->MouseY + (rect->y0);
2009
2010 ibox->Width = (rect->x1 - rect->x0);
2011 ibox->Height = (rect->y1 - rect->y0);
2012
2013 if(ibox->Left < bbox->Left) ibox->Left = bbox->Left;
2014 if(ibox->Top < bbox->Top) ibox->Top = bbox->Top;
2015
2016 if((ibox->Left > (bbox->Left + bbox->Width)) ||
2017 (ibox->Top > (bbox->Top + bbox->Height)) ||
2018 (ibox->Width < 0) || (ibox->Height < 0))
2019 {
2020 free(ibox);
2022 return NULL;
2023 }
2024
2026 return ibox;
2027}
2028
2029static void ami_gui_trap_mouse(struct gui_window_2 *gwin)
2030{
2031#ifdef __amigaos4__
2032 switch(gwin->drag_op)
2033 {
2034 case GDRAGGING_NONE:
2036 case GDRAGGING_OTHER:
2037 break;
2038
2039 default:
2040 if(gwin->ptr_lock)
2041 {
2042 SetWindowAttrs(gwin->win, WA_GrabFocus, 10,
2043 WA_MouseLimits, gwin->ptr_lock, TAG_DONE);
2044 }
2045 break;
2046 }
2047#endif
2048}
2049
2051{
2052 struct nsObject *node;
2053 struct nsObject *nnode;
2054 struct gui_window_2 *gwin;
2055
2056 if(IsMinListEmpty(window_list)) return;
2057
2058 node = (struct nsObject *)GetHead((struct List *)window_list);
2059
2060 do {
2061 nnode=(struct nsObject *)GetSucc((struct Node *)node);
2062 gwin = node->objstruct;
2063
2064 if(node->Type == AMINS_WINDOW)
2065 {
2067 }
2068 } while((node = nnode));
2069}
2070
2071/**
2072 * Find the current dimensions of a amiga browser window content area.
2073 *
2074 * \param gw The gui window to measure content area of.
2075 * \param width receives width of window
2076 * \param height receives height of window
2077 * \return NSERROR_OK on sucess and width and height updated
2078 * else error code.
2079 */
2080static nserror
2082 int *restrict width,
2083 int *restrict height)
2084{
2085 struct IBox *bbox;
2086 nserror res;
2087
2088 res = ami_gui_get_space_box((Object *)gw->shared->objects[GID_BROWSER],
2089 &bbox);
2090 if (res != NSERROR_OK) {
2091 amiga_warn_user("NoMemory", "");
2092 return res;
2093 }
2094
2095 *width = bbox->Width;
2096 *height = bbox->Height;
2097
2099
2100 return NSERROR_OK;
2101}
2102
2103/* Add a horizontal scroller, if not already present
2104 * Returns true if changed, false otherwise */
2105static bool ami_gui_hscroll_add(struct gui_window_2 *gwin)
2106{
2107 struct TagItem attrs[2];
2108
2109 if(gwin->objects[GID_HSCROLL] != NULL) return false;
2110
2111 attrs[0].ti_Tag = CHILD_MinWidth;
2112 attrs[0].ti_Data = 0;
2113 attrs[1].ti_Tag = TAG_DONE;
2114 attrs[1].ti_Data = 0;
2115
2117 GA_ID, GID_HSCROLL,
2118 GA_RelVerify, TRUE,
2119 SCROLLER_Orientation, SORIENT_HORIZ,
2120 ICA_TARGET, ICTARGET_IDCMP,
2121 ScrollerEnd;
2122#ifdef __amigaos4__
2123 IDoMethod(gwin->objects[GID_HSCROLLLAYOUT], LM_ADDCHILD,
2124 gwin->win, gwin->objects[GID_HSCROLL], attrs);
2125#else
2126 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_HSCROLLLAYOUT],
2127 gwin->win, NULL,
2128 LAYOUT_AddChild, gwin->objects[GID_HSCROLL], TAG_MORE, &attrs);
2129#endif
2130 return true;
2131}
2132
2133/* Remove the horizontal scroller, if present */
2134static bool ami_gui_hscroll_remove(struct gui_window_2 *gwin)
2135{
2136 if(gwin->objects[GID_HSCROLL] == NULL) return false;
2137
2138#ifdef __amigaos4__
2139 IDoMethod(gwin->objects[GID_HSCROLLLAYOUT], LM_REMOVECHILD,
2140 gwin->win, gwin->objects[GID_HSCROLL]);
2141#else
2142 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_HSCROLLLAYOUT],
2143 gwin->win, NULL,
2144 LAYOUT_RemoveChild, gwin->objects[GID_HSCROLL], TAG_DONE);
2145#endif
2146
2147 gwin->objects[GID_HSCROLL] = NULL;
2148
2149 return true;
2150}
2151
2152/* Add a vertical scroller, if not already present
2153 * Returns true if changed, false otherwise */
2154static bool ami_gui_vscroll_add(struct gui_window_2 *gwin)
2155{
2156 struct TagItem attrs[2];
2157
2158 if(gwin->objects[GID_VSCROLL] != NULL) return false;
2159
2160 attrs[0].ti_Tag = CHILD_MinWidth;
2161 attrs[0].ti_Data = 0;
2162 attrs[1].ti_Tag = TAG_DONE;
2163 attrs[1].ti_Data = 0;
2164
2166 GA_ID, GID_VSCROLL,
2167 GA_RelVerify, TRUE,
2168 ICA_TARGET, ICTARGET_IDCMP,
2169 ScrollerEnd;
2170#ifdef __amigaos4__
2171 IDoMethod(gwin->objects[GID_VSCROLLLAYOUT], LM_ADDCHILD,
2172 gwin->win, gwin->objects[GID_VSCROLL], attrs);
2173#else
2174 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_VSCROLLLAYOUT],
2175 gwin->win, NULL,
2176 LAYOUT_AddChild, gwin->objects[GID_VSCROLL], TAG_MORE, &attrs);
2177#endif
2178 return true;
2179}
2180
2181/* Remove the vertical scroller, if present */
2182static bool ami_gui_vscroll_remove(struct gui_window_2 *gwin)
2183{
2184 if(gwin->objects[GID_VSCROLL] == NULL) return false;
2185
2186#ifdef __amigaos4__
2187 IDoMethod(gwin->objects[GID_VSCROLLLAYOUT], LM_REMOVECHILD,
2188 gwin->win, gwin->objects[GID_VSCROLL]);
2189#else
2190 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_VSCROLLLAYOUT],
2191 gwin->win, NULL,
2192 LAYOUT_RemoveChild, gwin->objects[GID_VSCROLL], TAG_DONE);
2193#endif
2194
2195 gwin->objects[GID_VSCROLL] = NULL;
2196
2197 return true;
2198}
2199
2200/**
2201 * Check the scroll bar requirements for a browser window, and add/remove
2202 * the vertical scroller as appropriate. This should be the main entry
2203 * point used to perform this task.
2204 *
2205 * \param gwin "Shared" GUI window to check the state of
2206 */
2207static void ami_gui_scroller_update(struct gui_window_2 *gwin)
2208{
2209 int h = 1, w = 1, wh = 0, ww = 0;
2210 bool rethinkv = false;
2211 bool rethinkh = false;
2214
2215 browser_window_get_scrollbar_type(gwin->gw->bw, &hscroll, &vscroll);
2216
2217 if(browser_window_is_frameset(gwin->gw->bw) == true) {
2218 rethinkv = ami_gui_vscroll_remove(gwin);
2219 rethinkh = ami_gui_hscroll_remove(gwin);
2220 } else {
2221 if((browser_window_get_extents(gwin->gw->bw, false, &w, &h) == NSERROR_OK)) {
2222 gui_window_get_dimensions(gwin->gw, &ww, &wh);
2223 }
2224
2225 if(vscroll == BW_SCROLLING_NO) {
2226 rethinkv = ami_gui_vscroll_remove(gwin);
2227 } else {
2228 if (h > wh) rethinkv = ami_gui_vscroll_add(gwin);
2229 else rethinkv = ami_gui_vscroll_remove(gwin);
2230 }
2231
2232 if(hscroll == BW_SCROLLING_NO) {
2233 rethinkh = ami_gui_hscroll_remove(gwin);
2234 } else {
2235 if (w > ww) rethinkh = ami_gui_hscroll_add(gwin);
2236 else rethinkh = ami_gui_hscroll_remove(gwin);
2237 }
2238 }
2239
2240 if(rethinkv || rethinkh) {
2241 FlushLayoutDomainCache((struct Gadget *)gwin->objects[GID_MAIN]);
2242 RethinkLayout((struct Gadget *)gwin->objects[GID_MAIN],
2243 gwin->win, NULL, TRUE);
2245 }
2246}
2247
2248/* For future use
2249static void ami_gui_console_log_clear(struct gui_window *g)
2250{
2251 if(g->shared->objects[GID_LOG] != NULL) {
2252 SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], g->shared->win, NULL,
2253 LISTBROWSER_Labels, NULL,
2254 TAG_DONE);
2255 }
2256
2257 FreeListBrowserList(&g->loglist);
2258
2259 NewList(&g->loglist);
2260
2261 if(g->shared->objects[GID_LOG] != NULL) {
2262 SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], g->shared->win, NULL,
2263 LISTBROWSER_Labels, &g->loglist,
2264 TAG_DONE);
2265 }
2266}
2267*/
2268
2270{
2271 struct TagItem attrs[2];
2272
2273 if(g->shared->objects[GID_LOG] != NULL) return;
2274
2275 attrs[0].ti_Tag = CHILD_MinHeight;
2276 attrs[0].ti_Data = 50;
2277 attrs[1].ti_Tag = TAG_DONE;
2278 attrs[1].ti_Data = 0;
2279
2281 GA_ID, GID_LOG,
2282 LISTBROWSER_ColumnInfo, g->logcolumns,
2283 LISTBROWSER_ColumnTitles, TRUE,
2284 LISTBROWSER_Labels, &g->loglist,
2286 ListBrowserEnd;
2287
2288#ifdef __amigaos4__
2289 IDoMethod(g->shared->objects[GID_LOGLAYOUT], LM_ADDCHILD,
2290 g->shared->win, g->shared->objects[GID_LOG], NULL);
2291#else
2292 SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOGLAYOUT],
2293 g->shared->win, NULL,
2294 LAYOUT_AddChild, g->shared->objects[GID_LOG], TAG_MORE, &attrs);
2295#endif
2296
2297 FlushLayoutDomainCache((struct Gadget *)g->shared->objects[GID_MAIN]);
2298
2299 RethinkLayout((struct Gadget *)g->shared->objects[GID_MAIN],
2300 g->shared->win, NULL, TRUE);
2301
2302 ami_schedule_redraw(g->shared, true);
2303}
2304
2306{
2307 if(g->shared->objects[GID_LOG] == NULL) return;
2308
2309#ifdef __amigaos4__
2310 IDoMethod(g->shared->objects[GID_LOGLAYOUT], LM_REMOVECHILD,
2311 g->shared->win, g->shared->objects[GID_LOG]);
2312#else
2313 SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOGLAYOUT],
2314 g->shared->win, NULL,
2315 LAYOUT_RemoveChild, g->shared->objects[GID_LOG], TAG_DONE);
2316#endif
2317
2318 g->shared->objects[GID_LOG] = NULL;
2319
2320 FlushLayoutDomainCache((struct Gadget *)g->shared->objects[GID_MAIN]);
2321
2322 RethinkLayout((struct Gadget *)g->shared->objects[GID_MAIN],
2323 g->shared->win, NULL, TRUE);
2324
2325 ami_schedule_redraw(g->shared, true);
2326}
2327
2329{
2330 if(g->shared->objects[GID_LOG] == NULL) {
2332 return true;
2333 } else {
2335 return false;
2336 }
2337}
2338
2340{
2341 if(g->shared->objects[GID_LOG] == NULL) return;
2342
2343 RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], g->shared->win, NULL,
2344 LISTBROWSER_ColumnInfo, g->logcolumns,
2345 LISTBROWSER_Labels, &g->loglist,
2346 TAG_DONE);
2347}
2348
2349static void
2352 const char *msg,
2353 size_t msglen,
2355{
2356 bool foldable = !!(flags & BW_CS_FLAG_FOLDABLE);
2357 const char *src_text;
2358 const char *level_text;
2359 struct Node *node;
2360 ULONG style = 0;
2361 ULONG fgpen = TEXTPEN;
2362 ULONG lbflags = LBFLG_READONLY;
2363 char timestamp[256];
2364 time_t now = time(NULL);
2365 struct tm *timedata = localtime(&now);
2366
2367 strftime(timestamp, 256, "%c", timedata);
2368
2369 if(foldable) lbflags |= LBFLG_HASCHILDREN;
2370
2371 switch (src) {
2372 case BW_CS_INPUT:
2373 src_text = "client-input";
2374 break;
2375 case BW_CS_SCRIPT_ERROR:
2376 src_text = "scripting-error";
2377 break;
2379 src_text = "scripting-console";
2380 break;
2381 default:
2382 assert(0 && "Unknown scripting source");
2383 src_text = "unknown";
2384 break;
2385 }
2386
2387 switch (flags & BW_CS_FLAG_LEVEL_MASK) {
2389 level_text = "DEBUG";
2390 fgpen = DISABLEDTEXTPEN;
2391 lbflags |= LBFLG_CUSTOMPENS;
2392 break;
2394 level_text = "LOG";
2395 fgpen = DISABLEDTEXTPEN;
2396 lbflags |= LBFLG_CUSTOMPENS;
2397 break;
2399 level_text = "INFO";
2400 break;
2402 level_text = "WARN";
2403 break;
2405 level_text = "ERROR";
2406 style = FSF_BOLD;
2407 break;
2408 default:
2409 assert(0 && "Unknown console logging level");
2410 level_text = "unknown";
2411 break;
2412 }
2413
2414 if(g->shared->objects[GID_LOG] != NULL) {
2415 SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], g->shared->win, NULL,
2416 LISTBROWSER_Labels, NULL,
2417 TAG_DONE);
2418 }
2419
2420 /* Add log entry to list irrespective of whether the log is open. */
2421 if((node = AllocListBrowserNode(4,
2422 LBNA_Flags, lbflags,
2423 LBNA_Column, 0,
2424 LBNCA_SoftStyle, style,
2425 LBNCA_FGPen, fgpen,
2426 LBNCA_CopyText, TRUE,
2427 LBNCA_Text, timestamp,
2428 LBNA_Column, 1,
2429 LBNCA_SoftStyle, style,
2430 LBNCA_FGPen, fgpen,
2431 LBNCA_CopyText, TRUE,
2432 LBNCA_Text, src_text,
2433 LBNA_Column, 2,
2434 LBNCA_SoftStyle, style,
2435 LBNCA_FGPen, fgpen,
2436 LBNCA_CopyText, TRUE,
2437 LBNCA_Text, level_text,
2438 LBNA_Column, 3,
2439 LBNCA_SoftStyle, style,
2440 LBNCA_FGPen, fgpen,
2441 LBNCA_CopyText, TRUE,
2442 LBNCA_Text, msg,
2443 TAG_DONE))) {
2444 AddTail(&g->loglist, node);
2445 }
2446
2447 if(g->shared->objects[GID_LOG] != NULL) {
2448 RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], g->shared->win, NULL,
2449 LISTBROWSER_Labels, &g->loglist,
2450 TAG_DONE);
2451 }
2452
2453#ifdef __amigaos4__
2454 DebugPrintF("NETSURF: CONSOLE_LOG SOURCE %s %sFOLDABLE %s %.*s\n",
2455 src_text, foldable ? "" : "NOT-", level_text,
2456 (int)msglen, msg);
2457#endif
2458}
2459
2460
2461/**
2462 * function to add retrieved favicon to gui
2463 */
2464static void gui_window_set_icon(struct gui_window *g, struct hlcache_handle *icon)
2465{
2466 struct BitMap *bm = NULL;
2467 struct IBox *bbox;
2468 struct bitmap *icon_bitmap = NULL;
2469
2470 if(nsoption_bool(kiosk_mode) == true) return;
2471 if(!g) return;
2472
2473 if ((icon != NULL) && ((icon_bitmap = content_get_bitmap(icon)) != NULL))
2474 {
2475 bm = ami_bitmap_get_native(icon_bitmap, 16, 16, ami_plot_screen_is_palettemapped(),
2476 g->shared->win->RPort->BitMap, nsoption_colour(sys_colour_ButtonFace));
2477 }
2478
2479 if(g == g->shared->gw) {
2480 RefreshGList((struct Gadget *)g->shared->objects[GID_ICON],
2481 g->shared->win, NULL, 1);
2482
2483 if(bm)
2484 {
2485 ULONG tag, tag_data, minterm;
2486#ifdef __amigaos4__
2487 if(ami_plot_screen_is_palettemapped() == false) {
2488 tag = BLITA_UseSrcAlpha;
2489 tag_data = !amiga_bitmap_get_opaque(icon_bitmap);
2490 minterm = 0xc0;
2491 } else {
2492 tag = BLITA_MaskPlane;
2493#endif
2494 tag_data = (ULONG)ami_bitmap_get_mask(icon_bitmap, 16, 16, bm);
2495 minterm = MINTERM_SRCMASK;
2496#ifdef __amigaos4__
2497 }
2498#endif
2499 if(ami_gui_get_space_box((Object *)g->shared->objects[GID_ICON], &bbox) != NSERROR_OK) {
2500 amiga_warn_user("NoMemory", "");
2501 return;
2502 }
2503
2504 EraseRect(g->shared->win->RPort, bbox->Left, bbox->Top,
2505 bbox->Left + 16, bbox->Top + 16);
2506
2507#ifdef __amigaos4__
2508 BltBitMapTags(BLITA_SrcX, 0,
2509 BLITA_SrcY, 0,
2510 BLITA_DestX, bbox->Left,
2511 BLITA_DestY, bbox->Top,
2512 BLITA_Width, 16,
2513 BLITA_Height, 16,
2514 BLITA_Source, bm,
2515 BLITA_Dest, g->shared->win->RPort,
2516 BLITA_SrcType, BLITT_BITMAP,
2517 BLITA_DestType, BLITT_RASTPORT,
2518 BLITA_Minterm, minterm,
2519 tag, tag_data,
2520 TAG_DONE);
2521#else
2522 if(!amiga_bitmap_get_opaque(icon_bitmap)) {
2523 BltMaskBitMapRastPort(bm, 0, 0, g->shared->win->RPort,
2524 bbox->Left, bbox->Top, 16, 16, minterm, tag_data);
2525 } else {
2526 BltBitMapRastPort(bm, 0, 0, g->shared->win->RPort,
2527 bbox->Left, bbox->Top, 16, 16, 0xc0);
2528 }
2529#endif
2531 }
2532 }
2533
2534 g->favicon = icon;
2535}
2536
2537static void ami_gui_refresh_favicon(void *p)
2538{
2539 struct gui_window_2 *gwin = (struct gui_window_2 *)p;
2540 gui_window_set_icon(gwin->gw, gwin->gw->favicon);
2541}
2542
2543/* Gets the size that border gadget 1 (status) needs to be.
2544 * Returns the width of the size gadget as a convenience.
2545 */
2546#ifdef __amigaos4__
2547static ULONG ami_get_border_gadget_size(struct gui_window_2 *gwin,
2548 ULONG *restrict width, ULONG *restrict height)
2549{
2550 static ULONG sz_gad_width = 0;
2551 static ULONG sz_gad_height = 0;
2552 ULONG available_width;
2553
2554 if((sz_gad_width == 0) || (sz_gad_height == 0)) {
2555 struct DrawInfo *dri = GetScreenDrawInfo(scrn);
2556 GetGUIAttrs(NULL, dri,
2557 GUIA_SizeGadgetWidth, &sz_gad_width,
2558 GUIA_SizeGadgetHeight, &sz_gad_height,
2559 TAG_DONE);
2560 FreeScreenDrawInfo(scrn, dri);
2561 }
2562 available_width = gwin->win->Width - scrn->WBorLeft - sz_gad_width;
2563
2564 *width = available_width;
2565 *height = sz_gad_height;
2566
2567 return sz_gad_width;
2568}
2569#endif
2570
2572{
2573#ifdef __amigaos4__
2574 /* Reset gadget widths according to new calculation */
2575 ULONG size1, size2;
2576
2577 ami_get_border_gadget_size(gwin, &size1, &size2);
2578
2579 RefreshSetGadgetAttrs((struct Gadget *)(APTR)gwin->objects[GID_STATUS],
2580 gwin->win, NULL,
2581 GA_Width, size1,
2582 TAG_DONE);
2583
2584 RefreshWindowFrame(gwin->win);
2585#endif
2586}
2587
2588static BOOL ami_handle_msg(void)
2589{
2590 struct ami_generic_window *w = NULL;
2591 struct nsObject *node;
2592 struct nsObject *nnode;
2593 BOOL win_closed = FALSE;
2594
2596 /* no windows in list, so NetSurf should not be running */
2597 ami_try_quit();
2598 return FALSE;
2599 }
2600
2601 node = (struct nsObject *)GetHead((struct List *)window_list);
2602
2603 do {
2604 nnode=(struct nsObject *)GetSucc((struct Node *)node);
2605
2606 w = node->objstruct;
2607 if(w == NULL) continue;
2608
2609 if(w->tbl->event != NULL) {
2610 if((win_closed = w->tbl->event(w))) {
2611 if((node->Type != AMINS_GUIOPTSWINDOW) ||
2612 ((node->Type == AMINS_GUIOPTSWINDOW) && (scrn != NULL))) {
2613 ami_try_quit();
2614 break;
2615 }
2616 } else {
2617 node = nnode;
2618 continue;
2619 }
2620 }
2621 } while((node = nnode));
2622
2623 if(ami_gui_menu_quit_selected() == true) {
2625 }
2626
2627 if(ami_gui_menu_get_check_toggled() == true) {
2629 }
2630
2631 return win_closed;
2632}
2633
2634static BOOL ami_gui_event(void *w)
2635{
2636 struct gui_window_2 *gwin = (struct gui_window_2 *)w;
2637 ULONG result, storage = 0, x, y, xs, ys, width = 800, height = 600;
2638 uint16 code;
2639 struct IBox *bbox;
2640 struct InputEvent *ie;
2641 struct Node *tabnode;
2642 int nskey;
2643 struct timeval curtime;
2644 static int drag_x_move = 0, drag_y_move = 0;
2645 char *utf8 = NULL;
2646 nsurl *url;
2647 BOOL win_closed = FALSE;
2648
2649 while((result = RA_HandleInput(gwin->objects[OID_MAIN], &code)) != WMHI_LASTMSG) {
2650 switch(result & WMHI_CLASSMASK) // class
2651 {
2652 case WMHI_MOUSEMOVE:
2653 ami_gui_trap_mouse(gwin); /* re-assert mouse area */
2654
2655 drag_x_move = 0;
2656 drag_y_move = 0;
2657
2658 if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
2659 amiga_warn_user("NoMemory", "");
2660 break;
2661 }
2662
2663 x = (ULONG)((gwin->win->MouseX - bbox->Left));
2664 y = (ULONG)((gwin->win->MouseY - bbox->Top));
2665
2666 ami_get_hscroll_pos(gwin, (ULONG *)&xs);
2667 ami_get_vscroll_pos(gwin, (ULONG *)&ys);
2668
2669 x += xs;
2670 y += ys;
2671
2672 width=bbox->Width;
2673 height=bbox->Height;
2674
2676 {
2677 if(ami_drag_icon_move() == TRUE) {
2678 if((gwin->win->MouseX < bbox->Left) &&
2679 ((gwin->win->MouseX - bbox->Left) > -AMI_DRAG_THRESHOLD))
2680 drag_x_move = gwin->win->MouseX - bbox->Left;
2681 if((gwin->win->MouseX > (bbox->Left + bbox->Width)) &&
2682 ((gwin->win->MouseX - (bbox->Left + bbox->Width)) < AMI_DRAG_THRESHOLD))
2683 drag_x_move = gwin->win->MouseX - (bbox->Left + bbox->Width);
2684 if((gwin->win->MouseY < bbox->Top) &&
2685 ((gwin->win->MouseY - bbox->Top) > -AMI_DRAG_THRESHOLD))
2686 drag_y_move = gwin->win->MouseY - bbox->Top;
2687 if((gwin->win->MouseY > (bbox->Top + bbox->Height)) &&
2688 ((gwin->win->MouseY - (bbox->Top + bbox->Height)) < AMI_DRAG_THRESHOLD))
2689 drag_y_move = gwin->win->MouseY - (bbox->Top + bbox->Height);
2690 }
2691 }
2692
2694
2695 if((x>=xs) && (y>=ys) && (x<width+xs) && (y<height+ys))
2696 {
2697 ami_update_quals(gwin);
2698
2700 {
2703 }
2704 else if(gwin->mouse_state & BROWSER_MOUSE_PRESS_2)
2705 {
2708 }
2709 else
2710 {
2711 browser_window_mouse_track(gwin->gw->bw,gwin->mouse_state | gwin->key_state,x,y);
2712 }
2713 } else {
2714 if(!gwin->mouse_state) ami_set_pointer(gwin, GUI_POINTER_DEFAULT, true);
2715 }
2716 break;
2717
2718 case WMHI_MOUSEBUTTONS:
2719 if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
2720 amiga_warn_user("NoMemory", "");
2721 return FALSE;
2722 }
2723
2724 x = (ULONG)(gwin->win->MouseX - bbox->Left);
2725 y = (ULONG)(gwin->win->MouseY - bbox->Top);
2726
2727 ami_get_hscroll_pos(gwin, (ULONG *)&xs);
2728 ami_get_vscroll_pos(gwin, (ULONG *)&ys);
2729
2730 x += xs;
2731 y += ys;
2732
2733 width=bbox->Width;
2734 height=bbox->Height;
2735
2737
2738 ami_update_quals(gwin);
2739
2740 if((x>=xs) && (y>=ys) && (x<width+xs) && (y<height+ys))
2741 {
2742 //code = code>>16;
2743 switch(code)
2744 {
2745 case SELECTDOWN:
2748 break;
2749 case MIDDLEDOWN:
2752 break;
2753 }
2754 }
2755
2756 if(x<xs) x=xs;
2757 if(y<ys) y=ys;
2758 if(x>=width+xs) x=width+xs-1;
2759 if(y>=height+ys) y=height+ys-1;
2760
2761 switch(code)
2762 {
2763 case SELECTUP:
2765 {
2766 CurrentTime((ULONG *)&curtime.tv_sec, (ULONG *)&curtime.tv_usec);
2767
2769
2770 if(gwin->lastclick.tv_sec)
2771 {
2772 if(DoubleClick(gwin->lastclick.tv_sec,
2773 gwin->lastclick.tv_usec,
2774 curtime.tv_sec, curtime.tv_usec)) {
2777 } else {
2779 }
2780 }
2781 }
2782
2784 gwin->mouse_state | gwin->key_state,x,y);
2785
2787 {
2788 gwin->lastclick.tv_sec = 0;
2789 gwin->lastclick.tv_usec = 0;
2790 }
2791 else
2792 {
2793 gwin->lastclick.tv_sec = curtime.tv_sec;
2794 gwin->lastclick.tv_usec = curtime.tv_usec;
2795 }
2796 }
2797 else
2798 {
2799 browser_window_mouse_track(gwin->gw->bw, 0, x, y);
2800 }
2801 gwin->prev_mouse_state = gwin->mouse_state;
2802 gwin->mouse_state=0;
2803 break;
2804
2805 case MIDDLEUP:
2807 {
2808 CurrentTime((ULONG *)&curtime.tv_sec, (ULONG *)&curtime.tv_usec);
2809
2811
2812 if(gwin->lastclick.tv_sec)
2813 {
2814 if(DoubleClick(gwin->lastclick.tv_sec,
2815 gwin->lastclick.tv_usec,
2816 curtime.tv_sec, curtime.tv_usec)) {
2819 } else {
2821 }
2822 }
2823 }
2824
2826 gwin->mouse_state | gwin->key_state,x,y);
2827
2829 {
2830 gwin->lastclick.tv_sec = 0;
2831 gwin->lastclick.tv_usec = 0;
2832 }
2833 else
2834 {
2835 gwin->lastclick.tv_sec = curtime.tv_sec;
2836 gwin->lastclick.tv_usec = curtime.tv_usec;
2837 }
2838 }
2839 else
2840 {
2841 browser_window_mouse_track(gwin->gw->bw, 0, x, y);
2842 }
2843 gwin->prev_mouse_state = gwin->mouse_state;
2844 gwin->mouse_state=0;
2845 break;
2846#ifdef __amigaos4__
2847 case SIDEUP:
2848 ami_gui_history(gwin, true);
2849 break;
2850
2851 case EXTRAUP:
2852 ami_gui_history(gwin, false);
2853 break;
2854#endif
2855 }
2856
2857 if(ami_drag_has_data() && !gwin->mouse_state)
2858 ami_drag_save(gwin->win);
2859 break;
2860
2861 case WMHI_GADGETUP:
2862 switch(result & WMHI_GADGETMASK)
2863 {
2864 case GID_TABS:
2865 if(gwin->objects[GID_TABS] == NULL) break;
2866 if(ClickTabBase->lib_Version >= 53) {
2867 GetAttrs(gwin->objects[GID_TABS],
2868 CLICKTAB_NodeClosed, &tabnode, TAG_DONE);
2869 } else {
2870 tabnode = NULL;
2871 }
2872
2873 if(tabnode) {
2874 struct gui_window *closedgw;
2875
2876 GetClickTabNodeAttrs(tabnode,
2877 TNA_UserData, &closedgw,
2878 TAG_DONE);
2879
2880 browser_window_destroy(closedgw->bw);
2881 } else {
2882 ami_switch_tab(gwin, true);
2883 }
2884 break;
2885
2886 case GID_CLOSETAB:
2888 break;
2889
2890 case GID_ADDTAB:
2892 break;
2893
2894 case GID_URL:
2895 {
2896 nserror ret;
2897 nsurl *url;
2898 GetAttr(STRINGA_TextVal,
2899 (Object *)gwin->objects[GID_URL],
2900 (ULONG *)&storage);
2901 utf8 = ami_to_utf8_easy((const char *)storage);
2902
2904 ami_utf8_free(utf8);
2905 if (ret == NSERROR_OK) {
2907 url,
2908 NULL,
2910 NULL,
2911 NULL,
2912 NULL);
2914 }
2915 if (ret != NSERROR_OK) {
2917 }
2918 }
2919 break;
2920
2921 case GID_TOOLBARLAYOUT:
2922 /* Need fixing: never gets here */
2923 break;
2924
2925 case GID_SEARCH_ICON:
2926#ifdef __amigaos4__
2927 {
2928 char *prov = NULL;
2929 GetAttr(CHOOSER_SelectedNode, gwin->objects[GID_SEARCH_ICON],(ULONG *)&storage);
2930 if(storage != NULL) {
2931 GetChooserNodeAttrs((struct Node *)storage, CNA_Text, (ULONG *)&prov, TAG_DONE);
2932 nsoption_set_charp(search_web_provider, (char *)strdup(prov));
2933 }
2934 }
2935#else
2936 /* TODO: Fix for OS<3.2 */
2937#endif
2938 search_web_select_provider(nsoption_charp(search_web_provider));
2939 break;
2940
2941 case GID_SEARCHSTRING:
2942 {
2943 nserror ret;
2944 nsurl *url;
2945
2946 GetAttr(STRINGA_TextVal,
2947 (Object *)gwin->objects[GID_SEARCHSTRING],
2948 (ULONG *)&storage);
2949
2950 utf8 = ami_to_utf8_easy((const char *)storage);
2951
2953 ami_utf8_free(utf8);
2954 if (ret == NSERROR_OK) {
2956 url,
2957 NULL,
2959 NULL,
2960 NULL,
2961 NULL);
2963 }
2964 if (ret != NSERROR_OK) {
2966 }
2967
2968 }
2969 break;
2970
2971 case GID_HOME:
2972 {
2973 if (nsurl_create(nsoption_charp(homepage_url), &url) != NSERROR_OK) {
2974 amiga_warn_user("NoMemory", 0);
2975 } else {
2977 url,
2978 NULL,
2980 NULL,
2981 NULL,
2982 NULL);
2984 }
2985 }
2986 break;
2987
2988 case GID_STOP:
2990 browser_window_stop(gwin->gw->bw);
2991 break;
2992
2993 case GID_RELOAD:
2994 ami_update_quals(gwin);
2995
2997 {
2998 if(gwin->key_state & BROWSER_MOUSE_MOD_1)
2999 {
3000 browser_window_reload(gwin->gw->bw, true);
3001 }
3002 else
3003 {
3004 browser_window_reload(gwin->gw->bw, false);
3005 }
3006 }
3007 break;
3008
3009 case GID_BACK:
3010 ami_gui_history(gwin, true);
3011 break;
3012
3013 case GID_FORWARD:
3014 ami_gui_history(gwin, false);
3015 break;
3016
3017 case GID_PAGEINFO:
3018 {
3019 ULONG w_top, w_left;
3020 ULONG g_top, g_left, g_height;
3021
3022 GetAttr(WA_Top, gwin->objects[OID_MAIN], &w_top);
3023 GetAttr(WA_Left, gwin->objects[OID_MAIN], &w_left);
3024 GetAttr(GA_Top, gwin->objects[GID_PAGEINFO], &g_top);
3025 GetAttr(GA_Left, gwin->objects[GID_PAGEINFO], &g_left);
3026 GetAttr(GA_Height, gwin->objects[GID_PAGEINFO], &g_height);
3027
3028 if(ami_pageinfo_open(gwin->gw->bw,
3029 w_left + g_left,
3030 w_top + g_top + g_height) != NSERROR_OK) {
3031 NSLOG(netsurf, INFO, "Unable to open page info window");
3032 }
3033 }
3034 break;
3035
3036 case GID_FAVE:
3037 GetAttr(STRINGA_TextVal,
3038 (Object *)gwin->objects[GID_URL],
3039 (ULONG *)&storage);
3040 if(nsurl_create((const char *)storage, &url) == NSERROR_OK) {
3041 if(hotlist_has_url(url)) {
3043 } else {
3045 }
3047 }
3049 break;
3050
3051 case GID_HOTLIST:
3052 default:
3053// printf("GADGET: %ld\n",(result & WMHI_GADGETMASK));
3054 break;
3055 }
3056 break;
3057
3058 case WMHI_RAWKEY:
3059 ami_update_quals(gwin);
3060
3061 storage = result & WMHI_GADGETMASK;
3062 if(storage >= IECODE_UP_PREFIX) break;
3063
3064 GetAttr(WINDOW_InputEvent,gwin->objects[OID_MAIN],(ULONG *)&ie);
3065
3066 nskey = ami_key_to_nskey(storage, ie);
3067
3068 if((ie->ie_Qualifier & IEQUALIFIER_RCOMMAND) &&
3069 ((31 < nskey) && (nskey < 127))) {
3070 /* NB: Some keypresses are converted to generic keypresses above
3071 * rather than being "menu-emulated" here. */
3072 switch(nskey)
3073 {
3074 /* The following aren't available from the menu at the moment */
3075
3076 case 'r': // reload
3078 browser_window_reload(gwin->gw->bw, false);
3079 break;
3080
3081 case 'u': // open url
3082 if((nsoption_bool(kiosk_mode) == false))
3083 ActivateLayoutGadget((struct Gadget *)gwin->objects[GID_MAIN],
3084 gwin->win, NULL, (uint32)gwin->objects[GID_URL]);
3085 break;
3086 }
3087 }
3088 else
3089 {
3090 if(!browser_window_key_press(gwin->gw->bw, nskey))
3091 {
3092 switch(nskey)
3093 {
3094 case NS_KEY_UP:
3096 break;
3097
3098 case NS_KEY_DOWN:
3100 break;
3101
3102 case NS_KEY_LEFT:
3104 break;
3105
3106 case NS_KEY_RIGHT:
3108 break;
3109
3110 case NS_KEY_PAGE_UP:
3112 break;
3113
3114 case NS_KEY_PAGE_DOWN:
3115 case ' ':
3117 break;
3118
3119 case NS_KEY_LINE_START: // page left
3121 break;
3122
3123 case NS_KEY_LINE_END: // page right
3125 break;
3126
3127 case NS_KEY_TEXT_START: // home
3129 break;
3130
3131 case NS_KEY_TEXT_END: // end
3133 break;
3134
3135 case NS_KEY_WORD_RIGHT: // alt+right
3136 ami_change_tab(gwin, 1);
3137 break;
3138
3139 case NS_KEY_WORD_LEFT: // alt+left
3140 ami_change_tab(gwin, -1);
3141 break;
3142
3143 case NS_KEY_DELETE_LEFT: // backspace
3144 ami_gui_history(gwin, true);
3145 break;
3146
3147 /* RawKeys. NB: These are passthrus in ami_key_to_nskey() */
3148 case RAWKEY_F5: // reload
3150 browser_window_reload(gwin->gw->bw,false);
3151 break;
3152
3153 case RAWKEY_F8: // scale 100%
3154 ami_gui_set_scale(gwin->gw, 1.0);
3155 break;
3156
3157 case RAWKEY_F9: // decrease scale
3158 ami_gui_adjust_scale(gwin->gw, -0.1);
3159 break;
3160
3161 case RAWKEY_F10: // increase scale
3162 ami_gui_adjust_scale(gwin->gw, +0.1);
3163 break;
3164
3165 case RAWKEY_F12: // console log
3167 break;
3168
3169 case RAWKEY_HELP: // help
3171 break;
3172 }
3173 } else if(nskey == NS_KEY_COPY_SELECTION) {
3174 /* if we've copied a selection we need to clear it - style guide rules */
3176 }
3177 }
3178 break;
3179
3180 case WMHI_NEWSIZE:
3185 break;
3186
3187 case WMHI_CLOSEWINDOW:
3189 win_closed = TRUE;
3190 break;
3191#ifdef __amigaos4__
3192 case WMHI_ICONIFY:
3193 {
3194 struct bitmap *bm = NULL;
3196 &bm);
3197 gwin->dobj = amiga_icon_from_bitmap(bm);
3199 gwin->dobj);
3200 HideWindow(gwin->win);
3201 if(strlen(gwin->wintitle) > 23) {
3202 strncpy(gwin->icontitle, gwin->wintitle, 20);
3203 gwin->icontitle[20] = '.';
3204 gwin->icontitle[21] = '.';
3205 gwin->icontitle[22] = '.';
3206 gwin->icontitle[23] = '\0';
3207 } else {
3208 strlcpy(gwin->icontitle, gwin->wintitle, 23);
3209 }
3210 gwin->appicon = AddAppIcon((ULONG)gwin->objects[OID_MAIN],
3211 (ULONG)gwin, gwin->icontitle, appport,
3212 0, gwin->dobj, NULL);
3213
3214 cur_gw = NULL;
3215 }
3216 break;
3217#endif
3218 case WMHI_INACTIVE:
3219 gwin->gw->c_h_temp = gwin->gw->c_h;
3221 break;
3222
3223 case WMHI_ACTIVE:
3224 if(gwin->gw->bw) cur_gw = gwin->gw;
3225 if(gwin->gw->c_h_temp)
3226 gwin->gw->c_h = gwin->gw->c_h_temp;
3227 break;
3228
3229 case WMHI_INTUITICK:
3230 break;
3231
3232 default:
3233 //printf("class: %ld\n",(result & WMHI_CLASSMASK));
3234 break;
3235 }
3236
3237 if(win_destroyed)
3238 {
3239 /* we can't be sure what state our window_list is in, so let's
3240 jump out of the function and start again */
3241
3242 win_destroyed = false;
3243 return TRUE;
3244 }
3245
3246 if(drag_x_move || drag_y_move)
3247 {
3248 struct rect rect;
3249
3251 &gwin->gw->scrollx, &gwin->gw->scrolly);
3252
3253 rect.x0 = rect.x1 = gwin->gw->scrollx + drag_x_move;
3254 rect.y0 = rect.y1 = gwin->gw->scrolly + drag_y_move;
3255
3256 gui_window_set_scroll(gwin->gw, &rect);
3257 }
3258
3259// ReplyMsg((struct Message *)message);
3260 }
3261
3262 if(gwin->closed == true) {
3263 win_closed = TRUE;
3265 }
3266
3267 return win_closed;
3268}
3269
3270static void ami_gui_appicon_remove(struct gui_window_2 *gwin)
3271{
3272 if(gwin->appicon)
3273 {
3274 RemoveAppIcon(gwin->appicon);
3275 amiga_icon_free(gwin->dobj);
3276 gwin->appicon = NULL;
3277 }
3278}
3279
3281{
3282 int bm_idx;
3286
3287 /* if this isn't the visible tab, don't do anything */
3288 if((gwin == NULL) || (gwin->gw != gw)) return NSERROR_OK;
3289
3291
3292 switch(pistate) {
3294 bm_idx = GID_PAGEINFO_INTERNAL_BM;
3295 break;
3296
3297 case PAGE_STATE_LOCAL:
3298 bm_idx = GID_PAGEINFO_LOCAL_BM;
3299 break;
3300
3302 bm_idx = GID_PAGEINFO_INSECURE_BM;
3303 break;
3304
3306 bm_idx = GID_PAGEINFO_WARNING_BM;
3307 break;
3308
3310 bm_idx = GID_PAGEINFO_WARNING_BM;
3311 break;
3312
3313 case PAGE_STATE_SECURE:
3314 bm_idx = GID_PAGEINFO_SECURE_BM;
3315 break;
3316
3317 default:
3318 bm_idx = GID_PAGEINFO_INTERNAL_BM;
3319 break;
3320 }
3321
3322 RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_PAGEINFO], gwin->win, NULL,
3323 BUTTON_RenderImage, gwin->objects[bm_idx],
3324 GA_HintInfo, gwin->helphints[bm_idx],
3325 TAG_DONE);
3326
3327 return NSERROR_OK;
3328}
3329
3330static void ami_handle_appmsg(void)
3331{
3332 struct AppMessage *appmsg;
3333 struct gui_window_2 *gwin;
3334 int x, y;
3335 struct WBArg *appwinargs;
3336 STRPTR filename;
3337 int i = 0;
3338
3339 while((appmsg = (struct AppMessage *)GetMsg(appport)))
3340 {
3341 gwin = (struct gui_window_2 *)appmsg->am_UserData;
3342
3343 if(appmsg->am_Type == AMTYPE_APPICON)
3344 {
3346 ShowWindow(gwin->win, WINDOW_FRONTMOST);
3347 ActivateWindow(gwin->win);
3348 }
3349 else if(appmsg->am_Type == AMTYPE_APPWINDOW)
3350 {
3351 for(i = 0; i < appmsg->am_NumArgs; ++i)
3352 {
3353 if((appwinargs = &appmsg->am_ArgList[i]))
3354 {
3355 if((filename = malloc(1024)))
3356 {
3357 if(appwinargs->wa_Lock)
3358 {
3359 NameFromLock(appwinargs->wa_Lock, filename, 1024);
3360 }
3361
3362 AddPart(filename, appwinargs->wa_Name, 1024);
3363
3364 if(ami_mouse_to_ns_coords(gwin, &x, &y,
3365 appmsg->am_MouseX, appmsg->am_MouseY) == false)
3366 {
3367 nsurl *url;
3368
3369 if (netsurf_path_to_nsurl(filename, &url) != NSERROR_OK) {
3370 amiga_warn_user("NoMemory", 0);
3371 }
3372 else
3373 {
3374 if(i == 0)
3375 {
3377 url,
3378 NULL,
3380 NULL,
3381 NULL,
3382 NULL);
3383
3384 ActivateWindow(gwin->win);
3385 }
3386 else
3387 {
3390 url,
3391 NULL,
3392 gwin->gw->bw,
3393 NULL);
3394 }
3395 nsurl_unref(url);
3396 }
3397 }
3398 else
3399 {
3400 if(browser_window_drop_file_at_point(gwin->gw->bw, x, y, filename) == false)
3401 {
3402 nsurl *url;
3403
3404 if (netsurf_path_to_nsurl(filename, &url) != NSERROR_OK) {
3405 amiga_warn_user("NoMemory", 0);
3406 }
3407 else
3408 {
3409
3410 if(i == 0)
3411 {
3413 url,
3414 NULL,
3416 NULL,
3417 NULL,
3418 NULL);
3419
3420 ActivateWindow(gwin->win);
3421 }
3422 else
3423 {
3426 url,
3427 NULL,
3428 gwin->gw->bw,
3429 NULL);
3430
3431 }
3432 nsurl_unref(url);
3433 }
3434 }
3435 }
3436 free(filename);
3437 }
3438 }
3439 }
3440 }
3441 ReplyMsg((struct Message *)appmsg);
3442 }
3443}
3444
3445static void ami_handle_applib(void)
3446{
3447#ifdef __amigaos4__
3448 struct ApplicationMsg *applibmsg;
3449 struct browser_window *bw;
3450 nsurl *url;
3451 nserror error;
3452
3453 if(!applibport) return;
3454
3455 while((applibmsg=(struct ApplicationMsg *)GetMsg(applibport)))
3456 {
3457 switch (applibmsg->type)
3458 {
3459 case APPLIBMT_NewBlankDoc:
3460 {
3461
3462 error = nsurl_create(nsoption_charp(homepage_url), &url);
3463 if (error == NSERROR_OK) {
3465 url,
3466 NULL,
3467 NULL,
3468 &bw);
3469 nsurl_unref(url);
3470 }
3471 if (error != NSERROR_OK) {
3473 }
3474 }
3475 break;
3476
3477 case APPLIBMT_OpenDoc:
3478 {
3479 struct ApplicationOpenPrintDocMsg *applibopdmsg =
3480 (struct ApplicationOpenPrintDocMsg *)applibmsg;
3481
3482 error = netsurf_path_to_nsurl(applibopdmsg->fileName, &url);
3483 if (error == NSERROR_OK) {
3485 url,
3486 NULL,
3487 NULL,
3488 &bw);
3489 nsurl_unref(url);
3490 }
3491 if (error != NSERROR_OK) {
3493 }
3494 }
3495 break;
3496
3497 case APPLIBMT_ToFront:
3498 if(cur_gw)
3499 {
3500 ScreenToFront(scrn);
3501 WindowToFront(cur_gw->shared->win);
3502 ActivateWindow(cur_gw->shared->win);
3503 }
3504 break;
3505
3506 case APPLIBMT_OpenPrefs:
3507 ScreenToFront(scrn);
3509 break;
3510
3511 case APPLIBMT_Quit:
3512 case APPLIBMT_ForceQuit:
3514 break;
3515
3516 case APPLIBMT_CustomMsg:
3517 {
3518 struct ApplicationCustomMsg *applibcustmsg =
3519 (struct ApplicationCustomMsg *)applibmsg;
3520 NSLOG(netsurf, INFO,
3521 "Ringhio BackMsg received: %s",
3522 applibcustmsg->customMsg);
3523
3524 ami_download_parse_backmsg(applibcustmsg->customMsg);
3525 }
3526 break;
3527 }
3528 ReplyMsg((struct Message *)applibmsg);
3529 }
3530#endif
3531}
3532
3533void ami_get_msg(void)
3534{
3535 ULONG winsignal = 1L << sport->mp_SigBit;
3536 ULONG appsig = 1L << appport->mp_SigBit;
3537 ULONG schedulesig = 1L << schedulermsgport->mp_SigBit;
3538 ULONG ctrlcsig = SIGBREAKF_CTRL_C;
3539 uint32 signal = 0;
3540 fd_set read_fd_set, write_fd_set, except_fd_set;
3541 int max_fd = -1;
3542 struct MsgPort *printmsgport = ami_print_get_msgport();
3543 ULONG printsig = 0;
3544 ULONG helpsignal = ami_help_signal();
3545 if(printmsgport) printsig = 1L << printmsgport->mp_SigBit;
3546 uint32 signalmask = winsignal | appsig | schedulesig | rxsig |
3547 printsig | applibsig | helpsignal;
3548
3549 if ((fetch_fdset(&read_fd_set, &write_fd_set, &except_fd_set, &max_fd) == NSERROR_OK) &&
3550 (max_fd != -1)) {
3551 /* max_fd is the highest fd in use, but waitselect() needs to know how many
3552 * are in use, so we add 1. */
3553
3554 if (waitselect(max_fd + 1, &read_fd_set, &write_fd_set, &except_fd_set,
3555 NULL, (unsigned int *)&signalmask) != -1) {
3556 signal = signalmask;
3557 } else {
3558 NSLOG(netsurf, INFO, "waitselect() returned error");
3559 /* \todo Fix Ctrl-C handling.
3560 * WaitSelect() from bsdsocket.library returns -1 if the task was
3561 * signalled with a Ctrl-C. waitselect() from newlib.library does not.
3562 * Adding the Ctrl-C signal to our user signal mask causes a Ctrl-C to
3563 * occur sporadically. Otherwise we never get a -1 except on error.
3564 * NetSurf still terminates at the Wait() when network activity is over.
3565 */
3566 }
3567 } else {
3568 /* If fetcher_fdset fails or no network activity, do it the old fashioned way. */
3569 signalmask |= ctrlcsig;
3570 signal = Wait(signalmask);
3571 }
3572
3573 if(signal & winsignal)
3574 while(ami_handle_msg());
3575
3576 if(signal & appsig)
3578
3579 if(signal & rxsig)
3581
3582 if(signal & applibsig)
3584
3585 if(signal & printsig) {
3586 while(GetMsg(printmsgport)); //ReplyMsg
3588 }
3589
3590 if(signal & schedulesig) {
3592 }
3593
3594 if(signal & helpsignal)
3596
3597 if(signal & ctrlcsig)
3599}
3600
3601static void ami_change_tab(struct gui_window_2 *gwin, int direction)
3602{
3603 struct Node *tab_node = gwin->gw->tab_node;
3604 struct Node *ptab = NULL;
3605
3606 if(gwin->tabs <= 1) return;
3607
3608 if(direction > 0) {
3609 ptab = GetSucc(tab_node);
3610 } else {
3611 ptab = GetPred(tab_node);
3612 }
3613
3614 if(!ptab) return;
3615
3616 RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_TABS], gwin->win, NULL,
3617 CLICKTAB_CurrentNode, ptab,
3618 TAG_DONE);
3619
3620 ami_switch_tab(gwin, true);
3621}
3622
3623
3624static void gui_window_set_title(struct gui_window *g, const char *restrict title)
3625{
3626 struct Node *node;
3627 char *restrict utf8title;
3628
3629 if(!g) return;
3630 if(!title) return;
3631
3632 utf8title = ami_utf8_easy((char *)title);
3633
3634 if(g->tab_node) {
3635 node = g->tab_node;
3636
3637 if((g->tabtitle == NULL) || (strcmp(utf8title, g->tabtitle)))
3638 {
3639 SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_TABS],
3640 g->shared->win, NULL,
3641 CLICKTAB_Labels, ~0,
3642 TAG_DONE);
3643
3644 if(g->tabtitle) free(g->tabtitle);
3645 g->tabtitle = strdup(utf8title);
3646
3647 SetClickTabNodeAttrs(node, TNA_Text, g->tabtitle,
3649 TAG_DONE);
3650
3651 RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_TABS],
3652 g->shared->win, NULL,
3653 CLICKTAB_Labels, &g->shared->tab_list,
3654 TAG_DONE);
3655
3656 if(ClickTabBase->lib_Version < 53)
3657 RethinkLayout((struct Gadget *)g->shared->objects[GID_TABLAYOUT],
3658 g->shared->win, NULL, TRUE);
3659 }
3660 }
3661
3662 if(g == g->shared->gw) {
3663 if((g->shared->wintitle == NULL) || (strcmp(utf8title, g->shared->wintitle)))
3664 {
3665 if(g->shared->wintitle) free(g->shared->wintitle);
3666 g->shared->wintitle = strdup(utf8title);
3667 SetWindowTitles(g->shared->win, g->shared->wintitle, ami_gui_get_screen_title());
3668 }
3669 }
3670
3671 ami_utf8_free(utf8title);
3672}
3673
3675{
3676 struct IBox *bbox;
3677
3678 if(!g || !g->bw) return;
3679 if(browser_window_has_content(g->bw) == false) return;
3680
3681 if(g == g->shared->gw) {
3682 int width, height;
3683 if(ami_gui_get_space_box((Object *)g->shared->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
3684 amiga_warn_user("NoMemory", "");
3685 return;
3686 }
3687
3688 if(g->shared->objects[GID_VSCROLL]) {
3690 RefreshSetGadgetAttrs((struct Gadget *)(APTR)g->shared->objects[GID_VSCROLL],g->shared->win,NULL,
3691 SCROLLER_Total, (ULONG)(height),
3692 SCROLLER_Visible, bbox->Height,
3693 TAG_DONE);
3694 }
3695
3696 if(g->shared->objects[GID_HSCROLL])
3697 {
3699 RefreshSetGadgetAttrs((struct Gadget *)(APTR)g->shared->objects[GID_HSCROLL],
3700 g->shared->win, NULL,
3701 SCROLLER_Total, (ULONG)(width),
3702 SCROLLER_Visible, bbox->Width,
3703 TAG_DONE);
3704 }
3705
3707 }
3708
3710 g->shared->new_content = true;
3711}
3712
3713
3714/**
3715 * Invalidates an area of an amiga browser window
3716 *
3717 * \param g gui_window
3718 * \param rect area to redraw or NULL for the entire window area
3719 * \return NSERROR_OK on success or appropriate error code
3720 */
3722 const struct rect *restrict rect)
3723{
3724 struct nsObject *nsobj;
3725 struct rect *restrict deferred_rect;
3726
3727 if(!g) return NSERROR_BAD_PARAMETER;
3728
3729 if (rect == NULL) {
3730 if (g != g->shared->gw) {
3731 return NSERROR_OK;
3732 }
3733 } else {
3735 g->deferred_rects_pool)) {
3737 sizeof(struct rect));
3738 CopyMem(rect, deferred_rect, sizeof(struct rect));
3739 nsobj = AddObject(g->deferred_rects, AMINS_RECT);
3740 nsobj->objstruct = deferred_rect;
3741 } else {
3742 NSLOG(netsurf, INFO,
3743 "Ignoring duplicate or subset of queued box redraw");
3744 }
3745 }
3746 ami_schedule_redraw(g->shared, false);
3747
3748 return NSERROR_OK;
3749}
3750
3751
3752static void ami_switch_tab(struct gui_window_2 *gwin, bool redraw)
3753{
3754 struct Node *tabnode;
3755 struct IBox *bbox;
3756
3757 /* Clear the last new tab list */
3758 gwin->last_new_tab = NULL;
3759
3760 if(gwin->tabs == 0) return;
3761
3763 &gwin->gw->scrollx, &gwin->gw->scrolly);
3764
3765 GetAttr(CLICKTAB_CurrentNode, (Object *)gwin->objects[GID_TABS],
3766 (ULONG *)&tabnode);
3767 GetClickTabNodeAttrs(tabnode,
3768 TNA_UserData, &gwin->gw,
3769 TAG_DONE);
3770 cur_gw = gwin->gw;
3771
3773
3774 if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
3775 amiga_warn_user("NoMemory", "");
3776 return;
3777 }
3778
3779 if((gwin->gw->bw == NULL) || (browser_window_has_content(gwin->gw->bw)) == false) {
3780 RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_URL],
3781 gwin->win, NULL, STRINGA_TextVal, "", TAG_DONE);
3782
3783 ami_plot_clear_bbox(gwin->win->RPort, bbox);
3785 return;
3786 }
3787
3789 ami_update_buttons(gwin);
3791
3792 if(redraw)
3793 {
3794 struct rect rect;
3795
3796 ami_plot_clear_bbox(gwin->win->RPort, bbox);
3800 amiga_window_invalidate_area(gwin->gw, NULL);
3801
3802 rect.x0 = rect.x1 = gwin->gw->scrollx;
3803 rect.y0 = rect.y1 = gwin->gw->scrolly;
3804
3805 gui_window_set_scroll(gwin->gw, &rect);
3806 gwin->redraw_scroll = false;
3807
3812
3813 gui_window_set_icon(gwin->gw, gwin->gw->favicon);
3814 gui_page_info_change(gwin->gw);
3815 }
3816
3818}
3819
3821{
3822 struct nsObject *node;
3823 struct nsObject *nnode;
3824 struct ami_generic_window *w;
3825
3826 /* Disable the multiple tabs open warning */
3827 nsoption_set_bool(tab_close_warn, false);
3828
3830 node = (struct nsObject *)GetHead((struct List *)window_list);
3831
3832 do {
3833 nnode=(struct nsObject *)GetSucc((struct Node *)node);
3834 w = node->objstruct;
3835
3836 if(w->tbl->close != NULL) {
3837 if(node->Type == AMINS_WINDOW) {
3838 struct gui_window_2 *gwin = (struct gui_window_2 *)w;
3839 ShowWindow(gwin->win, WINDOW_BACKMOST); // do we need this??
3840 }
3841 w->tbl->close(w);
3842 }
3843 } while((node = nnode));
3844
3845 win_destroyed = true;
3846 }
3847
3849 /* last window closed, so exit */
3850 ami_quit = true;
3851 }
3852}
3853
3855{
3856 int res = -1;
3857#ifdef __amigaos4__
3858 char *utf8text = ami_utf8_easy(messages_get("TCPIPShutdown"));
3859 char *utf8gadgets = ami_utf8_easy(messages_get("AbortShutdown"));
3860
3861 DisplayBeep(NULL);
3862
3863 res = TimedDosRequesterTags(TDR_ImageType, TDRIMAGE_INFO,
3864 TDR_TitleString, messages_get("NetSurf"),
3865 TDR_FormatString, utf8text,
3866 TDR_GadgetString, utf8gadgets,
3867 TDR_Timeout, 5,
3868 TDR_Inactive, TRUE,
3869 TAG_DONE);
3870
3871 free(utf8text);
3872 free(utf8gadgets);
3873#endif
3874 if(res == -1) { /* Requester timed out */
3876 }
3877}
3878
3879static void ami_gui_close_screen(struct Screen *scrn, BOOL locked_screen, BOOL donotwait)
3880{
3881 if(scrn == NULL) return;
3882
3883 if(locked_screen) {
3884 UnlockPubScreen(NULL,scrn);
3885 locked_screen = FALSE;
3886 }
3887
3888 /* If this is our own screen, wait for visitor windows to close */
3889 if(screen_signal == -1) return;
3890
3891 if(CloseScreen(scrn) == TRUE) {
3892 if(screen_signal != -1) {
3893 FreeSignal(screen_signal);
3894 screen_signal = -1;
3895 scrn = NULL;
3896 }
3897 return;
3898 }
3899 if(donotwait == TRUE) return;
3900
3901 ULONG scrnsig = 1 << screen_signal;
3902 NSLOG(netsurf, INFO,
3903 "Waiting for visitor windows to close... (signal)");
3904 Wait(scrnsig);
3905
3906 while (CloseScreen(scrn) == FALSE) {
3907 NSLOG(netsurf, INFO,
3908 "Waiting for visitor windows to close... (polling)");
3909 Delay(50);
3910 }
3911
3912 FreeSignal(screen_signal);
3913 screen_signal = -1;
3914 scrn = NULL;
3915}
3916
3918{
3919 if(!IsMinListEmpty(window_list)) return;
3920
3921 if(nsoption_bool(close_no_quit) == false)
3922 {
3923 ami_quit = true;
3924 return;
3925 }
3926 else
3927 {
3929 }
3930}
3931
3932static void gui_quit(void)
3933{
3935
3936 urldb_save(nsoption_charp(url_file));
3937 urldb_save_cookies(nsoption_charp(cookie_file));
3938 hotlist_fini();
3939#ifdef __amigaos4__
3940 if(IApplication && ami_appid)
3941 UnregisterApplication(ami_appid, NULL);
3942#endif
3944
3946
3947 ami_font_fini();
3948 ami_help_free();
3949
3950 NSLOG(netsurf, INFO, "Freeing menu items");
3953
3954 NSLOG(netsurf, INFO, "Freeing mouse pointers");
3956
3959#ifdef __amigaos4__
3960 FreeStringClass(urlStringClass);
3961#endif
3962
3964
3967
3968 NSLOG(netsurf, INFO, "Closing screen");
3970 if(nsscreentitle) FreeVec(nsscreentitle);
3971}
3972
3973char *ami_gui_get_cache_favicon_name(nsurl *url, bool only_if_avail)
3974{
3975 STRPTR filename = NULL;
3976
3977 if ((filename = ASPrintf("%s/%x", current_user_faviconcache, nsurl_hash(url)))) {
3978 NSLOG(netsurf, INFO, "favicon cache location: %s", filename);
3979
3980 if (only_if_avail == true) {
3981 BPTR lock = 0;
3982 if((lock = Lock(filename, ACCESS_READ))) {
3983 UnLock(lock);
3984 return filename;
3985 }
3986 } else {
3987 return filename;
3988 }
3989 }
3990 return NULL;
3991}
3992
3993static void ami_gui_cache_favicon(nsurl *url, struct bitmap *favicon)
3994{
3995 STRPTR filename = NULL;
3996
3997 if ((filename = ami_gui_get_cache_favicon_name(url, false))) {
3998 if(favicon) amiga_bitmap_save(favicon, filename, AMI_BITMAP_SCALE_ICON);
3999 FreeVec(filename);
4000 }
4001}
4002
4004{
4005 char *url;
4006 nsurl *nsurl;
4007
4008 GetAttr(STRINGA_TextVal,
4009 (Object *)gwin->objects[GID_URL],
4010 (ULONG *)&url);
4011
4012 if(nsurl_create(url, &nsurl) == NSERROR_OK) {
4013 if(hotlist_has_url(nsurl)) {
4014 RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_FAVE], gwin->win, NULL,
4015 BUTTON_RenderImage, gwin->objects[GID_FAVE_RMV],
4017 TAG_DONE);
4018
4019 if (gwin->gw->favicon)
4021 } else {
4022 RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_FAVE], gwin->win, NULL,
4023 BUTTON_RenderImage, gwin->objects[GID_FAVE_ADD],
4025 TAG_DONE);
4026 }
4027
4029 }
4030}
4031
4032static bool ami_gui_hotlist_add(void *userdata, int level, int item,
4033 const char *title, nsurl *url, bool is_folder)
4034{
4035 struct ami_gui_tb_userdata *tb_userdata = (struct ami_gui_tb_userdata *)userdata;
4036 struct Node *speed_button_node;
4037 char menu_icon[1024];
4038 char *utf8title = NULL;
4039
4040 if(level != 1) return false;
4041 if(item > AMI_GUI_TOOLBAR_MAX) return false;
4042 if(is_folder == true) return false;
4043
4044 if(utf8_to_local_encoding(title,
4045 (strlen(title) < NSA_MAX_HOTLIST_BUTTON_LEN) ? strlen(title) : NSA_MAX_HOTLIST_BUTTON_LEN,
4046 &utf8title) != NSERROR_OK)
4047 return false;
4048
4049 char *iconname = ami_gui_get_cache_favicon_name(url, true);
4050 if (iconname == NULL) iconname = ASPrintf("icons/content.png");
4051 ami_locate_resource(menu_icon, iconname);
4052
4053 tb_userdata->gw->hotlist_toolbar_lab[item] = BitMapObj,
4054 IA_Scalable, TRUE,
4055 BITMAP_Screen, scrn,
4056 BITMAP_SourceFile, menu_icon,
4057 BITMAP_Masking, TRUE,
4058 BitMapEnd;
4059
4060 /* \todo make this scale the bitmap to these dimensions */
4061 SetAttrs(tb_userdata->gw->hotlist_toolbar_lab[item],
4062 BITMAP_Width, 16,
4063 BITMAP_Height, 16,
4064 TAG_DONE);
4065
4066 Object *lab_item = LabelObj,
4067 // LABEL_DrawInfo, dri,
4068 LABEL_DisposeImage, TRUE,
4069 LABEL_Image, tb_userdata->gw->hotlist_toolbar_lab[item],
4070 LABEL_Text, " ",
4071 LABEL_Text, utf8title,
4072 LabelEnd;
4073
4074 free(utf8title);
4075
4076 speed_button_node = AllocSpeedButtonNode(item,
4077 SBNA_Image, lab_item,
4079 SBNA_UserData, (void *)url,
4080 TAG_DONE);
4081
4082 AddTail(tb_userdata->sblist, speed_button_node);
4083
4084 tb_userdata->items++;
4085 return true;
4086}
4087
4088static int ami_gui_hotlist_scan(struct List *speed_button_list, struct gui_window_2 *gwin)
4089{
4090 struct ami_gui_tb_userdata userdata;
4091 userdata.gw = gwin;
4092 userdata.sblist = speed_button_list;
4093 userdata.items = 0;
4094
4095 ami_hotlist_scan((void *)&userdata, 0, messages_get("HotlistToolbar"), ami_gui_hotlist_add);
4096 return userdata.items;
4097}
4098
4100{
4101 struct TagItem attrs[2];
4102
4103 attrs[0].ti_Tag = CHILD_MinWidth;
4104 attrs[0].ti_Data = 0;
4105 attrs[1].ti_Tag = TAG_DONE;
4106 attrs[1].ti_Data = 0;
4107
4108 NewList(&gwin->hotlist_toolbar_list);
4109
4110 if(ami_gui_hotlist_scan(&gwin->hotlist_toolbar_list, gwin) > 0) {
4111 gwin->objects[GID_HOTLIST] =
4113 GA_ID, GID_HOTLIST,
4114 GA_RelVerify, TRUE,
4115 ICA_TARGET, ICTARGET_IDCMP,
4116 SPEEDBAR_BevelStyle, BVS_NONE,
4117 SPEEDBAR_Buttons, &gwin->hotlist_toolbar_list,
4118 SpeedBarEnd;
4119
4120 gwin->objects[GID_HOTLISTSEPBAR] =
4121 BevelObj,
4122 BEVEL_Style, BVS_SBAR_VERT,
4123 BevelEnd;
4124#ifdef __amigaos4__
4125 IDoMethod(gwin->objects[GID_HOTLISTLAYOUT], LM_ADDCHILD,
4126 gwin->win, gwin->objects[GID_HOTLIST], attrs);
4127
4128 IDoMethod(gwin->objects[GID_HOTLISTLAYOUT], LM_ADDIMAGE,
4129 gwin->win, gwin->objects[GID_HOTLISTSEPBAR], NULL);
4130
4131#else
4132 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_HOTLISTLAYOUT],
4133 gwin->win, NULL,
4134 LAYOUT_AddChild, gwin->objects[GID_HOTLIST], TAG_MORE, &attrs);
4135 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_HOTLISTLAYOUT],
4136 gwin->win, NULL,
4137 LAYOUT_AddChild, gwin->objects[GID_HOTLISTSEPBAR], TAG_DONE);
4138#endif
4139
4140 FlushLayoutDomainCache((struct Gadget *)gwin->objects[GID_MAIN]);
4141
4142 RethinkLayout((struct Gadget *)gwin->objects[GID_MAIN],
4143 gwin->win, NULL, TRUE);
4144
4145 ami_schedule_redraw(gwin, true);
4146 }
4147}
4148
4149static void ami_gui_hotlist_toolbar_free(struct gui_window_2 *gwin, struct List *speed_button_list)
4150{
4151 int i;
4152 struct Node *node;
4153 struct Node *nnode;
4154
4155 if(nsoption_bool(kiosk_mode) == true) return;
4156
4157 if(IsListEmpty(speed_button_list)) return;
4158 node = GetHead(speed_button_list);
4159
4160 do {
4161 nnode = GetSucc(node);
4162 Remove(node);
4163 FreeSpeedButtonNode(node);
4164 } while((node = nnode));
4165
4166 for(i = 0; i < AMI_GUI_TOOLBAR_MAX; i++) {
4167 if(gwin->hotlist_toolbar_lab[i]) {
4168 DisposeObject(gwin->hotlist_toolbar_lab[i]);
4169 gwin->hotlist_toolbar_lab[i] = NULL;
4170 }
4171 }
4172}
4173
4175{
4176#ifdef __amigaos4__
4177 IDoMethod(gwin->objects[GID_HOTLISTLAYOUT], LM_REMOVECHILD,
4178 gwin->win, gwin->objects[GID_HOTLIST]);
4179
4180 IDoMethod(gwin->objects[GID_HOTLISTLAYOUT], LM_REMOVECHILD,
4181 gwin->win, gwin->objects[GID_HOTLISTSEPBAR]);
4182#else
4183 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_HOTLISTLAYOUT],
4184 gwin->win, NULL,
4185 LAYOUT_RemoveChild, gwin->objects[GID_HOTLIST], TAG_DONE);
4186 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_HOTLISTLAYOUT],
4187 gwin->win, NULL,
4188 LAYOUT_RemoveChild, gwin->objects[GID_HOTLISTSEPBAR], TAG_DONE);
4189#endif
4190 FlushLayoutDomainCache((struct Gadget *)gwin->objects[GID_MAIN]);
4191
4192 RethinkLayout((struct Gadget *)gwin->objects[GID_MAIN],
4193 gwin->win, NULL, TRUE);
4194
4195 ami_schedule_redraw(gwin, true);
4196}
4197
4199{
4200 if(IsListEmpty(&gwin->hotlist_toolbar_list)) {
4202 return;
4203 }
4204
4205 /* Below should be SetAttr according to Autodocs */
4206 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_HOTLIST],
4207 gwin->win, NULL,
4208 SPEEDBAR_Buttons, ~0,
4209 TAG_DONE);
4210
4212
4213 if(ami_gui_hotlist_scan(&gwin->hotlist_toolbar_list, gwin) > 0) {
4214 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_HOTLIST],
4215 gwin->win, NULL,
4216 SPEEDBAR_Buttons, &gwin->hotlist_toolbar_list,
4217 TAG_DONE);
4218 } else {
4220 }
4221}
4222
4223/**
4224 * Update hotlist toolbar and recreate the menu for all windows
4225 */
4227{
4228 struct nsObject *node;
4229 struct nsObject *nnode;
4230 struct gui_window_2 *gwin;
4231
4232 if(IsMinListEmpty(window_list)) return;
4233
4235
4236 node = (struct nsObject *)GetHead((struct List *)window_list);
4237
4238 do {
4239 nnode=(struct nsObject *)GetSucc((struct Node *)node);
4240 gwin = node->objstruct;
4241
4242 if(node->Type == AMINS_WINDOW) {
4244 }
4245 } while((node = nnode));
4246}
4247
4248static void ami_toggletabbar(struct gui_window_2 *gwin, bool show)
4249{
4250 if(ClickTabBase->lib_Version < 53) return;
4251
4252 if(show) {
4253 struct TagItem attrs[3];
4254
4255 attrs[0].ti_Tag = CHILD_WeightedWidth;
4256 attrs[0].ti_Data = 0;
4257 attrs[1].ti_Tag = CHILD_WeightedHeight;
4258 attrs[1].ti_Data = 0;
4259 attrs[2].ti_Tag = TAG_DONE;
4260 attrs[2].ti_Data = 0;
4261
4262 gwin->objects[GID_TABS] = ClickTabObj,
4263 GA_ID, GID_TABS,
4264 GA_RelVerify, TRUE,
4265 GA_Underscore, 13, // disable kb shortcuts
4267 CLICKTAB_Labels, &gwin->tab_list,
4271 ClickTabEnd;
4272
4273 gwin->objects[GID_ADDTAB] = ButtonObj,
4274 GA_ID, GID_ADDTAB,
4275 GA_RelVerify, TRUE,
4277 GA_Text, "+",
4278 BUTTON_RenderImage, gwin->objects[GID_ADDTAB_BM],
4279 ButtonEnd;
4280#ifdef __amigaos4__
4281 IDoMethod(gwin->objects[GID_TABLAYOUT], LM_ADDCHILD,
4282 gwin->win, gwin->objects[GID_TABS], NULL);
4283
4284 IDoMethod(gwin->objects[GID_TABLAYOUT], LM_ADDCHILD,
4285 gwin->win, gwin->objects[GID_ADDTAB], attrs);
4286#else
4287 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_TABLAYOUT],
4288 gwin->win, NULL,
4289 LAYOUT_AddChild, gwin->objects[GID_TABS], TAG_DONE);
4290 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_TABLAYOUT],
4291 gwin->win, NULL,
4292 LAYOUT_AddChild, gwin->objects[GID_ADDTAB], TAG_MORE, &attrs);
4293#endif
4294 } else {
4295#ifdef __amigaos4__
4296 IDoMethod(gwin->objects[GID_TABLAYOUT], LM_REMOVECHILD,
4297 gwin->win, gwin->objects[GID_TABS]);
4298
4299 IDoMethod(gwin->objects[GID_TABLAYOUT], LM_REMOVECHILD,
4300 gwin->win, gwin->objects[GID_ADDTAB]);
4301#else
4302 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_TABLAYOUT],
4303 gwin->win, NULL,
4304 LAYOUT_RemoveChild, gwin->objects[GID_TABS], TAG_DONE);
4305 SetGadgetAttrs((struct Gadget *)gwin->objects[GID_TABLAYOUT],
4306 gwin->win, NULL,
4307 LAYOUT_RemoveChild, gwin->objects[GID_ADDTAB], TAG_DONE);
4308#endif
4309
4310 gwin->objects[GID_TABS] = NULL;
4311 gwin->objects[GID_ADDTAB] = NULL;
4312 }
4313
4314 FlushLayoutDomainCache((struct Gadget *)gwin->objects[GID_MAIN]);
4315
4316 RethinkLayout((struct Gadget *)gwin->objects[GID_MAIN],
4317 gwin->win, NULL, TRUE);
4318
4319 if (gwin->gw && gwin->gw->bw) {
4323 amiga_window_invalidate_area(gwin->gw, NULL);
4324 }
4325}
4326
4328{
4329 struct nsObject *node;
4330 struct nsObject *nnode;
4331 struct gui_window_2 *gwin;
4332
4333 if(IsMinListEmpty(window_list)) return;
4334
4335 node = (struct nsObject *)GetHead((struct List *)window_list);
4336
4337 do {
4338 nnode=(struct nsObject *)GetSucc((struct Node *)node);
4339 gwin = node->objstruct;
4340
4341 if(node->Type == AMINS_WINDOW)
4342 {
4343 if(gwin->tabs == 1) {
4344 if(nsoption_bool(tab_always_show) == true) {
4345 ami_toggletabbar(gwin, true);
4346 } else {
4347 ami_toggletabbar(gwin, false);
4348 }
4349 }
4350 }
4351 } while((node = nnode));
4352}
4353
4354
4355/**
4356 * Count windows, and optionally tabs.
4357 *
4358 * \param window window to count tabs of
4359 * \param tabs if window > 0, will be updated to contain the number of tabs
4360 * in that window, unchanged otherwise
4361 * \return number of windows currently open
4362 */
4363int ami_gui_count_windows(int window, int *tabs)
4364{
4365 int windows = 0;
4366 struct nsObject *node, *nnode;
4367 struct gui_window_2 *gwin;
4368
4370 node = (struct nsObject *)GetHead((struct List *)window_list);
4371 do {
4372 nnode=(struct nsObject *)GetSucc((struct Node *)node);
4373
4374 gwin = node->objstruct;
4375
4376 if(node->Type == AMINS_WINDOW) {
4377 windows++;
4378 if(window == windows) *tabs = gwin->tabs;
4379 }
4380 } while((node = nnode));
4381 }
4382 return windows;
4383}
4384
4385/**
4386 * Set the scale of a gui window
4387 *
4388 * \param gw gui_window to set scale for
4389 * \param scale scale to set
4390 */
4391void ami_gui_set_scale(struct gui_window *gw, float scale)
4392{
4393 browser_window_set_scale(gw->bw, scale, true);
4394 ami_schedule_redraw(gw->shared, true);
4395}
4396
4397void ami_gui_adjust_scale(struct gui_window *gw, float adjustment)
4398{
4399 browser_window_set_scale(gw->bw, adjustment, false);
4400 ami_schedule_redraw(gw->shared, true);
4401}
4402
4404{
4405 nsurl *url;
4406 nserror error;
4407 struct browser_window *bw = NULL;
4408
4409 error = nsurl_create(nsoption_charp(homepage_url), &url);
4410 if (error == NSERROR_OK) {
4413 url,
4414 NULL,
4415 gwin->gw->bw,
4416 &bw);
4417 nsurl_unref(url);
4418 }
4419 if (error != NSERROR_OK) {
4421 return error;
4422 }
4423
4424 return NSERROR_OK;
4425}
4426
4427static void ami_do_redraw_tiled(struct gui_window_2 *gwin, bool busy,
4428 int left, int top, int width, int height,
4429 int sx, int sy, struct IBox *bbox, struct redraw_context *ctx)
4430{
4431 struct gui_globals *glob = (struct gui_globals *)ctx->priv;
4432 int x, y;
4433 struct rect clip;
4434 int tile_size_x;
4435 int tile_size_y;
4436
4437 ami_plot_ra_get_size(glob, &tile_size_x, &tile_size_y);
4439
4440 if(top < 0) {
4441 height += top;
4442 top = 0;
4443 }
4444
4445 if(left < 0) {
4446 width += left;
4447 left = 0;
4448 }
4449
4450 if(top < sy) {
4451 height += (top - sy);
4452 top = sy;
4453 }
4454 if(left < sx) {
4455 width += (left - sx);
4456 left = sx;
4457 }
4458
4459 if(((top - sy) + height) > bbox->Height)
4460 height = bbox->Height - (top - sy);
4461
4462 if(((left - sx) + width) > bbox->Width)
4463 width = bbox->Width - (left - sx);
4464
4465 if(width <= 0) return;
4466 if(height <= 0) return;
4467
4468 if(busy) ami_set_pointer(gwin, GUI_POINTER_WAIT, false);
4469
4470 for(y = top; y < (top + height); y += tile_size_y) {
4471 clip.y0 = 0;
4472 clip.y1 = tile_size_y;
4473 if(clip.y1 > height) clip.y1 = height;
4474 if(((y - sy) + clip.y1) > bbox->Height)
4475 clip.y1 = bbox->Height - (y - sy);
4476
4477 for(x = left; x < (left + width); x += tile_size_x) {
4478 clip.x0 = 0;
4479 clip.x1 = tile_size_x;
4480 if(clip.x1 > width) clip.x1 = width;
4481 if(((x - sx) + clip.x1) > bbox->Width)
4482 clip.x1 = bbox->Width - (x - sx);
4483
4484 if(browser_window_redraw(gwin->gw->bw,
4485 clip.x0 - (int)x,
4486 clip.y0 - (int)y,
4487 &clip, ctx))
4488 {
4489 ami_clearclipreg(glob);
4490#ifdef __amigaos4__
4491 BltBitMapTags(BLITA_SrcType, BLITT_BITMAP,
4492 BLITA_Source, ami_plot_ra_get_bitmap(glob),
4493 BLITA_SrcX, 0,
4494 BLITA_SrcY, 0,
4495 BLITA_DestType, BLITT_RASTPORT,
4496 BLITA_Dest, gwin->win->RPort,
4497 BLITA_DestX, bbox->Left + (int)(x - sx),
4498 BLITA_DestY, bbox->Top + (int)(y - sy),
4499 BLITA_Width, (int)(clip.x1),
4500 BLITA_Height, (int)(clip.y1),
4501 TAG_DONE);
4502#else
4503 BltBitMapRastPort(ami_plot_ra_get_bitmap(glob), 0, 0, gwin->win->RPort,
4504 bbox->Left + (int)(x - sx),
4505 bbox->Top + (int)(y - sy),
4506 (int)(clip.x1), (int)(clip.y1), 0xC0);
4507#endif
4508 }
4509 }
4510 }
4511
4512 if(busy) ami_reset_pointer(gwin);
4513}
4514
4515
4516/**
4517 * Redraw an area of the browser window - Amiga-specific function
4518 *
4519 * \param g a struct gui_window
4520 * \param bw a struct browser_window
4521 * \param busy busy flag passed to tiled redraw.
4522 * \param x0 top-left co-ordinate (in document co-ordinates)
4523 * \param y0 top-left co-ordinate (in document co-ordinates)
4524 * \param x1 bottom-right co-ordinate (in document co-ordinates)
4525 * \param y1 bottom-right co-ordinate (in document co-ordinates)
4526 */
4527
4528static void ami_do_redraw_limits(struct gui_window *g, struct browser_window *bw, bool busy,
4529 int x0, int y0, int x1, int y1)
4530{
4531 struct IBox *bbox;
4532 ULONG sx, sy;
4533
4534 struct redraw_context ctx = {
4535 .interactive = true,
4536 .background_images = true,
4537 .plot = &amiplot,
4538 .priv = browserglob
4539 };
4540
4541 if(!g) return;
4542 if(browser_window_redraw_ready(bw) == false) return;
4543
4544 sx = g->scrollx;
4545 sy = g->scrolly;
4546
4547 if(g != g->shared->gw) return;
4548
4549 if(ami_gui_get_space_box((Object *)g->shared->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
4550 amiga_warn_user("NoMemory", "");
4551 return;
4552 }
4553
4554 ami_do_redraw_tiled(g->shared, busy, x0, y0,
4555 x1 - x0, y1 - y0, sx, sy, bbox, &ctx);
4556
4558
4559 return;
4560}
4561
4562
4563static void ami_refresh_window(struct gui_window_2 *gwin)
4564{
4565 /* simplerefresh only */
4566
4567 struct IBox *bbox;
4568 int sx, sy;
4569 struct RegionRectangle *regrect;
4570 struct rect r;
4571
4572 sx = gwin->gw->scrollx;
4573 sy = gwin->gw->scrolly;
4574
4575 ami_set_pointer(gwin, GUI_POINTER_WAIT, false);
4576
4577 if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
4578 amiga_warn_user("NoMemory", "");
4579 return;
4580 }
4581
4582 BeginRefresh(gwin->win);
4583
4584 r.x0 = (gwin->win->RPort->Layer->DamageList->bounds.MinX - bbox->Left) + sx - 1;
4585 r.x1 = (gwin->win->RPort->Layer->DamageList->bounds.MaxX - bbox->Left) + sx + 2;
4586 r.y0 = (gwin->win->RPort->Layer->DamageList->bounds.MinY - bbox->Top) + sy - 1;
4587 r.y1 = (gwin->win->RPort->Layer->DamageList->bounds.MaxY - bbox->Top) + sy + 2;
4588
4589 regrect = gwin->win->RPort->Layer->DamageList->RegionRectangle;
4590
4592
4593 while(regrect)
4594 {
4595 r.x0 = (regrect->bounds.MinX - bbox->Left) + sx - 1;
4596 r.x1 = (regrect->bounds.MaxX - bbox->Left) + sx + 2;
4597 r.y0 = (regrect->bounds.MinY - bbox->Top) + sy - 1;
4598 r.y1 = (regrect->bounds.MaxY - bbox->Top) + sy + 2;
4599
4600 regrect = regrect->Next;
4601
4603 }
4604
4605 EndRefresh(gwin->win, TRUE);
4606
4608 ami_reset_pointer(gwin);
4609}
4610
4611HOOKF(void, ami_scroller_hook, Object *, object, struct IntuiMessage *)
4612{
4613 ULONG gid;
4614 struct gui_window_2 *gwin = hook->h_Data;
4615 struct IntuiWheelData *wheel;
4616 struct Node *node = NULL;
4617 nsurl *url;
4618
4619 switch(msg->Class)
4620 {
4621 case IDCMP_IDCMPUPDATE:
4622 gid = GetTagData( GA_ID, 0, msg->IAddress );
4623
4624 switch( gid )
4625 {
4626 case GID_HSCROLL:
4627 case GID_VSCROLL:
4628 if(nsoption_bool(faster_scroll) == true) gwin->redraw_scroll = true;
4629 else gwin->redraw_scroll = false;
4630
4631 ami_schedule_redraw(gwin, true);
4632 break;
4633
4634 case GID_HOTLIST:
4635 if((node = (struct Node *)GetTagData(SPEEDBAR_SelectedNode, 0, msg->IAddress))) {
4636 GetSpeedButtonNodeAttrs(node, SBNA_UserData, (ULONG *)&url, TAG_DONE);
4637
4638 if(gwin->key_state & BROWSER_MOUSE_MOD_2) {
4640 url,
4641 NULL,
4642 gwin->gw->bw,
4643 NULL);
4644 } else {
4646 url,
4647 NULL,
4649 NULL,
4650 NULL,
4651 NULL);
4652
4653 }
4654 }
4655 break;
4656 }
4657 break;
4658#ifdef __amigaos4__
4660 if(msg->Code == IMSGCODE_INTUIWHEELDATA)
4661 {
4662 wheel = (struct IntuiWheelData *)msg->IAddress;
4663
4664 ami_gui_scroll_internal(gwin, wheel->WheelX * 50, wheel->WheelY * 50);
4665 }
4666 break;
4667#endif
4668 case IDCMP_SIZEVERIFY:
4669 break;
4670
4671 case IDCMP_REFRESHWINDOW:
4672 ami_refresh_window(gwin);
4673 break;
4674
4675 default:
4676 NSLOG(netsurf, INFO,
4677 "IDCMP hook unhandled event: %ld", msg->Class);
4678 break;
4679 }
4680// ReplyMsg((struct Message *)msg);
4681}
4682
4683/* exported function documented in gui.h */
4684nserror ami_gui_win_list_add(void *win, int type, const struct ami_win_event_table *table)
4685{
4686 struct nsObject *node = AddObject(window_list, type);
4687 if(node == NULL) return NSERROR_NOMEM;
4688 node->objstruct = win;
4689
4690 struct ami_generic_window *w = (struct ami_generic_window *)win;
4691 w->tbl = table;
4692 w->node = node;
4693
4694 return NSERROR_OK;
4695}
4696
4697/* exported function documented in gui.h */
4699{
4700 struct ami_generic_window *w = (struct ami_generic_window *)win;
4701
4702 if(w->node->Type == AMINS_TVWINDOW) {
4704 } else {
4705 DelObject(w->node);
4706 }
4707}
4708
4709static const struct ami_win_event_table ami_gui_table = {
4712};
4713
4714static struct gui_window *
4716 struct gui_window *existing,
4718{
4719 struct gui_window *g = NULL;
4720 ULONG offset = 0;
4721 struct Window *ref = NULL;
4722 char nav_west[100],nav_west_s[100],nav_west_g[100];
4723 char nav_east[100],nav_east_s[100],nav_east_g[100];
4724 char stop[100],stop_s[100],stop_g[100];
4725 char reload[100],reload_s[100],reload_g[100];
4726 char home[100],home_s[100],home_g[100];
4727 char closetab[100],closetab_s[100],closetab_g[100];
4728 char addtab[100],addtab_s[100],addtab_g[100];
4729 char fave[100], unfave[100];
4730 char pi_insecure[100], pi_internal[100], pi_local[100], pi_secure[100], pi_warning[100];
4731 char tabthrobber[100];
4732 ULONG refresh_mode = WA_SmartRefresh;
4733 ULONG defer_layout = TRUE;
4734 ULONG idcmp_sizeverify = IDCMP_SIZEVERIFY;
4735
4736 NSLOG(netsurf, INFO, "Creating window");
4737
4738 if (!scrn) ami_openscreenfirst();
4739
4740 if (nsoption_bool(kiosk_mode)) flags &= ~GW_CREATE_TAB;
4741 if (nsoption_bool(resize_with_contents)) idcmp_sizeverify = 0;
4742
4743 if(existing) {
4744 ref = existing->shared->win;
4745 }
4746
4747 g = calloc(1, sizeof(struct gui_window));
4748
4749 if(!g)
4750 {
4751 amiga_warn_user("NoMemory","");
4752 return NULL;
4753 }
4754
4755 NewList(&g->dllist);
4758 g->bw = bw;
4759
4760 NewList(&g->loglist);
4761#ifdef __amigaos4__
4762 g->logcolumns = AllocLBColumnInfo(4,
4763 LBCIA_Column, 0,
4764 // LBCIA_CopyTitle, TRUE,
4765 LBCIA_Title, "time", /**\TODO: add these to Messages */
4766 LBCIA_Weight, 10,
4767 LBCIA_DraggableSeparator, TRUE,
4768 LBCIA_Separator, TRUE,
4769 LBCIA_Column, 1,
4770 // LBCIA_CopyTitle, TRUE,
4771 LBCIA_Title, "source", /**\TODO: add these to Messages */
4772 LBCIA_Weight, 10,
4773 LBCIA_DraggableSeparator, TRUE,
4774 LBCIA_Separator, TRUE,
4775 LBCIA_Column, 2,
4776 // LBCIA_CopyTitle, TRUE,
4777 LBCIA_Title, "level", /**\TODO: add these to Messages */
4778 LBCIA_Weight, 5,
4779 LBCIA_DraggableSeparator, TRUE,
4780 LBCIA_Separator, TRUE,
4781 LBCIA_Column, 3,
4782 // LBCIA_CopyTitle, TRUE,
4783 LBCIA_Title, "message", /**\TODO: add these to Messages */
4784 LBCIA_Weight, 75,
4785 LBCIA_DraggableSeparator, TRUE,
4786 LBCIA_Separator, TRUE,
4787 TAG_DONE);
4788#else
4789 /**\TODO write OS3-compatible version */
4790#endif
4791
4792 if((flags & GW_CREATE_TAB) && existing)
4793 {
4794 g->shared = existing->shared;
4795 g->tab = g->shared->next_tab;
4796 g->shared->tabs++; /* do this early so functions know to update the tabs */
4797
4798 if((g->shared->tabs == 2) && (nsoption_bool(tab_always_show) == false)) {
4799 ami_toggletabbar(g->shared, true);
4800 }
4801
4802 SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_TABS],
4803 g->shared->win, NULL,
4804 CLICKTAB_Labels, ~0,
4805 TAG_DONE);
4806
4807 g->tab_node = AllocClickTabNode(TNA_Text, messages_get("NetSurf"),
4808 TNA_Number, g->tab,
4809 TNA_UserData, g,
4810 TNA_CloseGadget, TRUE,
4811 TAG_DONE);
4812
4813 if(nsoption_bool(new_tab_last)) {
4814 AddTail(&g->shared->tab_list, g->tab_node);
4815 } else {
4816 struct Node *insert_after = existing->tab_node;
4817
4818 if(g->shared->last_new_tab)
4819 insert_after = g->shared->last_new_tab;
4820 Insert(&g->shared->tab_list, g->tab_node, insert_after);
4821 }
4822
4823 g->shared->last_new_tab = g->tab_node;
4824
4825 RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_TABS],
4826 g->shared->win, NULL,
4827 CLICKTAB_Labels, &g->shared->tab_list,
4828 TAG_DONE);
4829
4830 if(flags & GW_CREATE_FOREGROUND) {
4831 RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_TABS],
4832 g->shared->win, NULL,
4833 CLICKTAB_Current, g->tab,
4834 TAG_DONE);
4835 }
4836
4837 if(ClickTabBase->lib_Version < 53) {
4838 RethinkLayout((struct Gadget *)g->shared->objects[GID_TABLAYOUT],
4839 g->shared->win, NULL, TRUE);
4840 }
4841
4842 g->shared->next_tab++;
4843
4844 if(flags & GW_CREATE_FOREGROUND) ami_switch_tab(g->shared,false);
4845
4848
4849 return g;
4850 }
4851
4852 g->shared = calloc(1, sizeof(struct gui_window_2));
4853
4854 if(!g->shared)
4855 {
4856 amiga_warn_user("NoMemory","");
4857 return NULL;
4858 }
4859
4861
4862 g->shared->scrollerhook.h_Entry = (void *)ami_scroller_hook;
4863 g->shared->scrollerhook.h_Data = g->shared;
4864
4865 g->shared->favicon_hook.h_Entry = (void *)ami_set_favicon_render_hook;
4866 g->shared->favicon_hook.h_Data = g->shared;
4867
4868 g->shared->throbber_hook.h_Entry = (void *)ami_set_throbber_render_hook;
4869 g->shared->throbber_hook.h_Data = g->shared;
4870
4871 g->shared->browser_hook.h_Entry = (void *)ami_gui_browser_render_hook;
4872 g->shared->browser_hook.h_Data = g->shared;
4873
4874 newprefs_hook.h_Entry = (void *)ami_gui_newprefs_hook;
4875 newprefs_hook.h_Data = 0;
4876
4880 g->shared->clicktab_ctxmenu = NULL;
4881
4882 if(nsoption_bool(window_simple_refresh) == true) {
4883 refresh_mode = WA_SimpleRefresh;
4884 defer_layout = FALSE; /* testing reveals this does work with SimpleRefresh,
4885 but the docs say it doesn't so err on the side of caution. */
4886 } else {
4887 refresh_mode = WA_SmartRefresh;
4888 defer_layout = TRUE;
4889 }
4890
4891 if(!nsoption_bool(kiosk_mode))
4892 {
4893 ULONG addtabclosegadget = TAG_IGNORE;
4894 ULONG iconifygadget = FALSE;
4895 int ws_idx = 0;
4896
4897#ifdef __amigaos4__
4898 if (nsoption_charp(pubscreen_name) &&
4899 (locked_screen == TRUE) &&
4900 (strcmp(nsoption_charp(pubscreen_name), "Workbench") == 0))
4901 iconifygadget = TRUE;
4902#endif
4903
4904 NSLOG(netsurf, INFO, "Creating menu");
4905 struct Menu *menu = ami_gui_menu_create(g->shared);
4906
4907 NewList(&g->shared->tab_list);
4908 g->tab_node = AllocClickTabNode(TNA_Text,messages_get("NetSurf"),
4909 TNA_Number, 0,
4910 TNA_UserData, g,
4911 TNA_CloseGadget, TRUE,
4912 TAG_DONE);
4913 AddTail(&g->shared->tab_list,g->tab_node);
4914
4916 g->shared->search_bm = NULL;
4917
4918 g->shared->tabs=1;
4919 g->shared->next_tab=1;
4920
4921 g->shared->svbuffer = calloc(1, 2000);
4922
4924 translate_escape_chars(messages_get("HelpToolbarBack"));
4926 translate_escape_chars(messages_get("HelpToolbarForward"));
4928 translate_escape_chars(messages_get("HelpToolbarStop"));
4930 translate_escape_chars(messages_get("HelpToolbarReload"));
4932 translate_escape_chars(messages_get("HelpToolbarHome"));
4933 g->shared->helphints[GID_URL] =
4934 translate_escape_chars(messages_get("HelpToolbarURL"));
4936 translate_escape_chars(messages_get("HelpToolbarWebSearch"));
4938 translate_escape_chars(messages_get("HelpToolbarAddTab"));
4939
4945
4946 g->shared->helphints[GID_FAVE_ADD] = ami_utf8_easy(messages_get("HelpToolbarHotlistStar"));
4947 g->shared->helphints[GID_FAVE_RMV] = ami_utf8_easy(messages_get("HelpToolbarHotlistStarLit"));
4948
4949 ami_get_theme_filename(nav_west, "theme_nav_west", false);
4950 ami_get_theme_filename(nav_west_s, "theme_nav_west_s", false);
4951 ami_get_theme_filename(nav_west_g, "theme_nav_west_g", false);
4952 ami_get_theme_filename(nav_east, "theme_nav_east", false);
4953 ami_get_theme_filename(nav_east_s, "theme_nav_east_s", false);
4954 ami_get_theme_filename(nav_east_g, "theme_nav_east_g", false);
4955 ami_get_theme_filename(stop, "theme_stop", false);
4956 ami_get_theme_filename(stop_s, "theme_stop_s", false);
4957 ami_get_theme_filename(stop_g, "theme_stop_g", false);
4958 ami_get_theme_filename(reload, "theme_reload", false);
4959 ami_get_theme_filename(reload_s, "theme_reload_s", false);
4960 ami_get_theme_filename(reload_g, "theme_reload_g", false);
4961 ami_get_theme_filename(home, "theme_home", false);
4962 ami_get_theme_filename(home_s, "theme_home_s", false);
4963 ami_get_theme_filename(home_g, "theme_home_g", false);
4964 ami_get_theme_filename(closetab, "theme_closetab", false);
4965 ami_get_theme_filename(closetab_s, "theme_closetab_s", false);
4966 ami_get_theme_filename(closetab_g, "theme_closetab_g", false);
4967 ami_get_theme_filename(addtab, "theme_addtab", false);
4968 ami_get_theme_filename(addtab_s, "theme_addtab_s", false);
4969 ami_get_theme_filename(addtab_g, "theme_addtab_g", false);
4970 ami_get_theme_filename(tabthrobber, "theme_tab_loading", false);
4971 ami_get_theme_filename(fave, "theme_fave", false);
4972 ami_get_theme_filename(unfave, "theme_unfave", false);
4973 ami_get_theme_filename(pi_insecure, "theme_pageinfo_insecure", false);
4974 ami_get_theme_filename(pi_internal, "theme_pageinfo_internal", false);
4975 ami_get_theme_filename(pi_local, "theme_pageinfo_local", false);
4976 ami_get_theme_filename(pi_secure, "theme_pageinfo_secure", false);
4977 ami_get_theme_filename(pi_warning, "theme_pageinfo_warning", false);
4978
4980 BITMAP_SourceFile, fave,
4981 BITMAP_Screen, scrn,
4982 BITMAP_Masking, TRUE,
4983 BitMapEnd;
4984
4986 BITMAP_SourceFile, unfave,
4987 BITMAP_Screen, scrn,
4988 BITMAP_Masking, TRUE,
4989 BitMapEnd;
4990
4992 BITMAP_SourceFile, addtab,
4993 BITMAP_SelectSourceFile, addtab_s,
4994 BITMAP_DisabledSourceFile, addtab_g,
4995 BITMAP_Screen, scrn,
4996 BITMAP_Masking, TRUE,
4997 BitMapEnd;
4998
5000 BITMAP_SourceFile, closetab,
5001 BITMAP_SelectSourceFile, closetab_s,
5002 BITMAP_DisabledSourceFile, closetab_g,
5003 BITMAP_Screen, scrn,
5004 BITMAP_Masking, TRUE,
5005 BitMapEnd;
5006
5008 BITMAP_SourceFile, pi_insecure,
5009 BITMAP_Screen, scrn,
5010 BITMAP_Masking, TRUE,
5011 BitMapEnd;
5012
5014 BITMAP_SourceFile, pi_internal,
5015 BITMAP_Screen, scrn,
5016 BITMAP_Masking, TRUE,
5017 BitMapEnd;
5018
5020 BITMAP_SourceFile, pi_local,
5021 BITMAP_Screen, scrn,
5022 BITMAP_Masking, TRUE,
5023 BitMapEnd;
5024
5026 BITMAP_SourceFile, pi_secure,
5027 BITMAP_Screen, scrn,
5028 BITMAP_Masking, TRUE,
5029 BitMapEnd;
5030
5032 BITMAP_SourceFile, pi_warning,
5033 BITMAP_Screen, scrn,
5034 BITMAP_Masking, TRUE,
5035 BitMapEnd;
5036
5037
5038 if(ClickTabBase->lib_Version < 53)
5039 {
5040 addtabclosegadget = LAYOUT_AddChild;
5042 GA_ID, GID_CLOSETAB,
5043 GA_RelVerify, TRUE,
5044 BUTTON_RenderImage, g->shared->objects[GID_CLOSETAB_BM],
5045 ButtonEnd;
5046
5048 GA_ID,GID_TABS,
5049 GA_RelVerify,TRUE,
5050 GA_Underscore,13, // disable kb shortcuts
5051 CLICKTAB_Labels,&g->shared->tab_list,
5053 ClickTabEnd;
5054
5056 GA_ID, GID_ADDTAB,
5057 GA_RelVerify, TRUE,
5058 GA_Text, "+",
5059 BUTTON_RenderImage, g->shared->objects[GID_ADDTAB_BM],
5060 ButtonEnd;
5061 }
5062 else
5063 {
5065 BITMAP_SourceFile, tabthrobber,
5066 BITMAP_Screen,scrn,
5067 BITMAP_Masking,TRUE,
5068 BitMapEnd;
5069 }
5070
5071 NSLOG(netsurf, INFO, "Creating window object");
5072
5074 WA_ScreenTitle, ami_gui_get_screen_title(),
5075 WA_Activate, TRUE,
5076 WA_DepthGadget, TRUE,
5077 WA_DragBar, TRUE,
5078 WA_CloseGadget, TRUE,
5079 WA_SizeGadget, TRUE,
5080 WA_PubScreen,scrn,
5081 WA_ReportMouse,TRUE,
5082 refresh_mode, TRUE,
5083 WA_SizeBBottom, TRUE,
5085 WA_IDCMP, IDCMP_MENUPICK | IDCMP_MOUSEMOVE |
5086 IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
5087 IDCMP_RAWKEY | idcmp_sizeverify |
5088 IDCMP_GADGETUP | IDCMP_IDCMPUPDATE |
5089 IDCMP_REFRESHWINDOW |
5090 IDCMP_ACTIVEWINDOW | IDCMP_EXTENDEDMOUSE,
5091 WINDOW_Position, WPOS_FULLSCREEN,
5092 WINDOW_RefWindow, ref,
5093 WINDOW_IconifyGadget, iconifygadget,
5094 WINDOW_MenuStrip, menu,
5095 WINDOW_MenuUserData, WGUD_HOOK,
5097 WINDOW_IDCMPHook, &g->shared->scrollerhook,
5098 WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE | IDCMP_REFRESHWINDOW |
5099 IDCMP_EXTENDEDMOUSE | IDCMP_SIZEVERIFY,
5100 WINDOW_SharedPort, sport,
5102 WINDOW_GadgetHelp, TRUE,
5103#ifdef __amigaos4__
5104 WINDOW_UniqueID, "NS_MAIN_WIN",
5105 WINDOW_PopupGadget, TRUE,
5106#endif
5107 WINDOW_UserData, g->shared,
5108 WINDOW_ParentGroup, g->shared->objects[GID_MAIN] = LayoutVObj,
5109 LAYOUT_DeferLayout, defer_layout,
5110 LAYOUT_SpaceOuter, TRUE,
5111 LAYOUT_AddChild, g->shared->objects[GID_TOOLBARLAYOUT] = LayoutHObj,
5112 LAYOUT_VertAlignment, LALIGN_CENTER,
5113 LAYOUT_AddChild, g->shared->objects[GID_BACK] = ButtonObj,
5114 GA_ID, GID_BACK,
5115 GA_RelVerify, TRUE,
5116 GA_Disabled, TRUE,
5119 BUTTON_RenderImage,BitMapObj,
5120 BITMAP_SourceFile,nav_west,
5121 BITMAP_SelectSourceFile,nav_west_s,
5122 BITMAP_DisabledSourceFile,nav_west_g,
5123 BITMAP_Screen,scrn,
5124 BITMAP_Masking,TRUE,
5125 BitMapEnd,
5126 ButtonEnd,
5127 CHILD_WeightedWidth,0,
5128 CHILD_WeightedHeight,0,
5129 LAYOUT_AddChild, g->shared->objects[GID_FORWARD] = ButtonObj,
5130 GA_ID, GID_FORWARD,
5131 GA_RelVerify, TRUE,
5132 GA_Disabled, TRUE,
5135 BUTTON_RenderImage,BitMapObj,
5136 BITMAP_SourceFile,nav_east,
5137 BITMAP_SelectSourceFile,nav_east_s,
5138 BITMAP_DisabledSourceFile,nav_east_g,
5139 BITMAP_Screen,scrn,
5140 BITMAP_Masking,TRUE,
5141 BitMapEnd,
5142 ButtonEnd,
5143 CHILD_WeightedWidth,0,
5144 CHILD_WeightedHeight,0,
5145 LAYOUT_AddChild, g->shared->objects[GID_STOP] = ButtonObj,
5146 GA_ID,GID_STOP,
5147 GA_RelVerify,TRUE,
5149 BUTTON_RenderImage,BitMapObj,
5150 BITMAP_SourceFile,stop,
5151 BITMAP_SelectSourceFile,stop_s,
5153 BITMAP_Screen,scrn,
5154 BITMAP_Masking,TRUE,
5155 BitMapEnd,
5156 ButtonEnd,
5157 CHILD_WeightedWidth,0,
5158 CHILD_WeightedHeight,0,
5159 LAYOUT_AddChild, g->shared->objects[GID_RELOAD] = ButtonObj,
5160 GA_ID,GID_RELOAD,
5161 GA_RelVerify,TRUE,
5163 BUTTON_RenderImage,BitMapObj,
5164 BITMAP_SourceFile,reload,
5165 BITMAP_SelectSourceFile,reload_s,
5167 BITMAP_Screen,scrn,
5168 BITMAP_Masking,TRUE,
5169 BitMapEnd,
5170 ButtonEnd,
5171 CHILD_WeightedWidth,0,
5172 CHILD_WeightedHeight,0,
5173 LAYOUT_AddChild, g->shared->objects[GID_HOME] = ButtonObj,
5174 GA_ID,GID_HOME,
5175 GA_RelVerify,TRUE,
5177 BUTTON_RenderImage,BitMapObj,
5178 BITMAP_SourceFile,home,
5179 BITMAP_SelectSourceFile,home_s,
5181 BITMAP_Screen,scrn,
5182 BITMAP_Masking,TRUE,
5183 BitMapEnd,
5184 ButtonEnd,
5185 CHILD_WeightedWidth,0,
5186 CHILD_WeightedHeight,0,
5187 LAYOUT_AddChild, LayoutHObj, // FavIcon, URL bar and hotlist star
5188 LAYOUT_VertAlignment, LALIGN_CENTER,
5189 LAYOUT_AddChild, g->shared->objects[GID_ICON] = SpaceObj,
5190 GA_ID, GID_ICON,
5191 SPACE_MinWidth, 16,
5192 SPACE_MinHeight, 16,
5193 SPACE_Transparent, TRUE,
5194 // SPACE_RenderHook, &g->shared->favicon_hook,
5195 SpaceEnd,
5196 CHILD_WeightedWidth, 0,
5197 CHILD_WeightedHeight, 0,
5198 LAYOUT_AddChild, g->shared->objects[GID_PAGEINFO] = ButtonObj,
5199 GA_ID, GID_PAGEINFO,
5200 GA_RelVerify, TRUE,
5201 GA_ReadOnly, FALSE,
5202 BUTTON_RenderImage, g->shared->objects[GID_PAGEINFO_INTERNAL_BM],
5203 ButtonEnd,
5204 CHILD_WeightedWidth, 0,
5205 CHILD_WeightedHeight, 0,
5206 LAYOUT_AddChild, g->shared->objects[GID_URL] =
5207#ifdef __amigaos4__
5208 NewObject(urlStringClass, NULL,
5209#else
5210 StringObj,
5211#endif
5212 STRINGA_MaxChars, 2000,
5213 GA_ID, GID_URL,
5214 GA_RelVerify, TRUE,
5216 GA_TabCycle, TRUE,
5217 STRINGA_Buffer, g->shared->svbuffer,
5218#ifdef __amigaos4__
5220#endif
5221 TAG_DONE),
5222 LAYOUT_AddChild, g->shared->objects[GID_FAVE] = ButtonObj,
5223 GA_ID, GID_FAVE,
5224 GA_RelVerify, TRUE,
5225 // GA_HintInfo, g->shared->helphints[GID_FAVE],
5226 BUTTON_RenderImage, g->shared->objects[GID_FAVE_ADD],
5227 ButtonEnd,
5228 CHILD_WeightedWidth, 0,
5229 CHILD_WeightedHeight, 0,
5230 LayoutEnd,
5231 // GA_ID, GID_TOOLBARLAYOUT,
5232 // GA_RelVerify, TRUE,
5233 // LAYOUT_RelVerify, TRUE,
5234 LAYOUT_WeightBar, TRUE,
5235 LAYOUT_AddChild, LayoutHObj,
5236 LAYOUT_VertAlignment, LALIGN_CENTER,
5237 LAYOUT_AddChild, g->shared->objects[GID_SEARCH_ICON] = ChooserObj,
5238 GA_ID, GID_SEARCH_ICON,
5239 GA_RelVerify, TRUE,
5240 CHOOSER_DropDown, TRUE,
5241 CHOOSER_Labels, g->shared->web_search_list,
5242 CHOOSER_MaxLabels, 40, /* Same as options GUI */
5243 ChooserEnd,
5244 CHILD_WeightedWidth,0,
5245 CHILD_WeightedHeight,0,
5246 LAYOUT_AddChild, g->shared->objects[GID_SEARCHSTRING] = StringObj,
5247 GA_ID,GID_SEARCHSTRING,
5248 STRINGA_TextVal, NULL,
5249 GA_RelVerify,TRUE,
5251 StringEnd,
5252 LayoutEnd,
5253 CHILD_WeightedWidth, nsoption_int(web_search_width),
5254 LAYOUT_AddChild, g->shared->objects[GID_THROBBER] = SpaceObj,
5255 GA_ID,GID_THROBBER,
5256 SPACE_MinWidth, ami_theme_throbber_get_width(),
5257 SPACE_MinHeight, ami_theme_throbber_get_height(),
5258 SPACE_Transparent,TRUE,
5259 // SPACE_RenderHook, &g->shared->throbber_hook,
5260 SpaceEnd,
5261 CHILD_WeightedWidth,0,
5262 CHILD_WeightedHeight,0,
5263 LayoutEnd,
5264 CHILD_WeightedHeight,0,
5265 LAYOUT_AddImage, BevelObj,
5266 BEVEL_Style, BVS_SBAR_VERT,
5267 BevelEnd,
5268 CHILD_WeightedHeight, 0,
5269 LAYOUT_AddChild, g->shared->objects[GID_HOTLISTLAYOUT] = LayoutVObj,
5270 LAYOUT_SpaceInner, FALSE,
5271 LayoutEnd,
5272 CHILD_WeightedHeight,0,
5273 LAYOUT_AddChild, g->shared->objects[GID_TABLAYOUT] = LayoutHObj,
5274 LAYOUT_SpaceInner,FALSE,
5275 addtabclosegadget, g->shared->objects[GID_CLOSETAB],
5276 CHILD_WeightedWidth,0,
5277 CHILD_WeightedHeight,0,
5278
5279 addtabclosegadget, g->shared->objects[GID_TABS],
5280 CHILD_CacheDomain,FALSE,
5281
5282 addtabclosegadget, g->shared->objects[GID_ADDTAB],
5283 CHILD_WeightedWidth,0,
5284 CHILD_WeightedHeight,0,
5285 LayoutEnd,
5286 CHILD_WeightedHeight,0,
5287 LAYOUT_AddChild, LayoutVObj,
5288 LAYOUT_AddChild, g->shared->objects[GID_VSCROLLLAYOUT] = LayoutHObj,
5289 LAYOUT_AddChild, LayoutVObj,
5290 LAYOUT_AddChild, g->shared->objects[GID_HSCROLLLAYOUT] = LayoutVObj,
5291 LAYOUT_AddChild, g->shared->objects[GID_BROWSER] = SpaceObj,
5292 GA_ID,GID_BROWSER,
5293 SPACE_Transparent,TRUE,
5294 SPACE_MinWidth, 16,
5295 SPACE_MinHeight, 16,
5296 SPACE_RenderHook, &g->shared->browser_hook,
5297 SpaceEnd,
5298 EndGroup,
5299 EndGroup,
5300 EndGroup,
5301// LAYOUT_WeightBar, TRUE,
5302 LAYOUT_AddChild, g->shared->objects[GID_LOGLAYOUT] = LayoutVObj,
5303 EndGroup,
5304 CHILD_WeightedHeight, 0,
5305#ifndef __amigaos4__
5306 LAYOUT_AddChild, g->shared->objects[GID_STATUS] = StringObj,
5307 GA_ID, GID_STATUS,
5308 GA_ReadOnly, TRUE,
5309 STRINGA_TextVal, NULL,
5310 GA_RelVerify, TRUE,
5311 StringEnd,
5312#endif
5313 EndGroup,
5314 EndGroup,
5315 EndWindow;
5316 }
5317 else
5318 {
5319 /* borderless kiosk mode window */
5320 g->tab = 0;
5321 g->shared->tabs = 0;
5322 g->tab_node = NULL;
5323
5325 WA_ScreenTitle, ami_gui_get_screen_title(),
5326 WA_Activate, TRUE,
5327 WA_DepthGadget, FALSE,
5328 WA_DragBar, FALSE,
5329 WA_CloseGadget, FALSE,
5330 WA_Borderless,TRUE,
5331 WA_RMBTrap,TRUE,
5332 WA_Top,0,
5333 WA_Left,0,
5334 WA_Width, scrn->Width,
5335 WA_Height, scrn->Height,
5336 WA_SizeGadget, FALSE,
5337 WA_PubScreen, scrn,
5338 WA_ReportMouse, TRUE,
5339 refresh_mode, TRUE,
5340 WA_IDCMP, IDCMP_MENUPICK | IDCMP_MOUSEMOVE |
5341 IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
5342 IDCMP_RAWKEY | IDCMP_REFRESHWINDOW |
5343 IDCMP_GADGETUP | IDCMP_IDCMPUPDATE |
5345 WINDOW_IDCMPHook,&g->shared->scrollerhook,
5346 WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE |
5347 IDCMP_EXTENDEDMOUSE | IDCMP_REFRESHWINDOW,
5348 WINDOW_SharedPort,sport,
5349 WINDOW_UserData,g->shared,
5351 WINDOW_ParentGroup, g->shared->objects[GID_MAIN] = LayoutHObj,
5352 LAYOUT_DeferLayout, defer_layout,
5353 LAYOUT_SpaceOuter, TRUE,
5354 LAYOUT_AddChild, g->shared->objects[GID_VSCROLLLAYOUT] = LayoutHObj,
5355 LAYOUT_AddChild, g->shared->objects[GID_HSCROLLLAYOUT] = LayoutVObj,
5356 LAYOUT_AddChild, g->shared->objects[GID_BROWSER] = SpaceObj,
5357 GA_ID,GID_BROWSER,
5358 SPACE_Transparent,TRUE,
5359 SpaceEnd,
5360 EndGroup,
5361 EndGroup,
5362 EndGroup,
5363 EndWindow;
5364 }
5365
5366 NSLOG(netsurf, INFO, "Opening window");
5367
5368 g->shared->win = (struct Window *)RA_OpenWindow(g->shared->objects[OID_MAIN]);
5369
5370 NSLOG(netsurf, INFO, "Window opened, adding border gadgets");
5371
5372 /* Clear the reference window pointer to ensure it doesn't get used later */
5373 SetAttrs(g->shared->objects[OID_MAIN], WINDOW_RefWindow, NULL, TAG_DONE);
5374
5375 if(!g->shared->win)
5376 {
5377 amiga_warn_user("NoMemory","");
5378 free(g->shared);
5379 free(g);
5380 return NULL;
5381 }
5382
5383 if(nsoption_bool(kiosk_mode) == false)
5384 {
5385#ifdef __amigaos4__
5386 ULONG width, height;
5387 struct DrawInfo *dri = GetScreenDrawInfo(scrn);
5388
5389 ami_get_border_gadget_size(g->shared,
5390 (ULONG *)&width, (ULONG *)&height);
5391
5393 NULL,
5394 "frbuttonclass",
5395 GA_ID, GID_STATUS,
5396 GA_Left, scrn->WBorLeft + 2,
5397 GA_RelBottom, scrn->WBorBottom - (height/2),
5398 GA_BottomBorder, TRUE,
5399 GA_Width, width,
5400 GA_Height, 1 + height - scrn->WBorBottom,
5401 GA_DrawInfo, dri,
5402 GA_ReadOnly, TRUE,
5403 GA_Disabled, TRUE,
5404 GA_Image, (struct Image *)NewObject(
5405 NULL,
5406 "gaugeiclass",
5407 GAUGEIA_Level, 0,
5408 IA_Top, (int)(- ceil((scrn->WBorBottom + height) / 2)),
5409 IA_Left, -4,
5410 IA_Height, 2 + height - scrn->WBorBottom,
5411 IA_Label, NULL,
5412 IA_InBorder, TRUE,
5413 IA_Screen, scrn,
5414 TAG_DONE),
5415 TAG_DONE);
5416
5417 AddGList(g->shared->win, (struct Gadget *)g->shared->objects[GID_STATUS],
5418 (UWORD)~0, -1, NULL);
5419
5420 /* Apparently you can't set GA_Width on creation time for frbuttonclass */
5421
5422 SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_STATUS],
5423 g->shared->win, NULL,
5424 GA_Width, width,
5425 TAG_DONE);
5426
5427 RefreshGadgets((APTR)g->shared->objects[GID_STATUS],
5428 g->shared->win, NULL);
5429
5430 FreeScreenDrawInfo(scrn, dri);
5431#endif //__amigaos4__
5432 ami_gui_hotlist_toolbar_add(g->shared); /* is this the right place for this? */
5433 if(nsoption_bool(tab_always_show)) ami_toggletabbar(g->shared, true);
5434 }
5435
5436 g->shared->gw = g;
5437 cur_gw = g;
5438
5439 g->shared->appwin = AddAppWindowA((ULONG)g->shared->objects[OID_MAIN],
5440 (ULONG)g->shared, g->shared->win, appport, NULL);
5441
5443
5444 if(locked_screen) {
5445 UnlockPubScreen(NULL,scrn);
5446 locked_screen = FALSE;
5447 }
5448
5449 ScreenToFront(scrn);
5450
5451 return g;
5452}
5453
5454static void ami_gui_close_tabs(struct gui_window_2 *gwin, bool other_tabs)
5455{
5456 struct Node *tab;
5457 struct Node *ntab;
5458 struct gui_window *gw;
5459
5460 if((gwin->tabs > 1) && (nsoption_bool(tab_close_warn) == true)) {
5461 int32 res = amiga_warn_user_multi(messages_get("MultiTabClose"), "Yes", "No", gwin->win);
5462
5463 if(res == 0) return;
5464 }
5465
5466 if(gwin->tabs) {
5467 tab = GetHead(&gwin->tab_list);
5468
5469 do {
5470 ntab=GetSucc(tab);
5471 GetClickTabNodeAttrs(tab,
5472 TNA_UserData,&gw,
5473 TAG_DONE);
5474
5475 if((other_tabs == false) || (gwin->gw != gw)) {
5477 }
5478 } while((tab=ntab));
5479 } else {
5480 if(other_tabs == false) browser_window_destroy(gwin->gw->bw);
5481 }
5482}
5483
5485{
5486 struct gui_window_2 *gwin = (struct gui_window_2 *)w;
5487 ami_gui_close_tabs(gwin, false);
5488}
5489
5491{
5492 ami_gui_close_tabs(gwin, true);
5493}
5494
5495static void gui_window_destroy(struct gui_window *g)
5496{
5497 struct Node *ptab = NULL;
5498 int gid;
5499
5500 if(!g) return;
5501
5502 if (ami_search_get_gwin(g->shared->searchwin) == g)
5503 {
5505 win_destroyed = true;
5506 }
5507
5508 if(g->hw)
5509 {
5511 win_destroyed = true;
5512 }
5513
5518
5519 cur_gw = NULL;
5520
5521 if(g->shared->tabs > 1) {
5522 SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_TABS],g->shared->win,NULL,
5523 CLICKTAB_Labels,~0,
5524 TAG_DONE);
5525
5526 GetAttr(CLICKTAB_CurrentNode, g->shared->objects[GID_TABS], (ULONG *)&ptab);
5527
5528 if(ptab == g->tab_node) {
5529 ptab = GetSucc(g->tab_node);
5530 if(!ptab) ptab = GetPred(g->tab_node);
5531 }
5532
5533 Remove(g->tab_node);
5534 FreeClickTabNode(g->tab_node);
5535 RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_TABS], g->shared->win, NULL,
5536 CLICKTAB_Labels, &g->shared->tab_list,
5537 CLICKTAB_CurrentNode, ptab,
5538 TAG_DONE);
5539
5540 if(ClickTabBase->lib_Version < 53)
5541 RethinkLayout((struct Gadget *)g->shared->objects[GID_TABLAYOUT],
5542 g->shared->win, NULL, TRUE);
5543
5544 g->shared->tabs--;
5545 ami_switch_tab(g->shared,true);
5547
5548 if((g->shared->tabs == 1) && (nsoption_bool(tab_always_show) == false))
5549 ami_toggletabbar(g->shared, false);
5550
5551 FreeListBrowserList(&g->loglist);
5552#ifdef __amigaos4__
5553 FreeLBColumnInfo(g->logcolumns);
5554#endif
5555
5556 if(g->tabtitle) free(g->tabtitle);
5557 free(g);
5558 return;
5559 }
5560
5562 free(g->shared->shared_pens);
5565
5566 DisposeObject(g->shared->objects[OID_MAIN]);
5568 if(g->shared->appwin) RemoveAppWindow(g->shared->appwin);
5570
5571 /* These aren't freed by the above.
5572 * TODO: nav_west etc need freeing too? */
5573 DisposeObject(g->shared->objects[GID_ADDTAB_BM]);
5574 DisposeObject(g->shared->objects[GID_CLOSETAB_BM]);
5575 DisposeObject(g->shared->objects[GID_TABS_FLAG]);
5576 DisposeObject(g->shared->objects[GID_FAVE_ADD]);
5577 DisposeObject(g->shared->objects[GID_FAVE_RMV]);
5578 DisposeObject(g->shared->objects[GID_PAGEINFO_INSECURE_BM]);
5579 DisposeObject(g->shared->objects[GID_PAGEINFO_INTERNAL_BM]);
5580 DisposeObject(g->shared->objects[GID_PAGEINFO_LOCAL_BM]);
5581 DisposeObject(g->shared->objects[GID_PAGEINFO_SECURE_BM]);
5582 DisposeObject(g->shared->objects[GID_PAGEINFO_WARNING_BM]);
5583
5585 if(g->shared->search_bm) DisposeObject(g->shared->search_bm);
5586
5587 /* This appears to be disposed along with the ClickTab object
5588 if(g->shared->clicktab_ctxmenu) DisposeObject((Object *)g->shared->clicktab_ctxmenu); */
5589 DisposeObject((Object *)g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_BACK]);
5590 DisposeObject((Object *)g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_FORWARD]);
5593
5594 FreeListBrowserList(&g->loglist);
5595#ifdef __amigaos4__
5596 FreeLBColumnInfo(g->logcolumns);
5597#endif
5598
5599 free(g->shared->wintitle);
5601 free(g->shared->svbuffer);
5602
5603 for(gid = 0; gid < GID_LAST; gid++)
5604 ami_utf8_free(g->shared->helphints[gid]);
5605
5607 if(g->tab_node) {
5608 Remove(g->tab_node);
5609 FreeClickTabNode(g->tab_node);
5610 }
5611 if(g->tabtitle) free(g->tabtitle);
5612 free(g); // g->shared should be freed by DelObject()
5613
5615 {
5616 /* last window closed, so exit */
5617 ami_try_quit();
5618 }
5619
5620 win_destroyed = true;
5621}
5622
5623
5624static void ami_redraw_callback(void *p)
5625{
5626 struct gui_window_2 *gwin = (struct gui_window_2 *)p;
5627
5628 if(gwin->redraw_required) {
5629 ami_do_redraw(gwin);
5630 }
5631
5633
5634 if(gwin->gw->c_h)
5635 {
5636 gui_window_place_caret(gwin->gw, gwin->gw->c_x,
5637 gwin->gw->c_y, gwin->gw->c_h, NULL);
5638 }
5639}
5640
5641/**
5642 * Schedule a redraw of the browser window - Amiga-specific function
5643 *
5644 * \param gwin a struct gui_window_2
5645 * \param full_redraw set to true to schedule a full redraw,
5646 should only be set to false when called from amiga_window_invalidate_area()
5647 */
5648void ami_schedule_redraw(struct gui_window_2 *gwin, bool full_redraw)
5649{
5650 int ms = 1;
5651
5652 if(full_redraw) gwin->redraw_required = true;
5654}
5655
5657{
5659}
5660
5661static void ami_gui_window_update_box_deferred(struct gui_window *g, bool draw)
5662{
5663 struct nsObject *node;
5664 struct nsObject *nnode;
5665 struct rect *rect;
5666
5667 if(!g) return;
5668 if(IsMinListEmpty(g->deferred_rects)) return;
5669
5670 if(draw == true) {
5672 } else {
5673 NSLOG(netsurf, INFO, "Ignoring deferred box redraw queue");
5674 }
5675
5676 node = (struct nsObject *)GetHead((struct List *)g->deferred_rects);
5677
5678 do {
5679 if(draw == true) {
5680 rect = (struct rect *)node->objstruct;
5681 ami_do_redraw_limits(g, g->bw, false,
5682 rect->x0, rect->y0, rect->x1, rect->y1);
5683 }
5684 nnode=(struct nsObject *)GetSucc((struct Node *)node);
5686 DelObjectNoFree(node);
5687 } while((node = nnode));
5688
5689 if(draw == true) ami_reset_pointer(g->shared);
5690}
5691
5692bool ami_gui_window_update_box_deferred_check(struct MinList *deferred_rects,
5693 const struct rect *restrict new_rect, APTR mempool)
5694{
5695 struct nsObject *node;
5696 struct nsObject *nnode;
5697 struct rect *restrict rect;
5698
5699 if(IsMinListEmpty(deferred_rects)) return true;
5700
5701 node = (struct nsObject *)GetHead((struct List *)deferred_rects);
5702
5703 do {
5704 nnode=(struct nsObject *)GetSucc((struct Node *)node);
5705 rect = (struct rect *)node->objstruct;
5706
5707 if((rect->x0 <= new_rect->x0) &&
5708 (rect->y0 <= new_rect->y0) &&
5709 (rect->x1 >= new_rect->x1) &&
5710 (rect->y1 >= new_rect->y1)) {
5711 return false;
5712 }
5713
5714 if ((new_rect->x0 <= rect->x0) &&
5715 (new_rect->y0 <= rect->y0) &&
5716 (new_rect->x1 >= rect->x1) &&
5717 (new_rect->y1 >= rect->y1)) {
5718 NSLOG(netsurf, INFO,
5719 "Removing queued redraw that is a subset of new box redraw");
5720 ami_memory_itempool_free(mempool, node->objstruct, sizeof(struct rect));
5721 DelObjectNoFree(node);
5722 /* Don't return - we might find more */
5723 }
5724 } while((node = nnode));
5725
5726 return true;
5727}
5728
5729
5730static void ami_do_redraw(struct gui_window_2 *gwin)
5731{
5732 ULONG hcurrent,vcurrent,xoffset,yoffset,width=800,height=600;
5733 struct IBox *bbox;
5734 ULONG oldh = gwin->oldh, oldv=gwin->oldv;
5735
5736 if(browser_window_redraw_ready(gwin->gw->bw) == false) return;
5737
5738 ami_get_hscroll_pos(gwin, (ULONG *)&hcurrent);
5739 ami_get_vscroll_pos(gwin, (ULONG *)&vcurrent);
5740
5741 gwin->gw->scrollx = hcurrent;
5742 gwin->gw->scrolly = vcurrent;
5743
5744 if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
5745 amiga_warn_user("NoMemory", "");
5746 return;
5747 }
5748
5749 width=bbox->Width;
5750 height=bbox->Height;
5751 xoffset=bbox->Left;
5752 yoffset=bbox->Top;
5753
5754 if(gwin->redraw_scroll)
5755 {
5756 if((abs(vcurrent-oldv) > height) || (abs(hcurrent-oldh) > width))
5757 gwin->redraw_scroll = false;
5758
5759 if(gwin->new_content) gwin->redraw_scroll = false;
5760 }
5761
5762 if(gwin->redraw_scroll)
5763 {
5764 struct rect rect;
5765
5766 gwin->gw->c_h_temp = gwin->gw->c_h;
5768
5769 ScrollWindowRaster(gwin->win, hcurrent - oldh, vcurrent - oldv,
5770 xoffset, yoffset, xoffset + width - 1, yoffset + height - 1);
5771
5772 gwin->gw->c_h = gwin->gw->c_h_temp;
5773
5774 if(vcurrent>oldv) /* Going down */
5775 {
5776 ami_spacebox_to_ns_coords(gwin, &rect.x0, &rect.y0, 0, height - (vcurrent - oldv) - 1);
5777 ami_spacebox_to_ns_coords(gwin, &rect.x1, &rect.y1, width + 1, height + 1);
5779 }
5780 else if(vcurrent<oldv) /* Going up */
5781 {
5782 ami_spacebox_to_ns_coords(gwin, &rect.x0, &rect.y0, 0, 0);
5783 ami_spacebox_to_ns_coords(gwin, &rect.x1, &rect.y1, width + 1, oldv - vcurrent + 1);
5785 }
5786
5787 if(hcurrent>oldh) /* Going right */
5788 {
5789 ami_spacebox_to_ns_coords(gwin, &rect.x0, &rect.y0, width - (hcurrent - oldh), 0);
5790 ami_spacebox_to_ns_coords(gwin, &rect.x1, &rect.y1, width + 1, height + 1);
5792 }
5793 else if(hcurrent<oldh) /* Going left */
5794 {
5795 ami_spacebox_to_ns_coords(gwin, &rect.x0, &rect.y0, 0, 0);
5796 ami_spacebox_to_ns_coords(gwin, &rect.x1, &rect.y1, oldh - hcurrent + 1, height + 1);
5798 }
5799 }
5800 else
5801 {
5802 struct redraw_context ctx = {
5803 .interactive = true,
5804 .background_images = true,
5805 .plot = &amiplot,
5806 .priv = browserglob
5807 };
5808
5809 ami_do_redraw_tiled(gwin, true, hcurrent, vcurrent, width, height, hcurrent, vcurrent, bbox, &ctx);
5810
5811 /* Tell NetSurf not to bother with the next queued box redraw, as we've redrawn everything. */
5813 }
5814
5815 ami_update_buttons(gwin);
5816
5817 gwin->oldh = hcurrent;
5818 gwin->oldv = vcurrent;
5819
5820 gwin->redraw_scroll = false;
5821 gwin->redraw_required = false;
5822 gwin->new_content = false;
5823
5825}
5826
5827
5828static void ami_get_hscroll_pos(struct gui_window_2 *gwin, ULONG *xs)
5829{
5830 if(gwin->objects[GID_HSCROLL])
5831 {
5832 GetAttr(SCROLLER_Top, (Object *)gwin->objects[GID_HSCROLL], xs);
5833 } else {
5834 *xs = 0;
5835 }
5836}
5837
5838static void ami_get_vscroll_pos(struct gui_window_2 *gwin, ULONG *ys)
5839{
5840 if(gwin->objects[GID_VSCROLL]) {
5841 GetAttr(SCROLLER_Top, gwin->objects[GID_VSCROLL], ys);
5842 } else {
5843 *ys = 0;
5844 }
5845}
5846
5847static bool gui_window_get_scroll(struct gui_window *g, int *restrict sx, int *restrict sy)
5848{
5849 ami_get_hscroll_pos(g->shared, (ULONG *)sx);
5850 ami_get_vscroll_pos(g->shared, (ULONG *)sy);
5851
5852 return true;
5853}
5854
5855/**
5856 * Set the scroll position of a amiga browser window.
5857 *
5858 * Scrolls the viewport to ensure the specified rectangle of the
5859 * content is shown. The amiga implementation scrolls the contents so
5860 * the specified point in the content is at the top of the viewport.
5861 *
5862 * \param g gui_window to scroll
5863 * \param rect The rectangle to ensure is shown.
5864 * \return NSERROR_OK on success or apropriate error code.
5865 */
5866static nserror
5868{
5869 struct IBox *bbox;
5870 int width, height;
5871 nserror res;
5872 int sx = 0, sy = 0;
5873
5874 if(!g) {
5875 return NSERROR_BAD_PARAMETER;
5876 }
5877 if(!g->bw || browser_window_has_content(g->bw) == false) {
5878 return NSERROR_BAD_PARAMETER;
5879 }
5880
5881 res = ami_gui_get_space_box((Object *)g->shared->objects[GID_BROWSER], &bbox);
5882 if(res != NSERROR_OK) {
5883 amiga_warn_user("NoMemory", "");
5884 return res;
5885 }
5886
5887 if (rect->x0 > 0) {
5888 sx = rect->x0;
5889 }
5890 if (rect->y0 > 0) {
5891 sy = rect->y0;
5892 }
5893
5895
5896 if(sx >= width - bbox->Width)
5897 sx = width - bbox->Width;
5898 if(sy >= height - bbox->Height)
5899 sy = height - bbox->Height;
5900
5901 if(width <= bbox->Width) sx = 0;
5902 if(height <= bbox->Height) sy = 0;
5903
5905
5906 if(g == g->shared->gw) {
5907 if(g->shared->objects[GID_VSCROLL]) {
5908 RefreshSetGadgetAttrs((struct Gadget *)(APTR)g->shared->objects[GID_VSCROLL],
5909 g->shared->win, NULL,
5910 SCROLLER_Top, (ULONG)(sy),
5911 TAG_DONE);
5912 }
5913
5914 if(g->shared->objects[GID_HSCROLL])
5915 {
5916 RefreshSetGadgetAttrs((struct Gadget *)(APTR)g->shared->objects[GID_HSCROLL],
5917 g->shared->win, NULL,
5918 SCROLLER_Top, (ULONG)(sx),
5919 TAG_DONE);
5920 }
5921
5922 ami_schedule_redraw(g->shared, true);
5923
5924 if(nsoption_bool(faster_scroll) == true) g->shared->redraw_scroll = true;
5925 else g->shared->redraw_scroll = false;
5926
5927 g->scrollx = sx;
5928 g->scrolly = sy;
5929 }
5930 return NSERROR_OK;
5931}
5932
5933static void gui_window_set_status(struct gui_window *g, const char *text)
5934{
5935 char *utf8text;
5936 ULONG size;
5937 UWORD chars;
5938 struct TextExtent textex;
5939
5940 if(!g) return;
5941 if(!text) return;
5942 if(!g->shared->objects[GID_STATUS]) return;
5943
5944 if(g == g->shared->gw) {
5945 utf8text = ami_utf8_easy((char *)text);
5946 if(utf8text == NULL) return;
5947
5948 GetAttr(GA_Width, g->shared->objects[GID_STATUS], (ULONG *)&size);
5949 chars = TextFit(&scrn->RastPort, utf8text, (UWORD)strlen(utf8text),
5950 &textex, NULL, 1, size - 4, scrn->RastPort.TxHeight);
5951
5952 utf8text[chars] = 0;
5953
5954 SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_STATUS],
5955 g->shared->win, NULL,
5956 NSA_STATUS_TEXT, utf8text,
5957 TAG_DONE);
5958
5959 RefreshGList((struct Gadget *)g->shared->objects[GID_STATUS],
5960 g->shared->win, NULL, 1);
5961
5963 g->shared->status = utf8text;
5964 }
5965}
5966
5968{
5969 size_t idn_url_l;
5970 char *idn_url_s = NULL;
5971 char *url_lc = NULL;
5972
5973 if(!g) return NSERROR_OK;
5974
5975 if(g == g->shared->gw) {
5976 if(nsoption_bool(display_decoded_idn) == true) {
5977 if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) == NSERROR_OK) {
5978 url_lc = ami_utf8_easy(idn_url_s);
5979 }
5980 }
5981
5982 RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_URL],
5983 g->shared->win, NULL,
5984 STRINGA_TextVal, url_lc ? url_lc : nsurl_access(url),
5985 TAG_DONE);
5986
5987 if(url_lc) {
5988 ami_utf8_free(url_lc);
5989 if(idn_url_s) free(idn_url_s);
5990 }
5991 }
5992
5994
5995 return NSERROR_OK;
5996}
5997
5998HOOKF(uint32, ami_set_favicon_render_hook, APTR, space, struct gpRender *)
5999{
6000 ami_schedule(0, ami_gui_refresh_favicon, hook->h_Data);
6001 return 0;
6002}
6003
6004/**
6005 * Gui callback when search provider details are updated.
6006 *
6007 * \param provider_name The providers name.
6008 * \param ico_bitmap The icon bitmap representing the provider.
6009 * \return NSERROR_OK on success else error code.
6010 */
6011static nserror gui_search_web_provider_update(const char *provider_name,
6012 struct bitmap *ico_bitmap)
6013{
6014 struct BitMap *bm = NULL;
6015 struct nsObject *node;
6016 struct nsObject *nnode;
6017 struct gui_window_2 *gwin;
6018
6020 if(nsoption_bool(kiosk_mode) == true) return NSERROR_BAD_PARAMETER;
6021
6022 if (ico_bitmap != NULL) {
6023 bm = ami_bitmap_get_native(ico_bitmap, 16, 16, ami_plot_screen_is_palettemapped(), NULL, nsoption_colour(sys_colour_ButtonFace));
6024 }
6025
6026 if(bm == NULL) return NSERROR_BAD_PARAMETER;
6027
6028 node = (struct nsObject *)GetHead((struct List *)window_list);
6029
6030 do {
6031 nnode=(struct nsObject *)GetSucc((struct Node *)node);
6032 gwin = node->objstruct;
6033
6034 if(node->Type == AMINS_WINDOW)
6035 {
6036 if(gwin->search_bm != NULL)
6037 DisposeObject(gwin->search_bm);
6038
6039 ULONG bm_masking_tag = TAG_IGNORE;
6040
6041 if(LIB_IS_AT_LEAST((struct Library *)ChooserBase, 53, 21)) {
6042 /* Broken in earlier versions */
6043 bm_masking_tag = BITMAP_Masking;
6044 }
6045
6046 gwin->search_bm = BitMapObj,
6047 BITMAP_Screen, scrn,
6048 BITMAP_Width, 16,
6049 BITMAP_Height, 16,
6050 BITMAP_BitMap, bm,
6051 BITMAP_HasAlpha, TRUE,
6052 bm_masking_tag, TRUE,
6053 BitMapEnd;
6054
6055 RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_SEARCH_ICON],
6056 gwin->win, NULL,
6057 GA_HintInfo, provider_name,
6058 GA_Image, gwin->search_bm,
6059 TAG_DONE);
6060 }
6061 } while((node = nnode));
6062
6063 return NSERROR_OK;
6064}
6065
6066HOOKF(uint32, ami_set_throbber_render_hook, APTR, space, struct gpRender *)
6067{
6068 struct gui_window_2 *gwin = hook->h_Data;
6070 return 0;
6071}
6072
6073HOOKF(uint32, ami_gui_browser_render_hook, APTR, space, struct gpRender *)
6074{
6075 struct gui_window_2 *gwin = hook->h_Data;
6076
6077 NSLOG(netsurf, DEBUG, "Render hook called with %ld (REDRAW=1)", msg->gpr_Redraw);
6078
6079 if(msg->gpr_Redraw != GREDRAW_REDRAW) return 0;
6080
6081 ami_schedule_redraw(gwin, true);
6082
6083 return 0;
6084}
6085
6086static void gui_window_place_caret(struct gui_window *g, int x, int y, int height,
6087 const struct rect *clip)
6088{
6089 struct IBox *bbox;
6090 int xs,ys;
6091
6092 if(!g) return;
6093
6095
6096 xs = g->scrollx;
6097 ys = g->scrolly;
6098
6099 SetAPen(g->shared->win->RPort,3);
6100
6101 if(ami_gui_get_space_box((Object *)g->shared->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
6102 amiga_warn_user("NoMemory", "");
6103 return;
6104 }
6105
6106 if((y-ys+height) > (bbox->Height)) height = bbox->Height-y+ys;
6107
6108 if(((x-xs) <= 0) || ((x-xs+2) >= (bbox->Width)) || ((y-ys) <= 0) || ((y-ys) >= (bbox->Height))) {
6110 return;
6111 }
6112
6113 g->c_w = 2;
6114
6115 SetDrMd(g->shared->win->RPort,COMPLEMENT);
6116 RectFill(g->shared->win->RPort, x + bbox->Left - xs, y + bbox->Top - ys,
6117 x + bbox->Left + g->c_w - xs, y+bbox->Top + height - ys);
6118 SetDrMd(g->shared->win->RPort,JAM1);
6119
6121
6122 g->c_x = x;
6123 g->c_y = y;
6124 g->c_h = height;
6125
6126 if((nsoption_bool(kiosk_mode) == false))
6128}
6129
6131{
6132 if(!g) return;
6133 if(g->c_h == 0) return;
6134
6135 if((nsoption_bool(kiosk_mode) == false))
6137
6138 ami_do_redraw_limits(g, g->bw, false, g->c_x, g->c_y,
6139 g->c_x + g->c_w + 1, g->c_y + g->c_h + 1);
6140
6141 g->c_h = 0;
6142}
6143
6145{
6146 struct hlcache_handle *c;
6147
6148 if(g && g->shared && g->bw && browser_window_has_content(g->bw))
6150 else return;
6151
6153 g->shared->new_content = true;
6154 g->scrollx = 0;
6155 g->scrolly = 0;
6156 g->shared->oldh = 0;
6157 g->shared->oldv = 0;
6158 g->favicon = NULL;
6163}
6164
6166 const struct rect *rect)
6167{
6168#ifdef __amigaos4__
6169 g->shared->drag_op = type;
6171
6172 if(type == GDRAGGING_NONE)
6173 {
6174 SetWindowAttrs(g->shared->win, WA_GrabFocus, 0,
6175 WA_MouseLimits, NULL, TAG_DONE);
6176
6177 if(g->shared->ptr_lock)
6178 {
6179 free(g->shared->ptr_lock);
6180 g->shared->ptr_lock = NULL;
6181 }
6182 }
6183#endif
6184 return true;
6185}
6186
6187/* return the text box at posn x,y in window coordinates
6188 x,y are updated to be document co-ordinates */
6189
6190bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *restrict x, ULONG *restrict y)
6191{
6192 struct IBox *bbox;
6193 ULONG xs, ys;
6194 struct browser_window_features data;
6195
6196 if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
6197 amiga_warn_user("NoMemory", "");
6198 return false;
6199 }
6200
6201 ami_get_hscroll_pos(gwin, (ULONG *)&xs);
6202 *x = *x - (bbox->Left) +xs;
6203
6204 ami_get_vscroll_pos(gwin, (ULONG *)&ys);
6205 *y = *y - (bbox->Top) + ys;
6206
6208
6209 browser_window_get_features(gwin->gw->bw, *x, *y, &data);
6210
6211 if (data.form_features == CTX_FORM_TEXT)
6212 return true;
6213
6214 return false;
6215}
6216
6217BOOL ami_gadget_hit(Object *obj, int x, int y)
6218{
6219 int top, left, width, height;
6220
6221 GetAttrs(obj,
6222 GA_Left, &left,
6223 GA_Top, &top,
6224 GA_Width, &width,
6225 GA_Height, &height,
6226 TAG_DONE);
6227
6228 if((x >= left) && (x <= (left + width)) && (y >= top) && (y <= (top + height)))
6229 return TRUE;
6230 else return FALSE;
6231}
6232
6233static Object *ami_gui_splash_open(void)
6234{
6235 Object *restrict win_obj, *restrict bm_obj;
6236 struct Window *win;
6237 struct Screen *wbscreen = LockPubScreen("Workbench");
6238 uint32 top = 0, left = 0;
6239 struct TextAttr tattr;
6240 struct TextFont *tfont;
6241
6242 win_obj = WindowObj,
6243#ifdef __amigaos4__
6244 WA_ToolBox, TRUE,
6245#endif
6246 WA_Borderless, TRUE,
6247 WA_BusyPointer, TRUE,
6248 WINDOW_Position, WPOS_CENTERSCREEN,
6249 WINDOW_LockWidth, TRUE,
6250 WINDOW_LockHeight, TRUE,
6251 WINDOW_ParentGroup, LayoutVObj,
6252 LAYOUT_AddImage, bm_obj = BitMapObj,
6253 BITMAP_SourceFile, "PROGDIR:Resources/splash.png",
6254 BITMAP_Screen, wbscreen,
6255 BITMAP_Precision, PRECISION_IMAGE,
6256 BitMapEnd,
6257 LayoutEnd,
6258 EndWindow;
6259
6260 if(win_obj == NULL) {
6261 NSLOG(netsurf, INFO, "Splash window object not created");
6262 return NULL;
6263 }
6264
6265 NSLOG(netsurf, INFO, "Attempting to open splash window...");
6266 win = RA_OpenWindow(win_obj);
6267
6268 if(win == NULL) {
6269 NSLOG(netsurf, INFO, "Splash window did not open");
6270 return NULL;
6271 }
6272
6273 if(bm_obj == NULL) {
6274 NSLOG(netsurf, INFO, "BitMap object not created");
6275 return NULL;
6276 }
6277
6278 GetAttrs(bm_obj, IA_Top, &top,
6279 IA_Left, &left,
6280 TAG_DONE);
6281
6282 SetDrMd(win->RPort, JAM1);
6283#ifdef __amigaos4__
6284 SetRPAttrs(win->RPort, RPTAG_APenColor, 0xFF3F6DFE, TAG_DONE);
6285 tattr.ta_Name = "DejaVu Serif Italic.font";
6286#else
6287 SetAPen(win->RPort, 3); /* Pen 3 is usually blue */
6288 tattr.ta_Name = "ruby.font";
6289#endif
6290 tattr.ta_YSize = 24;
6291 tattr.ta_Style = 0;
6292 tattr.ta_Flags = 0;
6293
6294 if((tfont = ami_font_open_disk_font(&tattr)))
6295 {
6296 SetFont(win->RPort, tfont);
6297 }
6298 else
6299 {
6300 tattr.ta_Name = "DejaVu Serif Oblique.font";
6301 if((tfont = ami_font_open_disk_font(&tattr)))
6302 SetFont(win->RPort, tfont);
6303 }
6304
6305 Move(win->RPort, left + 5, top + 25);
6306 Text(win->RPort, "Initialising...", strlen("Initialising..."));
6307
6308 if(tfont) ami_font_close_disk_font(tfont);
6309
6310#ifdef __amigaos4__
6311 tattr.ta_Name = "DejaVu Sans.font";
6312#else
6313 tattr.ta_Name = "helvetica.font";
6314#endif
6315 tattr.ta_YSize = 16;
6316 tattr.ta_Style = 0;
6317 tattr.ta_Flags = 0;
6318
6319 if((tfont = ami_font_open_disk_font(&tattr)))
6320 SetFont(win->RPort, tfont);
6321
6322 Move(win->RPort, left + 185, top + 220);
6323 Text(win->RPort, netsurf_version, strlen(netsurf_version));
6324
6325 if(tfont) ami_font_close_disk_font(tfont);
6326
6327 UnlockPubScreen(NULL, wbscreen);
6328
6329 return win_obj;
6330}
6331
6332static void ami_gui_splash_close(Object *win_obj)
6333{
6334 if(win_obj == NULL) return;
6335
6336 NSLOG(netsurf, INFO, "Closing splash window");
6337 DisposeObject(win_obj);
6338}
6339
6340static void gui_file_gadget_open(struct gui_window *g, struct hlcache_handle *hl,
6341 struct form_control *gadget)
6342{
6343 NSLOG(netsurf, INFO, "File open dialog request for %p/%p", g, gadget);
6344
6345 if(AslRequestTags(filereq,
6346 ASLFR_Window, g->shared->win,
6347 ASLFR_SleepWindow, TRUE,
6348 ASLFR_TitleText, messages_get("NetSurf"),
6349 ASLFR_Screen, scrn,
6350 ASLFR_DoSaveMode, FALSE,
6351 TAG_DONE)) {
6352 char fname[1024];
6353 strlcpy(fname, filereq->fr_Drawer, 1024);
6354 AddPart(fname, filereq->fr_File, 1024);
6355 browser_window_set_gadget_filename(g->bw, gadget, fname);
6356 }
6357}
6358
6359/* exported function documented in amiga/gui.h */
6361{
6362 return ami_appid;
6363}
6364
6365/* Get current user directory for user-specific NetSurf data
6366 * Returns NULL on error
6367 */
6368static char *ami_gui_get_user_dir(STRPTR current_user)
6369{
6370 BPTR lock = 0;
6371 char temp[1024];
6372 int32 user = 0;
6373
6374 if(current_user == NULL) {
6375 user = GetVar("user", temp, 1024, GVF_GLOBAL_ONLY);
6376 current_user = ASPrintf("%s", (user == -1) ? "Default" : temp);
6377 }
6378 NSLOG(netsurf, INFO, "User: %s", current_user);
6379
6380 if(users_dir == NULL) {
6381 users_dir = ASPrintf("%s", USERS_DIR);
6382 if(users_dir == NULL) {
6383 ami_misc_fatal_error("Failed to allocate memory");
6384 FreeVec(current_user);
6385 return NULL;
6386 }
6387 }
6388
6389 if(LIB_IS_AT_LEAST((struct Library *)DOSBase, 51, 96)) {
6390#ifdef __amigaos4__
6391 struct InfoData *infodata = AllocDosObject(DOS_INFODATA, 0);
6392 if(infodata == NULL) {
6393 ami_misc_fatal_error("Failed to allocate memory");
6394 FreeVec(current_user);
6395 return NULL;
6396 }
6397 GetDiskInfoTags(GDI_StringNameInput, users_dir,
6398 GDI_InfoData, infodata,
6399 TAG_DONE);
6400 if(infodata->id_DiskState == ID_DISKSTATE_WRITE_PROTECTED) {
6401 FreeDosObject(DOS_INFODATA, infodata);
6402 ami_misc_fatal_error("User directory MUST be on a writeable volume");
6403 FreeVec(current_user);
6404 return NULL;
6405 }
6406 FreeDosObject(DOS_INFODATA, infodata);
6407#else
6408#warning FIXME for OS3 and older OS4
6409#endif
6410 } else {
6411//TODO: check volume write status using old API
6412 }
6413
6414 int len = strlen(current_user);
6415 len += strlen(users_dir);
6416 len += 2; /* for poss path sep and NULL term */
6417
6418 current_user_dir = malloc(len);
6419 if(current_user_dir == NULL) {
6420 ami_misc_fatal_error("Failed to allocate memory");
6421 FreeVec(current_user);
6422 return NULL;
6423 }
6424
6425 strlcpy(current_user_dir, users_dir, len);
6426 AddPart(current_user_dir, current_user, len);
6427 FreeVec(users_dir);
6428 FreeVec(current_user);
6429
6430 NSLOG(netsurf, INFO, "User dir: %s", current_user_dir);
6431
6432 if((lock = CreateDirTree(current_user_dir)))
6433 UnLock(lock);
6434
6436
6438 if((lock = CreateDirTree(current_user_faviconcache))) UnLock(lock);
6439
6440 return current_user_dir;
6441}
6442
6443
6444/**
6445 * process miscellaneous window events
6446 *
6447 * \param gw The window receiving the event.
6448 * \param event The event code.
6449 * \return NSERROR_OK when processed ok
6450 */
6451static nserror
6453{
6454 switch (event) {
6457 break;
6458
6461 break;
6462
6465 break;
6466
6469 break;
6470
6473 break;
6474
6477 break;
6478
6481 break;
6482
6483 default:
6484 break;
6485 }
6486 return NSERROR_OK;
6487}
6488
6489
6492 .destroy = gui_window_destroy,
6493 .invalidate = amiga_window_invalidate_area,
6494 .get_scroll = gui_window_get_scroll,
6495 .set_scroll = gui_window_set_scroll,
6496 .get_dimensions = gui_window_get_dimensions,
6497 .event = gui_window_event,
6498
6499 .set_icon = gui_window_set_icon,
6500 .set_title = gui_window_set_title,
6501 .set_url = gui_window_set_url,
6502 .set_status = gui_window_set_status,
6503 .place_caret = gui_window_place_caret,
6504 .drag_start = gui_window_drag_start,
6505 .create_form_select_menu = gui_create_form_select_menu,
6506 .file_gadget_open = gui_file_gadget_open,
6507 .drag_save_object = gui_drag_save_object,
6508 .drag_save_selection = gui_drag_save_selection,
6509
6510 .console_log = gui_window_console_log,
6511
6512 /* from theme */
6513 .set_pointer = gui_window_set_pointer,
6514
6515 /* from download */
6516 .save_link = gui_window_save_link,
6517};
6518
6519
6522
6523 .get_resource_url = gui_get_resource_url,
6524};
6525
6528};
6529
6532
6533 .quit = gui_quit,
6534 .launch_url = gui_launch_url,
6535 .present_cookies = ami_cookies_present,
6536};
6537
6538/** Normal entry point from OS */
6539int main(int argc, char** argv)
6540{
6541 setbuf(stderr, NULL);
6542 char messages[100];
6543 char script[1024];
6544 char temp[1024];
6545 STRPTR current_user_cache = NULL;
6546 STRPTR current_user = NULL;
6547 BPTR lock = 0;
6548 nserror ret;
6549 int nargc = 0;
6550 char *nargv = NULL;
6551
6552 struct netsurf_table amiga_table = {
6554 .window = &amiga_window_table,
6555 .corewindow = amiga_core_window_table,
6556 .clipboard = amiga_clipboard_table,
6557 .download = amiga_download_table,
6558 .fetch = &amiga_fetch_table,
6559 .file = amiga_file_table,
6560 .utf8 = amiga_utf8_table,
6561 .search = amiga_search_table,
6562 .search_web = &amiga_search_web_table,
6563 .llcache = filesystem_llcache_table,
6564 .bitmap = amiga_bitmap_table,
6565 .layout = ami_layout_table,
6566 };
6567
6568#ifdef __amigaos4__
6569 signal(SIGINT, SIG_IGN);
6570#endif
6571 ret = netsurf_register(&amiga_table);
6572 if (ret != NSERROR_OK) {
6573 ami_misc_fatal_error("NetSurf operation table failed registration");
6574 return RETURN_FAIL;
6575 }
6576
6577 /* initialise logging. Not fatal if it fails but not much we
6578 * can do about it either.
6579 */
6580 nslog_init(NULL, &argc, argv);
6581
6582 /* Need to do this before opening any splash windows etc... */
6583 if ((ami_libs_open() == false)) {
6584 return RETURN_FAIL;
6585 }
6586
6587 /* Open splash window */
6588 Object *splash_window = ami_gui_splash_open();
6589
6590#ifndef __amigaos4__
6591 /* OS3 low memory handler */
6592 struct Interupt *memhandler = ami_memory_init();
6593#endif
6594
6595 if (ami_gui_resources_open() == false) { /* alloc msgports, objects and other miscelleny */
6596 ami_misc_fatal_error("Unable to allocate resources");
6597 ami_gui_splash_close(splash_window);
6599 return RETURN_FAIL;
6600 }
6601
6602 current_user = ami_gui_read_all_tooltypes(argc, argv);
6603 struct RDArgs *args = ami_gui_commandline(&argc, argv, &nargc, &nargv);
6604
6605 current_user_dir = ami_gui_get_user_dir(current_user);
6606 if(current_user_dir == NULL) {
6608 ami_gui_splash_close(splash_window);
6610 return RETURN_FAIL;
6611 }
6612
6613 ami_mime_init("PROGDIR:Resources/mimetypes");
6614 sprintf(temp, "%s/mimetypes.user", current_user_dir);
6615 ami_mime_init(temp);
6616
6617#ifdef __amigaos4__
6619#endif
6620
6621#ifdef WITH_AMIGA_DATATYPES
6622 /* DataTypes loader needs datatypes.library v45 */
6623 if(DataTypesBase->lib_Version >= 45)
6624 ret = amiga_datatypes_init();
6625#endif
6626
6627 /* user options setup */
6629 if (ret != NSERROR_OK) {
6630 ami_misc_fatal_error("Options failed to initialise");
6632 ami_gui_splash_close(splash_window);
6634 return RETURN_FAIL;
6635 }
6637 if(args != NULL) {
6638 nsoption_commandline(&nargc, &nargv, NULL);
6639 FreeArgs(args);
6640 }
6641
6642 if (ami_locate_resource(messages, "Messages") == false) {
6643 ami_misc_fatal_error("Cannot open Messages file");
6647 ami_gui_splash_close(splash_window);
6649 return RETURN_FAIL;
6650 }
6651
6652 ret = messages_add_from_file(messages);
6653
6654 current_user_cache = ASPrintf("%s/Cache", current_user_dir);
6655 if((lock = CreateDirTree(current_user_cache))) UnLock(lock);
6656
6657 ret = netsurf_init(current_user_cache);
6658
6659 if(current_user_cache != NULL) FreeVec(current_user_cache);
6660
6661 if (ret != NSERROR_OK) {
6662 ami_misc_fatal_error("NetSurf failed to initialise");
6666 ami_gui_splash_close(splash_window);
6668 return RETURN_FAIL;
6669 }
6670
6671 ret = amiga_icon_init();
6672
6673 search_web_init(nsoption_charp(search_engines_file));
6676 ami_amiupdate(); /* set env-vars for AmiUpdate */
6677 ami_font_init();
6682
6683 win_destroyed = false;
6684 ami_font_setdevicedpi(0); /* for early font requests, eg treeview init */
6685
6687
6688 urldb_load(nsoption_charp(url_file));
6689 urldb_load_cookies(nsoption_charp(cookie_file));
6690
6691 gui_init2(argc, argv);
6692
6693 ami_ctxmenu_init(); /* Requires screen pointer */
6694
6695 ami_gui_splash_close(splash_window);
6696
6697 strlcpy(script, nsoption_charp(arexx_dir), 1024);
6698 AddPart(script, nsoption_charp(arexx_startup), 1024);
6699 ami_arexx_execute(script);
6700
6701 NSLOG(netsurf, INFO, "Entering main loop");
6702
6703 while (!ami_quit) {
6704 ami_get_msg();
6705 }
6706
6707 strlcpy(script, nsoption_charp(arexx_dir), 1024);
6708 AddPart(script, nsoption_charp(arexx_shutdown), 1024);
6709 ami_arexx_execute(script);
6710
6711 ami_mime_free();
6712
6713 netsurf_exit();
6714
6717 free(current_user_dir);
6719
6720 /* finalise logging */
6722
6723#ifndef __amigaos4__
6724 /* OS3 low memory handler */
6725 ami_memory_fini(memhandler);
6726#endif
6727
6730
6731 return RETURN_OK;
6732}
6733
void ami_clipboard_free(void)
Definition: clipboard.c:82
void ami_clipboard_init(void)
Definition: clipboard.c:70
struct gui_clipboard_table * amiga_clipboard_table
Definition: clipboard.c:381
void gui_start_selection(struct gui_window *g)
Definition: clipboard.c:87
nserror ami_cookies_present(const char *search_term)
Open the cookie viewer.
Definition: cookies.c:336
struct core_window_table * amiga_core_window_table
Definition: corewindow.c:925
Interface to Intuition-based context menu operations.
struct Menu * ami_ctxmenu_clicktab_create(struct gui_window_2 *gwin, Object **clicktab_obj)
Definition: ctxmenu.h:90
struct Menu * ami_ctxmenu_history_create(int direction, struct gui_window_2 *gwin)
Definition: ctxmenu.h:89
struct Hook * ami_ctxmenu_get_hook(APTR data)
Definition: ctxmenu.h:87
void ami_ctxmenu_init(void)
Definition: ctxmenu.h:85
void ami_ctxmenu_release_hook(struct Hook *hook)
Definition: ctxmenu.h:88
@ AMI_CTXMENU_HISTORY_BACK
Definition: ctxmenu.h:30
@ AMI_CTXMENU_HISTORY_FORWARD
Definition: ctxmenu.h:31
void ami_ctxmenu_free(void)
Definition: ctxmenu.h:86
void ami_mime_free(void)
Definition: filetype.c:264
const char * fetch_filetype(const char *unix_path)
Determine the MIME type of a local file.
Definition: filetype.c:58
nserror ami_mime_init(const char *mimefile)
Definition: filetype.c:177
static void ami_gui_close_tabs(struct gui_window_2 *gwin, bool other_tabs)
Definition: gui.c:5454
static bool cli_force
Definition: gui.c:353
static void ami_gui_splash_close(Object *win_obj)
Definition: gui.c:6332
static nserror gui_window_get_dimensions(struct gui_window *gw, int *restrict width, int *restrict height)
Find the current dimensions of a amiga browser window content area.
Definition: gui.c:2081
static void ami_refresh_window(struct gui_window_2 *gwin)
Definition: gui.c:4563
static ULONG rxsig
Definition: gui.c:349
void ami_try_quit(void)
Definition: gui.c:3917
static void ami_gui_console_log_remove(struct gui_window *g)
Definition: gui.c:2305
bool ami_gui_window_update_box_deferred_check(struct MinList *deferred_rects, const struct rect *restrict new_rect, APTR mempool)
Check rect is not already queued for redraw.
Definition: gui.c:5692
struct ami_history_local_window * ami_gui_get_history_window(struct gui_window *gw)
Get local history window from gui_window.
Definition: gui.c:487
static void ami_update_buttons(struct gui_window_2 *gwin)
Definition: gui.c:1613
static void ami_gui_hotlist_toolbar_add(struct gui_window_2 *gwin)
Definition: gui.c:4099
static STRPTR nsscreentitle
Definition: gui.c:343
struct Window * ami_gui_get_window(struct gui_window *gw)
Get window from gui_window.
Definition: gui.c:577
static void gui_window_set_status(struct gui_window *g, const char *text)
Definition: gui.c:5933
static nsurl * gui_get_resource_url(const char *path)
Definition: gui.c:1203
static nserror gui_window_event(struct gui_window *gw, enum gui_window_event event)
process miscellaneous window events
Definition: gui.c:6452
static void gui_window_destroy(struct gui_window *g)
Definition: gui.c:5495
static uint32 ami_appid
Definition: gui.c:347
static void ami_gui_refresh_favicon(void *p)
Definition: gui.c:2537
static void gui_window_remove_caret(struct gui_window *g)
Definition: gui.c:6130
static void ami_gui_cache_favicon(nsurl *url, struct bitmap *favicon)
Definition: gui.c:3993
#define NSA_STATUS_TEXT
Definition: gui.c:188
#define EXTRAUP
Definition: gui.c:179
int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie)
Definition: gui.c:1691
static void ami_gui_scroller_update(struct gui_window_2 *gwin)
Check the scroll bar requirements for a browser window, and add/remove the vertical scroller as appro...
Definition: gui.c:2207
void ami_gui_set_find_window(struct gui_window *gw, struct find_window *fw)
Set search window in gui_window.
Definition: gui.c:499
static const __attribute__((used))
Definition: gui.c:360
static void gui_window_update_extent(struct gui_window *g)
Definition: gui.c:3674
static nserror ami_set_options(struct nsoption_s *defaults)
Set option defaults for amiga frontend.
Definition: gui.c:1047
static void ami_set_border_gadget_size(struct gui_window_2 *gwin)
Definition: gui.c:2571
int ami_gui2_get_ctxmenu_history_tmp(struct gui_window_2 *gwin)
Get ctxmenu history tmp from gui_window_2.
Definition: gui.c:611
static void ami_gui_appicon_remove(struct gui_window_2 *gwin)
Definition: gui.c:3270
struct Screen * ami_gui_get_screen(void)
Get a pointer to the screen NetSurf is running on.
Definition: gui.c:404
struct gui_utf8_table * amiga_utf8_table
Definition: utf8.c:136
struct Node * ami_gui_get_tab_node(struct gui_window *gw)
Get tab node from gui_window.
Definition: gui.c:463
void ami_gui_hotlist_update_all(void)
Update hotlist toolbar and recreate the menu for all windows.
Definition: gui.c:4226
void ami_gui_close_inactive_tabs(struct gui_window_2 *gwin)
Close all tabs in a window except the active one.
Definition: gui.c:5490
static bool ami_quit
Definition: gui.c:332
static void ami_gui_console_log_switch(struct gui_window *g)
Definition: gui.c:2339
static void ami_gui_console_log_add(struct gui_window *g)
Definition: gui.c:2269
void ami_gui2_set_new_content(struct gui_window_2 *gwin, bool new_content)
Set new_content in gui_window_2 Indicates the window needs redrawing.
Definition: gui.c:635
static void ami_amiupdate(void)
Definition: gui.c:1174
static struct Screen * scrn
Definition: gui.c:328
static bool ami_gui_map_filename(char **remapped, const char *restrict path, const char *restrict file, const char *restrict map)
Definition: gui.c:744
static struct gui_misc_table amiga_misc_table
Definition: gui.c:6530
static int screen_signal
Definition: gui.c:341
@ GID_TABLAYOUT
Definition: gui.c:205
@ GID_HOTLISTSEPBAR
Definition: gui.c:236
@ GID_SEARCHSTRING
Definition: gui.c:232
@ OID_HSCROLL
Definition: gui.c:203
@ GID_HSCROLLLAYOUT
Definition: gui.c:238
@ GID_MAIN
Definition: gui.c:204
@ GID_ICON
Definition: gui.c:209
@ GID_PAGEINFO_INSECURE_BM
Definition: gui.c:218
@ GID_FAVE_ADD
Definition: gui.c:224
@ OID_VSCROLL
Definition: gui.c:202
@ GID_ADDTAB_BM
Definition: gui.c:229
@ GID_FAVE_RMV
Definition: gui.c:225
@ GID_PAGEINFO_INTERNAL_BM
Definition: gui.c:219
@ GID_PAGEINFO_SECURE_BM
Definition: gui.c:221
@ GID_FORWARD
Definition: gui.c:214
@ GID_STOP
Definition: gui.c:210
@ GID_PAGEINFO_LOCAL_BM
Definition: gui.c:220
@ GID_CLOSETAB_BM
Definition: gui.c:227
@ OID_MAIN
Definition: gui.c:201
@ GID_LOG
Definition: gui.c:242
@ GID_STATUS
Definition: gui.c:207
@ GID_HSCROLL
Definition: gui.c:237
@ GID_HOME
Definition: gui.c:212
@ GID_LAST
Definition: gui.c:243
@ GID_FAVE
Definition: gui.c:223
@ GID_PAGEINFO
Definition: gui.c:217
@ GID_TABS
Definition: gui.c:230
@ GID_RELOAD
Definition: gui.c:211
@ GID_SEARCH_ICON
Definition: gui.c:216
@ GID_ADDTAB
Definition: gui.c:228
@ GID_TABS_FLAG
Definition: gui.c:231
@ GID_LOGLAYOUT
Definition: gui.c:241
@ GID_TOOLBARLAYOUT
Definition: gui.c:233
@ GID_CLOSETAB
Definition: gui.c:226
@ GID_HOTLISTLAYOUT
Definition: gui.c:235
@ GID_VSCROLLLAYOUT
Definition: gui.c:240
@ GID_THROBBER
Definition: gui.c:215
@ GID_PAGEINFO_WARNING_BM
Definition: gui.c:222
@ GID_URL
Definition: gui.c:208
@ GID_HOTLIST
Definition: gui.c:234
@ GID_BACK
Definition: gui.c:213
@ GID_VSCROLL
Definition: gui.c:239
@ GID_BROWSER
Definition: gui.c:206
void ami_gui2_set_ctxmenu_history_tmp(struct gui_window_2 *gwin, int temp)
Set ctxmenu history tmp in gui_window_2.
Definition: gui.c:605
static void ami_gui_hotlist_toolbar_remove(struct gui_window_2 *gwin)
Definition: gui.c:4174
static struct gui_window * gui_window_create(struct browser_window *bw, struct gui_window *existing, gui_window_create_flags flags)
Definition: gui.c:4715
static void ami_gui_hotlist_toolbar_update(struct gui_window_2 *gwin)
Definition: gui.c:4198
int main(int argc, char **argv)
Normal entry point from OS.
Definition: gui.c:6539
nserror ami_gui_win_list_add(void *win, int type, const struct ami_win_event_table *table)
Add a window to the NetSurf window list (to enable event processing)
Definition: gui.c:4684
static nserror gui_search_web_provider_update(const char *provider_name, struct bitmap *ico_bitmap)
Gui callback when search provider details are updated.
Definition: gui.c:6011
static void ami_update_quals(struct gui_window_2 *gwin)
Definition: gui.c:1838
static void ami_handle_appmsg(void)
Definition: gui.c:3330
uint32 ami_gui_get_app_id(void)
Get the application.library ID NetSurf is registered as.
Definition: gui.c:6360
static void ami_toggletabbar(struct gui_window_2 *gwin, bool show)
Definition: gui.c:4248
static STRPTR temp_homepage_url
Definition: gui.c:352
static struct IBox * ami_ns_rect_to_ibox(struct gui_window_2 *gwin, const struct rect *rect)
Definition: gui.c:1994
void ami_gui_history(struct gui_window_2 *gwin, bool back)
Definition: gui.c:1675
static void ami_set_screen_defaults(struct Screen *screen)
Definition: gui.c:1029
bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *restrict x, ULONG *restrict y)
Definition: gui.c:6190
void * ami_window_at_pointer(int type)
undocumented, or internal, or documented elsewhere
Definition: gui.c:683
void ami_gui_close_window(void *w)
Close a window and all tabs attached to it.
Definition: gui.c:5484
static nserror amiga_window_invalidate_area(struct gui_window *g, const struct rect *restrict rect)
Invalidates an area of an amiga browser window.
Definition: gui.c:3721
struct Menu * ami_gui_get_menu(struct gui_window *gw)
Get imenu from gui_window.
Definition: gui.c:583
static void gui_file_gadget_open(struct gui_window *g, struct hlcache_handle *hl, struct form_control *gadget)
Definition: gui.c:6340
void ami_gui_set_throbbing(struct gui_window *gw, bool throbbing)
Set throbbing status in gui_window.
Definition: gui.c:515
void ami_set_pointer(struct gui_window_2 *gwin, gui_pointer_shape shape, bool update)
Definition: gui.c:689
static void ami_do_redraw(struct gui_window_2 *gwin)
Definition: gui.c:5730
static void ami_get_vscroll_pos(struct gui_window_2 *gwin, ULONG *ys)
Definition: gui.c:5838
#define SCROLL_BOTTOM
Definition: gui.c:173
static nserror gui_window_set_url(struct gui_window *g, nsurl *url)
Definition: gui.c:5967
static UWORD ami_system_colour_scrollbar_fgpen(struct DrawInfo *drinfo)
Definition: gui.c:917
void ami_gui_adjust_scale(struct gui_window *gw, float adjustment)
Adjust scale by specified amount.
Definition: gui.c:4397
static struct MinList * window_list
Definition: gui.c:327
bool ami_locate_resource(char *fullpath, const char *file)
Definition: gui.c:815
#define SIDEUP
Definition: gui.c:177
static bool ami_gui_vscroll_add(struct gui_window_2 *gwin)
Definition: gui.c:2154
static ULONG applibsig
Definition: gui.c:348
bool ami_gui_get_throbbing(struct gui_window *gw)
Get throbbing status from gui_window.
Definition: gui.c:509
struct gui_window * ami_gui_get_active_gw(void)
Get a pointer to the gui_window which NetSurf considers to be the current/active one.
Definition: gui.c:399
static void ami_do_redraw_tiled(struct gui_window_2 *gwin, bool busy, int left, int top, int width, int height, int sx, int sy, struct IBox *bbox, struct redraw_context *ctx)
Definition: gui.c:4427
struct browser_window * ami_gui2_get_browser_window(struct gui_window_2 *gwin)
Get browser window from gui_window_2.
Definition: gui.c:426
static void gui_init2(int argc, char **argv)
Definition: gui.c:1422
static bool ami_gui_console_log_toggle(struct gui_window *g)
Definition: gui.c:2328
static BOOL locked_screen
Definition: gui.c:340
static Object * ami_gui_splash_open(void)
Definition: gui.c:6233
void ami_reset_pointer(struct gui_window_2 *gwin)
Definition: gui.c:697
static bool ami_gui_resources_open(void)
Definition: gui.c:889
void ami_gui2_set_ctxmenu_history(struct gui_window_2 *gwin, ULONG direction, Object *ctx_hist)
Set ctxmenu history in gui_window_2.
Definition: gui.c:623
static bool ami_gui_vscroll_remove(struct gui_window_2 *gwin)
Definition: gui.c:2182
static struct MsgPort * applibport
Definition: gui.c:346
static void gui_quit(void)
Definition: gui.c:3932
#define USERS_DIR
Definition: gui.c:355
static struct gui_fetch_table amiga_fetch_table
Definition: gui.c:6520
void ami_get_msg(void)
Definition: gui.c:3533
STRPTR ami_gui_get_screen_title(void)
Get the string for NetSurf's screen titlebar.
Definition: gui.c:1018
static bool ami_gui_hscroll_remove(struct gui_window_2 *gwin)
Definition: gui.c:2134
static void ami_redraw_callback(void *p)
Definition: gui.c:5624
#define NSA_QUAL_ALT
Definition: gui.c:183
static void ami_change_tab(struct gui_window_2 *gwin, int direction)
Definition: gui.c:3601
static void gui_window_set_title(struct gui_window *g, const char *restrict title)
Definition: gui.c:3624
struct ami_menu_data ** ami_gui2_get_menu_data(struct gui_window_2 *gwin)
Get menu_data from gui_window_2.
Definition: gui.c:599
static struct gui_globals * browserglob
Definition: gui.c:344
nserror ami_gui_new_blank_tab(struct gui_window_2 *gwin)
Definition: gui.c:4403
static void ami_schedule_redraw_remove(struct gui_window_2 *gwin)
Definition: gui.c:5656
#define SCROLL_PAGE_UP
Definition: gui.c:171
static char * ami_gui_read_tooltypes(struct WBArg *wbarg)
Definition: gui.c:1376
void ami_gui2_set_menu(struct gui_window_2 *gwin, struct Menu *menu)
Set imenu to gui_window_2.
Definition: gui.c:590
static struct MsgPort * sport
Definition: gui.c:329
static void gui_window_place_caret(struct gui_window *g, int x, int y, int height, const struct rect *clip)
Definition: gui.c:6086
void ami_gui2_set_closed(struct gui_window_2 *gwin, bool closed)
Set closed in gui_window_2.
Definition: gui.c:629
nserror ami_gui_get_space_box(Object *obj, struct IBox **bbox)
Compatibility function to get space.gadget render area.
Definition: gui.c:1844
Object * ami_gui2_get_object(struct gui_window_2 *gwin, int object_type)
Get object from gui_window.
Definition: gui.c:535
const char * ami_gui_get_win_title(struct gui_window *gw)
Get window title from gui_window.
Definition: gui.c:450
static void ami_gui_window_update_box_deferred(struct gui_window *g, bool draw)
Definition: gui.c:5661
static int ami_gui_hotlist_scan(struct List *speed_button_list, struct gui_window_2 *gwin)
Definition: gui.c:4088
static struct gui_window * cur_gw
Definition: gui.c:330
#define NSA_KBD_SCROLL_PX
Definition: gui.c:167
static nserror gui_window_set_scroll(struct gui_window *g, const struct rect *rect)
Set the scroll position of a amiga browser window.
Definition: gui.c:5867
int ami_gui_get_throbber_frame(struct gui_window *gw)
Get throbbing frame from gui_window.
Definition: gui.c:521
static char * users_dir
Definition: gui.c:356
const char * ami_gui_get_tab_title(struct gui_window *gw)
Get tab title from gui_window.
Definition: gui.c:457
static void gui_window_set_icon(struct gui_window *g, struct hlcache_handle *icon)
function to add retrieved favicon to gui
Definition: gui.c:2464
static char * current_user_dir
Definition: gui.c:357
static void ami_gui_resources_free(void)
Definition: gui.c:879
void ami_gui_set_history_window(struct gui_window *gw, struct ami_history_local_window *hw)
Set local history window in gui_window.
Definition: gui.c:493
struct gui_window * ami_gui2_get_gui_window(struct gui_window_2 *gwin)
Get gui_window from gui_window_2.
Definition: gui.c:444
static void ami_handle_applib(void)
Definition: gui.c:3445
STRPTR ami_locale_langs(int *codeset)
Definition: gui.c:703
struct List * ami_gui_get_download_list(struct gui_window *gw)
Get download list from gui_window.
Definition: gui.c:432
#define NSA_QUAL_SHIFT
Definition: gui.c:182
Object * ami_gui2_get_ctxmenu_history(struct gui_window_2 *gwin, ULONG direction)
Get ctxmenu history from gui_window_2.
Definition: gui.c:617
static void gui_window_new_content(struct gui_window *g)
Definition: gui.c:6144
static bool gui_window_get_scroll(struct gui_window *g, int *restrict sx, int *restrict sy)
Definition: gui.c:5847
#define AMINS_SCROLLERPEN
Definition: gui.c:166
#define BOOL_MISMATCH(a, b)
Definition: gui.c:194
static bool ami_spacebox_to_ns_coords(struct gui_window_2 *gwin, int *restrict x, int *restrict y, int space_x, int space_y)
Definition: gui.c:1875
static void ami_openscreen(void)
Definition: gui.c:1221
#define SCROLL_PAGE_DOWN
Definition: gui.c:172
static struct Hook newprefs_hook
Definition: gui.c:350
ULONG ami_gui2_get_tabs(struct gui_window_2 *gwin)
Get tabs from gui_window_2.
Definition: gui.c:469
void ami_gui_beep(void)
Beep.
Definition: gui.c:415
void ami_gui_free_space_box(struct IBox *bbox)
Free any data obtained via ami_gui_get_space_box().
Definition: gui.c:1870
bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *restrict x, int *restrict y, int mouse_x, int mouse_y)
Definition: gui.c:1890
static bool ami_gui_hotlist_add(void *userdata, int level, int item, const char *title, nsurl *url, bool is_folder)
Definition: gui.c:4032
static void ami_switch_tab(struct gui_window_2 *gwin, bool redraw)
Definition: gui.c:3752
static void ami_gui_trap_mouse(struct gui_window_2 *gwin)
Definition: gui.c:2029
static void ami_gui_hotlist_toolbar_free(struct gui_window_2 *gwin, struct List *speed_button_list)
Definition: gui.c:4149
struct hlcache_handle * ami_gui_get_favicon(struct gui_window *gw)
Get favicon from gui_window.
Definition: gui.c:481
HOOKF(void, ami_gui_newprefs_hook, APTR, window, APTR)
Definition: gui.c:1216
static void ami_do_redraw_limits(struct gui_window *g, struct browser_window *bw, bool busy, int x0, int y0, int x1, int y1)
Redraw an area of the browser window - Amiga-specific function.
Definition: gui.c:4528
void ami_gui_set_scale(struct gui_window *gw, float scale)
Set the scale of a gui window.
Definition: gui.c:4391
struct List * ami_gui2_get_tab_list(struct gui_window_2 *gwin)
Get tab list from gui_window_2.
Definition: gui.c:475
static const struct ami_win_event_table ami_gui_table
Definition: gui.c:4709
void ami_gui_win_list_remove(void *win)
Remove a window from the NetSurf window list.
Definition: gui.c:4698
int ami_gui_count_windows(int window, int *tabs)
Count windows, and optionally tabs.
Definition: gui.c:4363
static BOOL ami_gui_event(void *w)
Definition: gui.c:2634
static bool win_destroyed
Definition: gui.c:342
static void ami_quit_netsurf_delayed(void)
Definition: gui.c:3854
int ami_gui_get_quals(Object *win_obj)
Get which qualifier keys are being pressed.
Definition: gui.c:1813
static BOOL ami_handle_msg(void)
Definition: gui.c:2588
void ami_gui_update_hotlist_button(struct gui_window_2 *gwin)
Definition: gui.c:4003
static nserror gui_page_info_change(struct gui_window *gw)
Definition: gui.c:3280
void ami_schedule_redraw(struct gui_window_2 *gwin, bool full_redraw)
Schedule a redraw of the browser window - Amiga-specific function.
Definition: gui.c:5648
static bool gui_window_drag_start(struct gui_window *g, gui_drag_type type, const struct rect *rect)
Definition: gui.c:6165
static void gui_window_console_log(struct gui_window *g, browser_window_console_source src, const char *msg, size_t msglen, browser_window_console_flags flags)
Definition: gui.c:2350
static void ami_openscreenfirst(void)
Definition: gui.c:1308
static bool ami_gui_check_resource(char *fullpath, const char *file)
Definition: gui.c:793
static void ami_gui_menu_update_all(void)
Definition: gui.c:2050
static void ami_gui_close_screen(struct Screen *scrn, BOOL locked_screen, BOOL donotwait)
Definition: gui.c:3879
static bool ami_gui_hscroll_add(struct gui_window_2 *gwin)
Definition: gui.c:2105
struct Window * ami_gui2_get_window(struct gui_window_2 *gwin)
Get window from gui_window_2.
Definition: gui.c:571
#define SCROLL_TOP
Definition: gui.c:170
struct browser_window * ami_gui_get_browser_window(struct gui_window *gw)
Get browser window from gui_window.
Definition: gui.c:420
static struct MsgPort * schedulermsgport
Definition: gui.c:334
static struct MsgPort * appport
Definition: gui.c:335
static struct RDArgs * ami_gui_commandline(int *restrict argc, char **argv, int *restrict nargc, char **nargv)
Definition: gui.c:1315
static char * current_user_faviconcache
Definition: gui.c:358
static struct gui_window_table amiga_window_table
Definition: gui.c:6490
struct MinList * ami_gui_get_window_list(void)
Get the window list.
Definition: gui.c:409
char * ami_gui_get_cache_favicon_name(nsurl *url, bool only_if_avail)
Definition: gui.c:3973
struct gui_window_2 * ami_gui_get_gui_window_2(struct gui_window *gw)
Get gui_window_2 from gui_window.
Definition: gui.c:438
static struct gui_search_web_table amiga_search_web_table
Definition: gui.c:6526
void ami_gui_tabs_toggle_all(void)
Definition: gui.c:4327
static STRPTR ami_gui_read_all_tooltypes(int argc, char **argv)
Definition: gui.c:1394
static void ami_gui_scroll_internal(struct gui_window_2 *gwin, int xs, int ys)
Definition: gui.c:1917
static char * ami_gui_get_user_dir(STRPTR current_user)
Definition: gui.c:6368
BOOL ami_gadget_hit(Object *obj, int x, int y)
Definition: gui.c:6217
#define nsoption_default_set_int(OPTION, VALUE)
void ami_gui_set_throbber_frame(struct gui_window *gw, int frame)
Set throbbing frame in gui_window.
Definition: gui.c:528
static void ami_get_hscroll_pos(struct gui_window_2 *gwin, ULONG *xs)
Definition: gui.c:5828
void ami_quit_netsurf(void)
Definition: gui.c:3820
#define NSA_MAX_HOTLIST_BUTTON_LEN
Definition: gui.c:168
#define AMI_GUI_TOOLBAR_MAX
Definition: gui.h:57
struct MsgPort * ami_gui_get_shared_msgport(void)
Get shared message port.
@ AMI_WIN_MAIN
Definition: gui.h:47
@ AMI_GAD_URL
Definition: gui.h:45
@ AMI_GAD_TABS
Definition: gui.h:44
@ AMI_GAD_SEARCH
Definition: gui.h:46
@ AMI_GAD_THROBBER
Definition: gui.h:43
void ami_help_new_screen(struct Screen *screen)
Definition: help.c:66
ULONG ami_help_signal(void)
Definition: help.c:72
void ami_help_process(void)
Definition: help.c:80
void ami_help_open(ULONG node, struct Screen *screen)
Definition: help.c:50
void ami_help_free(void)
Definition: help.c:57
@ AMI_HELP_GUI
Definition: help.h:26
void ami_menu_free_glyphs(void)
Definition: menu.c:182
void ami_misc_fatal_error(const char *message)
Definition: misc.c:73
int32 amiga_warn_user_multi(const char *body, const char *opt1, const char *opt2, struct Window *win)
Definition: misc.c:93
nserror amiga_warn_user(const char *warning, const char *detail)
Warn the user of an event.
Definition: misc.c:79
char * translate_escape_chars(const char *s)
returns a string with escape chars translated and string converted to local charset (based on remove_...
Definition: misc.c:246
struct gui_file_table * amiga_file_table
Definition: misc.c:463
nserror ami_pageinfo_open(struct browser_window *bw, ULONG left, ULONG top)
Open the page info window.
Definition: pageinfo.c:224
const struct plotter_table amiplot
Definition: plotters.c:1148
bool ami_plot_screen_is_palettemapped(void)
Definition: plotters.c:546
void ami_plot_ra_free(struct gui_globals *gg)
Free a plotter render area.
Definition: plotters.c:257
struct BitMap * ami_plot_ra_get_bitmap(struct gui_globals *gg)
Get a drawing BitMap associated with a render area.
Definition: plotters.c:301
void ami_plot_clear_bbox(struct RastPort *rp, struct IBox *bbox)
Definition: plotters.c:408
void ami_plot_ra_set_pen_list(struct gui_globals *gg, struct MinList *pen_list)
Set a list of shared pens for a render area to use Only relevant for palette-mapped screens.
Definition: plotters.c:312
void ami_plot_ra_get_size(struct gui_globals *gg, int *width, int *height)
Get size of BitMap associated with a render area.
Definition: plotters.c:306
void ami_clearclipreg(struct gui_globals *gg)
Definition: plotters.c:317
struct gui_globals * ami_plot_ra_alloc(ULONG width, ULONG height, bool force32bit, bool alloc_pen_list)
Alloc a plotter render area.
Definition: plotters.c:111
void ami_plot_release_pens(struct MinList *shared_pens)
Definition: plotters.c:360
void ami_schedule_free(void)
Finalise amiga scheduler.
Definition: schedule.c:320
nserror ami_schedule(int t, void(*callback)(void *p), void *p)
Schedule a callback.
Definition: schedule.c:331
void ami_schedule_handle(struct MsgPort *nsmsgport)
Handle a message received from the scheduler process.
Definition: schedule.c:369
nserror ami_schedule_create(struct MsgPort *msgport)
Initialise amiga scheduler.
Definition: schedule.c:302
void ami_mouse_pointers_free(void)
Definition: theme.c:396
void ami_theme_throbber_free(void)
Definition: theme.c:191
int ami_theme_throbber_get_width(void)
Definition: theme.c:163
void ami_theme_init(void)
Definition: theme.c:134
void ami_init_mouse_pointers(void)
Definition: theme.c:284
void ami_theme_throbber_setup(void)
Definition: theme.c:173
void ami_throbber_redraw_schedule(int t, struct gui_window *g)
Definition: theme.c:517
int ami_theme_throbber_get_height(void)
Definition: theme.c:168
void ami_update_pointer(struct Window *win, gui_pointer_shape shape)
Definition: theme.c:221
void ami_get_theme_filename(char *filename, const char *themestring, bool protocol)
Definition: theme.c:198
void ami_arexx_cleanup(void)
Definition: arexx.c:185
STATIC char result[100]
Definition: arexx.c:77
bool ami_arexx_init(ULONG *rxsig)
Definition: arexx.c:127
void ami_arexx_self(const char *cmd)
Definition: arexx.c:167
void ami_arexx_execute(char *script)
Definition: arexx.c:172
void ami_arexx_handle(void)
Definition: arexx.c:156
void gui_window_set_pointer(struct gui_window *gw, gui_pointer_shape shape)
set the pointer shape
Definition: gui.c:482
Low-level source data cache backing store interface.
struct gui_llcache_table * filesystem_llcache_table
nserror browser_window_history_get_thumbnail(struct browser_window *bw, struct bitmap **bitmap_out)
Get the thumbnail bitmap for the current history entry.
nserror browser_window_history_forward(struct browser_window *bw, bool new_window)
Go forward in the history.
nserror browser_window_history_back(struct browser_window *bw, bool new_window)
Go back in the history.
Interface to browser history operations.
Browser window creation and manipulation interface.
nserror browser_window_schedule_reformat(struct browser_window *bw)
Reformat the browser window contents in a safe context.
bool browser_window_redraw_ready(struct browser_window *bw)
Check whether browser window is ready for redraw.
nserror browser_window_refresh_url_bar(struct browser_window *bw)
Update URL bar for a given browser window to bw's content's URL.
nserror browser_window_get_features(struct browser_window *bw, int x, int y, struct browser_window_features *data)
Get access to any page features at the given coordinates.
nserror browser_window_navigate(struct browser_window *bw, struct nsurl *url, struct nsurl *referrer, enum browser_window_nav_flags flags, char *post_urlenc, struct fetch_multipart_data *post_multipart, struct hlcache_handle *parent)
Start fetching a page in a browser window.
bool browser_window_redraw(struct browser_window *bw, int x, int y, const struct rect *clip, const struct redraw_context *ctx)
Redraw an area of a window.
bool browser_window_has_content(struct browser_window *bw)
Find out if a browser window is currently showing a content.
bool browser_window_back_available(struct browser_window *bw)
Check availability of Back action for a given browser window.
nserror browser_window_get_scrollbar_type(struct browser_window *bw, browser_scrolling *h, browser_scrolling *v)
Get the browser window's scrollbar details.
void browser_window_mouse_click(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle mouse clicks in a browser window.
bool browser_window_scroll_at_point(struct browser_window *bw, int x, int y, int scrx, int scry)
Send a scroll request to a browser window at a particular point.
void browser_window_destroy(struct browser_window *bw)
Close and destroy a browser window.
nserror browser_window_reload(struct browser_window *bw, bool all)
Reload the page in a browser window.
browser_scrolling
@ BW_SCROLLING_NO
@ BW_SCROLLING_YES
bool browser_window_reload_available(struct browser_window *bw)
Check availability of Reload action for a given browser window.
bool browser_window_forward_available(struct browser_window *bw)
Check availability of Forward action for a given browser window.
browser_window_page_info_state
Browser window page information states.
@ PAGE_STATE_INSECURE
Insecure page load.
@ PAGE_STATE_SECURE_ISSUES
Secure load, but has insecure elements.
@ PAGE_STATE_SECURE
Secure load.
@ PAGE_STATE_SECURE_OVERRIDE
Secure load, but had to override.
@ PAGE_STATE_LOCAL
Page loaded from file:/// etc.
@ PAGE_STATE_INTERNAL
Page loaded from internal handler.
const char * browser_window_get_title(struct browser_window *bw)
Get the title of a browser_window.
nserror browser_window_get_extents(struct browser_window *bw, bool scaled, int *width, int *height)
Get a browser window's content extents.
nserror browser_window_create(enum browser_window_create_flags flags, struct nsurl *url, struct nsurl *referrer, struct browser_window *existing, struct browser_window **bw)
Create and open a new root browser window with the given page.
void browser_window_stop(struct browser_window *bw)
Stop all fetching activity in a browser window.
bool browser_window_is_frameset(struct browser_window *bw)
Find out if a browser window contains a frameset.
nserror browser_window_set_scale(struct browser_window *bw, float scale, bool absolute)
Sets the scale of a browser window.
browser_window_page_info_state browser_window_get_page_info_state(const struct browser_window *bw)
Request the current browser window page info state.
struct hlcache_handle * browser_window_get_content(struct browser_window *bw)
Get a cache handle for the content within a browser window.
@ BW_CREATE_HISTORY
this will form a new history node (don't set for back/reload/etc)
@ BW_CREATE_TAB
New gui_window to be tab in same window as "existing" gui_window.
@ BW_CREATE_FOREGROUND
Request foreground opening.
@ BW_CREATE_CLONE
New gui_window to be clone of "existing" gui_window.
bool browser_window_stop_available(struct browser_window *bw)
Check availability of Stop action for a given browser window.
bool browser_window_drop_file_at_point(struct browser_window *bw, int x, int y, char *file)
Drop a file onto a browser window at a particular point, or determine if a file may be dropped onto t...
@ BW_NAVIGATE_HISTORY
this will form a new history node (don't set for back/reload/etc)
void browser_window_mouse_track(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle non-click mouse action in a browser window.
void browser_window_set_gadget_filename(struct browser_window *bw, struct form_control *gadget, const char *fn)
set filename on form control.
static osspriteop_area * buffer
The buffer characteristics.
Definition: buffer.c:55
browser_window_console_source
Sources of messages which end up in the browser window console.
Definition: console.h:30
@ BW_CS_SCRIPT_CONSOLE
Logging from some running script.
Definition: console.h:33
@ BW_CS_INPUT
Input from the client.
Definition: console.h:31
@ BW_CS_SCRIPT_ERROR
Error from some running script.
Definition: console.h:32
browser_window_console_flags
Flags for browser window console logging.
Definition: console.h:41
@ BW_CS_FLAG_LEVEL_LOG
Logged at the 'log' level, please only use one of the LEVEL flags.
Definition: console.h:55
@ BW_CS_FLAG_LEVEL_DEBUG
Logged at the 'debug' level, please use only one of the LEVEL flags.
Definition: console.h:53
@ BW_CS_FLAG_LEVEL_INFO
Logged at the 'info' level, please use only one of the LEVEL flags.
Definition: console.h:57
@ BW_CS_FLAG_LEVEL_MASK
Mask for the error level to allow easy comparison using the above.
Definition: console.h:64
@ BW_CS_FLAG_LEVEL_WARN
Logged at the 'warn' level, please use only one of the LEVEL flags.
Definition: console.h:59
@ BW_CS_FLAG_LEVEL_ERROR
Logged at the 'error' level, please use only one of the LEVEL flags.
Definition: console.h:61
@ BW_CS_FLAG_FOLDABLE
The log entry is foldable.
Definition: console.h:50
nserror fetch_fdset(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, int *maxfd_out)
Get the set of file descriptors the fetchers are currently using.
Definition: fetch.c:385
Fetching of data from a URL (interface).
Unified cookie database public interface.
void urldb_save_cookies(const char *filename)
Save persistent cookies to file.
Definition: urldb.c:4444
void urldb_load_cookies(const char *filename)
Load a cookie file into the database.
Definition: urldb.c:4277
#define amiga_datatypes_init()
Definition: datatypes.h:37
nserror hotlist_fini(void)
Finalise the hotlist.
Definition: hotlist.c:1386
nserror hotlist_add_url(nsurl *url)
Add an entry to the hotlist for given URL.
Definition: hotlist.c:1428
nserror hotlist_init(const char *load_path, const char *save_path)
Initialise the hotlist.
Definition: hotlist.c:1289
bool hotlist_has_url(nsurl *url)
Check whether given URL is present in hotlist.
Definition: hotlist.c:1491
void hotlist_remove_url(nsurl *url)
Remove any entries matching the given URL from the hotlist.
Definition: hotlist.c:1533
nserror search_web_omni(const char *term, enum search_web_omni_flags flags, struct nsurl **url_out)
Generate a nsurl from a search term.
Definition: searchweb.c:318
nserror search_web_init(const char *provider_fname)
Initialise the web search operations.
Definition: searchweb.c:531
nserror search_web_select_provider(const char *selection)
Change the currently selected web search provider.
Definition: searchweb.c:403
const char *const netsurf_version
User friendly version string.
Definition: version.c:23
Version information interface.
bool ami_drag_has_data(void)
Definition: drag.c:329
void gui_drag_save_selection(struct gui_window *g, const char *selection)
Definition: drag.c:303
void ami_drag_save(struct Window *win)
Definition: drag.c:307
bool ami_drag_icon_move(void)
Definition: drag.c:319
void gui_drag_save_object(struct gui_window *g, struct hlcache_handle *c, gui_save_type type)
Definition: drag.c:298
#define AMI_DRAG_THRESHOLD
Definition: drag.h:28
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_BAD_PARAMETER
Bad Parameter.
Definition: errors.h:48
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
const char * type
Definition: filetype.cpp:44
static void gui_window_start_throbber(struct gui_window *g)
Definition: gui.c:2057
static void gui_window_stop_throbber(struct gui_window *gw)
Definition: gui.c:2064
void ami_bitmap_fini(void)
Cleanup bitmap allocations.
Definition: bitmap.c:748
bool amiga_bitmap_save(void *bitmap, const char *path, unsigned flags)
Save a bitmap in the platform's native format.
Definition: bitmap.c:257
PLANEPTR ami_bitmap_get_mask(struct bitmap *bitmap, int width, int height, struct BitMap *n_bm)
Definition: bitmap.c:696
struct BitMap * ami_bitmap_get_native(struct bitmap *bitmap, int width, int height, bool palette_mapped, struct BitMap *friendbm, colour bg)
Definition: bitmap.c:736
struct gui_bitmap_table * amiga_bitmap_table
Definition: bitmap.c:833
bool amiga_bitmap_get_opaque(void *bitmap)
Gets whether a bitmap should be plotted opaque.
Definition: bitmap.c:309
#define AMI_BITMAP_SCALE_ICON
Definition: bitmap.h:31
void ami_free_download_list(struct List *dllist)
Definition: download.c:407
nserror gui_window_save_link(struct gui_window *g, nsurl *url, const char *title)
Definition: download.c:428
struct gui_download_table * amiga_download_table
Definition: download.c:534
void ami_download_parse_backmsg(const char *backmsg)
Definition: download.c:520
struct FileRequester * filereq
Definition: file.c:52
void ami_file_req_free(void)
Definition: file.c:300
void ami_file_req_init(void)
Definition: file.c:281
struct TextFont * ami_font_open_disk_font(struct TextAttr *tattr)
Definition: font.c:103
void ami_font_close_disk_font(struct TextFont *tfont)
Definition: font.c:109
void ami_font_init(void)
Definition: font.c:115
struct gui_layout_table * ami_layout_table
Definition: font.c:164
void ami_font_setdevicedpi(int id)
Definition: font.c:50
void ami_font_fini(void)
Definition: font.c:124
nserror ami_hotlist_scan(void *userdata, int first_item, const char *folder, bool(*cb_add_item)(void *userdata, int level, int item, const char *title, nsurl *url, bool folder))
Scan the hotlist.
Definition: hotlist.c:149
nserror ami_nsoption_read(void)
Definition: nsoption.c:29
nserror ami_nsoption_set_location(const char *current_user_dir)
Definition: nsoption.c:39
void ami_nsoption_free(void)
Definition: nsoption.c:52
nserror ami_nsoption_write(void)
Definition: nsoption.c:34
struct MinList * ami_AllocMinList(void)
List abstraction as OS3 appears to have problems with NewMinList()
Definition: object.c:63
struct MinList * NewObjList(void)
Definition: object.c:71
void FreeObjList(struct MinList *objlist)
Definition: object.c:117
void ami_object_fini(void)
Definition: object.c:50
bool ami_object_init(void)
Initialisation for itempool.
Definition: object.c:42
void DelObject(struct nsObject *dtzo)
Definition: object.c:107
struct nsObject * AddObject(struct MinList *objlist, ULONG otype)
Definition: object.c:77
void DelObjectNoFree(struct nsObject *dtzo)
Definition: object.c:112
@ AMINS_WINDOW
Definition: object.h:28
@ AMINS_GUIOPTSWINDOW
Definition: object.h:34
@ AMINS_TVWINDOW
Definition: object.h:31
@ AMINS_RECT
Definition: object.h:39
bool ami_print_cont(void)
Definition: print.c:460
struct MsgPort * ami_print_get_msgport(void)
Definition: print.c:494
struct gui_window * ami_search_get_gwin(struct find_window *fw)
Obtain gui window associated with find window.
Definition: search.c:127
struct gui_search_table * amiga_search_table
Definition: search.c:125
void ami_search_close(void)
Close search.
Definition: search.c:229
void ami_utf8_free(char *ptr)
Definition: utf8.c:104
nserror utf8_to_local_encoding(const char *string, size_t len, char **result)
Definition: utf8.c:89
char * ami_to_utf8_easy(const char *string)
Definition: utf8.c:119
char * ami_utf8_easy(const char *string)
Definition: utf8.c:109
nserror utf8_from_local_encoding(const char *string, size_t len, char **result)
Definition: utf8.c:80
struct atari_hotlist hl
Definition: hotlist.c:47
void ami_gui_menu_update_checked(struct gui_window_2 *gwin)
Definition: gui_menu.c:678
void ami_gui_menu_refresh_hotlist(void)
Refresh the Hotlist menu.
Definition: gui_menu.c:1148
void ami_gui_menu_update_disabled(struct gui_window *g, struct hlcache_handle *c)
Definition: gui_menu.c:722
struct Menu * ami_gui_menu_create(struct gui_window_2 *gwin)
Definition: gui_menu.c:1047
bool ami_gui_menu_get_check_toggled(void)
Gets if the menu needs updating because an item linked to a toggle menu item has been changed.
Definition: gui_menu.c:805
void ami_gui_menu_freemenus(struct Menu *menu, struct ami_menu_data **md)
Frees a menu.
Definition: gui_menu.c:1112
bool ami_gui_menu_quit_selected(void)
Gets if NetSurf has been quit from the menu.
Definition: gui_menu.c:1143
void ami_gui_menu_free(struct gui_window_2 *gwin)
Definition: gui_menu.c:1123
void ami_gui_menu_set_disabled(struct Window *win, struct Menu *menu, int item, bool disable)
Set disabled state of a menu item almost generic, but not quite.
Definition: gui_menu.c:666
@ AMI_MENU_AREXX_MAX
Definition: gui_menu.h:101
@ M_CLOSETAB
Definition: gui_menu.h:47
@ M_PASTE
Definition: gui_menu.h:57
static CONST_STRPTR tabs[OPTS_MAX_TABS]
Definition: gui_options.c:254
void ami_gui_opts_websearch_free(struct List *websearchlist)
Definition: gui_options.c:2366
struct List * ami_gui_opts_websearch(int *idx)
Definition: gui_options.c:2339
void ami_gui_opts_open(void)
Definition: gui_options.c:527
nserror ami_history_local_destroy(struct ami_history_local_window *history_local_win)
destroy a previously created local history view
Definition: history_local.c:74
struct DiskObject * amiga_icon_from_bitmap(struct bitmap *bm)
Definition: icon.c:522
void amiga_icon_free(struct DiskObject *dobj)
Definition: icon.c:571
void amiga_icon_superimpose_favicon_internal(struct hlcache_handle *icon, struct DiskObject *dobj)
Definition: icon.c:391
Content for image/x-amiga-icon (icon.library interface).
#define amiga_icon_init()
Definition: icon.h:36
struct fbtk_bitmap reload_g
struct fbtk_bitmap reload
Public content interface.
struct bitmap * content_get_bitmap(struct hlcache_handle *h)
Retrieve the bitmap contained in an image content.
Definition: content.c:1256
Interface to platform-specific fetcher operations.
Interface to platform-specific miscellaneous browser operation table.
Core mouse and pointer states.
browser_mouse_state
Mouse state: 1 is primary mouse button.
Definition: mouse.h:52
@ BROWSER_MOUSE_PRESS_1
primary button pressed
Definition: mouse.h:59
@ BROWSER_MOUSE_CLICK_2
button 2 clicked.
Definition: mouse.h:72
@ BROWSER_MOUSE_PRESS_2
auxillary button pressed
Definition: mouse.h:61
@ BROWSER_MOUSE_TRIPLE_CLICK
button triple clicked
Definition: mouse.h:83
@ BROWSER_MOUSE_CLICK_1
button 1 clicked.
Definition: mouse.h:70
@ BROWSER_MOUSE_MOD_2
2nd modifier key pressed (eg.
Definition: mouse.h:101
@ BROWSER_MOUSE_DOUBLE_CLICK
button double clicked
Definition: mouse.h:81
@ BROWSER_MOUSE_MOD_3
3rd modifier key pressed (eg.
Definition: mouse.h:103
@ BROWSER_MOUSE_MOD_1
1st modifier key pressed (eg.
Definition: mouse.h:99
@ BROWSER_MOUSE_DRAG_1
start of button 1 drag
Definition: mouse.h:86
@ BROWSER_MOUSE_HOLDING_2
during button 2 drag
Definition: mouse.h:96
@ BROWSER_MOUSE_HOLDING_1
during button 1 drag
Definition: mouse.h:94
@ BROWSER_MOUSE_DRAG_ON
a drag operation was started and a mouse button is still pressed
Definition: mouse.h:91
@ BROWSER_MOUSE_DRAG_2
start of button 2 drag
Definition: mouse.h:88
gui_pointer_shape
Definition: mouse.h:112
@ GUI_POINTER_WAIT
Definition: mouse.h:127
@ GUI_POINTER_DEFAULT
Definition: mouse.h:113
Interface to platform-specific graphical user interface window operations.
gui_window_create_flags
Window creation control flags.
Definition: window.h:66
@ GW_CREATE_TAB
Create tab in same window as existing.
Definition: window.h:69
@ GW_CREATE_FOREGROUND
Request this window/tab is foregrounded.
Definition: window.h:70
gui_drag_type
Definition: window.h:56
@ GDRAGGING_NONE
Definition: window.h:57
@ GDRAGGING_SCROLLBAR
Definition: window.h:58
@ GDRAGGING_OTHER
Definition: window.h:60
gui_window_event
Window events.
Definition: window.h:80
@ GW_EVENT_PAGE_INFO_CHANGE
Page status has changed and so the padlock should be updated.
Definition: window.h:129
@ GW_EVENT_REMOVE_CARET
Remove the caret, if present.
Definition: window.h:98
@ GW_EVENT_NEW_CONTENT
Called when the gui_window has new content.
Definition: window.h:118
@ GW_EVENT_STOP_THROBBER
stop the navigation throbber.
Definition: window.h:108
@ GW_EVENT_UPDATE_EXTENT
Update the extent of the inside of a browser window to that of the current content.
Definition: window.h:93
@ GW_EVENT_START_SELECTION
selection started
Definition: window.h:123
@ GW_EVENT_START_THROBBER
start the navigation throbber.
Definition: window.h:103
Interface to key press operations.
@ NS_KEY_REDO
Definition: keypress.h:71
@ NS_KEY_DELETE_LINE_START
Definition: keypress.h:68
@ NS_KEY_SHIFT_TAB
Definition: keypress.h:39
@ NS_KEY_LINE_START
Definition: keypress.h:57
@ NS_KEY_RIGHT
Definition: keypress.h:51
@ NS_KEY_LEFT
Definition: keypress.h:50
@ NS_KEY_SELECT_ALL
Definition: keypress.h:32
@ NS_KEY_PASTE
Definition: keypress.h:43
@ NS_KEY_TAB
Definition: keypress.h:36
@ NS_KEY_COPY_SELECTION
Definition: keypress.h:33
@ NS_KEY_DOWN
Definition: keypress.h:53
@ NS_KEY_CUT_SELECTION
Definition: keypress.h:44
@ NS_KEY_WORD_LEFT
Definition: keypress.h:61
@ NS_KEY_DELETE_LINE_END
Definition: keypress.h:67
@ NS_KEY_PAGE_UP
Definition: keypress.h:65
@ NS_KEY_PAGE_DOWN
Definition: keypress.h:66
@ NS_KEY_UNDO
Definition: keypress.h:70
@ NS_KEY_TEXT_START
Definition: keypress.h:59
@ NS_KEY_LINE_END
Definition: keypress.h:58
@ NS_KEY_TEXT_END
Definition: keypress.h:60
@ NS_KEY_DELETE_RIGHT
Definition: keypress.h:55
@ NS_KEY_CLEAR_SELECTION
Definition: keypress.h:45
@ NS_KEY_WORD_RIGHT
Definition: keypress.h:63
@ NS_KEY_DELETE_LEFT
Definition: keypress.h:35
@ NS_KEY_UP
Definition: keypress.h:52
@ NS_KEY_ESCAPE
Definition: keypress.h:47
bool browser_window_key_press(struct browser_window *bw, uint32_t key)
Handle key presses in a browser window.
Definition: textinput.c:107
void ami_openurl_open(void)
Initialise the fetcher.
Definition: launch.c:127
void ami_openurl_close(void)
Definition: launch.c:140
Fetching of data from a URL (Registration).
bool ami_libs_open(void)
Definition: libs.c:221
void ami_libs_close(void)
Definition: libs.c:301
#define SpeedBarObj
Definition: libs.h:75
#define LayoutHObj
Definition: libs.h:64
#define ListBrowserObj
Definition: libs.h:66
#define LabelObj
Definition: libs.h:63
#define WindowObj
Definition: libs.h:77
#define BitMapObj
Definition: libs.h:53
#define ChooserObj
Definition: libs.h:56
#define LayoutVObj
Definition: libs.h:65
#define ScrollerObj
Definition: libs.h:73
#define SpaceObj
Definition: libs.h:74
#define ButtonObj
Definition: libs.h:54
#define BevelObj
Definition: libs.h:52
#define StringObj
Definition: libs.h:76
#define ClickTabObj
Definition: libs.h:57
nserror nslog_init(nslog_ensure_t *ensure, int *pargc, char **argv)
Initialise the logging system.
Definition: log.c:190
void nslog_finalise(void)
Shut down the logging system.
Definition: log.c:299
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
void ami_memory_fini(struct Interrupt *memhandler)
Definition: memory.c:179
struct Interrupt * ami_memory_init(void)
Definition: memory.c:165
#define ami_memory_itempool_create(s)
Definition: memory.h:54
#define ami_memory_itempool_alloc(p, s)
Definition: memory.h:56
#define ami_memory_itempool_free(p, i, s)
Definition: memory.h:57
#define ami_memory_itempool_delete(p)
Definition: memory.h:55
nserror messages_add_from_file(const char *path)
Read keys and values from messages file into the standard Messages hash.
Definition: messages.c:177
const char * messages_get_errorcode(nserror code)
lookup of a message by errorcode from the standard Messages hash.
Definition: messages.c:263
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:256
Localised message support (interface).
NetSurf core interface registration, construction and destruction.
void netsurf_exit(void)
Finalise NetSurf core.
Definition: netsurf.c:232
nserror netsurf_init(const char *store_path)
Initialise netsurf core.
Definition: netsurf.c:107
nserror netsurf_register(struct netsurf_table *table)
Register operation table.
Definition: gui_factory.c:777
NetSurf URL handling (interface).
nserror nsurl_get_utf8(const nsurl *url, char **url_s, size_t *url_l)
Get a UTF-8 string (for human readable IDNs) from a NetSurf URL object.
nserror nsurl_create(const char *const url_s, nsurl **url)
Create a NetSurf URL object from a URL string.
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
uint32_t nsurl_hash(const nsurl *url)
Get a URL's hash value.
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
struct Node * GetPred(struct Node *node)
Definition: os3support.c:375
void FreeSysObject(ULONG type, APTR obj)
Definition: os3support.c:350
APTR NewObject(struct IClass *classPtr, CONST_STRPTR classID, ULONG tagList,...)
Definition: os3support.c:434
char * ASPrintf(const char *fmt,...)
Definition: os3support.c:139
uint32 GetAttrs(Object *obj, Tag tag1,...)
Definition: os3support.c:389
struct Node * GetHead(struct List *list)
Definition: os3support.c:364
ULONG RefreshSetGadgetAttrs(struct Gadget *g, struct Window *w, struct Requester *r, Tag tag1,...)
Definition: os3support.c:429
struct Node * GetSucc(struct Node *node)
Definition: os3support.c:381
#define AllocSysObjectTags(A, B, C, D)
Definition: os3support.h:157
#define LBS_ROWS
Definition: os3support.h:128
#define MINTERM_SRCMASK
Definition: os3support.h:139
#define SetCurrentDir(L)
Definition: os3support.h:161
#define RAWKEY_DEL
Definition: os3support.h:99
#define LBNCA_SoftStyle
Definition: os3support.h:82
#define RAWKEY_BACKSPACE
Definition: os3support.h:96
#define RAWKEY_F12
Definition: os3support.h:110
#define LIB_IS_AT_LEAST(B, V, R)
Definition: os3support.h:55
#define DN_FULLPATH
Definition: os3support.h:123
#define RAWKEY_PAGEUP
Definition: os3support.h:100
#define TNA_HintInfo
Definition: os3support.h:88
#define RAWKEY_ESC
Definition: os3support.h:98
#define RAWKEY_CRSRRIGHT
Definition: os3support.h:104
#define ASO_NoTrack
Definition: os3support.h:64
#define GA_ContextMenu
Definition: os3support.h:77
#define CLICKTAB_LabelTruncate
Definition: os3support.h:71
#define RAWKEY_F8
Definition: os3support.h:107
#define WINDOW_NewPrefsHook
Definition: os3support.h:93
#define WA_ContextMenuHook
Definition: os3support.h:89
#define WINDOW_BuiltInScroll
Definition: os3support.h:91
#define RAWKEY_END
Definition: os3support.h:113
#define IDoMethod
Definition: os3support.h:169
#define CLICKTAB_FlagImage
Definition: os3support.h:70
#define RAWKEY_F10
Definition: os3support.h:109
#define MEMF_PRIVATE
Definition: os3support.h:60
#define RPTAG_APenColor
Definition: os3support.h:76
#define RAWKEY_HOME
Definition: os3support.h:112
#define BITMAP_HasAlpha
Definition: os3support.h:66
#define RAWKEY_CRSRUP
Definition: os3support.h:102
#define RAWKEY_TAB
Definition: os3support.h:97
#define CLICKTAB_CloseImage
Definition: os3support.h:69
#define RAWKEY_F9
Definition: os3support.h:108
#define RAWKEY_CRSRLEFT
Definition: os3support.h:105
#define IDCMP_EXTENDEDMOUSE
Definition: os3support.h:121
#define IA_InBorder
Definition: os3support.h:80
#define SBNA_HintInfo
Definition: os3support.h:86
#define BLITA_UseSrcAlpha
Definition: os3support.h:67
#define BLITA_MaskPlane
Definition: os3support.h:68
#define CLICKTAB_NodeClosed
Definition: os3support.h:72
#define GAUGEIA_Level
Definition: os3support.h:79
#define DevNameFromLock(A, B, C, D)
Definition: os3support.h:162
#define IA_Label
Definition: os3support.h:81
#define RAWKEY_CRSRDOWN
Definition: os3support.h:103
#define BITMAP_DisabledSourceFile
Definition: os3support.h:65
#define RAWKEY_HELP
Definition: os3support.h:111
#define DISABLEDTEXTPEN
Definition: os3support.h:116
@ ASOT_PORT
Definition: os3support.h:226
#define GA_HintInfo
Definition: os3support.h:78
#define FOpen(A, B, C)
Definition: os3support.h:158
int32_t int32
Definition: os3support.h:183
#define ObtainCharsetInfo(A, B, C)
Definition: os3support.h:154
uint16_t uint16
Definition: os3support.h:182
#define IsMinListEmpty(L)
Definition: os3support.h:54
#define TNA_CloseGadget
Definition: os3support.h:87
uint32_t uint32
Definition: os3support.h:184
#define RAWKEY_PAGEDOWN
Definition: os3support.h:101
#define ShowWindow(...)
Definition: os3support.h:172
#define LISTBROWSER_Striping
Definition: os3support.h:83
#define WINDOW_BACKMOST
Definition: os3support.h:122
#define CreateDirTree(D)
Definition: os3support.h:160
#define WA_ToolBox
Definition: os3support.h:90
#define RAWKEY_F5
Definition: os3support.h:106
#define FClose(A)
Definition: os3support.h:159
#define SA_Compositing
Definition: os3support.h:84
nserror amiga_plugin_hack_init(void)
Definition: plugin_hack.c:75
int width
Definition: gui.c:161
static nserror gui_launch_url(struct nsurl *url)
Broadcast an URL that we can't handle.
Definition: gui.c:2045
int height
Definition: gui.c:162
void save_complete_init(void)
Initialise save complete module.
Save HTML document with dependencies (interface).
core web search facilities interface.
@ SEARCH_WEB_OMNI_NONE
no changes to default operation
Definition: searchweb.h:50
@ SEARCH_WEB_OMNI_SEARCHONLY
The search does not attempt to interpret the url as a url before using it as a search term.
Definition: searchweb.h:55
void gui_create_form_select_menu(struct gui_window *g, struct form_control *control)
Definition: selectmenu.c:190
Interface to utility string handling.
Class * MakeStringClass(void)
#define STRINGVIEW_Header
Definition: stringview.h:50
void FreeStringClass(Class *)
struct nsObject * node
Definition: gui.h:74
const struct ami_win_event_table * tbl
Definition: gui.h:75
struct gui_window_2 * gw
Definition: gui.c:323
struct List * sblist
Definition: gui.c:322
Amiga local history viewing window context.
Definition: history_local.c:57
struct gui_window * gw
Amiga GUI stuff.
Definition: history_local.c:62
BOOL(* event)(void *w)
Definition: gui.h:65
void(* close)(void *w)
Definition: gui.h:70
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
Page features at a specific spatial location.
enum browser_window_features::@56 form_features
type of form feature.
Browser window data.
struct browser_window * bw
Form control.
Definition: form_internal.h:73
function table for fetcher operations.
Definition: fetch.h:33
const char *(* filetype)(const char *unix_path)
Determine the MIME type of a local file.
Definition: fetch.h:45
Graphical user interface browser misc function table.
Definition: misc.h:39
nserror(* schedule)(int t, void(*callback)(void *p), void *p)
Schedule a callback.
Definition: misc.h:58
Graphical user interface browser web search function table.
Definition: searchweb.h:34
nserror(* provider_update)(const char *provider_name, struct bitmap *ico_bitmap)
called when the search provider details are updated.
Definition: searchweb.h:42
User interface utf8 characterset conversion routines.
Definition: utf8.h:31
browser_mouse_state mouse_state
Definition: gui.c:258
char *restrict helphints[GID_LAST]
Definition: gui.c:277
browser_mouse_state prev_mouse_state
Definition: gui.c:278
int throbber_frame
Definition: gui.c:252
Object *restrict objects[GID_LAST]
Definition: gui.c:249
struct List hotlist_toolbar_list
Definition: gui.c:270
bool closed
Definition: gui.c:294
char *restrict wintitle
Definition: gui.c:275
ULONG oldh
Definition: gui.c:262
Object *restrict hotlist_toolbar_lab[AMI_GUI_TOOLBAR_MAX]
Definition: gui.c:269
ULONG tabs
Definition: gui.c:254
struct ami_menu_data * menu_data[AMI_MENU_AREXX_MAX+1]
Definition: gui.c:267
ULONG oldv
Definition: gui.c:263
gui_pointer_shape mouse_pointer
Definition: gui.c:292
Object * search_bm
Definition: gui.c:272
char *restrict status
Definition: gui.c:274
gui_drag_type drag_op
Definition: gui.c:288
struct DiskObject * dobj
Definition: gui.c:281
browser_mouse_state key_state
Definition: gui.c:259
ULONG hotlist_items
Definition: gui.c:268
struct find_window * searchwin
Definition: gui.c:261
ULONG next_tab
Definition: gui.c:255
struct Hook * ctxmenu_hook
Definition: gui.c:285
struct Menu * imenu
Definition: gui.c:293
struct Hook throbber_hook
Definition: gui.c:283
char icontitle[24]
Definition: gui.c:276
bool new_content
Definition: gui.c:266
Object * clicktab_ctxmenu
Definition: gui.c:287
struct ami_generic_window w
Definition: gui.c:247
struct List * web_search_list
Definition: gui.c:271
struct gui_window * gw
Definition: gui.c:250
ULONG throbber_update_count
Definition: gui.c:260
struct AppIcon * appicon
Definition: gui.c:280
struct Hook browser_hook
Definition: gui.c:284
struct Hook scrollerhook
Definition: gui.c:257
struct Node * last_new_tab
Definition: gui.c:256
Object *restrict history_ctxmenu[2]
Definition: gui.c:286
bool redraw_scroll
Definition: gui.c:265
struct AppWindow * appwin
Definition: gui.c:290
struct timeval lastclick
Definition: gui.c:279
struct List tab_list
Definition: gui.c:253
int temp
Definition: gui.c:264
struct Hook favicon_hook
Definition: gui.c:282
struct IBox * ptr_lock
Definition: gui.c:289
struct MinList * shared_pens
Definition: gui.c:291
char *restrict svbuffer
Definition: gui.c:273
struct Window * win
Definition: gui.c:248
bool redraw_required
Definition: gui.c:251
Graphical user interface window function table.
Definition: window.h:137
struct gui_window *(* create)(struct browser_window *bw, struct gui_window *existing, gui_window_create_flags flags)
Create and open a gui window for a browsing context.
Definition: window.h:164
first entry in window list
Definition: gui.c:298
int c_h_temp
Definition: gui.c:306
struct gui_window_2 * shared
Definition: gui.c:299
bool throbbing
whether currently throbbing
Definition: gui.c:312
struct ColumnInfo * logcolumns
Definition: gui.c:317
char * tabtitle
Definition: gui.c:313
struct MinList * deferred_rects
Definition: gui.c:315
char * url
Definition: gui.h:154
APTR deferred_rects_pool
Definition: gui.c:314
int scrollx
current scroll location
Definition: gui.c:307
int tab
Definition: gui.c:300
struct List loglist
Definition: gui.c:318
int c_y
Definition: gui.c:303
struct List dllist
Definition: gui.c:310
struct hlcache_handle * favicon
Definition: gui.c:311
struct ami_history_local_window * hw
Definition: gui.c:309
int c_h
Definition: gui.c:305
struct Node * tab_node
Definition: gui.c:301
int scrolly
current scroll location
Definition: gui.c:308
int c_x
Definition: gui.c:302
int c_w
Definition: gui.c:304
struct browser_window * bw
The 'content' window that is rendered in the gui_window.
Definition: gui.c:316
High-level cache handle.
Definition: hlcache.c:66
NetSurf operation function table.
Definition: gui_table.h:48
struct gui_misc_table * misc
Browser table.
Definition: gui_table.h:57
ULONG Type
Definition: object.h:45
void * objstruct
Definition: object.h:46
union nsoption_s::@149 value
colour c
Definition: nsoption.h:122
Rectangle coordinates.
Definition: types.h:40
int x0
Definition: types.h:41
int y0
Top left.
Definition: types.h:41
int x1
Definition: types.h:42
int y1
Bottom right.
Definition: types.h:42
Redraw context.
Definition: plotters.h:51
bool interactive
Redraw to show interactive features.
Definition: plotters.h:59
void * priv
Private context.
Definition: plotters.h:81
Definition: theme.h:64
uint32_t colour
Colour type: XBGR.
Definition: types.h:35
struct rect rect
Rectangle coordinates.
static int mouse_x
Definition: url_complete.c:66
static int mouse_y
Definition: url_complete.c:67
Unified URL information database public interface.
nserror urldb_save(const char *filename)
Export the current database to file.
Definition: urldb.c:3091
nserror urldb_load(const char *filename)
Import an URL database from file, replacing any existing database.
Definition: urldb.c:2874
struct List * URLHistory_GetList(void)
nserror netsurf_path_to_nsurl(const char *path, struct nsurl **url)
Create a nsurl from a path.
Definition: file.c:307
nserror netsurf_mkpath(char **str, size_t *size, size_t nelm,...)
Generate a path from one or more component elemnts.
Definition: file.c:288
Default operations table for files.
struct nsoption_s * nsoptions_default
global default option table.
Definition: nsoption.c:46
static struct nsoption_s defaults[]
The table of compiled in default options.
Definition: nsoption.c:64
struct nsoption_s * nsoptions
global active option table.
Definition: nsoption.c:45
nserror nsoption_commandline(int *pargc, char **argv, struct nsoption_s *opts)
Process commandline and set options approriately.
Definition: nsoption.c:858
nserror nsoption_init(nsoption_set_default_t *set_defaults, struct nsoption_s **popts, struct nsoption_s **pdefs)
Initialise option system.
Definition: nsoption.c:610
nserror nsoption_finalise(struct nsoption_s *opts, struct nsoption_s *defs)
Finalise option system.
Definition: nsoption.c:665
Option reading and saving interface.
#define nsoption_charp(OPTION)
Get the value of a string option.
Definition: nsoption.h:335
#define nsoption_setnull_charp(OPTION, VALUE)
set string option in default table if currently unset
Definition: nsoption.h:380
#define nsoption_int(OPTION)
Get the value of an integer option.
Definition: nsoption.h:317
#define nsoption_set_int(OPTION, VALUE)
set an integer option in the default table
Definition: nsoption.h:352
nsoption_e
Definition: nsoption.h:133
#define nsoption_set_bool(OPTION, VALUE)
set a boolean option in the default table
Definition: nsoption.h:348
#define nsoption_set_charp(OPTION, VALUE)
set string option in default table
Definition: nsoption.h:376
#define nsoption_colour(OPTION)
Get the value of a netsurf colour option.
Definition: nsoption.h:344
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:308
uint32_t utf8_to_ucs4(const char *s_in, size_t l)
Convert a UTF-8 multibyte sequence into a single UCS4 character.
Definition: utf8.c:41
size_t utf8_char_byte_length(const char *s)
Calculate the length (in bytes) of a UTF-8 character.
Definition: utf8.c:104
UTF-8 manipulation functions (interface).
Interface to a number of general purpose functionality.
static nserror path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
Plots a path.
Definition: plot.c:821
static nserror text(const struct redraw_context *ctx, const struct plot_font_style *fstyle, int x, int y, const char *text, size_t length)
Text plotting.
Definition: plot.c:978
static nserror clip(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plot.c:357