3c94fd1c875940f8f224dd51111914034447dbd4
[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     const Ewk_Web_Error *error = (const Ewk_Web_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_web_error_code_get(error), ewk_web_error_description_get(error), ewk_web_error_url_get(error));
154
155     ewk_view_html_string_load(webview, eina_strbuf_string_get(buffer), 0, ewk_web_error_url_get(error));
156     eina_strbuf_free(buffer);
157 }
158
159 static Context *create_context(const char *url, Eina_Bool fullscreen)
160 {
161     Context *app = malloc(sizeof(Context));
162
163     app->ee = ecore_evas_new(0, 0, 0, width, height, 0);
164
165     ecore_evas_title_set(app->ee, APP_NAME);
166     ecore_evas_callback_resize_set(app->ee, on_ecore_evas_resize);
167     ecore_evas_borderless_set(app->ee, 0);
168     ecore_evas_fullscreen_set(app->ee, fullscreen);
169     ecore_evas_show(app->ee);
170
171     app->evas = ecore_evas_get(app->ee);
172
173     app->bg = evas_object_rectangle_add(app->evas);
174     evas_object_name_set(app->bg, "bg");
175     evas_object_size_hint_weight_set(app->bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
176
177     evas_object_move(app->bg, 0, 0);
178     evas_object_resize(app->bg, width, height);
179     evas_object_color_set(app->bg, 255, 150, 150, 255);
180     evas_object_show(app->bg);
181
182     /* Create webview */
183     app->browser = ewk_view_add(app->evas);
184     evas_object_name_set(app->browser, "browser");
185
186     evas_object_smart_callback_add(app->browser, "load,error", on_error, app);
187     evas_object_smart_callback_add(app->browser, "load,progress", on_progress, app);
188     evas_object_smart_callback_add(app->browser, "title,changed", on_title_changed, app);
189
190     evas_object_event_callback_add(app->browser, EVAS_CALLBACK_KEY_DOWN, on_key_down, app);
191
192     evas_object_size_hint_weight_set(app->browser, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
193     evas_object_resize(app->browser, width, height);
194     evas_object_show(app->browser);
195     evas_object_focus_set(app->browser, EINA_TRUE);
196
197     ewk_view_uri_set(app->browser, url);
198
199     return app;
200 }
201
202 int main(int argc, char *argv[])
203 {
204     const char *url = NULL;
205     int n = 0, valid_option_count = 0;
206     Eina_Bool fullscreen = EINA_FALSE;
207
208     if (!ecore_evas_init())
209         return EXIT_FAILURE;
210
211     static struct option options[] = {
212         { "help",       no_argument,       NULL, 'h' },
213         { "fullscreen", no_argument,       NULL, 'f' },
214         { "url",        required_argument, NULL, 'u' },
215         { "width",      required_argument, NULL, 'w' },
216         { "height",     required_argument, NULL, 'd' },
217         { NULL, 0, 0, 0 }
218     };
219
220     while (n >= 0) {
221         n = getopt_long(argc, argv, "hfu:w:d:", options, NULL);
222         if (n < 0)
223             continue;
224         switch (n) {
225         case 'u':
226             url = strdup(optarg);
227             break;
228         case 'w':
229             width = atoi(optarg);
230             break;
231         case 'd':
232             height = atoi(optarg);
233             break;
234         case 'f':
235             fullscreen = EINA_TRUE;
236             break;
237         case 'h':
238         default:
239             fprintf(stderr, "Usage: %s [--help] [--fullscreen] [--width=<w>] [--height=<d>] [URL]\n", argv[0]);
240             exit(-1);
241         }
242         valid_option_count++;
243     }
244     
245     if (!url) {
246         if (valid_option_count < argc - 1)
247             url = strdup(argv[argc - 1]);
248         else
249             url = DEFAULT_URL;
250     }
251
252     Context *browser = create_context(url, fullscreen);
253     Ecore_Event_Handler *handle = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, main_signal_exit, 0);
254
255     ecore_main_loop_begin();
256
257     ecore_event_handler_del(handle);
258     ecore_evas_free(browser->ee);
259     free(browser);
260
261     ecore_evas_shutdown();
262
263     return 0;
264 }
265
266 /* Local Variables:      */
267 /* mode:c                */
268 /* c-basic-offset:4      */
269 /* indent-tabs-mode: nil */
270 /* End:                  */