Gitweb links:

...log 
http://git.netsurf-browser.org/netsurf.git/shortlog/bf9ccc57c8787e4b8d4f8d717e9cfbfccdc8fc73
...commit 
http://git.netsurf-browser.org/netsurf.git/commit/bf9ccc57c8787e4b8d4f8d717e9cfbfccdc8fc73
...tree 
http://git.netsurf-browser.org/netsurf.git/tree/bf9ccc57c8787e4b8d4f8d717e9cfbfccdc8fc73

The branch, master has been updated
       via  bf9ccc57c8787e4b8d4f8d717e9cfbfccdc8fc73 (commit)
       via  78199c017782067bda94307c7bfc9dc9c1f1eefd (commit)
      from  faec17a90362fe53a952083472199e0d69d747b1 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=bf9ccc57c8787e4b8d4f8d717e9cfbfccdc8fc73
commit bf9ccc57c8787e4b8d4f8d717e9cfbfccdc8fc73
Author: Chris Young <[email protected]>
Commit: Chris Young <[email protected]>

    Amiga: Implement a simple listbrowser log in the GUI
    Can be revealed/hidden with F12 and is currently undocumented.

diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c
index cff727b..0346ac2 100644
--- a/frontends/amiga/gui.c
+++ b/frontends/amiga/gui.c
@@ -72,6 +72,7 @@
 #include <proto/clicktab.h>
 #include <proto/label.h>
 #include <proto/layout.h>
+#include <proto/listbrowser.h>
 #include <proto/scroller.h>
 #include <proto/space.h>
 #include <proto/speedbar.h>
@@ -83,6 +84,7 @@
 #include <gadgets/chooser.h>
 #include <gadgets/clicktab.h>
 #include <gadgets/layout.h>
+#include <gadgets/listbrowser.h>
 #include <gadgets/scroller.h>
 #include <gadgets/space.h>
 #include <gadgets/speedbar.h>
@@ -230,6 +232,8 @@ enum
        GID_HSCROLLLAYOUT,
        GID_VSCROLL,
        GID_VSCROLLLAYOUT,
+       GID_LOGLAYOUT,
+       GID_LOG,
        GID_LAST
 };
 
@@ -303,6 +307,8 @@ struct gui_window
        APTR deferred_rects_pool;
        struct MinList *deferred_rects;
        struct browser_window *bw;
+       struct ColumnInfo *logcolumns;
+       struct List loglist;
 };
 
 struct ami_gui_tb_userdata {
@@ -1771,6 +1777,7 @@ int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie)
                case RAWKEY_F8:
                case RAWKEY_F9:
                case RAWKEY_F10:
+               case RAWKEY_F12:
                case RAWKEY_HELP:
                        // don't translate
                        nskey = keycode;
@@ -2232,6 +2239,213 @@ static void ami_gui_scroller_update(struct gui_window_2 
*gwin)
        }
 }
 
