diff options
author | Ben Murdoch <benm@google.com> | 2011-05-05 14:36:32 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-10 15:38:30 +0100 |
commit | f05b935882198ccf7d81675736e3aeb089c5113a (patch) | |
tree | 4ea0ca838d9ef1b15cf17ddb3928efb427c7e5a1 /Tools/EWebLauncher | |
parent | 60fbdcc62bced8db2cb1fd233cc4d1e4ea17db1b (diff) | |
download | external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.zip external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.tar.gz external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.tar.bz2 |
Merge WebKit at r74534: Initial merge by git.
Change-Id: I6ccd1154fa1b19c2ec2a66878eb675738735f1eb
Diffstat (limited to 'Tools/EWebLauncher')
-rw-r--r-- | Tools/EWebLauncher/main.c | 903 |
1 files changed, 903 insertions, 0 deletions
diff --git a/Tools/EWebLauncher/main.c b/Tools/EWebLauncher/main.c new file mode 100644 index 0000000..5f417d0 --- /dev/null +++ b/Tools/EWebLauncher/main.c @@ -0,0 +1,903 @@ +/* + * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia + * Copyright (C) 2009, 2010 ProFUSION embedded systems + * Copyright (C) 2009, 2010 Samsung Electronics + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "EWebKit.h" + +#include <ctype.h> +#include <Ecore.h> +#include <Ecore_Evas.h> +#include <Ecore_File.h> +#include <Ecore_Getopt.h> +#include <Ecore_X.h> +#include <Edje.h> +#include <Evas.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#define DEFAULT_WIDTH 800 +#define DEFAULT_HEIGHT 600 +#define DEFAULT_ZOOM_INIT 1.0 + +#define info(format, args...) \ + do { \ + if (verbose) \ + printf(format, ##args); \ + } while (0) + +#define MIN_ZOOM_LEVEL 0 +#define DEFAULT_ZOOM_LEVEL 5 +#define MAX_ZOOM_LEVEL 13 + +static int currentZoomLevel = DEFAULT_ZOOM_LEVEL; +static float currentZoom = 1.0; + +// the zoom values are chosen to be like in Mozilla Firefox 3 +static int zoomLevels[] = {30, 50, 67, 80, 90, + 100, + 110, 120, 133, 150, 170, 200, 240, 300}; + +static int verbose = 0; + +static Eina_List *windows = NULL; + +static char *themePath = NULL; + +static const char *backingStores[] = { + "tiled", + "single", + NULL +}; + +typedef struct _Window_Properties { + Eina_Bool toolbarsVisible:1; + Eina_Bool statusbarVisible:1; + Eina_Bool scrollbarsVisible:1; + Eina_Bool menubarVisible:1; +} Window_Properties; + +Window_Properties windowProperties = { /* Pretend we have them and they are initially visible */ + EINA_TRUE, + EINA_TRUE, + EINA_TRUE, + EINA_TRUE +}; + +static const Ecore_Getopt options = { + "EWebLauncher", + "%prog [options] [url]", + "0.0.1", + "(C)2008 INdT (The Nokia Technology Institute)\n" + "(C)2009, 2010 ProFUSION embedded systems\n" + "(C)2009, 2010 Samsung Electronics", + "GPL", + "Test Web Browser using the Enlightenment Foundation Libraries of WebKit", + EINA_TRUE, { + ECORE_GETOPT_STORE_STR + ('e', "engine", "ecore-evas engine to use."), + ECORE_GETOPT_CALLBACK_NOARGS + ('E', "list-engines", "list ecore-evas engines.", + ecore_getopt_callback_ecore_evas_list_engines, NULL), + ECORE_GETOPT_CHOICE + ('b', "backing-store", "choose backing store to use.", backingStores), + ECORE_GETOPT_STORE_DEF_BOOL + ('F', "fullscreen", "fullscreen mode.", 0), + ECORE_GETOPT_CALLBACK_ARGS + ('g', "geometry", "geometry to use in x:y:w:h form.", "X:Y:W:H", + ecore_getopt_callback_geometry_parse, NULL), + ECORE_GETOPT_STORE_STR + ('t', "theme", "path to read the theme file from."), + ECORE_GETOPT_STORE_STR + ('U', "user-agent", "custom user agent string to use."), + ECORE_GETOPT_STORE_DEF_BOOL + ('S', "sudo-workaround", "Workaround mode for making Flash work with sudo.", 0), + ECORE_GETOPT_COUNT + ('v', "verbose", "be more verbose."), + ECORE_GETOPT_VERSION + ('V', "version"), + ECORE_GETOPT_COPYRIGHT + ('R', "copyright"), + ECORE_GETOPT_LICENSE + ('L', "license"), + ECORE_GETOPT_HELP + ('h', "help"), + ECORE_GETOPT_SENTINEL + } +}; + +typedef struct _Viewport { + int w; + int h; + float initScale; + float minScale; + float maxScale; + float devicePixelRatio; + Eina_Bool userScalable; +} Viewport; + +typedef struct _ELauncher { + Ecore_Evas *ee; + Evas *evas; + Evas_Object *bg; + Evas_Object *browser; + const char *theme; + const char *userAgent; + const char *backingStore; + Viewport viewport; +} ELauncher; + +static void browserDestroy(Ecore_Evas *ee); +static void closeWindow(Ecore_Evas *ee); +static int browserCreate(const char *url, const char *theme, const char *userAgent, Eina_Rectangle geometry, const char *engine, const char *backingStore, unsigned char isFullscreen, const char *databasePath); + +static void +print_history(Eina_List *list) +{ + Eina_List *l; + void *d; + + if (!verbose) + return; + + printf("Session history contains:\n"); + + EINA_LIST_FOREACH(list, l, d) { + Ewk_History_Item *item = (Ewk_History_Item*)d; + cairo_surface_t *cs = ewk_history_item_icon_surface_get(item); + char buf[PATH_MAX]; + int s = snprintf(buf, sizeof(buf), "/tmp/favicon-%s.png", ewk_history_item_uri_original_get(item)); + for (s--; s >= (int)sizeof("/tmp/favicon-"); s--) { + if (!isalnum(buf[s]) && buf[s] != '.') + buf[s] = '_'; + } + cs = ewk_history_item_icon_surface_get(item); + + if (cs && cairo_surface_status(cs) == CAIRO_STATUS_SUCCESS) + cairo_surface_write_to_png(cs, buf); + else + buf[0] = '\0'; + + printf("* '%s' title='%s' icon='%s'\n", + ewk_history_item_uri_original_get(item), + ewk_history_item_title_get(item), buf); + } +} + +static int +nearest_zoom_level_get(float factor) +{ + int i, intFactor = (int)(factor * 100.0); + for (i = 0; zoomLevels[i] <= intFactor; i++) { } + printf("factor=%f, intFactor=%d, zoomLevels[%d]=%d, zoomLevels[%d]=%d\n", + factor, intFactor, i-1, zoomLevels[i-1], i, zoomLevels[i]); + if (intFactor - zoomLevels[i-1] < zoomLevels[i] - intFactor) + return i - 1; + return i; +} + +static Eina_Bool +zoom_level_set(Evas_Object *webview, int level) +{ + float factor = ((float) zoomLevels[level]) / 100.0; + Evas_Coord ox, oy, mx, my, cx, cy; + evas_pointer_canvas_xy_get(evas_object_evas_get(webview), &mx, &my); + evas_object_geometry_get(webview, &ox, &oy, NULL, NULL); + cx = mx - ox; + cy = my - oy; + return ewk_view_zoom_animated_set(webview, factor, 0.5, cx, cy); +} + +static void +on_ecore_evas_resize(Ecore_Evas *ee) +{ + Evas_Object *webview; + Evas_Object *bg; + int w, h; + + ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); + + bg = evas_object_name_find(ecore_evas_get(ee), "bg"); + evas_object_move(bg, 0, 0); + evas_object_resize(bg, w, h); + + webview = evas_object_name_find(ecore_evas_get(ee), "browser"); + evas_object_move(webview, 10, 10); + evas_object_resize(webview, w - 20, h - 20); +} + +static void +title_set(Ecore_Evas *ee, const char *title, int progress) +{ + const char *appname = "EFL Test Launcher"; + const char *separator = " - "; + char label[4096]; + int size; + + if (!title || !strcmp(title, "")) { + ecore_evas_title_set(ee, appname); + return; + } + + if (progress < 100) + size = snprintf(label, sizeof(label), "%s (%d%%)%s%s", title, progress, separator, appname); + else + size = snprintf(label, sizeof(label), "%s %s%s", title, separator, appname); + + if (size >= (int)sizeof(label)) + return; + + ecore_evas_title_set(ee, label); +} + +/** + * This is en example function to adjust viewport via viewport tag's arguments. + * Application can invoke this function in order to adjust viewport tag when it is required. + */ +static void +viewport_set() +{ + ELauncher *app; + app = (ELauncher*) eina_list_data_get(windows); + + ewk_view_fixed_layout_size_set(app->browser, app->viewport.w, app->viewport.h); + ewk_view_zoom_set(app->browser, app->viewport.initScale, 0, 0); + if (!ewk_view_zoom_range_set(app->browser, app->viewport.minScale, app->viewport.maxScale)) + info(" Fail to set zoom range. minScale = %f, maxScale = %f\n", app->viewport.minScale, app->viewport.maxScale); + ewk_view_user_scalable_set(app->browser, app->viewport.userScalable); +} + +static void +on_title_changed(void *user_data, Evas_Object *webview, void *event_info) +{ + ELauncher *app = (ELauncher *)user_data; + const char *title = (const char *)event_info; + + title_set(app->ee, title, 100); +} + +static void +on_progress(void *user_data, Evas_Object *webview, void *event_info) +{ + ELauncher *app = (ELauncher *)user_data; + double *progress = (double *)event_info; + + title_set(app->ee, ewk_view_title_get(app->browser), *progress * 100); +} + +static void +on_load_finished(void *user_data, Evas_Object *webview, void *event_info) +{ + const Ewk_Frame_Load_Error *err = (const Ewk_Frame_Load_Error *)event_info; + + if (!err) + info("Succeeded loading page.\n"); + else if (err->is_cancellation) + info("Load was cancelled.\n"); + else + info("Failed loading page: %d %s \"%s\", url=%s\n", + err->code, err->domain, err->description, err->failing_url); + + currentZoom = ewk_view_zoom_get(webview); + currentZoomLevel = nearest_zoom_level_get(currentZoom); + info("WebCore Zoom=%f, currentZoomLevel=%d\n", currentZoom, currentZoomLevel); +} + +static void +on_toolbars_visible_set(void* user_data, Evas_Object* webview, void* event_info) +{ + Eina_Bool *visible = (Eina_Bool *)event_info; + if (*visible) { + info("Toolbars visible changed: show"); + windowProperties.toolbarsVisible = EINA_TRUE; + } else { + info("Toolbars visible changed: hide"); + windowProperties.toolbarsVisible = EINA_FALSE; + } +} + +static void +on_toolbars_visible_get(void* user_data, Evas_Object* webview, void* event_info) +{ + Eina_Bool *visible = (Eina_Bool *)event_info; + *visible = windowProperties.toolbarsVisible; +} + +static void +on_statusbar_visible_set(void* user_data, Evas_Object* webview, void* event_info) +{ + Eina_Bool *visible = (Eina_Bool *)event_info; + if (*visible) { + info("Statusbar visible changed: show"); + windowProperties.statusbarVisible = EINA_TRUE; + } else { + info("Statusbar visible changed: hide"); + windowProperties.statusbarVisible = EINA_FALSE; + } +} + +static void +on_statusbar_visible_get(void* user_data, Evas_Object* webview, void* event_info) +{ + Eina_Bool *visible = (Eina_Bool *)event_info; + *visible = windowProperties.statusbarVisible; +} + +static void +on_scrollbars_visible_set(void* user_data, Evas_Object* webview, void* event_info) +{ + Eina_Bool *visible = (Eina_Bool *)event_info; + if (*visible) { + info("Scrollbars visible changed: show"); + windowProperties.scrollbarsVisible = EINA_TRUE; + } else { + info("Scrollbars visible changed: hide"); + windowProperties.scrollbarsVisible = EINA_FALSE; + } +} + +static void +on_scrollbars_visible_get(void* user_data, Evas_Object* webview, void* event_info) +{ + Eina_Bool *visible = (Eina_Bool *)event_info; + *visible = windowProperties.scrollbarsVisible; +} + +static void +on_menubar_visible_set(void* user_data, Evas_Object* webview, void* event_info) +{ + Eina_Bool *visible = (Eina_Bool *)event_info; + if (*visible) { + info("Menubar visible changed: show"); + windowProperties.menubarVisible = EINA_TRUE; + } else { + info("Menubar visible changed: hide"); + windowProperties.menubarVisible = EINA_FALSE; + } +} + +static void +on_menubar_visible_get(void* user_data, Evas_Object* webview, void* event_info) +{ + Eina_Bool *visible = (Eina_Bool *)event_info; + *visible = windowProperties.menubarVisible; +} + +static void +on_tooltip_text_set(void* user_data, Evas_Object* webview, void* event_info) +{ + const char *text = (const char *)event_info; + if (text && *text != '\0') + info("%s\n", text); +} + +static void +on_inputmethod_changed(void* user_data, Evas_Object* webview, void* event_info) +{ + Eina_Bool active = (Eina_Bool)(long)event_info; + unsigned int imh; + info("Keyboard changed: %d\n", active); + + if (!active) + return; + + imh = ewk_view_imh_get(webview); + info(" Keyboard flags: %#.2x\n", imh); + +} + +/** + * "viewport,changed" signal will be always emitted regardless of the viewport existence. + * + * If you don't want to process the viewport tag, you can either do nothing in this callback + * or simply ignore the signal in your application. + * + * More information about this can be found at http://developer.apple.com/safari/library/docum + * entation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html + */ +static void +on_viewport_changed(void* user_data, Evas_Object* webview, void* event_info) +{ + ELauncher *app = (ELauncher *)user_data; + + float w, h, initScale, minScale, maxScale, devicePixelRatio; + Eina_Bool userScalable; + + ewk_view_viewport_attributes_get(webview, &w, &h, &initScale, &maxScale, &minScale, &devicePixelRatio, &userScalable); + + /** + * If there is no argument in viewport tag, argument's value is -1. + */ + if ((int)w == -1) + w = DEFAULT_WIDTH; + if ((int)h == -1) + h = DEFAULT_HEIGHT; + if ((int)initScale == -1) + initScale = DEFAULT_ZOOM_INIT; // There's no scale separated from zooming in webkit-efl. + if ((int)minScale == -1) + minScale = ewk_view_zoom_range_min_get(webview); + if ((int)maxScale == -1) + maxScale = ewk_view_zoom_range_max_get(webview); + if ((int)devicePixelRatio == -1) + devicePixelRatio = ewk_view_device_pixel_ratio_get(webview); + if ((int)userScalable == -1) + userScalable = EINA_TRUE; + + app->viewport.w = (int)w; + app->viewport.h = (int)h; + app->viewport.initScale = initScale; + app->viewport.minScale = minScale; + app->viewport.maxScale = maxScale; + app->viewport.devicePixelRatio = devicePixelRatio; + app->viewport.userScalable = userScalable; + viewport_set(); +} + +static void +on_mouse_down(void* data, Evas* e, Evas_Object* webview, void* event_info) +{ + Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down*) event_info; + if (ev->button == 2) + evas_object_focus_set(webview, !evas_object_focus_get(webview)); +} + +static void +on_focus_out(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + info("the webview lost keyboard focus\n"); +} + +static void +on_focus_in(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + info("the webview gained keyboard focus\n"); +} + +static void +on_resized(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Coord w, h; + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + ewk_view_fixed_layout_size_set(obj, w, h); +} + +static void +on_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Key_Down *ev = (Evas_Event_Key_Down*) event_info; + ELauncher *app = data; + static const char *encodings[] = { + "ISO-8859-1", + "UTF-8", + NULL + }; + static int currentEncoding = -1; + + if (!strcmp(ev->key, "Escape")) { + closeWindow(app->ee); + } else if (!strcmp(ev->key, "F1")) { + info("Back (F1) was pressed\n"); + if (ewk_view_back_possible(obj)) { + Ewk_History *history = ewk_view_history_get(obj); + Eina_List *list = ewk_history_back_list_get(history); + print_history(list); + ewk_history_item_list_free(list); + ewk_view_back(obj); + } else + info("Back ignored: No back history\n"); + } else if (!strcmp(ev->key, "F2")) { + info("Forward (F2) was pressed\n"); + if (ewk_view_forward_possible(obj)) { + Ewk_History *history = ewk_view_history_get(obj); + Eina_List *list = ewk_history_forward_list_get(history); + print_history(list); + ewk_history_item_list_free(list); + ewk_view_forward(obj); + } else + info("Forward ignored: No forward history\n"); + } else if (!strcmp(ev->key, "F3")) { + currentEncoding++; + currentEncoding %= (sizeof(encodings) / sizeof(encodings[0])); + info("Set encoding (F3) pressed. New encoding to %s", encodings[currentEncoding]); + ewk_view_setting_encoding_custom_set(obj, encodings[currentEncoding]); + } else if (!strcmp(ev->key, "F4")) { + Evas_Object *frame = ewk_view_frame_main_get(obj); + Evas_Coord x, y; + Ewk_Hit_Test *ht; + + evas_pointer_canvas_xy_get(evas_object_evas_get(obj), &x, &y); + ht = ewk_frame_hit_test_new(frame, x, y); + if (!ht) + printf("No hit test returned for point %d,%d\n", x, y); + else { + printf("Hit test for point %d,%d\n" + " pos=%3d,%3d\n" + " bounding_box=%d,%d + %dx%d\n" + " title='%s'\n" + " alternate_text='%s'\n" + " frame=%p (%s)\n" + " link {\n" + " text='%s'\n" + " url='%s'\n" + " title='%s'\n" + " target frame=%p (%s)\n" + " }\n" + " flags {\n" + " editable=%hhu\n" + " selected=%hhu\n" + " }\n", + x, y, + ht->x, ht->y, + ht->bounding_box.x, ht->bounding_box.y, ht->bounding_box.w, ht->bounding_box.h, + ht->title, + ht->alternate_text, + ht->frame, evas_object_name_get(ht->frame), + ht->link.text, + ht->link.url, + ht->link.title, + ht->link.target_frame, evas_object_name_get(ht->link.target_frame), + ht->flags.editable, + ht->flags.selected); + ewk_frame_hit_test_free(ht); + } + + } else if (!strcmp(ev->key, "F5")) { + info("Reload (F5) was pressed, reloading.\n"); + ewk_view_reload(obj); + } else if (!strcmp(ev->key, "F6")) { + info("Stop (F6) was pressed, stop loading.\n"); + ewk_view_stop(obj); + /* } FIXME: uncomment code below after Bug 18662 lands upstream. + else if (!strcmp(ev->key, "F12")) { + bool status = ewk_webframe_object_keyboard_navigation_get(page); + ewk_webframe_object_keyboard_navigation_set(page, !status); + info("Command::keyboard navigation toggle\n");*/ + } else if (!strcmp(ev->key, "F7")) { + info("Zoom out (F7) was pressed.\n"); + if (currentZoomLevel > MIN_ZOOM_LEVEL && zoom_level_set(obj, currentZoomLevel - 1)) + currentZoomLevel--; + } else if (!strcmp(ev->key, "F8")) { + info("Zoom in (F8) was pressed.\n"); + if (currentZoomLevel < MAX_ZOOM_LEVEL && zoom_level_set(obj, currentZoomLevel + 1)) + currentZoomLevel++; + } else if (!strcmp(ev->key, "F9")) { + info("Create new window (F9) was pressed.\n"); + Eina_Rectangle geometry = {0, 0, 0, 0}; + browserCreate("http://www.google.com", + app->theme, app->userAgent, geometry, app-> backingStore, + NULL, 0, NULL); + } else if (!strcmp(ev->key, "F10")) { + Evas_Coord x, y, w, h; + Evas_Object *frame = ewk_view_frame_main_get(obj); + float zoom = zoomLevels[currentZoomLevel] / 100.0; + + ewk_frame_visible_content_geometry_get(frame, EINA_FALSE, &x, &y, &w, &h); + x -= w; + y -= h; + w *= 4; + h *= 4; + info("Pre-render %d,%d + %dx%d\n", x, y, w, h); + ewk_view_pre_render_region(obj, x, y, w, h, zoom); + } else if (!strcmp(ev->key, "F11")) { + info("Pre-render 1 extra column/row with current zoom"); + ewk_view_pre_render_relative_radius(obj, 1); + } else if (!strcmp(ev->key, "d")) { + info("Render suspended"); + ewk_view_disable_render(obj); + } else if (!strcmp(ev->key, "e")) { + info("Render resumed"); + ewk_view_enable_render(obj); + } +} + +static void +on_browser_del(void *data, Evas *evas, Evas_Object *browser, void *event) +{ + ELauncher *app = (ELauncher*) data; + + evas_object_event_callback_del(app->browser, EVAS_CALLBACK_KEY_DOWN, on_key_down); + evas_object_event_callback_del(app->browser, EVAS_CALLBACK_MOUSE_DOWN, on_mouse_down); + evas_object_event_callback_del(app->browser, EVAS_CALLBACK_FOCUS_IN, on_focus_in); + evas_object_event_callback_del(app->browser, EVAS_CALLBACK_FOCUS_OUT, on_focus_out); + evas_object_event_callback_del(app->browser, EVAS_CALLBACK_DEL, on_browser_del); +} + +static void +on_closeWindow(Ecore_Evas *ee) +{ + browserDestroy(ee); +} + +static int +quit(Eina_Bool success, const char *msg) +{ + edje_shutdown(); + ecore_evas_shutdown(); + + if (msg) + fputs(msg, (success) ? stdout : stderr); + + if (themePath) { + free(themePath); + themePath = NULL; + } + + if (!success) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} + +static int +browserCreate(const char *url, const char *theme, const char *userAgent, Eina_Rectangle geometry, const char *engine, const char *backingStore, unsigned char isFullscreen, const char *databasePath) +{ + if ((geometry.w <= 0) && (geometry.h <= 0)) { + geometry.w = DEFAULT_WIDTH; + geometry.h = DEFAULT_HEIGHT; + } + + ELauncher *app = (ELauncher*) malloc(sizeof(ELauncher)); + if (!app) + return quit(EINA_FALSE, "ERROR: could not create EWebLauncher window\n"); + + app->ee = ecore_evas_new(engine, 0, 0, geometry.w, geometry.h, NULL); + + if (!app->ee) + return quit(EINA_FALSE, "ERROR: could not construct evas-ecore\n"); + + if (isFullscreen) + ecore_evas_fullscreen_set(app->ee, EINA_TRUE); + + ecore_evas_title_set(app->ee, "EFL Test Launcher"); + ecore_evas_callback_resize_set(app->ee, on_ecore_evas_resize); + ecore_evas_callback_delete_request_set(app->ee, closeWindow); + + app->evas = ecore_evas_get(app->ee); + + if (!app->evas) + return quit(EINA_FALSE, "ERROR: could not get evas from evas-ecore\n"); + + app->theme = theme; + app->userAgent = userAgent; + app->backingStore = backingStore; + + app->bg = evas_object_rectangle_add(app->evas); + evas_object_name_set(app->bg, "bg"); + evas_object_color_set(app->bg, 255, 0, 255, 255); + evas_object_move(app->bg, 0, 0); + evas_object_resize(app->bg, geometry.w, geometry.h); + evas_object_layer_set(app->bg, EVAS_LAYER_MIN); + evas_object_show(app->bg); + + if (backingStore && !strcasecmp(backingStore, "single")) { + app->browser = ewk_view_single_add(app->evas); + info("backing store: single\n"); + } else { + app->browser = ewk_view_tiled_add(app->evas); + info("backing store: tiled\n"); + } + ewk_view_theme_set(app->browser, theme); + if (userAgent) + ewk_view_setting_user_agent_set(app->browser, userAgent); + ewk_view_setting_local_storage_database_path_set(app->browser, databasePath); + + evas_object_name_set(app->browser, "browser"); + + evas_object_smart_callback_add(app->browser, "title,changed", on_title_changed, app); + evas_object_smart_callback_add(app->browser, "load,progress", on_progress, app); + evas_object_smart_callback_add(app->browser, "load,finished", on_load_finished, app); + evas_object_smart_callback_add(app->browser, "viewport,changed", on_viewport_changed, app); + + evas_object_smart_callback_add(app->browser, "toolbars,visible,set", on_toolbars_visible_set, app); + evas_object_smart_callback_add(app->browser, "toolbars,visible,get", on_toolbars_visible_get, app); + evas_object_smart_callback_add(app->browser, "statusbar,visible,set", on_statusbar_visible_set, app); + evas_object_smart_callback_add(app->browser, "statusbar,visible,get", on_statusbar_visible_get, app); + evas_object_smart_callback_add(app->browser, "scrollbars,visible,set", on_scrollbars_visible_set, app); + evas_object_smart_callback_add(app->browser, "scrollbars,visible,get", on_scrollbars_visible_get, app); + evas_object_smart_callback_add(app->browser, "menubar,visible,set", on_menubar_visible_set, app); + evas_object_smart_callback_add(app->browser, "menubar,visible,get", on_menubar_visible_get, app); + evas_object_smart_callback_add(app->browser, "tooltip,text,set", on_tooltip_text_set, app); + evas_object_smart_callback_add(app->browser, "inputmethod,changed", on_inputmethod_changed, app); + +/* ewk_callback_resize_requested_add(app->browser, on_resize_requested, app->ee); */ + + evas_object_event_callback_add(app->browser, EVAS_CALLBACK_RESIZE, on_resized, app); + evas_object_event_callback_add(app->browser, EVAS_CALLBACK_KEY_DOWN, on_key_down, app); + evas_object_event_callback_add(app->browser, EVAS_CALLBACK_MOUSE_DOWN, on_mouse_down, app); + evas_object_event_callback_add(app->browser, EVAS_CALLBACK_FOCUS_IN, on_focus_in, app); + evas_object_event_callback_add(app->browser, EVAS_CALLBACK_FOCUS_OUT, on_focus_out, app); + evas_object_event_callback_add(app->browser, EVAS_CALLBACK_DEL, on_browser_del, app); + + evas_object_move(app->browser, 10, 10); + evas_object_resize(app->browser, geometry.w - 20, geometry.h - 20); + + if (url && (url[0] != '\0')) + ewk_view_uri_set(app->browser, url); + + evas_object_show(app->browser); + ecore_evas_show(app->ee); + + evas_object_focus_set(app->browser, EINA_TRUE); + + windows = eina_list_append(windows, app); + + return 1; +} + +static void +browserDestroy(Ecore_Evas *ee) +{ + ecore_evas_free(ee); + if (!eina_list_count(windows)) + ecore_main_loop_quit(); +} + +static void +closeWindow(Ecore_Evas *ee) +{ + Eina_List *l; + void *app; + EINA_LIST_FOREACH(windows, l, app) + { + if (((ELauncher*) app)->ee == ee) + break; + } + windows = eina_list_remove(windows, app); + browserDestroy(ee); + free(app); +} + +static Eina_Bool +main_signal_exit(void *data, int ev_type, void *ev) +{ + ELauncher *app; + while (windows) { + app = (ELauncher*) eina_list_data_get(windows); + ecore_evas_free(app->ee); + windows = eina_list_remove(windows, app); + } + if (!eina_list_count(windows)) + ecore_main_loop_quit(); + return EINA_TRUE; +} + +static char * +findThemePath(const char *theme) +{ + const char *defaultTheme = DATA_DIR"/default.edj"; + char *rpath; + struct stat st; + + if (!theme) + theme = defaultTheme; + + rpath = realpath(theme, NULL); + if (!rpath) + return NULL; + + if (stat(rpath, &st)) { + free(rpath); + return NULL; + } + + return rpath; +} + +int +main(int argc, char *argv[]) +{ + const char *default_url = "http://www.google.com/"; + + Eina_Rectangle geometry = {0, 0, 0, 0}; + char *url = NULL; + char *userAgent = NULL; + const char *tmp; + const char *proxyUri; + char path[PATH_MAX]; + + char *engine = NULL; + char *theme = NULL; + char *backingStore = (char *)backingStores[0]; + + unsigned char quitOption = 0; + unsigned char isFullscreen = 0; + unsigned char sudoWorkaround = 0; + int args; + + Ecore_Getopt_Value values[] = { + ECORE_GETOPT_VALUE_STR(engine), + ECORE_GETOPT_VALUE_BOOL(quitOption), + ECORE_GETOPT_VALUE_STR(backingStore), + ECORE_GETOPT_VALUE_BOOL(isFullscreen), + ECORE_GETOPT_VALUE_PTR_CAST(geometry), + ECORE_GETOPT_VALUE_STR(theme), + ECORE_GETOPT_VALUE_STR(userAgent), + ECORE_GETOPT_VALUE_BOOL(sudoWorkaround), + ECORE_GETOPT_VALUE_INT(verbose), + ECORE_GETOPT_VALUE_BOOL(quitOption), + ECORE_GETOPT_VALUE_BOOL(quitOption), + ECORE_GETOPT_VALUE_BOOL(quitOption), + ECORE_GETOPT_VALUE_BOOL(quitOption), + ECORE_GETOPT_VALUE_NONE + }; + + if (!ecore_evas_init()) + return EXIT_FAILURE; + + if (!edje_init()) { + ecore_evas_shutdown(); + return EXIT_FAILURE; + } + + ecore_app_args_set(argc, (const char**) argv); + args = ecore_getopt_parse(&options, values, argc, argv); + + if (args < 0) + return quit(EINA_FALSE, "ERROR: could not parse options.\n"); + + if (quitOption) + return quit(EINA_TRUE, NULL); + + if (args < argc) + url = argv[args]; + else + url = (char*) default_url; + + if (sudoWorkaround) + strcat(getenv("HOME"), "blah"); + + themePath = findThemePath(theme); + if (!themePath) + return quit(EINA_FALSE, "ERROR: could not find theme.\n"); + + ewk_init(); + tmp = getenv("TMPDIR"); + if (!tmp) + tmp = "/tmp"; + snprintf(path, sizeof(path), "%s/.ewebkit-%u", tmp, getuid()); + ecore_file_mkpath(path); + ewk_settings_icon_database_path_set(path); + ewk_settings_web_database_path_set(path); + + proxyUri = getenv("http_proxy"); + if (proxyUri) + ewk_settings_proxy_uri_set(proxyUri); + + browserCreate(url, themePath, userAgent, geometry, engine, backingStore, isFullscreen, path); + ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, main_signal_exit, &windows); + + ecore_main_loop_begin(); + + ewk_shutdown(); + + return quit(EINA_TRUE, NULL); +} |