]> git.armaanb.net Git - chorizo.git/blob - zea.c
Rename sn to zea
[chorizo.git] / zea.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include <gtk/gtk.h>
5 #include <gdk/gdkx.h>
6 #include <webkit/webkit.h>
7
8
9 #define DOWNLOAD_DIR "/tmp/tmp"
10
11
12 static void zea_destroy_client(GtkWidget *, gpointer);
13 static gboolean zea_do_download(WebKitWebView *, WebKitDownload *, gpointer);
14 static gboolean zea_download_request(WebKitWebView *, WebKitWebFrame *,
15                                      WebKitNetworkRequest *, gchar *,
16                                      WebKitWebPolicyDecision *, gpointer);
17 static void zea_new_client(const gchar *uri);
18 static gboolean zea_new_client_request(WebKitWebView *, WebKitWebFrame *,
19                                        WebKitNetworkRequest *,
20                                        WebKitWebNavigationAction *,
21                                        WebKitWebPolicyDecision *, gpointer);
22 static void zea_title_changed(GObject *, GParamSpec *, gpointer);
23
24
25 static Window embed = 0;
26 static int clients = 0;
27 static double global_zoom = 1.0;
28
29
30 struct Client
31 {
32         GtkWidget *win;
33         GtkWidget *scroll;
34         GtkWidget *web_view;
35 };
36
37
38 void
39 zea_destroy_client(GtkWidget *obj, gpointer data)
40 {
41         struct Client *c = (struct Client *)data;
42
43         (void)obj;
44
45         webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(c->web_view));
46         gtk_widget_destroy(c->web_view);
47         gtk_widget_destroy(c->scroll);
48         gtk_widget_destroy(c->win);
49         free(c);
50
51         clients--;
52         if (clients == 0)
53                 gtk_main_quit();
54 }
55
56 gboolean
57 zea_do_download(WebKitWebView *web_view, WebKitDownload *download, gpointer data)
58 {
59         const gchar *uri;
60         char id[16] = "";
61         int ret;
62
63         (void)web_view;
64         (void)data;
65
66         uri = webkit_download_get_uri(download);
67         if (fork() == 0)
68         {
69                 chdir(DOWNLOAD_DIR);
70                 if (embed == 0)
71                         ret = execlp("xterm", "xterm", "-hold", "-e", "wget", uri, NULL);
72                 else
73                 {
74                         if (snprintf(id, 16, "%ld", embed) >= 16)
75                         {
76                                 fprintf(stderr, "zea: id for xterm embed truncated!\n");
77                                 exit(EXIT_FAILURE);
78                         }
79                         ret = execlp("xterm", "xterm", "-hold", "-into", id, "-e", "wget",
80                                      uri, NULL);
81                 }
82
83                 if (ret == -1)
84                 {
85                         fprintf(stderr, "zea: exec'ing xterm for download");
86                         perror(" failed");
87                         exit(EXIT_FAILURE);
88                 }
89         }
90
91         return FALSE;
92 }
93
94 gboolean
95 zea_download_request(WebKitWebView *web_view, WebKitWebFrame *frame,
96                      WebKitNetworkRequest *request, gchar *mime_type,
97                      WebKitWebPolicyDecision *policy_decision,
98                      gpointer data)
99 {
100         (void)frame;
101         (void)request;
102         (void)data;
103
104         if (!webkit_web_view_can_show_mime_type(web_view, mime_type))
105         {
106                 webkit_web_policy_decision_download(policy_decision);
107                 return TRUE;
108         }
109         return FALSE;
110 }
111
112 void
113 zea_new_client(const gchar *uri)
114 {
115         struct Client *c = malloc(sizeof(struct Client));
116         if (!c)
117         {
118                 fprintf(stderr, "zea: fatal: malloc failed\n");
119                 exit(EXIT_FAILURE);
120         }
121
122         if (embed == 0)
123         {
124                 c->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
125         }
126         else
127         {
128                 c->win = gtk_plug_new(embed);
129         }
130
131         /* When using Gtk2, zea only shows a white area when run in
132          * suckless' tabbed. It appears we need to set a default window size
133          * for this to work. This is not needed when using Gtk3. */
134         gtk_window_set_default_size(GTK_WINDOW(c->win), 1024, 768);
135
136         g_signal_connect(G_OBJECT(c->win), "destroy",
137                          G_CALLBACK(zea_destroy_client), c);
138         gtk_window_set_title(GTK_WINDOW(c->win), "zea");
139
140         c->web_view = webkit_web_view_new();
141         webkit_web_view_set_full_content_zoom(WEBKIT_WEB_VIEW(c->web_view), TRUE);
142         webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(c->web_view), global_zoom);
143         g_signal_connect(G_OBJECT(c->web_view), "notify::title",
144                          G_CALLBACK(zea_title_changed), c->win);
145         g_signal_connect(G_OBJECT(c->web_view),
146                          "new-window-policy-decision-requested",
147                          G_CALLBACK(zea_new_client_request), NULL);
148         g_signal_connect(G_OBJECT(c->web_view),
149                          "mime-type-policy-decision-requested",
150                          G_CALLBACK(zea_download_request), NULL);
151         g_signal_connect(G_OBJECT(c->web_view), "download-requested",
152                          G_CALLBACK(zea_do_download), NULL);
153
154         c->scroll = gtk_scrolled_window_new(NULL, NULL);
155
156         gtk_container_add(GTK_CONTAINER(c->scroll), c->web_view);
157         gtk_container_add(GTK_CONTAINER(c->win), c->scroll);
158
159         gtk_widget_show_all(c->win);
160
161         webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), uri);
162
163         clients++;
164 }
165
166 gboolean
167 zea_new_client_request(WebKitWebView *web_view, WebKitWebFrame *frame,
168                        WebKitNetworkRequest *request,
169                        WebKitWebNavigationAction *navigation_action,
170                        WebKitWebPolicyDecision *policy_decision,
171                        gpointer user_data)
172 {
173         (void)web_view;
174         (void)frame;
175         (void)navigation_action;
176         (void)user_data;
177
178         webkit_web_policy_decision_ignore(policy_decision);
179         zea_new_client(webkit_network_request_get_uri(request));
180
181         return TRUE;
182 }
183
184 void
185 zea_title_changed(GObject *obj, GParamSpec *pspec, gpointer data)
186 {
187         const gchar *t;
188         WebKitWebView *view = WEBKIT_WEB_VIEW(obj);
189         GtkWindow *win = GTK_WINDOW(data);
190
191         (void)pspec;
192
193         t = webkit_web_view_get_title(view);
194         gtk_window_set_title(win, (t == NULL ? "zea" : t));
195 }
196
197 int
198 main(int argc, char **argv)
199 {
200         int opt;
201
202         gtk_init(&argc, &argv);
203
204         while ((opt = getopt(argc, argv, "z:e:")) != -1)
205         {
206                 switch (opt)
207                 {
208                         case 'z':
209                                 global_zoom = atof(optarg);
210                                 break;
211                         case 'e':
212                                 embed = atol(optarg);
213                                 break;
214                 }
215         }
216
217         if (optind >= argc)
218         {
219                 fprintf(stderr, "Usage: zea [OPTIONS] <URI>\n");
220                 exit(EXIT_FAILURE);
221         }
222
223         zea_new_client(argv[optind]);
224         gtk_main();
225         exit(EXIT_SUCCESS);
226 }