URI: 
       twebext-surf.c - surf - surf browser, a WebKit2GTK based browser
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       twebext-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 }