+static void ami_gui_console_log_clear(struct gui_window *g)
+{
+       if(g->shared->objects[GID_LOG] != NULL) {
+               SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], 
g->shared->win, NULL,
+                                               LISTBROWSER_Labels, NULL,
+                                               TAG_DONE);
+       }
+       
+       FreeListBrowserList(&g->loglist);
+
+       NewList(&g->loglist);
+
+       if(g->shared->objects[GID_LOG] != NULL) {
+               SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], 
g->shared->win, NULL,
+                                               LISTBROWSER_Labels, &g->loglist,
+                                               TAG_DONE);
+       }
+}
+
+static void ami_gui_console_log_add(struct gui_window *g)
+{
+       struct TagItem attrs[2];
+
+       if(g->shared->objects[GID_LOG] != NULL) return;
+
+       attrs[0].ti_Tag = CHILD_MinHeight;
+       attrs[0].ti_Data = 50;
+       attrs[1].ti_Tag = TAG_DONE;
+       attrs[1].ti_Data = 0;
+
+       g->shared->objects[GID_LOG] = ListBrowserObj,
+                                       GA_ID, GID_LOG,
+                                       LISTBROWSER_ColumnInfo, g->logcolumns,
+                                       LISTBROWSER_ColumnTitles, TRUE,
+                                       LISTBROWSER_Labels, &g->loglist,
+                                       LISTBROWSER_Striping, LBS_ROWS,
+                               ListBrowserEnd;
+
+#ifdef __amigaos4__
+       IDoMethod(g->shared->objects[GID_LOGLAYOUT], LM_ADDCHILD,
+                       g->shared->win, g->shared->objects[GID_LOG], NULL);
+#else
+       SetAttrs(g->shared->objects[GID_LOGLAYOUT],
+               LAYOUT_AddChild, g->shared->objects[GID_LOG], TAG_MORE, &attrs);
+#endif
+
+       FlushLayoutDomainCache((struct Gadget *)g->shared->objects[GID_MAIN]);
+
+       RethinkLayout((struct Gadget *)g->shared->objects[GID_MAIN],
+                       g->shared->win, NULL, TRUE);
+               
+       ami_schedule_redraw(g->shared, true);
+}
+
+static void ami_gui_console_log_remove(struct gui_window *g)
+{
+       if(g->shared->objects[GID_LOG] == NULL) return;
+
+#ifdef __amigaos4__
+       IDoMethod(g->shared->objects[GID_LOGLAYOUT], LM_REMOVECHILD,
+                       g->shared->win, g->shared->objects[GID_LOG]);
+#else
+       SetAttrs(g->shared->objects[GID_LOGLAYOUT],
+               LAYOUT_RemoveChild, g->shared->objects[GID_LOG], TAG_DONE);
+#endif
+
+       g->shared->objects[GID_LOG] = NULL;
+
+       FlushLayoutDomainCache((struct Gadget *)g->shared->objects[GID_MAIN]);
+
+       RethinkLayout((struct Gadget *)g->shared->objects[GID_MAIN],
+                       g->shared->win, NULL, TRUE);
+
+       ami_schedule_redraw(g->shared, true);
+}
+
+static bool ami_gui_console_log_toggle(struct gui_window *g)
+{
+       if(g->shared->objects[GID_LOG] == NULL) {
+               ami_gui_console_log_add(g);
+               return true;
+       } else {
+               ami_gui_console_log_remove(g);
+               return false;
+       }
+}
+
+static void ami_gui_console_log_switch(struct gui_window *g)
+{
+       if(g->shared->objects[GID_LOG] == NULL) return;
+
+       RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], 
g->shared->win, NULL,
+                                       LISTBROWSER_ColumnInfo, g->logcolumns,
+                                       LISTBROWSER_Labels, &g->loglist,
+                                       TAG_DONE);
+}
+
+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)
+{
+       bool foldable = !!(flags & BW_CS_FLAG_FOLDABLE);
+       const char *src_text;
+       const char *level_text;
+       struct Node *node;
+       ULONG style = 0;
+       ULONG fgpen = FOREGROUNDPEN;
+       ULONG lbflags = LBFLG_READONLY;
+       char timestamp[256];
+       time_t now = time(NULL);
+       struct tm *timedata = localtime(&now);
+
+       strftime(timestamp, 256, "%c", timedata);
+
+       if(foldable) lbflags |= LBFLG_HASCHILDREN;
+
+       switch (src) {
+       case BW_CS_INPUT:
+               src_text = "client-input";
+               break;
+       case BW_CS_SCRIPT_ERROR:
+               src_text = "scripting-error";
+               break;
+       case BW_CS_SCRIPT_CONSOLE:
+               src_text = "scripting-console";
+               break;
+       default:
+               assert(0 && "Unknown scripting source");
+               src_text = "unknown";
+               break;
+       }
+
+       switch (flags & BW_CS_FLAG_LEVEL_MASK) {
+       case BW_CS_FLAG_LEVEL_DEBUG:
+               level_text = "DEBUG";
+               fgpen = DISABLEDTEXTPEN;
+               lbflags |= LBFLG_CUSTOMPENS;
+               break;
+       case BW_CS_FLAG_LEVEL_LOG:
+               level_text = "LOG";
+               fgpen = DISABLEDTEXTPEN;
+               lbflags |= LBFLG_CUSTOMPENS;
+               break;
+       case BW_CS_FLAG_LEVEL_INFO:
+               level_text = "INFO";
+               break;
+       case BW_CS_FLAG_LEVEL_WARN:
+               level_text = "WARN";
+               break;
+       case BW_CS_FLAG_LEVEL_ERROR:
+               level_text = "ERROR";
+               style = FSF_BOLD;
+               break;
+       default:
+               assert(0 && "Unknown console logging level");
+               level_text = "unknown";
+               break;
+       }
+
+       if(g->shared->objects[GID_LOG] != NULL) {
+               SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], 
g->shared->win, NULL,
+                                               LISTBROWSER_Labels, NULL,
+                                               TAG_DONE);
+       }
+
+       /* Add log entry to list irrespective of whether the log is open. */
+       if((node = AllocListBrowserNode(4,
+                               LBNA_Flags, lbflags,
+                               LBNA_Column, 0,
+                                       LBNCA_SoftStyle, style,
+                                       LBNCA_FGPen, fgpen,
+                                       LBNCA_CopyText, TRUE,
+                                       LBNCA_Text, timestamp,
+                               LBNA_Column, 1,
+                                       LBNCA_SoftStyle, style,
+                                       LBNCA_FGPen, fgpen,
+                                       LBNCA_CopyText, TRUE,
+                                       LBNCA_Text, src_text,
+                               LBNA_Column, 2,
+                                       LBNCA_SoftStyle, style,
+                                       LBNCA_FGPen, fgpen,
+                                       LBNCA_CopyText, TRUE,
+                                       LBNCA_Text, level_text,
+                               LBNA_Column, 3,
+                                       LBNCA_SoftStyle, style,
+                                       LBNCA_FGPen, fgpen,
+                                       LBNCA_CopyText, TRUE,
+                                       LBNCA_Text, msg,
+                               TAG_DONE))) {
+               AddTail(&g->loglist, node);
+       }
+
+       if(g->shared->objects[GID_LOG] != NULL) {
+               RefreshSetGadgetAttrs((struct Gadget 
*)g->shared->objects[GID_LOG], g->shared->win, NULL,
+                                               LISTBROWSER_Labels, &g->loglist,
+                                               TAG_DONE);
+       }
+
+       DebugPrintF("NETSURF: CONSOLE_LOG SOURCE %s %sFOLDABLE %s %.*s\n",
+             src_text, foldable ? "" : "NOT-", level_text,
+             (int)msglen, msg);
+}
+
+
 /**
  * function to add retrieved favicon to gui
  */
@@ -2905,6 +3119,10 @@ static BOOL ami_gui_event(void *w)
                                                                
ami_gui_adjust_scale(gwin->gw, +0.1);
                                                        break;
                                                        
+                                                       case RAWKEY_F12: // 
console log
+                                                               
ami_gui_console_log_toggle(gwin->gw);
+                                                       break;
+
                                                        case RAWKEY_HELP: // 
help
                                                                
ami_help_open(AMI_HELP_GUI, scrn);
                                                        break;
@@ -3320,6 +3538,8 @@ static void ami_switch_tab(struct gui_window_2 *gwin, 
bool redraw)
                                TAG_DONE);
        cur_gw = gwin->gw;
 
+       ami_gui_console_log_switch(gwin->gw);
+
        if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) 
