webext-surf.c - surf - surf browser, a WebKit based browser | |
git clone git://git.suckless.org/surf | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
webext-surf.c (3687B) | |
--- | |
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 /* | |
23 * Return: | |
24 * 0 No data processed: need more data | |
25 * > 0 Amount of data processed or discarded | |
26 */ | |
27 static size_t | |
28 evalmsg(char *msg, size_t sz) | |
29 { | |
30 char js[48]; | |
31 WebKitWebPage *page; | |
32 JSCContext *jsc; | |
33 JSCValue *jsv; | |
34 | |
35 if (!(page = webkit_web_extension_get_page(webext, msg[0]))) | |
36 return sz; | |
37 | |
38 if (sz < 2) | |
39 return 0; | |
40 | |
41 jsc = webkit_frame_get_js_context(webkit_web_page_get_main_frame… | |
42 jsv = NULL; | |
43 | |
44 switch (msg[1]) { | |
45 case 'h': | |
46 if (sz < 3) { | |
47 sz = 0; | |
48 break; | |
49 } | |
50 sz = 3; | |
51 snprintf(js, sizeof(js), | |
52 "window.scrollBy(window.innerWidth/100*%hhd,0);… | |
53 msg[2]); | |
54 jsv = jsc_context_evaluate(jsc, js, -1); | |
55 break; | |
56 case 'v': | |
57 if (sz < 3) { | |
58 sz = 0; | |
59 break; | |
60 } | |
61 sz = 3; | |
62 snprintf(js, sizeof(js), | |
63 "window.scrollBy(0,window.innerHeight/100*%hhd)… | |
64 msg[2]); | |
65 jsv = jsc_context_evaluate(jsc, js, -1); | |
66 break; | |
67 default: | |
68 fprintf(stderr, "%s:%d:evalmsg: unknown cmd(%zu): '%#x'\… | |
69 __FILE__, __LINE__, sz, msg[1]); | |
70 } | |
71 | |
72 g_object_unref(jsc); | |
73 if (jsv) | |
74 g_object_unref(jsv); | |
75 | |
76 return sz; | |
77 } | |
78 | |
79 static gboolean | |
80 readsock(GIOChannel *s, GIOCondition c, gpointer unused) | |
81 { | |
82 static char msg[MSGBUFSZ]; | |
83 static size_t msgoff; | |
84 GError *gerr = NULL; | |
85 size_t sz; | |
86 gsize rsz; | |
87 | |
88 if (g_io_channel_read_chars(s, msg+msgoff, sizeof(msg)-msgoff, &… | |
89 G_IO_STATUS_NORMAL) { | |
90 if (gerr) { | |
91 fprintf(stderr, "webext: error reading socket: %… | |
92 gerr->message); | |
93 g_error_free(gerr); | |
94 } | |
95 return TRUE; | |
96 } | |
97 if (msgoff >= sizeof(msg)) { | |
98 fprintf(stderr, "%s:%d:%s: msgoff: %zu", __FILE__, __LIN… | |
99 return FALSE; | |
100 } | |
101 | |
102 for (rsz += msgoff; rsz; rsz -= sz) { | |
103 sz = evalmsg(msg, rsz); | |
104 if (sz == 0) { | |
105 /* need more data */ | |
106 break; | |
107 } | |
108 if (sz != rsz) { | |
109 /* continue processing message */ | |
110 memmove(msg, msg+sz, rsz-sz); | |
111 } | |
112 } | |
113 msgoff = rsz; | |
114 | |
115 return TRUE; | |
116 } | |
117 | |
118 static void | |
119 pageusermessagereply(GObject *o, GAsyncResult *r, gpointer page) | |
120 { | |
121 WebKitUserMessage *m; | |
122 GUnixFDList *gfd; | |
123 GIOChannel *gchansock; | |
124 const char *name; | |
125 int nfd; | |
126 | |
127 m = webkit_web_page_send_message_to_view_finish(page, r, NULL); | |
128 name = webkit_user_message_get_name(m); | |
129 if (strcmp(name, "surf-pipe") != 0) { | |
130 fprintf(stderr, "webext-surf: Unknown User Reply: %s\n",… | |
131 return; | |
132 } | |
133 | |
134 gfd = webkit_user_message_get_fd_list(m); | |
135 if ((nfd = g_unix_fd_list_get_length(gfd)) != 1) { | |
136 fprintf(stderr, "webext-surf: Too many file-descriptors:… | |
137 return; | |
138 } | |
139 | |
140 sock = g_unix_fd_list_get(gfd, 0, NULL); | |
141 | |
142 gchansock = g_io_channel_unix_new(sock); | |
143 g_io_channel_set_encoding(gchansock, NULL, NULL); | |
144 g_io_channel_set_flags(gchansock, g_io_channel_get_flags(gchanso… | |
145 | G_IO_FLAG_NONBLOCK, NULL); | |
146 g_io_channel_set_close_on_unref(gchansock, TRUE); | |
147 g_io_add_watch(gchansock, G_IO_IN, readsock, NULL); | |
148 } | |
149 | |
150 void | |
151 pagecreated(WebKitWebExtension *e, WebKitWebPage *p, gpointer unused) | |
152 { | |
153 WebKitUserMessage *msg; | |
154 | |
155 msg = webkit_user_message_new("page-created", NULL); | |
156 webkit_web_page_send_message_to_view(p, msg, NULL, pageusermessa… | |
157 } | |
158 | |
159 G_MODULE_EXPORT void | |
160 webkit_web_extension_initialize(WebKitWebExtension *e) | |
161 { | |
162 webext = e; | |
163 | |
164 g_signal_connect(G_OBJECT(e), "page-created", | |
165 G_CALLBACK(pagecreated), NULL); | |
166 } |