surf

surf browser, a WebKit based browser
git clone git://git.suckless.org/surf
Log | Files | Refs | README | LICENSE

webext-surf.c (3323B)


      1 #include <sys/socket.h>
      2 #include <sys/stat.h>
      3 #include <fcntl.h>
      4 #include <inttypes.h>
      5 #include <limits.h>
      6 #include <stdio.h>
      7 #include <stdlib.h>
      8 
      9 #include <gio/gio.h>
     10 #include <gio/gunixfdlist.h>
     11 #include <webkit2/webkit-web-extension.h>
     12 #include <webkitdom/webkitdom.h>
     13 #include <webkitdom/WebKitDOMDOMWindowUnstable.h>
     14 
     15 #include "common.h"
     16 
     17 #define LENGTH(x)   (sizeof(x) / sizeof(x[0]))
     18 
     19 static WebKitWebExtension *webext;
     20 static int sock;
     21 
     22 static void
     23 msgsurf(guint64 pageid, const char *s)
     24 {
     25 	static char msg[MSGBUFSZ];
     26 	size_t sln = strlen(s);
     27 	int ret;
     28 
     29 	if ((ret = snprintf(msg, sizeof(msg), "%c%s", pageid, s))
     30 	    >= sizeof(msg)) {
     31 		fprintf(stderr, "webext: msg: message too long: %d\n", ret);
     32 		return;
     33 	}
     34 
     35 	if (send(sock, msg, ret, 0) < 0)
     36 		fprintf(stderr, "webext: error sending: %s\n", msg+1);
     37 }
     38 
     39 static gboolean
     40 readsock(GIOChannel *s, GIOCondition c, gpointer unused)
     41 {
     42 	static char js[48], msg[MSGBUFSZ];
     43 	WebKitWebPage *page;
     44 	JSCContext *jsc;
     45 	GError *gerr = NULL;
     46 	gsize msgsz;
     47 
     48 	if (g_io_channel_read_chars(s, msg, sizeof(msg), &msgsz, &gerr) !=
     49 	    G_IO_STATUS_NORMAL) {
     50 		if (gerr) {
     51 			fprintf(stderr, "webext: error reading socket: %s\n",
     52 			        gerr->message);
     53 			g_error_free(gerr);
     54 		}
     55 		return TRUE;
     56 	}
     57 
     58 	if (msgsz < 2) {
     59 		fprintf(stderr, "webext: readsock: message too short: %d\n",
     60 		        msgsz);
     61 		return TRUE;
     62 	}
     63 
     64 	if (!(page = webkit_web_extension_get_page(webext, msg[0])))
     65 		return TRUE;
     66 
     67 	jsc = webkit_frame_get_js_context(webkit_web_page_get_main_frame(page));
     68 
     69 	switch (msg[1]) {
     70 	case 'h':
     71 		if (msgsz != 3)
     72 			return TRUE;
     73 		snprintf(js, sizeof(js),
     74 		         "window.scrollBy(window.innerWidth/100*%d,0);",
     75 		         msg[2]);
     76 		jsc_context_evaluate(jsc, js, -1);
     77 		break;
     78 	case 'v':
     79 		if (msgsz != 3)
     80 			return TRUE;
     81 		snprintf(js, sizeof(js),
     82 		         "window.scrollBy(0,window.innerHeight/100*%d);",
     83 		         msg[2]);
     84 		jsc_context_evaluate(jsc, js, -1);
     85 		break;
     86 	}
     87 
     88 	return TRUE;
     89 }
     90 
     91 static void
     92 pageusermessagereply(GObject *o, GAsyncResult *r, gpointer page)
     93 {
     94 	WebKitUserMessage *m;
     95 	GUnixFDList *gfd;
     96 	GIOChannel *gchansock;
     97 	const char *name;
     98 	int nfd;
     99 
    100 	m = webkit_web_page_send_message_to_view_finish(page, r, NULL);
    101 	name = webkit_user_message_get_name(m);
    102 	if (strcmp(name, "surf-pipe") != 0) {
    103 		fprintf(stderr, "webext-surf: Unknown User Reply: %s\n", name);
    104 		return;
    105 	}
    106 
    107 	gfd = webkit_user_message_get_fd_list(m);
    108 	if ((nfd = g_unix_fd_list_get_length(gfd)) != 1) {
    109 		fprintf(stderr, "webext-surf: Too many file-descriptors: %d\n", nfd);
    110 		return;
    111 	}
    112 
    113 	sock = g_unix_fd_list_get(gfd, 0, NULL);
    114 
    115 	gchansock = g_io_channel_unix_new(sock);
    116 	g_io_channel_set_encoding(gchansock, NULL, NULL);
    117 	g_io_channel_set_flags(gchansock, g_io_channel_get_flags(gchansock)
    118 	                       | G_IO_FLAG_NONBLOCK, NULL);
    119 	g_io_channel_set_close_on_unref(gchansock, TRUE);
    120 	g_io_add_watch(gchansock, G_IO_IN, readsock, NULL);
    121 }
    122 
    123 void
    124 pagecreated(WebKitWebExtension *e, WebKitWebPage *p, gpointer unused)
    125 {
    126 	WebKitUserMessage *msg;
    127 
    128 	msg = webkit_user_message_new("page-created", NULL);
    129 	webkit_web_page_send_message_to_view(p, msg, NULL, pageusermessagereply, p);
    130 }
    131 
    132 G_MODULE_EXPORT void
    133 webkit_web_extension_initialize(WebKitWebExtension *e)
    134 {
    135 	webext = e;
    136 
    137 	g_signal_connect(G_OBJECT(e), "page-created",
    138 	                 G_CALLBACK(pagecreated), NULL);
    139 }