!= NSERROR_OK) {
                amiga_warn_user("NoMemory", "");
                return;
@@ -4355,6 +4575,38 @@ gui_window_create(struct browser_window *bw,
        g->deferred_rects_pool = ami_memory_itempool_create(sizeof(struct 
rect));
        g->bw = bw;
 
+       NewList(&g->loglist);
+#ifdef __amigaos4__
+       g->logcolumns = AllocLBColumnInfo(4,
+                       LBCIA_Column, 0,
+                       //      LBCIA_CopyTitle, TRUE,
+                               LBCIA_Title, "time", /**\TODO: add these to 
Messages */
+                               LBCIA_Weight, 10,
+                               LBCIA_DraggableSeparator, TRUE,
+                               LBCIA_Separator, TRUE,
+                       LBCIA_Column, 1,
+                       //      LBCIA_CopyTitle, TRUE,
+                               LBCIA_Title, "source", /**\TODO: add these to 
Messages */
+                               LBCIA_Weight, 10,
+                               LBCIA_DraggableSeparator, TRUE,
+                               LBCIA_Separator, TRUE,
+                       LBCIA_Column, 2,
+                       //      LBCIA_CopyTitle, TRUE,
+                               LBCIA_Title, "level", /**\TODO: add these to 
Messages */
+                               LBCIA_Weight, 5,
+                               LBCIA_DraggableSeparator, TRUE,
+                               LBCIA_Separator, TRUE,
+                       LBCIA_Column, 3,
+                       //      LBCIA_CopyTitle, TRUE,
+                               LBCIA_Title, "message", /**\TODO: add these to 
Messages */
+                               LBCIA_Weight, 75,
+                               LBCIA_DraggableSeparator, TRUE,
+                               LBCIA_Separator, TRUE,
+               TAG_DONE);
+#else
+       /**\TODO write OS3-compatible version */
+#endif
+
        if((flags & GW_CREATE_TAB) && existing)
        {
                g->shared = existing->shared;
@@ -4806,6 +5058,10 @@ gui_window_create(struct browser_window *bw,
                                                        EndGroup,
                                                EndGroup,
                                        EndGroup,
+//                                     LAYOUT_WeightBar, TRUE,
+                                       LAYOUT_AddChild, 
g->shared->objects[GID_LOGLAYOUT] = LayoutVObj,
+                                       EndGroup,
+                                       CHILD_WeightedHeight, 0,
 #ifndef __amigaos4__
                                        LAYOUT_AddChild, 
g->shared->objects[GID_STATUS] = StringObj,
                                                GA_ID, GID_STATUS,
@@ -5051,6 +5307,11 @@ static void gui_window_destroy(struct gui_window *g)
                if((g->shared->tabs == 1) && (nsoption_bool(tab_always_show) == 
false))
                        ami_toggletabbar(g->shared, false);
 
+               FreeListBrowserList(&g->loglist);
+#ifdef __amigaos4__
+               FreeLBColumnInfo(g->logcolumns);
+#endif
+
                if(g->tabtitle) free(g->tabtitle);
                free(g);
                return;
@@ -5084,6 +5345,11 @@ static void gui_window_destroy(struct gui_window *g)
        ami_ctxmenu_release_hook(g->shared->ctxmenu_hook);
        ami_gui_menu_free(g->shared);
 
+       FreeListBrowserList(&g->loglist);
+#ifdef __amigaos4__
+       FreeLBColumnInfo(g->logcolumns);
+#endif
+
        free(g->shared->wintitle);
        ami_utf8_free(g->shared->status);
        free(g->shared->svbuffer);
@@ -6016,6 +6282,7 @@ static char *ami_gui_get_user_dir(STRPTR current_user)
        return current_user_dir;
 }
 
+
 static struct gui_window_table amiga_window_table = {
        .create = gui_window_create,
        .destroy = gui_window_destroy,
@@ -6036,9 +6303,11 @@ static struct gui_window_table amiga_window_table = {
        .create_form_select_menu = gui_create_form_select_menu,
        .file_gadget_open = gui_file_gadget_open,
        .drag_save_object = gui_drag_save_object,
-       .drag_save_selection =gui_drag_save_selection,
+       .drag_save_selection = gui_drag_save_selection,
        .start_selection = gui_start_selection,
 
+       .console_log = gui_window_console_log,
+
        /* from theme */
        .set_pointer = gui_window_set_pointer,
        .start_throbber = gui_window_start_throbber,
diff --git a/frontends/amiga/libs.c b/frontends/amiga/libs.c
index 7de768b..109baa4 100644
--- a/frontends/amiga/libs.c
+++ b/frontends/amiga/libs.c
@@ -280,6 +280,7 @@ bool ami_libs_open(void)
        AMINS_CLASS_OPEN("gadgets/integer.gadget",       41, Integer,       
INTEGER,       false)
        AMINS_CLASS_OPEN("images/label.image",           41, Label,         
LABEL,         false)
        AMINS_CLASS_OPEN("gadgets/layout.gadget",        43, Layout,        
LAYOUT,        true)
+       AMINS_CLASS_OPEN("gadgets/listbrowser.gadget",   41, ListBrowser,   
LISTBROWSER,   true)
        AMINS_CLASS_OPEN("gadgets/radiobutton.gadget",   41, RadioButton,   
RADIOBUTTON,   false)
        AMINS_CLASS_OPEN("gadgets/scroller.gadget",      42, Scroller,      
SCROLLER,      false)
        AMINS_CLASS_OPEN("gadgets/space.gadget",         41, Space,         
SPACE,         false)
@@ -287,10 +288,7 @@ bool ami_libs_open(void)
        AMINS_CLASS_OPEN("gadgets/string.gadget",        41, String,        
STRING,        false)
        AMINS_CLASS_OPEN("window.class",                 42, Window,        
WINDOW,        false)
 
-#ifdef __amigaos4__
-       /* BOOPSI classes only required on OS4 */
-       AMINS_CLASS_OPEN("gadgets/listbrowser.gadget",   45, ListBrowser,   
LISTBROWSER,   true)
-#else
+#ifndef __amigaos4__
        /* BOOPSI classes only required prior to OS4 */
        PageClass = PAGE_GetClass();
 #endif
@@ -317,15 +315,13 @@ void ami_libs_close(void)
        AMINS_CLASS_CLOSE(Integer)
        AMINS_CLASS_CLOSE(Label)
        AMINS_CLASS_CLOSE(Layout)
+       AMINS_CLASS_CLOSE(ListBrowser)
        AMINS_CLASS_CLOSE(RadioButton)
        AMINS_CLASS_CLOSE(Scroller)
        AMINS_CLASS_CLOSE(Space)
        AMINS_CLASS_CLOSE(SpeedBar)
        AMINS_CLASS_CLOSE(String)
        AMINS_CLASS_CLOSE(Window)
-#ifdef __amigaos4__
-       AMINS_CLASS_CLOSE(ListBrowser)
-#endif
 
        /* Libraries */
        AMINS_LIB_CLOSE(GuiGFX)
diff --git a/frontends/amiga/libs.h b/frontends/amiga/libs.h
index aa3622a..db5b65c 100644
--- a/frontends/amiga/libs.h
+++ b/frontends/amiga/libs.h
@@ -63,6 +63,7 @@ extern Class *WindowClass;
 #define LabelObj                       NewObject(LabelClass, NULL
 #define LayoutHObj                     NewObject(LayoutClass, NULL, 
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ
 #define LayoutVObj                     NewObject(LayoutClass, NULL, 
LAYOUT_Orientation, LAYOUT_ORIENT_VERT
+#define ListBrowserObj                 NewObject(ListBrowserClass, NULL
 #ifdef __amigaos4__
 #define PageObj                                NewObject(NULL, "page.gadget"
 #else
diff --git a/frontends/amiga/os3support.h b/frontends/amiga/os3support.h
index aa3027d..fde032a 100644
--- a/frontends/amiga/os3support.h
+++ b/frontends/amiga/os3support.h
@@ -78,6 +78,8 @@
 #define GAUGEIA_Level          TAG_IGNORE
 #define IA_InBorder                    TAG_IGNORE
 #define IA_Label                       TAG_IGNORE
+#define LBNCA_SoftStyle                TAG_IGNORE
+#define LISTBROWSER_Striping   TAG_IGNORE
 #define SA_Compositing         TAG_IGNORE
 #define SBNA_Text                      TAG_IGNORE
 #define SBNA_HintInfo          TAG_IGNORE
@@ -104,10 +106,15 @@
 #define RAWKEY_F8      0x57
 #define RAWKEY_F9      0x58
 #define RAWKEY_F10     0x59
+#define RAWKEY_F12  0x6F
 #define RAWKEY_HELP    0x5F
 #define RAWKEY_HOME    0x70
 #define RAWKEY_END     0x71
 
+/* New pens - these may not be equivalent */
+#define DISABLEDTEXTPEN HIGHLIGHTTEXTPEN
+#define TITLEPEN FILLPEN
+
 /* Other constants */
 #define BVS_DISPLAY BVS_NONE
 #define IDCMP_EXTENDEDMOUSE 0
@@ -117,6 +124,7 @@
 #define OFF_OPEN 0
 #define AFF_OTAG 0
 #define ML_SEPARATOR NM_BARLABEL
+#define LBS_ROWS 0
 
 /* Renamed structures */
 #define AnchorPathOld AnchorPath


commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=78199c017782067bda94307c7bfc9dc9c1f1eefd
commit 78199c017782067bda94307c7bfc9dc9c1f1eefd
Author: Chris Young <[email protected]>
Commit: Chris Young <[email protected]>

    Amiga: Allow running JS from ARexx
    Option arexx_allow_exec enables the EXEC command.
    It is disabled by default and currently undocumented.
    Theoretically this could be used by a form filler application.

diff --git a/frontends/amiga/arexx.c b/frontends/amiga/arexx.c
index 05e7802..243e927 100644
--- a/frontends/amiga/arexx.c
+++ b/frontends/amiga/arexx.c
@@ -69,7 +69,8 @@ enum
        RX_ACTIVE,
        RX_CLOSE,
        RX_HOTLIST,
-       RX_SLABSTATS
+       RX_SLABSTATS,
+       RX_EXEC
 };
 
 static Object *arexx_obj = NULL;
@@ -98,6 +99,7 @@ RXHOOKF(rx_active);
 RXHOOKF(rx_close);
 RXHOOKF(rx_hotlist);
 RXHOOKF(rx_slabstats);
+RXHOOKF(rx_exec);
 
 STATIC struct ARexxCmd Commands[] =
 {
@@ -118,6 +120,7 @@ STATIC struct ARexxCmd Commands[] =
        {"CLOSE",       RX_CLOSE,       rx_close,       
"W=WINDOW/K/N,T=TAB/K/N",               0,      NULL,   0,      0,      NULL },
        {"HOTLIST",     RX_HOTLIST,     rx_hotlist,     "A=ACTION/A",           
0,      NULL,   0,      0,      NULL },
        {"SLABSTATS",   RX_SLABSTATS,   rx_slabstats,   "FILE",                 
0,      NULL,   0,      0,      NULL },
+       {"EXEC",        RX_EXEC,        rx_exec,        
"W=WINDOW/K/N,T=TAB/K/N,COMMAND/A/F",           0,      NULL,   0,      0,      
NULL },
        { NULL,                 0,                              NULL,           
NULL,           0,      NULL,   0,      0,      NULL }
 };
 
@@ -674,6 +677,33 @@ RXHOOKF(rx_hotlist)
        }
 }
 
+RXHOOKF(rx_exec)
+{
+       struct gui_window *gw = ami_gui_get_active_gw();
+       bool res = false;
+
+       if(nsoption_bool(arexx_allow_exec) == false) {
+               cmd->ac_RC = RETURN_FAIL;
+               return;
+       }
+
+       if((cmd->ac_ArgList[0]) && (cmd->ac_ArgList[1]))
+               gw = ami_find_tab(*(ULONG *)cmd->ac_ArgList[0], *(ULONG 
*)cmd->ac_ArgList[1]);
+
+       if(gw) {
+               NSLOG(netsurf, WARNING, "Executing js: %s", (char 
*)cmd->ac_ArgList[2]);
+               res = browser_window_exec(ami_gui_get_browser_window(gw),
+                       (char *)cmd->ac_ArgList[2], strlen((char 
*)cmd->ac_ArgList[2]));
+       }
+
+       if(res == false) {
+               cmd->ac_RC = RETURN_ERROR;
+       } else {
+               cmd->ac_RC = RETURN_OK;
+       }
+
+}
+
 RXHOOKF(rx_slabstats)
 {
 #ifndef __amigaos4__
diff --git a/frontends/amiga/options.h b/frontends/amiga/options.h
index f67a9b6..196b057 100644
--- a/frontends/amiga/options.h
+++ b/frontends/amiga/options.h
@@ -47,6 +47,7 @@ NSOPTION_STRING(search_engines_file, 
"PROGDIR:Resources/SearchEngines")
 NSOPTION_STRING(arexx_dir, "PROGDIR:Rexx")
 NSOPTION_STRING(arexx_startup, "Startup.nsrx")
 NSOPTION_STRING(arexx_shutdown, "Shutdown.nsrx")
+NSOPTION_BOOL(arexx_allow_exec, false)
 NSOPTION_STRING(download_dir, NULL)
 NSOPTION_BOOL(download_notify, true)
 NSOPTION_BOOL(download_notify_progress, false)


-----------------------------------------------------------------------

Summary of changes:
 frontends/amiga/arexx.c      |   32 ++++-
 frontends/amiga/gui.c        |  271 +++++++++++++++++++++++++++++++++++++++++-
 frontends/amiga/libs.c       |   10 +-
 frontends/amiga/libs.h       |    1 +
 frontends/amiga/options.h    |    1 +
 frontends/amiga/os3support.h |    8 ++
 6 files changed, 314 insertions(+), 9 deletions(-)

diff --git a/frontends/amiga/arexx.c b/frontends/amiga/arexx.c
index 05e7802..243e927 100644
--- a/frontends/amiga/arexx.c
+++ b/frontends/amiga/arexx.c
@@ -69,7 +69,8 @@ enum
        RX_ACTIVE,
        RX_CLOSE,
        RX_HOTLIST,
-       RX_SLABSTATS
+       RX_SLABSTATS,
+       RX_EXEC
 };
 
 static Object *arexx_obj = NULL;
@@ -98,6 +99,7 @@ RXHOOKF(rx_active);
 RXHOOKF(rx_close);
 RXHOOKF(rx_hotlist);
 RXHOOKF(rx_slabstats);
+RXHOOKF(rx_exec);
 
 STATIC struct ARexxCmd Commands[] =
 {
@@ -118,6 +120,7 @@ STATIC struct ARexxCmd Commands[] =
        {"CLOSE",       RX_CLOSE,       rx_close,       
"W=WINDOW/K/N,T=TAB/K/N",               0,      NULL,   0,      0,      NULL },
        {"HOTLIST",     RX_HOTLIST,     rx_hotlist,     "A=ACTION/A",           
0,      NULL,   0,      0,      NULL },
        {"SLABSTATS",   RX_SLABSTATS,   rx_slabstats,   "FILE",                 
0,      NULL,   0,      0,      NULL },
+       {"EXEC",        RX_EXEC,        rx_exec,        
"W=WINDOW/K/N,T=TAB/K/N,COMMAND/A/F",           0,      NULL,   0,      0,      
NULL },
        { NULL,                 0,                              NULL,           
NULL,           0,      NULL,   0,      0,      NULL }
 };
 
@@ -674,6 +677,33 @@ RXHOOKF(rx_hotlist)
        }
 }
 
