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 }