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 }