surf-fifo-20220310-c5c1646.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       surf-fifo-20220310-c5c1646.diff (8358B)
       ---
            1 From c5c1646470c4a278a9e44dc3934b4e0346518d40 Mon Sep 17 00:00:00 2001
            2 From: avalonwilliams <avalonwilliams@protonmail.com>
            3 Date: Wed, 9 Mar 2022 23:53:08 -0500
            4 Subject: [PATCH] fifo patch
            5 
            6 Adds a small command language for remote control of surf through
            7 a fifo pipe, allowing for more complex scripts and features to be
            8 added through shell scripts. Also adds a javascript injection function
            9 that you can bind keys to.
           10 ---
           11  config.def.h |   1 +
           12  surf.c       | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++
           13  2 files changed, 211 insertions(+)
           14 
           15 diff --git a/config.def.h b/config.def.h
           16 index 1355ba3..dcc8d64 100644
           17 --- a/config.def.h
           18 +++ b/config.def.h
           19 @@ -6,6 +6,7 @@ static char *styledir       = "~/.surf/styles/";
           20  static char *certdir        = "~/.surf/certificates/";
           21  static char *cachedir       = "~/.surf/cache/";
           22  static char *cookiefile     = "~/.surf/cookies.txt";
           23 +static char *fifodir        = "~/.surf/fifo/";
           24  
           25  /* Webkit default features */
           26  /* Highest priority value will be used.
           27 diff --git a/surf.c b/surf.c
           28 index 03d8242..327698e 100644
           29 --- a/surf.c
           30 +++ b/surf.c
           31 @@ -17,6 +17,8 @@
           32  #include <stdlib.h>
           33  #include <string.h>
           34  #include <unistd.h>
           35 +#include <sys/types.h>
           36 +#include <sys/stat.h>
           37  
           38  #include <gdk/gdk.h>
           39  #include <gdk/gdkkeysyms.h>
           40 @@ -141,6 +143,24 @@ typedef struct {
           41          regex_t re;
           42  } SiteSpecific;
           43  
           44 +typedef enum {
           45 +        ARGTYPE_INT,
           46 +        ARGTYPE_FLT,
           47 +        ARGTYPE_STR,
           48 +        ARGTYPE_NIL,
           49 +} ArgType;
           50 +
           51 +typedef struct {
           52 +        char *cmd;
           53 +        void (*func)(Client *c, const Arg *a);
           54 +        ArgType t;
           55 +} Cmd;
           56 +
           57 +typedef struct {
           58 +        char *p;
           59 +        ParamName pv;
           60 +} ParamMap;
           61 +
           62  /* Surf */
           63  static void die(const char *errstr, ...);
           64  static void usage(void);
           65 @@ -239,6 +259,13 @@ static void clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h);
           66  static void clicknewwindow(Client *c, const Arg *a, WebKitHitTestResult *h);
           67  static void clickexternplayer(Client *c, const Arg *a, WebKitHitTestResult *h);
           68  
           69 +static gboolean init_fifo(Client *c);
           70 +static gboolean start_fifo(Client *c, char *path);
           71 +static void fifo_read_cb(GObject *f, GAsyncResult *r, gpointer d);
           72 +static void dispatchcmd(Client *c, char *cmd, char *a);
           73 +static void injectjs(Client *c, const Arg *a);
           74 +static void togglewrapper(Client *c, const Arg *a);
           75 +
           76  static char winid[64];
           77  static char togglestats[11];
           78  static char pagestats[2];
           79 @@ -255,6 +282,7 @@ static Parameter *curconfig;
           80  static int modparams[ParameterLast];
           81  static int spair[2];
           82  char *argv0;
           83 +static GFile *fifof;
           84  
           85  static ParamName loadtransient[] = {
           86          Certificate,
           87 @@ -298,6 +326,45 @@ static ParamName loadfinished[] = {
           88          ParameterLast
           89  };
           90  
           91 +static ParamMap paramnames[] = {
           92 +        { "autoplay",     MediaManualPlay  },
           93 +        { "caret",        CaretBrowsing    },
           94 +        { "frameflat",    FrameFlattening  },
           95 +        { "geolocation",  Geolocation      },
           96 +        { "hidebg",       HideBackground   },
           97 +        { "images",       LoadImages       },
           98 +        { "indicators",   ShowIndicators   },
           99 +        { "java",         Java             },
          100 +        { "js",           JavaScript       },
          101 +        { "kiosk",        KioskMode        },
          102 +        { "microphone",   AccessMicrophone },
          103 +        { "scrollbars",   ScrollBars       },
          104 +        { "smoothscroll", SmoothScrolling  },
          105 +        { "spellcheck",   SpellChecking    },
          106 +        { "stricttls",    StrictTLS        },
          107 +        { "style",        Style            },
          108 +        { "webcam",       AccessWebcam     },
          109 +        { "webgl",        WebGL            },
          110 +};
          111 +
          112 +static Cmd commands[] = {
          113 +        { "clipboard",        clipboard,          ARGTYPE_INT },
          114 +        { "find",             find,               ARGTYPE_INT },
          115 +        { "inject",           injectjs,           ARGTYPE_STR },
          116 +        { "loaduri",          loaduri,            ARGTYPE_STR },
          117 +        { "reload",           reload,             ARGTYPE_INT },
          118 +        { "scrollh",          scrollh,            ARGTYPE_INT },
          119 +        { "scrollv",          scrollv,            ARGTYPE_INT },
          120 +        { "showcert",         showcert,           ARGTYPE_NIL },
          121 +        { "spawn",            spawn,              ARGTYPE_STR },
          122 +        { "stop",             stop,               ARGTYPE_NIL },
          123 +        { "toggle",           togglewrapper,      ARGTYPE_STR },
          124 +        { "togglecookies",    togglecookiepolicy, ARGTYPE_NIL },
          125 +        { "togglefullscreen", togglefullscreen,   ARGTYPE_NIL },
          126 +        { "toggleinspector",  toggleinspector,    ARGTYPE_NIL },
          127 +        { "zoom",             zoom,               ARGTYPE_INT },
          128 +};
          129 +
          130  /* configuration, allows nested code to access above variables */
          131  #include "config.h"
          132  
          133 @@ -351,6 +418,7 @@ setup(void)
          134          cookiefile = buildfile(cookiefile);
          135          scriptfile = buildfile(scriptfile);
          136          certdir    = buildpath(certdir);
          137 +        fifodir    = buildpath(fifodir);
          138          if (curconfig[Ephemeral].val.i)
          139                  cachedir = NULL;
          140          else
          141 @@ -1080,9 +1148,15 @@ destroyclient(Client *c)
          142  void
          143  cleanup(void)
          144  {
          145 +        GError *error = NULL;
          146 +
          147          while (clients)
          148                  destroyclient(clients);
          149  
          150 +        if (fifof != NULL)
          151 +                if (!g_file_delete(fifof, NULL, &error))
          152 +                        g_warning("cleanup: couldn't delete fifo: %s\n", error->message);
          153 +
          154          close(spair[0]);
          155          close(spair[1]);
          156          g_free(cookiefile);
          157 @@ -1874,6 +1948,141 @@ msgext(Client *c, char type, const Arg *a)
          158                          c->pageid, type, a->i, ret);
          159  }
          160  
          161 +gboolean
          162 +init_fifo(Client *c)
          163 +{
          164 +        gboolean r = FALSE;
          165 +        char *path = g_strconcat(fifodir, "/", winid, NULL);
          166 +
          167 +        if (path) {
          168 +                if (g_file_test(path, G_FILE_TEST_EXISTS) && unlink(path))
          169 +                        fprintf(stderr, "surf: couldn't unlink old fifo: %s\n", path);
          170 +
          171 +                if (!mkfifo(path, 0600)) {
          172 +                        r = start_fifo(c, path);
          173 +                } else {
          174 +                        fprintf(stderr, "init_fifo: couldn't create fifo: %s\n", path);
          175 +                        r = FALSE;
          176 +                }
          177 +        }
          178 +
          179 +
          180 +        // fifo info no longer needed
          181 +        g_free(fifodir);
          182 +        if (path)
          183 +                g_free(path);
          184 +
          185 +        return r;
          186 +}
          187 +
          188 +gboolean
          189 +start_fifo(Client *c, char *path)
          190 +{
          191 +        GError *error = NULL;
          192 +        GFileIOStream *fs;
          193 +        GOutputStream *os;
          194 +        GDataInputStream *is;
          195 +        fifof = g_file_new_for_path (path);
          196 +
          197 +        /* open in read/write so no blocking occurs */
          198 +        fs = g_file_open_readwrite(fifof, NULL, &error);
          199 +        if (!fs) {
          200 +                fprintf(stderr, "surf: can't open: %s\n", error->message);
          201 +                g_error_free(error);
          202 +                return FALSE;
          203 +        }
          204 +
          205 +        os = g_io_stream_get_output_stream(G_IO_STREAM(fs));
          206 +        if (!g_output_stream_close(os, NULL, &error)) {
          207 +                fprintf(stderr, "start_fifo: failed to close write end: %s\n",
          208 +                          error->message);
          209 +                g_error_free(error);
          210 +                return FALSE;
          211 +        }
          212 +
          213 +        is = g_data_input_stream_new(g_io_stream_get_input_stream(G_IO_STREAM(fs)));
          214 +
          215 +        g_data_input_stream_read_line_async(is, G_PRIORITY_DEFAULT, NULL,
          216 +                                            &fifo_read_cb, c);
          217 +
          218 +        g_setenv("SURF_FIFO", path, TRUE);
          219 +
          220 +        return TRUE;
          221 +}
          222 +
          223 +void
          224 +fifo_read_cb(GObject *f, GAsyncResult *r, gpointer d)
          225 +{
          226 +        Client *c = (Client *)d;
          227 +        GDataInputStream *s = (GDataInputStream *)f;
          228 +        GError *error = NULL;
          229 +        gsize length;
          230 +        gchar *rest;
          231 +
          232 +        gchar *line = g_data_input_stream_read_line_finish(s, r, &length, &error);
          233 +        if (error) {
          234 +                fprintf(stderr, "fifo_read_cb: error reading: %s\n", error->message);
          235 +                return;
          236 +        }
          237 +
          238 +        if (!line)
          239 +                return;
          240 +
          241 +        line = strtok_r(line, " ", &rest);
          242 +
          243 +        dispatchcmd(c, line, rest);
          244 +
          245 +        g_data_input_stream_read_line_async(s, G_PRIORITY_DEFAULT, NULL,
          246 +                                            &fifo_read_cb, c);
          247 +}
          248 +
          249 +void
          250 +dispatchcmd(Client *c, char *cmd, char *a)
          251 +{
          252 +        Arg arg;
          253 +        int i;
          254 +
          255 +        for (i = 0; i < LENGTH(commands); i++) {
          256 +                if (strcmp(cmd, commands[i].cmd) == 0) {
          257 +                        switch (commands[i].t) {
          258 +                        case ARGTYPE_STR: arg = (Arg)(const void *)a; break;
          259 +                        case ARGTYPE_INT: arg = (Arg)atoi(a);         break;
          260 +                        case ARGTYPE_FLT: arg = (Arg)(float)atof(a);  break;
          261 +                        case ARGTYPE_NIL: arg = (Arg)0;               break;
          262 +                        }
          263 +
          264 +                        if (commands[i].t == ARGTYPE_INT) {
          265 +                                printf("%i\n", arg.i);
          266 +                        }
          267 +                        commands[i].func(c, (const Arg *)&arg);
          268 +                        return;
          269 +                }
          270 +        }
          271 +
          272 +        fprintf(stderr, "%s: no such command\n", cmd);
          273 +}
          274 +
          275 +void
          276 +injectjs(Client *c, const Arg *a)
          277 +{
          278 +        evalscript(c, "%s", (char *)a->v);
          279 +}
          280 +
          281 +void
          282 +togglewrapper(Client *c, const Arg *a)
          283 +{
          284 +        int i;
          285 +
          286 +        for (i = 0; i < LENGTH(paramnames); i++) {
          287 +                if (strcmp(paramnames[i].p, (char *)a->v) == 0) {
          288 +                        Arg targ = (Arg)(const void *)paramnames[i].pv;
          289 +                        return toggle(c, &targ);
          290 +                }
          291 +        }
          292 +
          293 +        fprintf(stderr, "toggle: no such setting '%s'", (char *)a->v);
          294 +}
          295 +
          296  void
          297  scrollv(Client *c, const Arg *a)
          298  {
          299 @@ -2123,6 +2332,7 @@ main(int argc, char *argv[])
          300          setup();
          301          c = newclient(NULL);
          302          showview(NULL, c);
          303 +        init_fifo(c);
          304  
          305          loaduri(c, &arg);
          306          updatetitle(c);
          307 -- 
          308 2.35.1
          309