tMerge remote-tracking branch 'upstream/surf-webkit2' into master - surf - [for… | |
git clone git://src.adamsgaard.dk/surf | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 00b428177753db5915102ff834801b641c660c11 | |
parent e5f5686d373bff6b9eceec06f2d8e57b729972a6 | |
Author: Anders Damsgaard <[email protected]> | |
Date: Mon, 2 Nov 2020 08:23:48 +0100 | |
Merge remote-tracking branch 'upstream/surf-webkit2' into master | |
Diffstat: | |
M Makefile | 46 ++++++++++++++++-------------… | |
D common.c | 15 --------------- | |
M common.h | 2 -- | |
M config.def.h | 6 ++++++ | |
M config.mk | 7 ++++--- | |
D libsurf-webext.c | 128 -----------------------------… | |
M surf.c | 111 ++++++++++++++++++++---------… | |
A webext-surf.c | 106 ++++++++++++++++++++++++++++++ | |
8 files changed, 210 insertions(+), 211 deletions(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
t@@ -5,13 +5,12 @@ | |
include config.mk | |
SRC = surf.c | |
-CSRC = common.c | |
-WEBEXTSRC = libsurf-webext.c | |
+WSRC = webext-surf.c | |
OBJ = $(SRC:.c=.o) | |
-COBJ = $(CSRC:.c=.o) | |
-WEBEXTOBJ = $(WEBEXTSRC:.c=.o) | |
+WOBJ = $(WSRC:.c=.o) | |
+WLIB = $(WSRC:.c=.so) | |
-all: options libsurf-webext.so surf | |
+all: options surf $(WLIB) | |
options: | |
@echo surf build options: | |
t@@ -23,26 +22,23 @@ options: | |
.c.o: | |
$(CC) $(SURFCFLAGS) $(CFLAGS) -c $< | |
+.o.so: | |
+ $(CC) -shared -Wl,-soname,$@ $(LDFLAGS) -o $@ $< $(WEBEXTLIBS) | |
+ | |
config.h: | |
cp config.def.h $@ | |
-$(OBJ): config.h common.h config.mk | |
-$(COBJ): config.h common.h config.mk | |
-$(WEBEXTOBJ): config.h common.h config.mk | |
- | |
-$(WEBEXTOBJ): $(WEBEXTSRC) | |
- $(CC) $(WEBEXTCFLAGS) $(CFLAGS) -c $(WEBEXTSRC) | |
+$(OBJ) $(WOBJ): config.h common.h config.mk | |
-libsurf-webext.so: $(WEBEXTOBJ) $(COBJ) | |
- $(CC) -shared -Wl,-soname,$@ $(LDFLAGS) -o $@ \ | |
- $(WEBEXTOBJ) $(COBJ) $(WEBEXTLIBS) | |
+surf: $(OBJ) | |
+ $(CC) $(SURFLDFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) | |
-surf: $(OBJ) $(COBJ) | |
- $(CC) $(SURFLDFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(COBJ) $(LIBS) | |
+$(WOBJ): | |
+ $(CC) $(WEBEXTCFLAGS) $(CFLAGS) -c $(@:.o=.c) | |
clean: | |
- rm -f surf $(OBJ) $(COBJ) | |
- rm -f libsurf-webext.so $(WEBEXTOBJ) | |
+ rm -f surf $(OBJ) | |
+ rm -f $(WLIB) $(WOBJ) | |
distclean: clean | |
rm -f config.h surf-$(VERSION).tar.gz | |
t@@ -51,7 +47,7 @@ dist: distclean | |
mkdir -p surf-$(VERSION) | |
cp -R LICENSE Makefile config.mk config.def.h README \ | |
surf-open.sh arg.h TODO.md surf.png \ | |
- surf.1 $(SRC) $(WEBEXTSRC) surf-$(VERSION) | |
+ surf.1 $(SRC) $(CSRC) $(WSRC) surf-$(VERSION) | |
tar -cf surf-$(VERSION).tar surf-$(VERSION) | |
gzip surf-$(VERSION).tar | |
rm -rf surf-$(VERSION) | |
t@@ -61,8 +57,10 @@ install: all | |
cp -f surf $(DESTDIR)$(PREFIX)/bin | |
chmod 755 $(DESTDIR)$(PREFIX)/bin/surf | |
mkdir -p $(DESTDIR)$(LIBDIR) | |
- cp -f libsurf-webext.so $(DESTDIR)$(LIBDIR) | |
- chmod 644 $(DESTDIR)$(LIBDIR)/libsurf-webext.so | |
+ cp -f $(WLIB) $(DESTDIR)$(LIBDIR) | |
+ for wlib in $(WLIB); do \ | |
+ chmod 644 $(DESTDIR)$(LIBDIR)/$$wlib; \ | |
+ done | |
mkdir -p $(DESTDIR)$(MANPREFIX)/man1 | |
sed "s/VERSION/$(VERSION)/g" < surf.1 > $(DESTDIR)$(MANPREFIX)/man1/su… | |
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/surf.1 | |
t@@ -70,8 +68,10 @@ install: all | |
uninstall: | |
rm -f $(DESTDIR)$(PREFIX)/bin/surf | |
rm -f $(DESTDIR)$(MANPREFIX)/man1/surf.1 | |
- rm -f $(DESTDIR)$(LIBDIR)/libsurf-webext.so | |
+ for wlib in $(WLIB); do \ | |
+ rm -f $(DESTDIR)$(LIBDIR)/$$wlib; \ | |
+ done | |
- rmdir $(DESTDIR)$(LIBDIR) | |
.SUFFIXES: .so .o .c | |
-.PHONY: all options clean-dist clean dist install uninstall | |
+.PHONY: all options distclean clean dist install uninstall | |
diff --git a/common.c b/common.c | |
t@@ -1,15 +0,0 @@ | |
-#include <stdarg.h> | |
-#include <stdio.h> | |
-#include <stdlib.h> | |
- | |
-void | |
-die(const char *errstr, ...) | |
-{ | |
- va_list ap; | |
- | |
- va_start(ap, errstr); | |
- vfprintf(stderr, errstr, ap); | |
- va_end(ap); | |
- exit(1); | |
-} | |
- | |
diff --git a/common.h b/common.h | |
t@@ -1,3 +1 @@ | |
#define MSGBUFSZ 8 | |
- | |
-void die(char *, ...); | |
diff --git a/config.def.h b/config.def.h | |
t@@ -6,6 +6,11 @@ static char *styledir = "~/.surf/styles/"; | |
static char *certdir = "~/.surf/certificates/"; | |
static char *cachedir = "~/.surf/cache/"; | |
static char *cookiefile = "~/.surf/cookies.txt"; | |
+static char **plugindirs = (char*[]){ | |
+ "~/.surf/plugins/", | |
+ LIBPREFIX "/mozilla/plugins/", | |
+ NULL | |
+}; | |
/* Webkit default features */ | |
/* Highest priority value will be used. | |
t@@ -24,6 +29,7 @@ static Parameter defconfig[ParameterLast] = { | |
[DefaultCharset] = { { .v = "UTF-8" }, }, | |
[DiskCache] = { { .i = 1 }, }, | |
[DNSPrefetch] = { { .i = 0 }, }, | |
+ [Ephemeral] = { { .i = 0 }, }, | |
[FileURLsCrossAccess] = { { .i = 0 }, }, | |
[FontSize] = { { .i = 12 }, }, | |
[FrameFlattening] = { { .i = 0 }, }, | |
diff --git a/config.mk b/config.mk | |
t@@ -22,9 +22,10 @@ INCS = $(X11INC) $(GTKINC) | |
LIBS = $(X11LIB) $(GTKLIB) -lgthread-2.0 | |
# flags | |
-CPPFLAGS = -DVERSION=\"$(VERSION)\" -DWEBEXTDIR=\"$(LIBDIR)\" \ | |
- -D_DEFAULT_SOURCE -DGCR_API_SUBJECT_TO_CHANGE | |
-SURFCFLAGS = $(INCS) $(CPPFLAGS) -fPIC | |
+CPPFLAGS = -DVERSION=\"$(VERSION)\" -DGCR_API_SUBJECT_TO_CHANGE \ | |
+ -DLIBPREFIX=\"$(LIBPREFIX)\" -DWEBEXTDIR=\"$(LIBDIR)\" \ | |
+ -D_DEFAULT_SOURCE | |
+SURFCFLAGS = -fPIC $(INCS) $(CPPFLAGS) | |
WEBEXTCFLAGS = -fPIC $(WEBEXTINC) | |
# compiler | |
diff --git a/libsurf-webext.c b/libsurf-webext.c | |
t@@ -1,128 +0,0 @@ | |
-#include <sys/stat.h> | |
-#include <fcntl.h> | |
-#include <limits.h> | |
-#include <stdlib.h> | |
- | |
-#include <gio/gio.h> | |
-#include <webkit2/webkit-web-extension.h> | |
-#include <webkitdom/webkitdom.h> | |
-#include <webkitdom/WebKitDOMDOMWindowUnstable.h> | |
- | |
-#include "common.h" | |
- | |
-#define LENGTH(x) (sizeof(x) / sizeof(x[0])) | |
- | |
-typedef struct Page { | |
- guint64 id; | |
- WebKitWebPage *webpage; | |
- struct Page *next; | |
-} Page; | |
- | |
-static int pipein, pipeout; | |
-static Page *pages; | |
- | |
-Page * | |
-newpage(WebKitWebPage *page) | |
-{ | |
- Page *p; | |
- | |
- if (!(p = calloc(1, sizeof(Page)))) | |
- die("Cannot malloc!\n"); | |
- | |
- p->next = pages; | |
- pages = p; | |
- | |
- p->id = webkit_web_page_get_id(page); | |
- p->webpage = page; | |
- | |
- return p; | |
-} | |
- | |
-static void | |
-msgsurf(Page *p, const char *s) | |
-{ | |
- static char msg[MSGBUFSZ]; | |
- size_t sln = strlen(s); | |
- int ret; | |
- | |
- if ((ret = snprintf(msg, sizeof(msg), "%c%c%s", | |
- 2 + sln, p ? p->id : 0, s)) | |
- >= sizeof(msg)) { | |
- fprintf(stderr, "webext: message too long: %d\n", ret); | |
- return; | |
- } | |
- | |
- if (pipeout && write(pipeout, msg, sizeof(msg)) < 0) | |
- fprintf(stderr, "webext: error sending: %.*s\n", ret-2, msg+2); | |
-} | |
- | |
-static gboolean | |
-readpipe(GIOChannel *s, GIOCondition c, gpointer unused) | |
-{ | |
- static char msg[MSGBUFSZ], msgsz; | |
- WebKitDOMDOMWindow *view; | |
- GError *gerr = NULL; | |
- glong wh, ww; | |
- Page *p; | |
- | |
- if (g_io_channel_read_chars(s, msg, LENGTH(msg), NULL, &gerr) != | |
- G_IO_STATUS_NORMAL) { | |
- fprintf(stderr, "webext: error reading pipe: %s\n", | |
- gerr->message); | |
- g_error_free(gerr); | |
- return TRUE; | |
- } | |
- if ((msgsz = msg[0]) < 3) { | |
- fprintf(stderr, "webext: message too short: %d\n", msgsz); | |
- return TRUE; | |
- } | |
- | |
- for (p = pages; p; p = p->next) { | |
- if (p->id == msg[1]) | |
- break; | |
- } | |
- if (!p || !(view = webkit_dom_document_get_default_view( | |
- webkit_web_page_get_dom_document(p->webpage)))) | |
- return TRUE; | |
- | |
- switch (msg[2]) { | |
- case 'h': | |
- if (msgsz != 4) | |
- return TRUE; | |
- ww = webkit_dom_dom_window_get_inner_width(view); | |
- webkit_dom_dom_window_scroll_by(view, | |
- (ww / 100) * msg[3], 0); | |
- break; | |
- case 'v': | |
- if (msgsz != 4) | |
- return TRUE; | |
- wh = webkit_dom_dom_window_get_inner_height(view); | |
- webkit_dom_dom_window_scroll_by(view, | |
- 0, (wh / 100) * msg[3]); | |
- break; | |
- } | |
- | |
- return TRUE; | |
-} | |
- | |
-static void | |
-webpagecreated(WebKitWebExtension *e, WebKitWebPage *wp, gpointer unused) | |
-{ | |
- Page *p = newpage(wp); | |
-} | |
- | |
-G_MODULE_EXPORT void | |
-webkit_web_extension_initialize_with_user_data(WebKitWebExtension *e, GVariant… | |
-{ | |
- GIOChannel *gchanpipe; | |
- | |
- g_signal_connect(e, "page-created", G_CALLBACK(webpagecreated), NULL); | |
- | |
- g_variant_get(gv, "(ii)", &pipein, &pipeout); | |
- msgsurf(NULL, "i"); | |
- | |
- gchanpipe = g_io_channel_unix_new(pipein); | |
- g_io_channel_set_encoding(gchanpipe, NULL, NULL); | |
- g_io_channel_set_close_on_unref(gchanpipe, TRUE); | |
- g_io_add_watch(gchanpipe, G_IO_IN, readpipe, NULL); | |
-} | |
diff --git a/surf.c b/surf.c | |
t@@ -3,9 +3,11 @@ | |
* To understand surf, start reading main(). | |
*/ | |
#include <sys/file.h> | |
+#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <glib.h> | |
+#include <inttypes.h> | |
#include <libgen.h> | |
#include <limits.h> | |
#include <pwd.h> | |
t@@ -62,6 +64,7 @@ typedef enum { | |
DiskCache, | |
DefaultCharset, | |
DNSPrefetch, | |
+ Ephemeral, | |
FileURLsCrossAccess, | |
FontSize, | |
FrameFlattening, | |
t@@ -109,7 +112,7 @@ typedef struct Client { | |
GTlsCertificate *cert, *failedcert; | |
GTlsCertificateFlags tlserr; | |
Window xid; | |
- unsigned long pageid; | |
+ guint64 pageid; | |
int progress, fullscreen, https, insecure, errorpage; | |
const char *title, *overtitle, *targeturi; | |
const char *needle; | |
t@@ -145,6 +148,7 @@ typedef struct { | |
} SiteSpecific; | |
/* Surf */ | |
+static void die(const char *errstr, ...); | |
static void usage(void); | |
static void setup(void); | |
static void sigchld(int unused); | |
t@@ -189,7 +193,7 @@ static gboolean buttonreleased(GtkWidget *w, GdkEvent *e, … | |
static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event, | |
gpointer d); | |
static gboolean winevent(GtkWidget *w, GdkEvent *e, Client *c); | |
-static gboolean readpipe(GIOChannel *s, GIOCondition ioc, gpointer unused); | |
+static gboolean readsock(GIOChannel *s, GIOCondition ioc, gpointer unused); | |
static void showview(WebKitWebView *v, Client *c); | |
static GtkWidget *createwindow(Client *c); | |
static gboolean loadfailedtls(WebKitWebView *v, gchar *uri, | |
t@@ -255,7 +259,7 @@ static char *stylefile; | |
static const char *useragent; | |
static Parameter *curconfig; | |
static int modparams[ParameterLast]; | |
-static int pipein[2], pipeout[2]; | |
+static int spair[2]; | |
char *argv0; | |
static ParamName loadtransient[] = { | |
t@@ -306,6 +310,17 @@ static ParamName loadfinished[] = { | |
#include "config.h" | |
void | |
+die(const char *errstr, ...) | |
+{ | |
+ va_list ap; | |
+ | |
+ va_start(ap, errstr); | |
+ vfprintf(stderr, errstr, ap); | |
+ va_end(ap); | |
+ exit(1); | |
+} | |
+ | |
+void | |
usage(void) | |
{ | |
die("usage: surf [-bBdDfFgGiIkKmMnNpPsStTvwxX]\n" | |
t@@ -342,18 +357,24 @@ setup(void) | |
/* dirs and files */ | |
cookiefile = buildfile(cookiefile); | |
scriptfile = buildfile(scriptfile); | |
- cachedir = buildpath(cachedir); | |
certdir = buildpath(certdir); | |
+ if (curconfig[Ephemeral].val.i) | |
+ cachedir = NULL; | |
+ else | |
+ cachedir = buildpath(cachedir); | |
gdkkb = gdk_seat_get_keyboard(gdk_display_get_default_seat(gdpy)); | |
- if (pipe(pipeout) < 0 || pipe(pipein) < 0) { | |
- fputs("Unable to create pipes\n", stderr); | |
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, spair) < 0) { | |
+ fputs("Unable to create sockets\n", stderr); | |
+ spair[0] = spair[1] = -1; | |
} else { | |
- gchanin = g_io_channel_unix_new(pipein[0]); | |
+ gchanin = g_io_channel_unix_new(spair[0]); | |
g_io_channel_set_encoding(gchanin, NULL, NULL); | |
+ g_io_channel_set_flags(gchanin, g_io_channel_get_flags(gchanin) | |
+ | G_IO_FLAG_NONBLOCK, NULL); | |
g_io_channel_set_close_on_unref(gchanin, TRUE); | |
- g_io_add_watch(gchanin, G_IO_IN, readpipe, NULL); | |
+ g_io_add_watch(gchanin, G_IO_IN, readsock, NULL); | |
} | |
t@@ -1042,8 +1063,8 @@ spawn(Client *c, const Arg *a) | |
if (fork() == 0) { | |
if (dpy) | |
close(ConnectionNumber(dpy)); | |
- close(pipein[0]); | |
- close(pipeout[1]); | |
+ close(spair[0]); | |
+ close(spair[1]); | |
setsid(); | |
execvp(((char **)a->v)[0], (char **)a->v); | |
fprintf(stderr, "%s: execvp %s", argv0, ((char **)a->v)[0]); | |
t@@ -1077,8 +1098,8 @@ cleanup(void) | |
while (clients) | |
destroyclient(clients); | |
- close(pipein[0]); | |
- close(pipeout[1]); | |
+ close(spair[0]); | |
+ close(spair[1]); | |
g_free(cookiefile); | |
g_free(scriptfile); | |
g_free(stylefile); | |
t@@ -1133,11 +1154,16 @@ newview(Client *c, WebKitWebView *rv) | |
contentmanager = webkit_user_content_manager_new(); | |
- context = webkit_web_context_new_with_website_data_manager( | |
- webkit_website_data_manager_new( | |
- "base-cache-directory", cachedir, | |
- "base-data-directory", cachedir, | |
- NULL)); | |
+ if (curconfig[Ephemeral].val.i) { | |
+ context = webkit_web_context_new_ephemeral(); | |
+ } else { | |
+ context = webkit_web_context_new_with_website_data_man… | |
+ webkit_website_data_manager_new( | |
+ "base-cache-directory", cachedir, | |
+ "base-data-directory", cachedir, | |
+ NULL)); | |
+ } | |
+ | |
cookiemanager = webkit_web_context_get_cookie_manager(context); | |
t@@ -1153,10 +1179,15 @@ newview(Client *c, WebKitWebView *rv) | |
webkit_web_context_set_cache_model(context, | |
curconfig[DiskCache].val.i ? WEBKIT_CACHE_MODEL_WEB_BROWSE… | |
WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER); | |
+ /* plugins directories */ | |
+ for (; *plugindirs; ++plugindirs) | |
+ webkit_web_context_set_additional_plugins_directory( | |
+ context, *plugindirs); | |
/* Currently only works with text file to be compatible with c… | |
- webkit_cookie_manager_set_persistent_storage(cookiemanager, | |
- cookiefile, WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); | |
+ if (!curconfig[Ephemeral].val.i) | |
+ webkit_cookie_manager_set_persistent_storage(cookieman… | |
+ cookiefile, WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); | |
/* cookie policy */ | |
webkit_cookie_manager_set_accept_policy(cookiemanager, | |
cookiepolicy_get()); | |
t@@ -1211,30 +1242,26 @@ newview(Client *c, WebKitWebView *rv) | |
} | |
static gboolean | |
-readpipe(GIOChannel *s, GIOCondition ioc, gpointer unused) | |
+readsock(GIOChannel *s, GIOCondition ioc, gpointer unused) | |
{ | |
- static char msg[MSGBUFSZ], msgsz; | |
+ static char msg[MSGBUFSZ]; | |
GError *gerr = NULL; | |
+ gsize msgsz; | |
- if (g_io_channel_read_chars(s, msg, sizeof(msg), NULL, &gerr) != | |
+ if (g_io_channel_read_chars(s, msg, sizeof(msg), &msgsz, &gerr) != | |
G_IO_STATUS_NORMAL) { | |
- fprintf(stderr, "surf: error reading pipe: %s\n", | |
- gerr->message); | |
- g_error_free(gerr); | |
+ if (gerr) { | |
+ fprintf(stderr, "surf: error reading socket: %s\n", | |
+ gerr->message); | |
+ g_error_free(gerr); | |
+ } | |
return TRUE; | |
} | |
- if ((msgsz = msg[0]) < 3) { | |
+ if (msgsz < 2) { | |
fprintf(stderr, "surf: message too short: %d\n", msgsz); | |
return TRUE; | |
} | |
- switch (msg[2]) { | |
- case 'i': | |
- close(pipein[1]); | |
- close(pipeout[0]); | |
- break; | |
- } | |
- | |
return TRUE; | |
} | |
t@@ -1243,10 +1270,10 @@ initwebextensions(WebKitWebContext *wc, Client *c) | |
{ | |
GVariant *gv; | |
- if (!pipeout[0] || !pipein[1]) | |
+ if (spair[1] < 0) | |
return; | |
- gv = g_variant_new("(ii)", pipeout[0], pipein[1]); | |
+ gv = g_variant_new("i", spair[1]); | |
webkit_web_context_set_web_extensions_initialization_user_data(wc, gv); | |
webkit_web_context_set_web_extensions_directory(wc, WEBEXTDIR); | |
t@@ -1425,7 +1452,7 @@ createwindow(Client *c) | |
gtk_window_set_wmclass(GTK_WINDOW(w), wmstr, "Surf"); | |
g_free(wmstr); | |
- wmstr = g_strdup_printf("%s[%lu]", "Surf", c->pageid); | |
+ wmstr = g_strdup_printf("%s[%"PRIu64"]", "Surf", c->pageid); | |
gtk_window_set_role(GTK_WINDOW(w), wmstr); | |
g_free(wmstr); | |
t@@ -1518,6 +1545,7 @@ loadchanged(WebKitWebView *v, WebKitLoadEvent e, Client … | |
break; | |
case WEBKIT_LOAD_COMMITTED: | |
setatom(c, AtomUri, uri); | |
+ c->title = uri; | |
seturiparameters(c, uri, loadcommitted); | |
c->https = webkit_web_view_get_tls_info(c->view, &c->cert, | |
&c->tlserr); | |
t@@ -1853,15 +1881,18 @@ msgext(Client *c, char type, const Arg *a) | |
static char msg[MSGBUFSZ]; | |
int ret; | |
- if ((ret = snprintf(msg, sizeof(msg), "%c%c%c%c", | |
- 4, c->pageid, type, a->i)) | |
+ if (spair[0] < 0) | |
+ return; | |
+ | |
+ if ((ret = snprintf(msg, sizeof(msg), "%c%c%c", c->pageid, type, a->i)) | |
>= sizeof(msg)) { | |
fprintf(stderr, "surf: message too long: %d\n", ret); | |
return; | |
} | |
- if (pipeout[1] && write(pipeout[1], msg, sizeof(msg)) < 0) | |
- fprintf(stderr, "surf: error sending: %.*s\n", ret-2, msg+2); | |
+ if (send(spair[0], msg, ret, 0) != ret) | |
+ fprintf(stderr, "surf: error sending: %u%c%d (%d)\n", | |
+ c->pageid, type, a->i, ret); | |
} | |
void | |
diff --git a/webext-surf.c b/webext-surf.c | |
t@@ -0,0 +1,106 @@ | |
+#include <sys/socket.h> | |
+#include <sys/stat.h> | |
+#include <fcntl.h> | |
+#include <inttypes.h> | |
+#include <limits.h> | |
+#include <stdio.h> | |
+#include <stdlib.h> | |
+ | |
+#include <gio/gio.h> | |
+#include <webkit2/webkit-web-extension.h> | |
+#include <webkitdom/webkitdom.h> | |
+#include <webkitdom/WebKitDOMDOMWindowUnstable.h> | |
+ | |
+#include "common.h" | |
+ | |
+#define LENGTH(x) (sizeof(x) / sizeof(x[0])) | |
+ | |
+static WebKitWebExtension *webext; | |
+static int sock; | |
+ | |
+static void | |
+msgsurf(guint64 pageid, const char *s) | |
+{ | |
+ static char msg[MSGBUFSZ]; | |
+ size_t sln = strlen(s); | |
+ int ret; | |
+ | |
+ if ((ret = snprintf(msg, sizeof(msg), "%c%s", pageid, s)) | |
+ >= sizeof(msg)) { | |
+ fprintf(stderr, "webext: msg: message too long: %d\n", ret); | |
+ return; | |
+ } | |
+ | |
+ if (send(sock, msg, ret, 0) < 0) | |
+ fprintf(stderr, "webext: error sending: %s\n", msg+1); | |
+} | |
+ | |
+static gboolean | |
+readsock(GIOChannel *s, GIOCondition c, gpointer unused) | |
+{ | |
+ static char js[48], msg[MSGBUFSZ]; | |
+ WebKitWebPage *page; | |
+ JSCContext *jsc; | |
+ GError *gerr = NULL; | |
+ gsize msgsz; | |
+ | |
+ if (g_io_channel_read_chars(s, msg, sizeof(msg), &msgsz, &gerr) != | |
+ G_IO_STATUS_NORMAL) { | |
+ if (gerr) { | |
+ fprintf(stderr, "webext: error reading socket: %s\n", | |
+ gerr->message); | |
+ g_error_free(gerr); | |
+ } | |
+ return TRUE; | |
+ } | |
+ | |
+ if (msgsz < 2) { | |
+ fprintf(stderr, "webext: readsock: message too short: %d\n", | |
+ msgsz); | |
+ return TRUE; | |
+ } | |
+ | |
+ if (!(page = webkit_web_extension_get_page(webext, msg[0]))) | |
+ return TRUE; | |
+ | |
+ jsc = webkit_frame_get_js_context(webkit_web_page_get_main_frame(page)… | |
+ | |
+ switch (msg[1]) { | |
+ case 'h': | |
+ if (msgsz != 3) | |
+ return TRUE; | |
+ snprintf(js, sizeof(js), | |
+ "window.scrollBy(window.innerWidth/100*%d,0);", | |
+ msg[2]); | |
+ jsc_context_evaluate(jsc, js, -1); | |
+ break; | |
+ case 'v': | |
+ if (msgsz != 3) | |
+ return TRUE; | |
+ snprintf(js, sizeof(js), | |
+ "window.scrollBy(0,window.innerHeight/100*%d);", | |
+ msg[2]); | |
+ jsc_context_evaluate(jsc, js, -1); | |
+ break; | |
+ } | |
+ | |
+ return TRUE; | |
+} | |
+ | |
+G_MODULE_EXPORT void | |
+webkit_web_extension_initialize_with_user_data(WebKitWebExtension *e, | |
+ const GVariant *gv) | |
+{ | |
+ GIOChannel *gchansock; | |
+ | |
+ webext = e; | |
+ | |
+ g_variant_get(gv, "i", &sock); | |
+ | |
+ gchansock = g_io_channel_unix_new(sock); | |
+ g_io_channel_set_encoding(gchansock, NULL, NULL); | |
+ g_io_channel_set_flags(gchansock, g_io_channel_get_flags(gchansock) | |
+ | G_IO_FLAG_NONBLOCK, NULL); | |
+ g_io_channel_set_close_on_unref(gchansock, TRUE); | |
+ g_io_add_watch(gchansock, G_IO_IN, readsock, NULL); | |
+} |