surf

surf browser, a WebKit2GTK based browser
Log | Files | Refs | README | LICENSE

libsurf-webext.c (2609B)


      1 #include <sys/stat.h>
      2 #include <fcntl.h>
      3 #include <limits.h>
      4 #include <stdlib.h>
      5 
      6 #include <gio/gio.h>
      7 #include <webkit2/webkit-web-extension.h>
      8 #include <webkitdom/webkitdom.h>
      9 #include <webkitdom/WebKitDOMDOMWindowUnstable.h>
     10 
     11 #include "common.h"
     12 
     13 #define LENGTH(x)   (sizeof(x) / sizeof(x[0]))
     14 
     15 typedef struct Page {
     16 	guint64 id;
     17 	WebKitWebPage *webpage;
     18 	WebKitDOMDOMWindow *view;
     19 	struct Page *next;
     20 } Page;
     21 
     22 static int pipein, pipeout;
     23 static Page *pages;
     24 
     25 Page *
     26 newpage(WebKitWebPage *page)
     27 {
     28 	Page *p;
     29 
     30 	if (!(p = calloc(1, sizeof(Page))))
     31 		die("Cannot malloc!\n");
     32 
     33 	p->next = pages;
     34 	pages = p;
     35 
     36 	p->id = webkit_web_page_get_id(page);
     37 	p->webpage = page;
     38 
     39 	return p;
     40 }
     41 
     42 static void
     43 msgsurf(Page *p, const char *s)
     44 {
     45 	char msg[BUFSIZ];
     46 
     47 	msg[0] = p ? p->id : 0;
     48 	snprintf(&msg[1], sizeof(msg) - 1, "%s", s);
     49 
     50 	if (pipeout)
     51 		write(pipeout, msg, sizeof(msg));
     52 }
     53 
     54 static gboolean
     55 readpipe(GIOChannel *s, GIOCondition c, gpointer unused)
     56 {
     57 	char msg[BUFSIZ];
     58 	gsize msgsz;
     59 	GError *gerr = NULL;
     60 	glong wh, ww;
     61 	Page *p;
     62 
     63 	if (g_io_channel_read_chars(s, msg, LENGTH(msg), &msgsz, &gerr) !=
     64 	    G_IO_STATUS_NORMAL) {
     65 		fprintf(stderr, "Unable to read pipe: %s\n", gerr->message);
     66 		g_error_free(gerr);
     67 		return TRUE;
     68 	}
     69 	msg[msgsz] = '\0';
     70 
     71 	for (p = pages; p; p = p->next) {
     72 		if (p->id == msg[0])
     73 			break;
     74 	}
     75 	if (!p || !p->view)
     76 		return TRUE;
     77 
     78 	switch (msg[1]) {
     79 	case 'h':
     80 		ww = webkit_dom_dom_window_get_inner_width(p->view);
     81 		webkit_dom_dom_window_scroll_by(p->view,
     82 		                                (ww / 100) * msg[2], 0);
     83 		break;
     84 	case 'v':
     85 		wh = webkit_dom_dom_window_get_inner_height(p->view);
     86 		webkit_dom_dom_window_scroll_by(p->view,
     87 		                                0, (wh / 100) * msg[2]);
     88 		break;
     89 	}
     90 
     91 	return TRUE;
     92 }
     93 
     94 static void
     95 documentloaded(WebKitWebPage *wp, Page *p)
     96 {
     97 	p->view = webkit_dom_document_get_default_view(
     98 	          webkit_web_page_get_dom_document(wp));
     99 }
    100 
    101 static void
    102 webpagecreated(WebKitWebExtension *e, WebKitWebPage *p, gpointer unused)
    103 {
    104 	Page *np = newpage(p);
    105 
    106 	g_signal_connect(p, "document-loaded",
    107 	                 G_CALLBACK(documentloaded), np);
    108 }
    109 
    110 G_MODULE_EXPORT void
    111 webkit_web_extension_initialize_with_user_data(WebKitWebExtension *e, GVariant *gv)
    112 {
    113 	GIOChannel *gchanpipe;
    114 
    115 	g_signal_connect(e, "page-created",
    116 	                 G_CALLBACK(webpagecreated), NULL);
    117 
    118 	g_variant_get(gv, "(ii)", &pipein, &pipeout);
    119 	msgsurf(NULL, "i");
    120 
    121 	gchanpipe = g_io_channel_unix_new(pipein);
    122 	g_io_channel_set_encoding(gchanpipe, NULL, NULL);
    123 	g_io_channel_set_close_on_unref(gchanpipe, TRUE);
    124 	g_io_add_watch(gchanpipe, G_IO_IN, readpipe, NULL);
    125 }