+RXHOOKF(rx_exec)
+{
+       struct gui_window *gw = ami_gui_get_active_gw();
+       bool res = false;
+
+       if(nsoption_bool(arexx_allow_exec) == false) {
+               cmd->ac_RC = RETURN_FAIL;
+               return;
+       }
+
+       if((cmd->ac_ArgList[0]) && (cmd->ac_ArgList[1]))
+               gw = ami_find_tab(*(ULONG *)cmd->ac_ArgList[0], *(ULONG 
*)cmd->ac_ArgList[1]);
+
+       if(gw) {
+               NSLOG(netsurf, WARNING, "Executing js: %s", (char 
*)cmd->ac_ArgList[2]);
+               res = browser_window_exec(ami_gui_get_browser_window(gw),
+                       (char *)cmd->ac_ArgList[2], strlen((char 
*)cmd->ac_ArgList[2]));
+       }
+
+       if(res == false) {
+               cmd->ac_RC = RETURN_ERROR;
+       } else {
+               cmd->ac_RC = RETURN_OK;
+       }
+
+}
+
 RXHOOKF(rx_slabstats)
 {
 #ifndef __amigaos4__
diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c
index cff727b..0346ac2 100644
--- a/frontends/amiga/gui.c
+++ b/frontends/amiga/gui.c
@@ -72,6 +72,7 @@
 #include <proto/clicktab.h>
 #include <proto/label.h>
 #include <proto/layout.h>
+#include <proto/listbrowser.h>
 #include <proto/scroller.h>
 #include <proto/space.h>
 #include <proto/speedbar.h>
@@ -83,6 +84,7 @@
 #include <gadgets/chooser.h>
 #include <gadgets/clicktab.h>
 #include <gadgets/layout.h>
+#include <gadgets/listbrowser.h>
 #include <gadgets/scroller.h>
 #include <gadgets/space.h>
 #include <gadgets/speedbar.h>
@@ -230,6 +232,8 @@ enum
        GID_HSCROLLLAYOUT,
        GID_VSCROLL,
        GID_VSCROLLLAYOUT,
+       GID_LOGLAYOUT,
+       GID_LOG,
        GID_LAST
 };
 
