Bumped package version to 0.2 to reflect build fix.
[profile/ivi/webskeleton.git] / webskeleton.c
1 /*
2  *  This native HTML container is derived from the EFL based MiniBrowser
3  *  source in the webkit tree.
4  * 
5  *  Copyright 2012 Samsung Electronics
6  *  Copyright 2012 Intel Corporation. All rights reserved.
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 #include <EWebKit2.h>
24 #include <Ecore.h>
25 #include <Ecore_Evas.h>
26 #include <Eina.h>
27 #include <Evas.h>
28 #include <getopt.h>
29
30 static const char DEFAULT_URL[] = "http://www.linuxfoundation.org/";
31 static const char APP_NAME[] = "WebSkeleton";
32 static int width = 800;
33 static int height = 600;
34 Eina_Bool fullscreen = EINA_FALSE;
35
36 #define info(format, args...)                   \
37     do {                                        \
38         if (verbose)                            \
39             printf(format, ##args);             \
40     } while (0)
41
42 static int verbose = 0;
43
44 typedef struct _Context {
45     Ecore_Evas *ee;
46     Evas *evas;
47     Evas_Object *bg;
48     Evas_Object *browser;
49 } Context;
50
51 static Eina_Bool main_signal_exit(void *data, int ev_type, void *ev)
52 {
53     ecore_main_loop_quit();
54     return EINA_TRUE;
55 }
56
57 static void on_ecore_evas_resize(Ecore_Evas *ee)
58 {
59     Evas_Object *webview;
60     Evas_Object *bg;
61     int w, h;
62
63     ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
64
65     bg = evas_object_name_find(ecore_evas_get(ee), "bg");
66     evas_object_move(bg, 0, 0);
67     evas_object_resize(bg, w, h);
68
69     webview = evas_object_name_find(ecore_evas_get(ee), "browser");
70     evas_object_move(webview, 0, 0);
71     evas_object_resize(webview, w, h);
72 }
73
74 static void
75 on_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
76 {
77     Evas_Event_Key_Down *ev = (Evas_Event_Key_Down*) event_info;
78     Context *app = (Context *)data;
79     const Evas_Modifier *modifier = evas_key_modifier_get(e);
80
81     if (!strcmp(ev->key, "Left") && evas_key_modifier_is_set(modifier, "Alt")) {
82         info("Alt-Left was pressed, moving back in history\n");
83         if (!ewk_view_back(obj))
84             info("Back ignored: No back history\n");
85     } else if (!strcmp(ev->key, "Right") &&
86                evas_key_modifier_is_set(modifier, "Alt")) {
87         info("Alt-Right was pressed, moving forward in history\n");
88         if (!ewk_view_forward(obj))
89             info("Forward ignored: No forward history\n");
90     } else if (!strcmp(ev->key, "r") && 
91                evas_key_modifier_is_set(modifier, "Control")) {
92         info("Control-r was pressed, reloading.\n");
93         ewk_view_reload(obj);
94     } else if (!strcmp(ev->key, "F6")) {
95         info("Stop (F6) was pressed, stop loading.\n");
96         ewk_view_stop(obj);
97     } else if (!strcmp(ev->key, "F11")) {
98         info("Fullscreen (F12) was pressed, toggling fullscreen view.\n");
99         fullscreen = !fullscreen;
100         ecore_evas_fullscreen_set(app->ee, fullscreen);
101     } else if (!strcmp(ev->key, "Escape")) {
102         info("Escape was pressed, exiting....\n");
103         exit(0);
104     }
105 }
106
107 static void
108 title_set(Ecore_Evas *ee, const char *title, int progress)
109 {
110     Eina_Strbuf* buffer;
111
112     if (!title || !*title) {
113         ecore_evas_title_set(ee, APP_NAME);
114         return;
115     }
116
117     buffer = eina_strbuf_new();
118     if (progress < 100)
119         eina_strbuf_append_printf(buffer, "%s (%d%%) - %s", title, progress, APP_NAME);
120     else
121         eina_strbuf_append_printf(buffer, "%s - %s", title, APP_NAME);
122
123     ecore_evas_title_set(ee, eina_strbuf_string_get(buffer));
124     eina_strbuf_free(buffer);
125 }
126
127 static void
128 on_title_changed(void *user_data, Evas_Object *webview, void *event_info)
129 {
130     Context *app = (Context *)user_data;
131     const char *title = (const char *)event_info;
132
133     title_set(app->ee, title, 100);
134 }
135
136 static void
137 on_progress(void *user_data, Evas_Object *webview, void *event_info)
138 {
139     Context *app = (Context *)user_data;
140     double progress = *(double *)event_info;
141
142     title_set(app->ee, ewk_view_title_get(app->browser), progress * 100);
143 }
144
145 static void
146 on_error(void *user_data, Evas_Object *webview, void *event_info)
147 {
148     Eina_Strbuf* buffer;
149     Ewk_Error *error = (Ewk_Error *)event_info;
150
151     buffer = eina_strbuf_new();
152     eina_strbuf_append_printf(buffer, "<html><body><div style=\"color:#ff0000\">ERROR!</div><br><div>Code: %d<br>Description: %s<br>URL: %s</div></body</html>",
153                               ewk_error_code_get(error), ewk_error_description_get(error), ewk_error_url_get(error));
154
155     ewk_view_html_contents_set(webview, eina_strbuf_string_get(buffer), 0);
156
157     eina_strbuf_free(buffer);
158 }
159
160 static Context *create_context(const char *url, Eina_Bool fullscreen)
161 {
162     Context *app = malloc(sizeof(Context));
163
164     app->ee = ecore_evas_new(0, 0, 0, width, height, 0);
165
166     ecore_evas_title_set(app->ee, APP_NAME);
167     ecore_evas_callback_resize_set(app->ee, on_ecore_evas_resize);
168     ecore_evas_borderless_set(app->ee, 0);
169     ecore_evas_fullscreen_set(app->ee, fullscreen);
170     ecore_evas_show(app->ee);
171
172     app->evas = ecore_evas_get(app->ee);
173
174     app->bg = evas_object_rectangle_add(app->evas);
175     evas_object_name_set(app->bg, "bg");
176     evas_object_size_hint_weight_set(app->bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
177
178     evas_object_move(app->bg, 0, 0);
179     evas_object_resize(app->bg, width, height);
180     evas_object_color_set(app->bg, 255, 150, 150, 255);
181     evas_object_show(app->bg);
182
183     /* Create webview */
184     app->browser = ewk_view_add(app->evas);
185     evas_object_name_set(app->browser, "browser");
186
187     evas_object_smart_callback_add(app->browser, "load,error", on_error, app);
188     evas_object_smart_callback_add(app->browser, "load,progress", on_progress, app);
189     evas_object_smart_callback_add(app->browser, "title,changed", on_title_changed, app);
190
191     evas_object_event_callback_add(app->browser, EVAS_CALLBACK_KEY_DOWN, on_key_down, app);
192
193     evas_object_size_hint_weight_set(app->browser, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
194     evas_object_resize(app->browser, width, height);
195     evas_object_show(app->browser);
196     evas_object_focus_set(app->browser, EINA_TRUE);
197
198     ewk_view_uri_set(app->browser, url);
199
200     return app;
201 }
202
203 int main(int argc, char *argv[])
204 {
205     const char *url = NULL;
206     int n = 0, valid_option_count = 0;
207     Eina_Bool fullscreen = EINA_FALSE;
208
209     if (!ecore_evas_init())
210         return EXIT_FAILURE;
211
212     static struct option options[] = {
213         { "help",       no_argument,       NULL, 'h' },
214         { "fullscreen", no_argument,       NULL, 'f' },
215         { "url",        required_argument, NULL, 'u' },
216         { "width",      required_argument, NULL, 'w' },
217         { "height",     required_argument, NULL, 'd' },
218         { NULL, 0, 0, 0 }
219     };
220
221     while (n >= 0) {
222         n = getopt_long(argc, argv, "hfu:w:d:", options, NULL);
223         if (n < 0)
224             continue;
225         switch (n) {
226         case 'u':
227             url = strdup(optarg);
228             break;
229         case 'w':
230             width = atoi(optarg);
231             break;
232         case 'd':
233             height = atoi(optarg);
234             break;
235         case 'f':
236             fullscreen = EINA_TRUE;
237             break;
238         case 'h':
239         default:
240             fprintf(stderr, "Usage: %s [--help] [--fullscreen] [--width=<w>] [--height=<d>] [URL]\n", argv[0]);
241             exit(-1);
242         }
243         valid_option_count++;
244     }
245     
246     if (!url) {
247         if (valid_option_count < argc - 1)
248             url = strdup(argv[argc - 1]);
249         else
250             url = DEFAULT_URL;
251     }
252
253     Context *browser = create_context(url, fullscreen);
254     Ecore_Event_Handler *handle = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, main_signal_exit, 0);
255
256     ecore_main_loop_begin();
257
258     ecore_event_handler_del(handle);
259     ecore_evas_free(browser->ee);
260     free(browser);
261
262     ecore_evas_shutdown();
263
264     return 0;
265 }
266
267 /* Local Variables:      */
268 /* mode:c                */
269 /* c-basic-offset:4      */
270 /* indent-tabs-mode: nil */
271 /* End:                  */