6 #include <gdk/gdkkeysyms.h>
7 #include <webkit/webkit.h>
10 #define DOWNLOAD_DIR "/tmp/tmp"
13 static void zea_destroy_client(GtkWidget *, gpointer);
14 static gboolean zea_do_download(WebKitWebView *, WebKitDownload *, gpointer);
15 static gboolean zea_download_request(WebKitWebView *, WebKitWebFrame *,
16 WebKitNetworkRequest *, gchar *,
17 WebKitWebPolicyDecision *, gpointer);
18 static gboolean zea_location_key(GtkWidget *, GdkEvent *, gpointer);
19 static void zea_new_client(const gchar *uri);
20 static gboolean zea_new_client_request(WebKitWebView *, WebKitWebFrame *,
21 WebKitNetworkRequest *,
22 WebKitWebNavigationAction *,
23 WebKitWebPolicyDecision *, gpointer);
24 static void zea_title_changed(GObject *, GParamSpec *, gpointer);
25 static void zea_uri_changed(GObject *, GParamSpec *, gpointer);
26 static gboolean zea_web_view_key(GtkWidget *, GdkEvent *, gpointer);
29 static Window embed = 0;
30 static int clients = 0;
31 static double global_zoom = 1.0;
45 zea_destroy_client(GtkWidget *obj, gpointer data)
47 struct Client *c = (struct Client *)data;
51 webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(c->web_view));
52 gtk_widget_destroy(c->web_view);
53 gtk_widget_destroy(c->scroll);
54 gtk_widget_destroy(c->win);
63 zea_do_download(WebKitWebView *web_view, WebKitDownload *download, gpointer data)
72 uri = webkit_download_get_uri(download);
77 ret = execlp("xterm", "xterm", "-hold", "-e", "wget", uri, NULL);
80 if (snprintf(id, 16, "%ld", embed) >= 16)
82 fprintf(stderr, "zea: id for xterm embed truncated!\n");
85 ret = execlp("xterm", "xterm", "-hold", "-into", id, "-e", "wget",
91 fprintf(stderr, "zea: exec'ing xterm for download");
101 zea_download_request(WebKitWebView *web_view, WebKitWebFrame *frame,
102 WebKitNetworkRequest *request, gchar *mime_type,
103 WebKitWebPolicyDecision *policy_decision,
110 if (!webkit_web_view_can_show_mime_type(web_view, mime_type))
112 webkit_web_policy_decision_download(policy_decision);
119 zea_location_key(GtkWidget *widget, GdkEvent *event, gpointer data)
121 struct Client *c = (struct Client *)data;
125 if (event->type == GDK_KEY_PRESS)
127 if (((GdkEventKey *)event)->keyval == GDK_KEY_Return)
129 gtk_widget_grab_focus(c->web_view);
130 webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view),
131 gtk_entry_get_text(GTK_ENTRY(c->location)));
140 zea_new_client(const gchar *uri)
142 struct Client *c = malloc(sizeof(struct Client));
145 fprintf(stderr, "zea: fatal: malloc failed\n");
151 c->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
155 c->win = gtk_plug_new(embed);
158 /* When using Gtk2, zea only shows a white area when run in
159 * suckless' tabbed. It appears we need to set a default window size
160 * for this to work. This is not needed when using Gtk3. */
161 gtk_window_set_default_size(GTK_WINDOW(c->win), 1024, 768);
163 g_signal_connect(G_OBJECT(c->win), "destroy",
164 G_CALLBACK(zea_destroy_client), c);
165 gtk_window_set_title(GTK_WINDOW(c->win), "zea");
167 c->web_view = webkit_web_view_new();
168 webkit_web_view_set_full_content_zoom(WEBKIT_WEB_VIEW(c->web_view), TRUE);
169 webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(c->web_view), global_zoom);
170 g_signal_connect(G_OBJECT(c->web_view), "notify::title",
171 G_CALLBACK(zea_title_changed), c);
172 g_signal_connect(G_OBJECT(c->web_view), "notify::uri",
173 G_CALLBACK(zea_uri_changed), c);
174 g_signal_connect(G_OBJECT(c->web_view),
175 "new-window-policy-decision-requested",
176 G_CALLBACK(zea_new_client_request), NULL);
177 g_signal_connect(G_OBJECT(c->web_view),
178 "mime-type-policy-decision-requested",
179 G_CALLBACK(zea_download_request), NULL);
180 g_signal_connect(G_OBJECT(c->web_view), "download-requested",
181 G_CALLBACK(zea_do_download), NULL);
182 g_signal_connect(G_OBJECT(c->web_view), "key-press-event",
183 G_CALLBACK(zea_web_view_key), c);
185 c->scroll = gtk_scrolled_window_new(NULL, NULL);
187 gtk_container_add(GTK_CONTAINER(c->scroll), c->web_view);
189 c->location = gtk_entry_new();
190 g_signal_connect(G_OBJECT(c->location), "key-press-event",
191 G_CALLBACK(zea_location_key), c);
193 c->vbox = gtk_vbox_new(FALSE, 0);
194 gtk_box_pack_start(GTK_BOX(c->vbox), c->location, FALSE, FALSE, 0);
195 gtk_container_add(GTK_CONTAINER(c->vbox), c->scroll);
197 gtk_container_add(GTK_CONTAINER(c->win), c->vbox);
199 gtk_widget_grab_focus(c->web_view);
200 gtk_widget_show_all(c->win);
202 webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), uri);
208 zea_new_client_request(WebKitWebView *web_view, WebKitWebFrame *frame,
209 WebKitNetworkRequest *request,
210 WebKitWebNavigationAction *navigation_action,
211 WebKitWebPolicyDecision *policy_decision,
216 (void)navigation_action;
219 webkit_web_policy_decision_ignore(policy_decision);
220 zea_new_client(webkit_network_request_get_uri(request));
226 zea_title_changed(GObject *obj, GParamSpec *pspec, gpointer data)
229 struct Client *c = (struct Client *)data;
234 t = webkit_web_view_get_title(WEBKIT_WEB_VIEW(c->web_view));
235 gtk_window_set_title(GTK_WINDOW(c->win), (t == NULL ? "zea" : t));
239 zea_uri_changed(GObject *obj, GParamSpec *pspec, gpointer data)
242 struct Client *c = (struct Client *)data;
247 t = webkit_web_view_get_uri(WEBKIT_WEB_VIEW(c->web_view));
248 gtk_entry_set_text(GTK_ENTRY(c->location), (t == NULL ? "zea" : t));
252 zea_web_view_key(GtkWidget *widget, GdkEvent *event, gpointer data)
254 struct Client *c = (struct Client *)data;
258 if (event->type == GDK_KEY_PRESS)
260 if (((GdkEventKey *)event)->state & GDK_MOD1_MASK)
262 if (((GdkEventKey *)event)->keyval == GDK_KEY_l)
264 gtk_widget_grab_focus(c->location);
274 main(int argc, char **argv)
278 gtk_init(&argc, &argv);
280 while ((opt = getopt(argc, argv, "z:e:")) != -1)
285 global_zoom = atof(optarg);
288 embed = atol(optarg);
295 fprintf(stderr, "Usage: zea [OPTIONS] <URI>\n");
299 zea_new_client(argv[optind]);