@@ -303,6 +307,8 @@ struct gui_window
        APTR deferred_rects_pool;
        struct MinList *deferred_rects;
        struct browser_window *bw;
+       struct ColumnInfo *logcolumns;
+       struct List loglist;
 };
 
 struct ami_gui_tb_userdata {
@@ -1771,6 +1777,7 @@ int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie)
                case RAWKEY_F8:
                case RAWKEY_F9:
                case RAWKEY_F10:
+               case RAWKEY_F12:
                case RAWKEY_HELP:
                        // don't translate
                        nskey = keycode;
@@ -2232,6 +2239,213 @@ static void ami_gui_scroller_update(struct gui_window_2 
*gwin)
        }
 }
 
+static void ami_gui_console_log_clear(struct gui_window *g)
+{
+       if(g->shared->objects[GID_LOG] != NULL) {
+               SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], 
g->shared->win, NULL,
+                                               LISTBROWSER_Labels, NULL,
+                                               TAG_DONE);
+       }
+       
+       FreeListBrowserList(&g->loglist);
+
+       NewList(&g->loglist);
+
+       if(g->shared->objects[GID_LOG] != NULL) {
+               SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], 
g->shared->win, NULL,
+                                               LISTBROWSER_Labels, &g->loglist,
+                                               TAG_DONE);
+       }
+}
+
+static void ami_gui_console_log_add(struct gui_window *g)
+{
+       struct TagItem attrs[2];
+
+       if(g->shared->objects[GID_LOG] != NULL) return;
+
+       attrs[0].ti_Tag = CHILD_MinHeight;
+       attrs[0].ti_Data = 50;
+       attrs[1].ti_Tag = TAG_DONE;
+       attrs[1].ti_Data = 0;
+
+       g->shared->objects[GID_LOG] = ListBrowserObj,
+                                       GA_ID, GID_LOG,
+                                       LISTBROWSER_ColumnInfo, g->logcolumns,
+                                       LISTBROWSER_ColumnTitles, TRUE,
+                                       LISTBROWSER_Labels, &g->loglist,
+                                       LISTBROWSER_Striping, LBS_ROWS,
+                               ListBrowserEnd;
+
+#ifdef __amigaos4__
+       IDoMethod(g->shared->objects[GID_LOGLAYOUT], LM_ADDCHILD,
+                       g->shared->win, g->shared->objects[GID_LOG], NULL);
+#else
+       SetAttrs(g->shared->objects[GID_LOGLAYOUT],
+               LAYOUT_AddChild, g->shared->objects[GID_LOG], TAG_MORE, &attrs);
+#endif
+
+       FlushLayoutDomainCache((struct Gadget *)g->shared->objects[GID_MAIN]);
+
+       RethinkLayout((struct Gadget *)g->shared->objects[GID_MAIN],
+                       g->shared->win, NULL, TRUE);
+               
+       ami_schedule_redraw(g->shared, true);
+}
+
+static void ami_gui_console_log_remove(struct gui_window *g)
+{
+       if(g->shared->objects[GID_LOG] == NULL) return;
+
+#ifdef __amigaos4__
+       IDoMethod(g->shared->objects[GID_LOGLAYOUT], LM_REMOVECHILD,
+                       g->shared->win, g->shared->objects[GID_LOG]);
+#else
+       SetAttrs(g->shared->objects[GID_LOGLAYOUT],
+               LAYOUT_RemoveChild, g->shared->objects[GID_LOG], TAG_DONE);
+#endif
+
+       g->shared->objects[GID_LOG] = NULL;
+
+       FlushLayoutDomainCache((struct Gadget *)g->shared->objects[GID_MAIN]);
+
+       RethinkLayout((struct Gadget *)g->shared->objects[GID_MAIN],
+                       g->shared->win, NULL, TRUE);
+
+       ami_schedule_redraw(g->shared, true);
+}
+
+static bool ami_gui_console_log_toggle(struct gui_window *g)
+{
+       if(g->shared->objects[GID_LOG] == NULL) {
+               ami_gui_console_log_add(g);
+               return true;
+       } else {
+               ami_gui_console_log_remove(g);
+               return false;
+       }
+}
+
+static void ami_gui_console_log_switch(struct gui_window *g)
+{
+       if(g->shared->objects[GID_LOG] == NULL) return;
+
+       RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], 
g->shared->win, NULL,
+                                       LISTBROWSER_ColumnInfo, g->logcolumns,
+                                       LISTBROWSER_Labels, &g->loglist,
+                                       TAG_DONE);
+}
+
+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)
+{
+       bool foldable = !!(flags & BW_CS_FLAG_FOLDABLE);
+       const char *src_text;
+       const char *level_text;
+       struct Node *node;
+       ULONG style = 0;
+       ULONG fgpen = FOREGROUNDPEN;
+       ULONG lbflags = LBFLG_READONLY;
+       char timestamp[256];
+       time_t now = time(NULL);
+       struct tm *timedata = localtime(&now);
+
+       strftime(timestamp, 256, "%c", timedata);
+
+       if(foldable) lbflags |= LBFLG_HASCHILDREN;
+
+       switch (src) {
+       case BW_CS_INPUT:
+               src_text = "client-input";
+               break;
+       case BW_CS_SCRIPT_ERROR:
+               src_text = "scripting-error";
+               break;
+       case BW_CS_SCRIPT_CONSOLE:
+               src_text = "scripting-console";
+               break;
+       default:
+               assert(0 && "Unknown scripting source");
+               src_text = "unknown";
+               break;
+       }
+
+       switch (flags & BW_CS_FLAG_LEVEL_MASK) {
+       case BW_CS_FLAG_LEVEL_DEBUG:
+               level_text = "DEBUG";
+               fgpen = DISABLEDTEXTPEN;
+               lbflags |= LBFLG_CUSTOMPENS;
+               break;
+       case BW_CS_FLAG_LEVEL_LOG:
+               level_text = "LOG";
+               fgpen = DISABLEDTEXTPEN;
+               lbflags |= LBFLG_CUSTOMPENS;
+               break;
+       case BW_CS_FLAG_LEVEL_INFO:
+               level_text = "INFO";
+               break;
+       case BW_CS_FLAG_LEVEL_WARN:
+               level_text = "WARN";
+               break;
+       case BW_CS_FLAG_LEVEL_ERROR:
+               level_text = "ERROR";
+               style = FSF_BOLD;
+               break;
+       default:
+               assert(0 && "Unknown console logging level");
+               level_text = "unknown";
+               break;
+       }
+
+       if(g->shared->objects[GID_LOG] != NULL) {
+               SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], 
g->shared->win, NULL,
+                                               LISTBROWSER_Labels, NULL,
+                                               TAG_DONE);
+       }
+
+       /* Add log entry to list irrespective of whether the log is open. */
+       if((node = AllocListBrowserNode(4,
+                               LBNA_Flags, lbflags,
+                               LBNA_Column, 0,
+                                       LBNCA_SoftStyle, style,
+                                       LBNCA_FGPen, fgpen,
+                                       LBNCA_CopyText, TRUE,
+                                       LBNCA_Text, timestamp,
+                               LBNA_Column, 1,
+                                       LBNCA_SoftStyle, style,
+                                       LBNCA_FGPen, fgpen,
+                                       LBNCA_CopyText, TRUE,
+                                       LBNCA_Text, src_text,
+                               LBNA_Column, 2,
+                                       LBNCA_SoftStyle, style,
+                                       LBNCA_FGPen, fgpen,
+                                       LBNCA_CopyText, TRUE,
+                                       LBNCA_Text, level_text,
+                               LBNA_Column, 3,
+                                       LBNCA_SoftStyle, style,
+                                       LBNCA_FGPen, fgpen,
+                                       LBNCA_CopyText, TRUE,
+                                       LBNCA_Text, msg,
+                               TAG_DONE))) {
+               AddTail(&g->loglist, node);
+       }
+
+       if(g->shared->objects[GID_LOG] != NULL) {
+               RefreshSetGadgetAttrs((struct Gadget 
*)g->shared->objects[GID_LOG], g->shared->win, NULL,
+                                               LISTBROWSER_Labels, &g->loglist,
+                                               TAG_DONE);
+       }
+
+       DebugPrintF("NETSURF: CONSOLE_LOG SOURCE %s %sFOLDABLE %s %.*s\n",
+             src_text, foldable ? "" : "NOT-", level_text,
+             (int)msglen, msg);
+}
+
+
 /**
  * function to add retrieved favicon to gui
  */
