tazweb view src/main.c @ rev 64

Clean-up main() and rename draw_loader since it's standard functions not a callback
author Christophe Lincoln <pankso@slitaz.org>
date Fri Apr 22 08:57:59 2011 +0200 (2011-04-22)
parents 8389defee9b9
children 0b5ed969f4f2
line source
1 /*
2 * TazWeb is a radically simple web browser providing a single window
3 * with a single toolbar with buttons, an URL entry and search as well
4 * as a contextual menu, but no menu bar or tabs.
5 *
6 * Copyright (C) 2011 SliTaz GNU/Linux - BSD License
7 * See AUTHORS and LICENSE for detailed information
8 *
9 */
11 #include <gtk/gtk.h>
12 #include <webkit/webkit.h>
14 #define CONFIG g_strdup_printf ("%s/.config/tazweb", g_get_home_dir ())
16 /* Loader color - #d66018 #7b705c */
17 static gchar *loader_color = "#351a0a";
19 static GtkWidget *main_window, *scrolled, *loader, *toolbar;
20 static GtkWidget *uri_entry, *search_entry;
21 static WebKitWebView* web_view;
22 static WebKitWebFrame* frame;
23 static gdouble load_progress;
24 static guint status_context_id;
25 static gchar* main_title;
26 static gchar *title;
27 static gint progress;
28 const gchar* uri;
30 /* Create an icon */
31 static GdkPixbuf*
32 create_pixbuf (const gchar * image)
33 {
34 GdkPixbuf *pixbuf;
35 pixbuf = gdk_pixbuf_new_from_file (image, NULL);
36 return pixbuf;
37 }
39 /* Loader area */
40 static void
41 draw_loader ()
42 {
43 GdkGC *gc = gdk_gc_new (loader->window);
44 GdkColor fg;
46 uri = webkit_web_view_get_uri (web_view);
47 const gint width = progress * loader->allocation.width / 100;
49 gdk_color_parse (loader_color, &fg);
50 gdk_gc_set_rgb_fg_color (gc, &fg);
51 gdk_draw_rectangle (loader->window,
52 loader->style->bg_gc [GTK_WIDGET_STATE (loader)],
53 TRUE, 0, 0, loader->allocation.width, loader->allocation.height);
54 gdk_draw_rectangle (loader->window, gc, TRUE, 0, 0, width,
55 loader->allocation.height);
56 g_object_unref (gc);
57 }
59 /* Loader progress */
60 static gboolean
61 expose_loader_cb (GtkWidget *area, GdkEventExpose *event, gpointer data)
62 {
63 draw_loader();
64 return TRUE;
65 }
67 /* Update title and loader */
68 static void
69 update ()
70 {
71 title = g_strdup (main_title);
72 if (! main_title)
73 title = g_strdup_printf ("Unknow - TazWeb", main_title);
74 draw_loader ();
75 gtk_window_set_title (GTK_WINDOW (main_window), title);
76 g_free (title);
77 }
79 /* Get the page title */
80 static void
81 notify_title_cb (WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
82 {
83 main_title = g_strdup (webkit_web_view_get_title (web_view));
84 update ();
85 }
87 /* Request progress in window title */
88 static void
89 notify_progress_cb (WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
90 {
91 progress = webkit_web_view_get_progress (web_view) * 100;
92 update ();
93 }
95 /* Notify loader and url entry */
96 static void
97 notify_load_status_cb (WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
98 {
99 switch (webkit_web_view_get_load_status (web_view))
100 {
101 case WEBKIT_LOAD_COMMITTED:
102 break;
103 case WEBKIT_LOAD_FINISHED:
104 progress = 0;
105 update ();
106 break;
107 }
108 frame = webkit_web_view_get_main_frame (web_view);
109 uri = webkit_web_frame_get_uri (frame);
110 if (uri)
111 gtk_entry_set_text (GTK_ENTRY (uri_entry), uri);
112 }
114 static void
115 destroy_cb (GtkWidget* widget, gpointer data)
116 {
117 gtk_main_quit ();
118 }
120 /* Show page source */
121 static void
122 view_source_cb ()
123 {
124 gboolean source;
126 frame = webkit_web_view_get_main_frame (web_view);
127 uri = webkit_web_frame_get_uri (frame);
128 source = webkit_web_view_get_view_source_mode (web_view);
130 webkit_web_view_set_view_source_mode(web_view, !source);
131 webkit_web_view_load_uri (web_view, uri);
132 }
134 /* URL entry callback function */
135 static void
136 uri_entry_cb (GtkWidget* entry, gpointer data)
137 {
138 uri = gtk_entry_get_text (GTK_ENTRY (entry));
139 g_assert (uri);
140 webkit_web_view_load_uri (web_view, uri);
141 }
143 /* Search entry callback function */
144 static void
145 search_entry_cb (GtkWidget* entry, gpointer data)
146 {
147 uri = g_strdup_printf ("http://www.google.com/search?q=%s",
148 gtk_entry_get_text (GTK_ENTRY (entry)));
149 g_assert (uri);
150 webkit_web_view_load_uri (web_view, uri);
151 }
153 /* Home button callback function */
154 static void
155 go_home_cb (GtkWidget* widget, gpointer data)
156 {
157 uri = g_strdup_printf ("file://%s/home.html", CONFIG);
158 g_assert (uri);
159 webkit_web_view_load_uri (web_view, uri);
160 }
162 /* Fullscreen and unfullscreen callback function */
163 static void
164 fullscreen_cb (GtkWindow* window, gpointer data)
165 {
166 GdkWindowState state;
167 state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (main_window)));
169 if (state & GDK_WINDOW_STATE_FULLSCREEN)
170 gtk_window_unfullscreen (GTK_WINDOW (main_window));
171 else
172 gtk_window_fullscreen (GTK_WINDOW (main_window));
173 }
175 /* TazWeb doc callback function */
176 static void
177 tazweb_doc_cb (GtkWidget* widget, gpointer data)
178 {
179 uri = ("file:///usr/share/doc/tazweb/tazweb.html");
180 g_assert (uri);
181 webkit_web_view_load_uri (web_view, uri);
182 }
184 /* Download function */
185 static gboolean
186 download_requested_cb (WebKitWebView *web_view, WebKitDownload *download,
187 gpointer user_data)
188 {
189 uri = webkit_download_get_uri (download);
190 const gchar *buffer;
191 asprintf (&buffer, "tazbox dl-out %s", uri);
192 system (buffer);
193 }
195 /* Zoom ou and in callback function */
196 static void
197 zoom_out_cb (GtkWidget *main_window)
198 {
199 webkit_web_view_zoom_out (web_view);
200 }
202 static void
203 zoom_in_cb (GtkWidget *main_window)
204 {
205 webkit_web_view_zoom_in (web_view);
206 }
208 /* Add items to WebKit contextual menu */
209 static void
210 populate_menu_cb (WebKitWebView *web_view, GtkMenu *menu, gpointer data)
211 {
212 GtkWidget *item;
214 /* separator */
215 item = gtk_separator_menu_item_new ();
216 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
218 /* Zoom in */
219 item = gtk_image_menu_item_new_with_label ("Zoom in");
220 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
221 gtk_image_new_from_stock (GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_MENU));
222 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
223 g_signal_connect (item, "activate", G_CALLBACK (zoom_in_cb), NULL);
225 /* Zoom out */
226 item = gtk_image_menu_item_new_with_label ("Zoom out");
227 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
228 gtk_image_new_from_stock (GTK_STOCK_ZOOM_OUT, GTK_ICON_SIZE_MENU));
229 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
230 g_signal_connect (item, "activate", G_CALLBACK (zoom_out_cb), NULL);
232 /* separator */
233 item = gtk_separator_menu_item_new ();
234 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
236 /* TazWeb documentation */
237 item = gtk_image_menu_item_new_with_label ("TazWeb manual");
238 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
239 gtk_image_new_from_stock (GTK_STOCK_INFO, GTK_ICON_SIZE_MENU));
240 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
241 g_signal_connect (item, "activate", G_CALLBACK (tazweb_doc_cb), NULL);
243 /* View source mode */
244 item = gtk_image_menu_item_new_with_label ("View source mode");
245 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
246 gtk_image_new_from_stock (GTK_STOCK_PROPERTIES, GTK_ICON_SIZE_MENU));
247 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
248 g_signal_connect (item, "activate", G_CALLBACK (view_source_cb), NULL);
250 gtk_widget_show_all (GTK_WIDGET (menu));
251 }
253 /* Scrolled window for the web_view */
254 static GtkWidget*
255 create_browser ()
256 {
257 scrolled = gtk_scrolled_window_new (NULL, NULL);
258 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
259 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
261 web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ());
262 gtk_container_add (GTK_CONTAINER (scrolled), GTK_WIDGET (web_view));
264 /* Connect events */
265 g_signal_connect (web_view, "notify::title",
266 G_CALLBACK (notify_title_cb), web_view);
267 g_signal_connect (web_view, "notify::progress",
268 G_CALLBACK (notify_progress_cb), web_view);
269 g_signal_connect (web_view, "notify::load-status",
270 G_CALLBACK (notify_load_status_cb), web_view);
271 g_signal_connect (web_view, "download-requested",
272 G_CALLBACK (download_requested_cb), NULL);
274 /* Connect WebKit contextual menu items */
275 g_object_connect (G_OBJECT (web_view), "signal::populate-popup",
276 G_CALLBACK (populate_menu_cb), web_view, NULL);
278 return scrolled;
279 }
281 /* Loader area */
282 static GtkWidget*
283 create_loader ()
284 {
285 loader = gtk_drawing_area_new ();
286 gtk_widget_set_size_request (loader, 0, 1);
287 g_signal_connect (G_OBJECT (loader), "expose_event",
288 G_CALLBACK (expose_loader_cb), NULL);
290 return loader;
291 }
293 static GtkWidget*
294 create_toolbar ()
295 {
296 GtkToolItem* item;
298 toolbar = gtk_toolbar_new ();
299 gtk_widget_set_size_request (toolbar, 0, 33);
300 gtk_toolbar_set_orientation (GTK_TOOLBAR (toolbar),
301 GTK_ORIENTATION_HORIZONTAL);
302 gtk_toolbar_set_style (GTK_TOOLBAR (toolbar),
303 GTK_TOOLBAR_BOTH_HORIZ);
305 /* Home button */
306 item = gtk_tool_button_new_from_stock (GTK_STOCK_HOME);
307 g_signal_connect (G_OBJECT (item), "clicked",
308 G_CALLBACK (go_home_cb), NULL);
309 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
311 /* URL entry */
312 item = gtk_tool_item_new ();
313 gtk_tool_item_set_expand (item, TRUE);
314 uri_entry = gtk_entry_new ();
315 gtk_container_add (GTK_CONTAINER (item), uri_entry);
316 g_signal_connect (G_OBJECT (uri_entry), "activate",
317 G_CALLBACK (uri_entry_cb), NULL);
318 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
320 /* Separator */
321 item = gtk_separator_tool_item_new ();
322 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
324 /* Search entry */
325 item = gtk_tool_item_new ();
326 search_entry = gtk_entry_new ();
327 gtk_container_add (GTK_CONTAINER (item), search_entry);
328 g_signal_connect (G_OBJECT (search_entry), "activate",
329 G_CALLBACK (search_entry_cb), NULL);
330 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
332 /* The Fullscreen button */
333 item = gtk_tool_button_new_from_stock (GTK_STOCK_FULLSCREEN);
334 g_signal_connect (G_OBJECT (item), "clicked",
335 G_CALLBACK (fullscreen_cb), NULL);
336 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
338 return toolbar;
339 }
341 /* Main window */
342 static GtkWidget*
343 create_window ()
344 {
345 GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
346 GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
348 /* Default TazWeb window size ratio to 3/4 --> 720, 540*/
349 gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
350 gtk_window_set_icon (GTK_WINDOW (window),
351 create_pixbuf ("/usr/share/pixmaps/tazweb.png"));
352 gtk_widget_set_name (window, "TazWeb");
353 g_signal_connect (window, "destroy", G_CALLBACK (destroy_cb), NULL);
355 /* Pack box and container */
356 gtk_box_pack_start (GTK_BOX (vbox), create_browser (), TRUE, TRUE, 0);
357 gtk_container_add (GTK_CONTAINER (vbox), create_loader());
358 gtk_box_set_child_packing (GTK_BOX (vbox), loader,
359 FALSE, FALSE, 0, GTK_PACK_START);
360 gtk_box_pack_start (GTK_BOX (vbox), create_toolbar (), FALSE, FALSE, 0);
361 gtk_container_add (GTK_CONTAINER (window), vbox);
363 main_window = window;
364 gtk_widget_show_all (main_window);
365 }
367 int
368 main (int argc, char* argv[])
369 {
370 gtk_init (&argc, &argv);
371 if (!g_thread_supported ())
372 g_thread_init (NULL);
374 /* Get a default home.html if missing */
375 if (! g_file_test (CONFIG, G_FILE_TEST_EXISTS))
376 system ("cp -r /usr/share/tazweb $HOME/.config/tazweb");
378 /* Load the start page file or the url in argument */
379 uri = (gchar*) (argc > 1 ? argv[1] :
380 "file:///usr/share/webhome/index.html");
382 create_window ();
383 webkit_web_view_load_uri (web_view, uri);
384 gtk_widget_grab_focus (GTK_WIDGET (web_view));
385 gtk_main ();
387 return 0;
388 }