webext-surf.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. #include <gio/gio.h>
  9. #include <webkit2/webkit-web-extension.h>
  10. #include <webkitdom/webkitdom.h>
  11. #include <webkitdom/WebKitDOMDOMWindowUnstable.h>
  12. #include "common.h"
  13. #define LENGTH(x) (sizeof(x) / sizeof(x[0]))
  14. static WebKitWebExtension *webext;
  15. static int sock;
  16. static void
  17. msgsurf(guint64 pageid, const char *s)
  18. {
  19. static char msg[MSGBUFSZ];
  20. size_t sln = strlen(s);
  21. int ret;
  22. if ((ret = snprintf(msg, sizeof(msg), "%c%s", pageid, s))
  23. >= sizeof(msg)) {
  24. fprintf(stderr, "webext: msg: message too long: %d\n", ret);
  25. return;
  26. }
  27. if (send(sock, msg, ret, 0) < 0)
  28. fprintf(stderr, "webext: error sending: %s\n", msg+1);
  29. }
  30. static gboolean
  31. readsock(GIOChannel *s, GIOCondition c, gpointer unused)
  32. {
  33. static char js[48], msg[MSGBUFSZ];
  34. WebKitWebPage *page;
  35. JSCContext *jsc;
  36. GError *gerr = NULL;
  37. gsize msgsz;
  38. if (g_io_channel_read_chars(s, msg, sizeof(msg), &msgsz, &gerr) !=
  39. G_IO_STATUS_NORMAL) {
  40. if (gerr) {
  41. fprintf(stderr, "webext: error reading socket: %s\n",
  42. gerr->message);
  43. g_error_free(gerr);
  44. }
  45. return TRUE;
  46. }
  47. if (msgsz < 2) {
  48. fprintf(stderr, "webext: readsock: message too short: %d\n",
  49. msgsz);
  50. return TRUE;
  51. }
  52. if (!(page = webkit_web_extension_get_page(webext, msg[0])))
  53. return TRUE;
  54. jsc = webkit_frame_get_js_context(webkit_web_page_get_main_frame(page));
  55. switch (msg[1]) {
  56. case 'h':
  57. if (msgsz != 3)
  58. return TRUE;
  59. snprintf(js, sizeof(js),
  60. "window.scrollBy(window.innerWidth/100*%d,0);",
  61. msg[2]);
  62. jsc_context_evaluate(jsc, js, -1);
  63. break;
  64. case 'v':
  65. if (msgsz != 3)
  66. return TRUE;
  67. snprintf(js, sizeof(js),
  68. "window.scrollBy(0,window.innerHeight/100*%d);",
  69. msg[2]);
  70. jsc_context_evaluate(jsc, js, -1);
  71. break;
  72. }
  73. return TRUE;
  74. }
  75. G_MODULE_EXPORT void
  76. webkit_web_extension_initialize_with_user_data(WebKitWebExtension *e,
  77. const GVariant *gv)
  78. {
  79. GIOChannel *gchansock;
  80. webext = e;
  81. g_variant_get(gv, "i", &sock);
  82. gchansock = g_io_channel_unix_new(sock);
  83. g_io_channel_set_encoding(gchansock, NULL, NULL);
  84. g_io_channel_set_flags(gchansock, g_io_channel_get_flags(gchansock)
  85. | G_IO_FLAG_NONBLOCK, NULL);
  86. g_io_channel_set_close_on_unref(gchansock, TRUE);
  87. g_io_add_watch(gchansock, G_IO_IN, readsock, NULL);
  88. }