@@ -2905,6 +3119,10 @@ static BOOL ami_gui_event(void *w)
                                                                
ami_gui_adjust_scale(gwin->gw, +0.1);
                                                        break;
                                                        
+                                                       case RAWKEY_F12: // 
console log
+                                                               
ami_gui_console_log_toggle(gwin->gw);
+                                                       break;
+
                                                        case RAWKEY_HELP: // 
help
                                                                
ami_help_open(AMI_HELP_GUI, scrn);
                                                        break;
@@ -3320,6 +3538,8 @@ static void ami_switch_tab(struct gui_window_2 *gwin, 
bool redraw)
                                TAG_DONE);
        cur_gw = gwin->gw;
 
+       ami_gui_console_log_switch(gwin->gw);
+
        if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) 
!= NSERROR_OK) {
                amiga_warn_user("NoMemory", "");
                return;
@@ -4355,6 +4575,38 @@ gui_window_create(struct browser_window *bw,
        g->deferred_rects_pool = ami_memory_itempool_create(sizeof(struct 
rect));
        g->bw = bw;
 
+       NewList(&g->loglist);
+#ifdef __amigaos4__
+       g->logcolumns = AllocLBColumnInfo(4,
+                       LBCIA_Column, 0,
+                       //      LBCIA_CopyTitle, TRUE,
+                               LBCIA_Title, "time", /**\TODO: add these to 
Messages */
+                               LBCIA_Weight, 10,
+                               LBCIA_DraggableSeparator, TRUE,
+                               LBCIA_Separator, TRUE,
+                       LBCIA_Column, 1,
+                       //      LBCIA_CopyTitle, TRUE,
+                               LBCIA_Title, "source", /**\TODO: add these to 
Messages */
+                               LBCIA_Weight, 10,
+                               LBCIA_DraggableSeparator, TRUE,
+                               LBCIA_Separator, TRUE,
+                       LBCIA_Column, 2,
+                       //      LBCIA_CopyTitle, TRUE,
+                               LBCIA_Title, "level", /**\TODO: add these to 
Messages */
+                               LBCIA_Weight, 5,
+                               LBCIA_DraggableSeparator, TRUE,
+                               LBCIA_Separator, TRUE,
+                       LBCIA_Column, 3,
+                       //      LBCIA_CopyTitle, TRUE,
+                               LBCIA_Title, "message", /**\TODO: add these to 
Messages */
+                               LBCIA_Weight, 75,
+                               LBCIA_DraggableSeparator, TRUE,
+                               LBCIA_Separator, TRUE,
+               TAG_DONE);
+#else
+       /**\TODO write OS3-compatible version */
+#endif
+
        if((flags & GW_CREATE_TAB) && existing)
        {
                g->shared = existing->shared;
@@ -4806,6 +5058,10 @@ gui_window_create(struct browser_window *bw,
                                                        EndGroup,
                                                EndGroup,
                                        EndGroup,
+//                                     LAYOUT_WeightBar, TRUE,
+                                       LAYOUT_AddChild, 
g->shared->objects[GID_LOGLAYOUT] = LayoutVObj,
+                                       EndGroup,
+                                       CHILD_WeightedHeight, 0,
 #ifndef __amigaos4__
                                        LAYOUT_AddChild, 
g->shared->objects[GID_STATUS] = StringObj,
                                                GA_ID, GID_STATUS,
@@ -5051,6 +5307,11 @@ static void gui_window_destroy(struct gui_window *g)
                if((g->shared->tabs == 1) && (nsoption_bool(tab_always_show) == 
false))
                        ami_toggletabbar(g->shared, false);
 
+               FreeListBrowserList(&g->loglist);
+#ifdef __amigaos4__
+               FreeLBColumnInfo(g->logcolumns);
+#endif
+
                if(g->tabtitle) free(g->tabtitle);
                free(g);
                return;
@@ -5084,6 +5345,11 @@ static void gui_window_destroy(struct gui_window *g)
        ami_ctxmenu_release_hook(g->shared->ctxmenu_hook);
        ami_gui_menu_free(g->shared);
 
+       FreeListBrowserList(&g->loglist);
+#ifdef __amigaos4__
+       FreeLBColumnInfo(g->logcolumns);
+#endif
+
        free(g->shared->wintitle);
        ami_utf8_free(g->shared->status);
        free(g->shared->svbuffer);
@@ -6016,6 +6282,7 @@ static char *ami_gui_get_user_dir(STRPTR current_user)
        return current_user_dir;
 }
 
+
 static struct gui_window_table amiga_window_table = {
        .create = gui_window_create,
        .destroy = gui_window_destroy,
@@ -6036,9 +6303,11 @@ static struct gui_window_table amiga_window_table = {
        .create_form_select_menu = gui_create_form_select_menu,
        .file_gadget_open = gui_file_gadget_open,
        .drag_save_object = gui_drag_save_object,
-       .drag_save_selection =gui_drag_save_selection,
+       .drag_save_selection = gui_drag_save_selection,
        .start_selection = gui_start_selection,
 
+       .console_log = gui_window_console_log,
+
        /* from theme */
        .set_pointer = gui_window_set_pointer,
        .start_throbber = gui_window_start_throbber,
diff --git a/frontends/amiga/libs.c b/frontends/amiga/libs.c
index 7de768b..109baa4 100644
--- a/frontends/amiga/libs.c
+++ b/frontends/amiga/libs.c
@@ -280,6 +280,7 @@ bool ami_libs_open(void)
        AMINS_CLASS_OPEN("gadgets/integer.gadget",       41, Integer,       
INTEGER,       false)
        AMINS_CLASS_OPEN("images/label.image",           41, Label,         
LABEL,         false)
        AMINS_CLASS_OPEN("gadgets/layout.gadget",        43, Layout,        
LAYOUT,        true)
+       AMINS_CLASS_OPEN("gadgets/listbrowser.gadget",   41, ListBrowser,   
LISTBROWSER,   true)
        AMINS_CLASS_OPEN("gadgets/radiobutton.gadget",   41, RadioButton,   
RADIOBUTTON,   false)
        AMINS_CLASS_OPEN("gadgets/scroller.gadget",      42, Scroller,      
SCROLLER,      false)
        AMINS_CLASS_OPEN("gadgets/space.gadget",         41, Space,         
SPACE,         false)
@@ -287,10 +288,7 @@ bool ami_libs_open(void)
        AMINS_CLASS_OPEN("gadgets/string.gadget",        41, String,        
STRING,        false)
        AMINS_CLASS_OPEN("window.class",                 42, Window,        
WINDOW,        false)
 
-#ifdef __amigaos4__
-       /* BOOPSI classes only required on OS4 */
-       AMINS_CLASS_OPEN("gadgets/listbrowser.gadget",   45, ListBrowser,   
LISTBROWSER,   true)
-#else
+#ifndef __amigaos4__
        /* BOOPSI classes only required prior to OS4 */
        PageClass = PAGE_GetClass();
 #endif
@@ -317,15 +315,13 @@ void ami_libs_close(void)
        AMINS_CLASS_CLOSE(Integer)
        AMINS_CLASS_CLOSE(Label)
        AMINS_CLASS_CLOSE(Layout)
+       AMINS_CLASS_CLOSE(ListBrowser)
        AMINS_CLASS_CLOSE(RadioButton)
        AMINS_CLASS_CLOSE(Scroller)
        AMINS_CLASS_CLOSE(Space)
        AMINS_CLASS_CLOSE(SpeedBar)
        AMINS_CLASS_CLOSE(String)
        AMINS_CLASS_CLOSE(Window)
-#ifdef __amigaos4__
-       AMINS_CLASS_CLOSE(ListBrowser)
-#endif
 
        /* Libraries */
        AMINS_LIB_CLOSE(GuiGFX)
diff --git a/frontends/amiga/libs.h b/frontends/amiga/libs.h
index aa3622a..db5b65c 100644
--- a/frontends/amiga/libs.h
+++ b/frontends/amiga/libs.h
@@ -63,6 +63,7 @@ extern Class *WindowClass;
 #define LabelObj                       NewObject(LabelClass, NULL
 #define LayoutHObj                     NewObject(LayoutClass, NULL, 
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ
 #define LayoutVObj                     NewObject(LayoutClass, NULL, 
LAYOUT_Orientation, LAYOUT_ORIENT_VERT
+#define ListBrowserObj                 NewObject(ListBrowserClass, NULL
 #ifdef __amigaos4__
 #define PageObj                                NewObject(NULL, "page.gadget"
 #else
diff --git a/frontends/amiga/options.h b/frontends/amiga/options.h
index f67a9b6..196b057 100644
--- a/frontends/amiga/options.h
+++ b/frontends/amiga/options.h
@@ -47,6 +47,7 @@ NSOPTION_STRING(search_engines_file, 
"PROGDIR:Resources/SearchEngines")
 NSOPTION_STRING(arexx_dir, "PROGDIR:Rexx")
 NSOPTION_STRING(arexx_startup, "Startup.nsrx")
 NSOPTION_STRING(arexx_shutdown, "Shutdown.nsrx")
+NSOPTION_BOOL(arexx_allow_exec, false)
 NSOPTION_STRING(download_dir, NULL)
 NSOPTION_BOOL(download_notify, true)
 NSOPTION_BOOL(download_notify_progress, false)
diff --git a/frontends/amiga/os3support.h b/frontends/amiga/os3support.h
index aa3027d..fde032a 100644
--- a/frontends/amiga/os3support.h
+++ b/frontends/amiga/os3support.h
@@ -78,6 +78,8 @@
 #define GAUGEIA_Level          TAG_IGNORE
 #define IA_InBorder                    TAG_IGNORE
 #define IA_Label                       TAG_IGNORE
+#define LBNCA_SoftStyle                TAG_IGNORE
+#define LISTBROWSER_Striping   TAG_IGNORE
 #define SA_Compositing         TAG_IGNORE
 #define SBNA_Text                      TAG_IGNORE
 #define SBNA_HintInfo          TAG_IGNORE
@@ -104,10 +106,15 @@
 #define RAWKEY_F8      0x57
 #define RAWKEY_F9      0x58
 #define RAWKEY_F10     0x59
+#define RAWKEY_F12  0x6F
 #define RAWKEY_HELP    0x5F
 #define RAWKEY_HOME    0x70
 #define RAWKEY_END     0x71
 
+/* New pens - these may not be equivalent */
+#define DISABLEDTEXTPEN HIGHLIGHTTEXTPEN
+#define TITLEPEN FILLPEN
+
 /* Other constants */
 #define BVS_DISPLAY BVS_NONE
 #define IDCMP_EXTENDEDMOUSE 0
@@ -117,6 +124,7 @@
 #define OFF_OPEN 0
 #define AFF_OTAG 0
 #define ML_SEPARATOR NM_BARLABEL
+#define LBS_ROWS 0
 
 /* Renamed structures */
 #define AnchorPathOld AnchorPath


-- 
NetSurf Browser

_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org

Reply via email to