Advertisement
Guest User

webkit2gtk+ draw

a guest
Jul 2nd, 2014
356
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.06 KB | None | 0 0
  1. #include <gtk/gtk.h>
  2. #include <stdlib.h>
  3. #include <stdlib.h>
  4. #include <webkit2/webkit2.h>
  5. #include <JavaScriptCore/JSContextRef.h>
  6. #include <JavaScriptCore/JSStringRef.h>
  7. #include <webkit2/webkit-web-extension.h>
  8.  
  9.     GtkWidget *window;
  10.     GtkWidget *controll_window;
  11.     GtkWidget *web_view;
  12. /*
  13. static JSValueRef echoCallback(JSContextRef jsContext, JSObjectRef obj1, JSObjectRef obj2, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsvalref)
  14. {
  15.     printf("JS callback\n");
  16.     if (argumentCount <= 0)
  17.         return JSValueMakeUndefined(jsContext);
  18.  
  19.     JSStringRef jstr= JSValueToStringCopy(jsContext, arguments[0], 0);
  20.     return JSValueMakeString(jsContext, jstr);
  21. }
  22. */
  23. static void
  24. window_object_cleared_callback (WebKitScriptWorld *world,
  25.                                 WebKitWebPage     *web_page,
  26.                                 WebKitFrame       *frame,
  27.                                 gpointer           user_data)
  28. {
  29.     /*JSGlobalContextRef jsContext;
  30.     JSObjectRef        globalObject;*/
  31.  
  32.     /*jsContext = webkit_frame_get_javascript_context_for_script_world (frame, world);
  33.     globalObject = JSContextGetGlobalObject (jsContext);*/
  34.     printf("%s callback in UI process\n", __func__);
  35.  
  36.  
  37.     /* Use JSC API to add the JavaScript code you want */
  38.     /*g_assert(jsContext);
  39.     g_assert(globalObject);
  40.    
  41.     JSStringRef functionName = JSStringCreateWithUTF8CString("MyEcho");
  42.     JSObjectRef function = JSObjectMakeFunctionWithCallback(jsContext, functionName, echoCallback);
  43.     JSObjectSetProperty(jsContext, globalObject, functionName, function, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0);
  44.     */
  45. }
  46.  
  47. void handle_load_change() {
  48.     printf("load-changed\n");
  49. }
  50.  
  51. gboolean damage_event_handler(GtkWidget *widget, GdkEvent *event, gpointer user_data)
  52. {
  53.     GTimeVal current_time;
  54.     gchar* time_str;
  55.  
  56.     g_get_current_time(&current_time);
  57.     time_str = g_time_val_to_iso8601(&current_time);
  58.     printf("%s %s damage-event ", time_str, (char*)user_data);
  59.     g_free(time_str);
  60.     if(event->type == GDK_EXPOSE || event->type == GDK_DAMAGE) { // all or part of the window has become visible and needs to be redrawn.
  61.             GdkEventExpose expose = event->expose;
  62.         GdkRectangle rect = expose.area;
  63.  
  64.         if(event->type == GDK_EXPOSE) {
  65.             printf("GDK_EXPOSE ");
  66.         } else if(event->type == GDK_DAMAGE) {
  67.             printf("GDK_DAMAGE ");
  68.         }
  69.             if (expose.type == GDK_EXPOSE) {
  70.             printf("GDK_EXPOSE ");
  71.             } else if (expose.type == GDK_DAMAGE) {
  72.             printf("GDK_DAMAGE ");
  73.             }
  74.         printf("{{X: %d, Y: %d, W: %d, H: %d}, count: %d}", rect.x, rect.y, rect.width, rect.height, expose.count);
  75.     } else {
  76.         printf("event->type = %d)", event->type);
  77.     }
  78.     printf("\n");
  79.     return FALSE;
  80. }
  81.  
  82. /*
  83.  * This signal is emitted when a widget is supposed to render itself. The widget 's top left corner must be painted at the origin of the passed in context and be sized to the values returned by gtk_widget_get_allocated_width() and gtk_widget_get_allocated_height().
  84.  *
  85.  * Signal handlers connected to this signal can modify the cairo context passed as cr in any way they like and don't need to restore it. The signal emission takes care of calling cairo_save() before and cairo_restore() after invoking the handler.
  86.  *
  87.  * The signal handler will get a cr with a clip region already set to the widget's dirty region, i.e. to the area that needs repainting. Complicated widgets that want to avoid redrawing themselves completely can get the full extents of the clip region with gdk_cairo_get_clip_rectangle(), or they can get a finer-grained representation of the dirty region with cairo_copy_clip_rectangle_list().
  88.  */
  89. gboolean draw_event_handler(GtkWidget *widget, cairo_t *cr, gpointer user_data)
  90. {  
  91.     cairo_rectangle_list_t *rect_list;
  92.     cairo_rectangle_t *rect;
  93.     int i;
  94.     GTimeVal current_time;
  95.     gchar* time_str;
  96.     cairo_surface_t *surface;
  97.  
  98.  
  99.     rect_list= cairo_copy_clip_rectangle_list(cr);
  100.     g_get_current_time(&current_time);
  101.     time_str = g_time_val_to_iso8601(&current_time);
  102.     printf("%s %s draw ", time_str, (char*)user_data);
  103.     g_free(time_str);
  104.     if(rect_list->status == CAIRO_STATUS_SUCCESS) {
  105.         printf("%d ", rect_list->num_rectangles);
  106.  
  107.         surface = cairo_get_group_target(cr);
  108.         for(i=0; i < rect_list->num_rectangles; i++) {
  109.             rect = rect_list->rectangles + i;
  110.             printf("{X: %f, Y: %f, W: %f, H:%f} ", rect->x, rect->y, rect->width, rect->height);
  111.             if(cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS) {
  112.                 cairo_surface_t *surface_rect;
  113.                 unsigned char* data;
  114.                 int width, height, stride;
  115.             gchar *checksum;
  116.  
  117.                 surface_rect = cairo_surface_create_for_rectangle(surface, rect->x, rect->y, rect->width, rect->height);
  118.             if(surface_rect != NULL) {
  119.                 data = cairo_image_surface_get_data (surface_rect);
  120.                 width = cairo_image_surface_get_width (surface_rect);
  121.                 height = cairo_image_surface_get_height (surface_rect);
  122.                 stride = cairo_image_surface_get_stride (surface_rect);
  123.                 /*width = rect->width;
  124.                 height = rect->height;
  125.                 stride = 4*width;*/
  126.  
  127.                 checksum = g_compute_checksum_for_data(G_CHECKSUM_MD5, data, (gsize)(height*stride));
  128.                 printf("%dx%d-%s ", width, height, checksum);
  129.                 cairo_surface_destroy (surface_rect);
  130.                 g_free(checksum);
  131.             }
  132.             }
  133.             /*draw something*/
  134.                /* GdkRGBA color;
  135.                 cairo_arc (cr, rect->x + rect->width / 2.0, rect->y + rect->height / 2.0, MIN (rect->width, rect->height) / 2.0, 0, 2 * G_PI);
  136.                 gtk_style_context_get_color (gtk_widget_get_style_context (widget), 0, &color);
  137.                 gdk_cairo_set_source_rgba (cr, &color);
  138.             cairo_fill (cr);*/
  139.         }
  140.     } else {
  141.         printf("rect_list->status = %d ", rect_list->status);
  142.     }
  143.     printf("\n");
  144.     cairo_rectangle_list_destroy(rect_list);
  145.     return FALSE;
  146. }
  147.  
  148. void init_signals() {
  149.     g_signal_connect (webkit_script_world_get_default (),
  150.                       "window-object-cleared",
  151.                       G_CALLBACK (window_object_cleared_callback),
  152.                       NULL);
  153.     g_signal_connect (web_view,
  154.                       "load-changed",
  155.                       G_CALLBACK (handle_load_change),
  156.                       NULL);
  157.  
  158.     g_signal_connect_after (window, "damage-event", G_CALLBACK(damage_event_handler), "window");
  159.     g_signal_connect_after (window, "draw", G_CALLBACK(draw_event_handler), "window");
  160.  
  161.     g_signal_connect_after (web_view, "damage-event", G_CALLBACK(damage_event_handler), "web_view");
  162.     g_signal_connect_after (web_view, "draw", G_CALLBACK(draw_event_handler), "web_view");
  163.  
  164. }
  165.  
  166. void load_web_process_extensions() {
  167.     printf("%s\n", __func__);
  168.      webkit_web_context_set_web_extensions_directory(webkit_web_context_get_default(),"./extension");
  169. }
  170.  
  171. static void
  172. web_view_javascript_finished (GObject      *object,
  173.                               GAsyncResult *result,
  174.                               gpointer      user_data)
  175. {
  176.     WebKitJavascriptResult *js_result;
  177.     JSValueRef              value;
  178.     JSGlobalContextRef      context;
  179.     GError                 *error = NULL;
  180.  
  181.     js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (object), result, &error);
  182.     if (!js_result) {
  183.         g_warning ("Error running javascript: %s", error->message);
  184.         g_error_free (error);
  185.         return;
  186.     }
  187.  
  188.     context = webkit_javascript_result_get_global_context (js_result);
  189.     value = webkit_javascript_result_get_value (js_result);
  190.     if (JSValueIsString (context, value)) {
  191.         JSStringRef js_str_value;
  192.         gchar      *str_value;
  193.         gsize       str_length;
  194.  
  195.         js_str_value = JSValueToStringCopy (context, value, NULL);
  196.         str_length = JSStringGetMaximumUTF8CStringSize (js_str_value);
  197.         str_value = (gchar *)g_malloc (str_length);
  198.         JSStringGetUTF8CString (js_str_value, str_value, str_length);
  199.         JSStringRelease (js_str_value);
  200.         g_print ("Script result: %s\n", str_value);
  201.         g_free (str_value);
  202.     } else {
  203.         g_warning ("Javascript: Non string return value");
  204.         JSStringRef js_str_value;
  205.         gchar      *str_value;
  206.         gsize       str_length;
  207.  
  208.         js_str_value = JSValueToStringCopy (context, value, NULL);
  209.         str_length = JSStringGetMaximumUTF8CStringSize (js_str_value);
  210.         str_value = (gchar *)g_malloc (str_length);
  211.         JSStringGetUTF8CString (js_str_value, str_value, str_length);
  212.         JSStringRelease (js_str_value);
  213.         g_print ("Script result: %s\n", str_value);
  214.         g_free (str_value);
  215.     }
  216.     webkit_javascript_result_unref (js_result);
  217. }
  218.  
  219.  
  220. void run_java_script(GtkWidget *web_view, gchar *js_script_text) {
  221.     GAsyncReadyCallback cCallback = web_view_javascript_finished;
  222.     gpointer userData = NULL;
  223.    
  224.     printf("%s: %s\n", __func__, js_script_text);
  225.     webkit_web_view_run_javascript(WEBKIT_WEB_VIEW(web_view), js_script_text, NULL, cCallback, userData);
  226. }
  227.  
  228. void click(GtkWidget *web_view, short x, short y) {
  229.     gchar* click_js = g_strdup_printf("document.elementFromPoint(%d, %d).click();", x, y);
  230.     run_java_script(web_view, click_js);
  231.     g_free(click_js);
  232. }
  233.  
  234. gboolean fake_click() {
  235.     printf("fake click\n");
  236.     click(web_view, 100, 100);
  237.     return TRUE;
  238. }
  239.  
  240. void real_click_button(GtkWidget *clck_button, gpointer data) {
  241.     int x = 0, y = 0;
  242.     const char *text = gtk_entry_get_text(GTK_ENTRY(data));
  243.     sscanf(text, "%d,%d", &x, &y);
  244.     printf("real_click %d, %d\n", x ,y);
  245.     click(web_view, x, y);
  246. }
  247.  
  248. void follow_uri_button(GtkWidget *uri_button, gpointer data) {
  249.     const char *uri = gtk_entry_get_text(GTK_ENTRY(data));
  250.     webkit_web_view_load_uri(WEBKIT_WEB_VIEW(web_view), uri);
  251. }
  252.  
  253. void javascript_button_execute(GtkWidget *js_button, gpointer data) {
  254.     gchar *js = (gchar*)gtk_entry_get_text(GTK_ENTRY(data));
  255.     run_java_script(web_view, js);
  256. }
  257.  
  258.  
  259.  
  260. void application_quit() {
  261.     printf("bye\n");
  262.     exit(0);
  263. }
  264. void make_controll_window() {
  265.       /*buttons*/
  266.       GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
  267.       GtkWidget *entry_click = gtk_entry_new();
  268.       GtkWidget *button_click = gtk_button_new_with_label("Generate click");
  269.       GtkWidget *entry_uri = gtk_entry_new();
  270.       GtkWidget *button_uri = gtk_button_new_with_label("Go");
  271.       GtkWidget *entry_js = gtk_entry_new();
  272.       GtkWidget *button_js = gtk_button_new_with_label("execute script");
  273.       controll_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  274.       g_signal_connect(G_OBJECT(controll_window), "destroy", G_CALLBACK(application_quit), NULL);
  275.       gtk_window_set_title(GTK_WINDOW(controll_window), "controlls");
  276.       //gtk_window_set_default_size(GTK_WINDOW(controll_window), 60, 60);
  277.       gtk_window_set_resizable(GTK_WINDOW(controll_window), FALSE);
  278.       gtk_window_set_position(GTK_WINDOW(controll_window), GTK_WIN_POS_CENTER);
  279.       g_signal_connect(G_OBJECT(button_click), "clicked", G_CALLBACK(real_click_button), entry_click);
  280.       g_signal_connect(G_OBJECT(button_uri), "clicked", G_CALLBACK(follow_uri_button), entry_uri);
  281.       g_signal_connect(G_OBJECT(button_js), "clicked", G_CALLBACK(javascript_button_execute), entry_js);
  282.  
  283.       gtk_box_pack_start(GTK_BOX(box), entry_click, FALSE, FALSE, 2);
  284.       gtk_box_pack_start(GTK_BOX(box), button_click, FALSE, FALSE, 2);
  285.       gtk_box_pack_start(GTK_BOX(box), entry_uri, FALSE, FALSE, 2);
  286.       gtk_box_pack_start(GTK_BOX(box), button_uri, FALSE, FALSE, 2);
  287.       gtk_box_pack_start(GTK_BOX(box), entry_js, FALSE, FALSE, 2);
  288.       gtk_box_pack_start(GTK_BOX(box), button_js, FALSE, FALSE, 2);
  289.       gtk_container_add(GTK_CONTAINER(controll_window), box);
  290.       gtk_widget_show_all(controll_window);
  291. }
  292.  
  293. int main(int argc, char **argv)
  294. {
  295.     //load_web_process_extensions();
  296.     gdk_threads_enter();
  297.     gtk_init(&argc, &argv);
  298.  
  299.      //GtkWidget *window = gtk_offscreen_window_new();
  300.      //https://developer.gnome.org/gtk2/2.24/GtkWindow.html#gtk-window-new
  301.      window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  302.      web_view = webkit_web_view_new();
  303.  
  304.      //do not duble buffer
  305.      gtk_widget_set_double_buffered(web_view, FALSE);
  306.  
  307.      g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(application_quit), NULL);
  308.      init_signals();
  309.      
  310.      gtk_window_set_title(GTK_WINDOW(window), "Test");
  311.       gtk_window_set_default_size(GTK_WINDOW(window), 600, 800);
  312.       gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
  313.       gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  314.  
  315.       //add web-view
  316.       gtk_container_add(GTK_CONTAINER(window), web_view);
  317.       gtk_widget_set_double_buffered(GTK_WIDGET(web_view), FALSE);
  318.  
  319.       gtk_widget_show_all(window);
  320.  
  321.        //settings are set. Load url.
  322.        webkit_web_view_load_uri(WEBKIT_WEB_VIEW(web_view), "http://wemar:8000/ui_new/113/menu");
  323.      
  324.        make_controll_window();
  325.        
  326.        
  327.        // fake click every 2 secs
  328.        //g_timeout_add(2000, fake_click, NULL);
  329.        //
  330.  
  331.     gtk_main();
  332.     gdk_threads_leave();
  333.     return 0;
  334. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement