1d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt/*
2d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Hotspot 2.0 client - Web browser using WebKit
3d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Copyright (c) 2013, Qualcomm Atheros, Inc.
4d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *
5d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * This software may be distributed under the terms of the BSD license.
6d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * See README for more details.
7d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt */
8d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
9d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "includes.h"
10d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include <webkit/webkit.h>
11d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
12d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "common.h"
13d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "browser.h"
14d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
15d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
16d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstruct browser_context {
17d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	GtkWidget *win;
18d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int success;
19d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int progress;
20d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *hover_link;
21d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *title;
22d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt};
23d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
24d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void win_cb_destroy(GtkWidget *win, struct browser_context *ctx)
25d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
26d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_DEBUG, "BROWSER:%s", __func__);
27d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gtk_main_quit();
28d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
29d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
30d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
31d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void browser_update_title(struct browser_context *ctx)
32d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
33d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char buf[100];
34d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
35d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctx->hover_link) {
36d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		gtk_window_set_title(GTK_WINDOW(ctx->win), ctx->hover_link);
37d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
38d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
39d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
40d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctx->progress == 100) {
41d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		gtk_window_set_title(GTK_WINDOW(ctx->win),
42d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				     ctx->title ? ctx->title :
43d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				     "Hotspot 2.0 client");
44d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
45d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
46d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
47d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	snprintf(buf, sizeof(buf), "[%d%%] %s", ctx->progress,
48d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		 ctx->title ? ctx->title : "Hotspot 2.0 client");
49d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gtk_window_set_title(GTK_WINDOW(ctx->win), buf);
50d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
51d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
52d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
53d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void view_cb_notify_progress(WebKitWebView *view, GParamSpec *pspec,
54d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				    struct browser_context *ctx)
55d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
56d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctx->progress = 100 * webkit_web_view_get_progress(view);
57d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_DEBUG, "BROWSER:%s progress=%d", __func__,
58d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		   ctx->progress);
59d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	browser_update_title(ctx);
60d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
61d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
62d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
63d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void view_cb_notify_load_status(WebKitWebView *view, GParamSpec *pspec,
64d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				       struct browser_context *ctx)
65d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
66d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int status = webkit_web_view_get_load_status(view);
67d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_DEBUG, "BROWSER:%s load-status=%d uri=%s",
68d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		   __func__, status, webkit_web_view_get_uri(view));
69d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
70d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
71d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
72d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void view_cb_resource_request_starting(WebKitWebView *view,
73d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					      WebKitWebFrame *frame,
74d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					      WebKitWebResource *res,
75d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					      WebKitNetworkRequest *req,
76d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					      WebKitNetworkResponse *resp,
77d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					      struct browser_context *ctx)
78d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
79d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	const gchar *uri = webkit_network_request_get_uri(req);
80d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_DEBUG, "BROWSER:%s uri=%s", __func__, uri);
81d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (g_str_has_suffix(uri, "/favicon.ico"))
82d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		webkit_network_request_set_uri(req, "about:blank");
83d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (g_str_has_prefix(uri, "osu://")) {
84d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ctx->success = atoi(uri + 6);
85d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		gtk_main_quit();
86d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
87d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (g_str_has_prefix(uri, "http://localhost:12345")) {
88d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		/*
89d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		 * This is used as a special trigger to indicate that the
90d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		 * user exchange has been completed.
91d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		 */
92d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ctx->success = 1;
93d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		gtk_main_quit();
94d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
95d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
96d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
97d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
98d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic gboolean view_cb_mime_type_policy_decision(
99d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	WebKitWebView *view, WebKitWebFrame *frame, WebKitNetworkRequest *req,
100d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gchar *mime, WebKitWebPolicyDecision *policy,
101d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct browser_context *ctx)
102d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
103d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_DEBUG, "BROWSER:%s mime=%s", __func__, mime);
104d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
105d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (!webkit_web_view_can_show_mime_type(view, mime)) {
106d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		webkit_web_policy_decision_download(policy);
107d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return TRUE;
108d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
109d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
110d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return FALSE;
111d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
112d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
113d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
114d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic gboolean view_cb_download_requested(WebKitWebView *view,
115d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					   WebKitDownload *dl,
116d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					   struct browser_context *ctx)
117d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
118d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	const gchar *uri;
119d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	uri = webkit_download_get_uri(dl);
120d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_DEBUG, "BROWSER:%s uri=%s", __func__, uri);
121d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return FALSE;
122d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
123d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
124d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
125d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void view_cb_hovering_over_link(WebKitWebView *view, gchar *title,
126d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				       gchar *uri, struct browser_context *ctx)
127d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
128d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_DEBUG, "BROWSER:%s title=%s uri=%s", __func__, title,
129d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		   uri);
130d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(ctx->hover_link);
131d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (uri)
132d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ctx->hover_link = os_strdup(uri);
133d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	else
134d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ctx->hover_link = NULL;
135d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
136d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	browser_update_title(ctx);
137d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
138d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
139d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
140d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void view_cb_title_changed(WebKitWebView *view, WebKitWebFrame *frame,
141d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				  const char *title,
142d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				  struct browser_context *ctx)
143d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
144d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_DEBUG, "BROWSER:%s title=%s", __func__, title);
145d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(ctx->title);
146d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctx->title = os_strdup(title);
147d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	browser_update_title(ctx);
148d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
149d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
150d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
151d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint hs20_web_browser(const char *url)
152d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
153d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	GtkWidget *scroll;
154d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	SoupSession *s;
155d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	WebKitWebView *view;
156d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	WebKitWebSettings *settings;
157d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct browser_context ctx;
158d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
159d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	memset(&ctx, 0, sizeof(ctx));
160d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (!gtk_init_check(NULL, NULL))
161d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
162d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
163d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	s = webkit_get_default_session();
164d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_object_set(G_OBJECT(s), "ssl-ca-file",
165d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		     "/etc/ssl/certs/ca-certificates.crt", NULL);
166d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_object_set(G_OBJECT(s), "ssl-strict", FALSE, NULL);
167d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
168d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctx.win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
169d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gtk_window_set_wmclass(GTK_WINDOW(ctx.win), "Hotspot 2.0 client",
170d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			       "Hotspot 2.0 client");
171d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gtk_window_set_default_size(GTK_WINDOW(ctx.win), 800, 600);
172d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
173d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	scroll = gtk_scrolled_window_new(NULL, NULL);
174d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
175d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				       GTK_POLICY_NEVER, GTK_POLICY_NEVER);
176d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
177d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_signal_connect(G_OBJECT(ctx.win), "destroy",
178d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			 G_CALLBACK(win_cb_destroy), &ctx);
179d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
180d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	view = WEBKIT_WEB_VIEW(webkit_web_view_new());
181d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_signal_connect(G_OBJECT(view), "notify::progress",
182d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			 G_CALLBACK(view_cb_notify_progress), &ctx);
183d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_signal_connect(G_OBJECT(view), "notify::load-status",
184d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			 G_CALLBACK(view_cb_notify_load_status), &ctx);
185d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_signal_connect(G_OBJECT(view), "resource-request-starting",
186d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			 G_CALLBACK(view_cb_resource_request_starting), &ctx);
187d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_signal_connect(G_OBJECT(view), "mime-type-policy-decision-requested",
188d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			 G_CALLBACK(view_cb_mime_type_policy_decision), &ctx);
189d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_signal_connect(G_OBJECT(view), "download-requested",
190d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			 G_CALLBACK(view_cb_download_requested), &ctx);
191d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_signal_connect(G_OBJECT(view), "hovering-over-link",
192d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			 G_CALLBACK(view_cb_hovering_over_link), &ctx);
193d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_signal_connect(G_OBJECT(view), "title-changed",
194d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			 G_CALLBACK(view_cb_title_changed), &ctx);
195d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
196d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gtk_container_add(GTK_CONTAINER(scroll), GTK_WIDGET(view));
197d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gtk_container_add(GTK_CONTAINER(ctx.win), GTK_WIDGET(scroll));
198d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
199d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gtk_widget_grab_focus(GTK_WIDGET(view));
200d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gtk_widget_show_all(ctx.win);
201d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
202d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	settings = webkit_web_view_get_settings(view);
203d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_object_set(G_OBJECT(settings), "user-agent",
204d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		     "Mozilla/5.0 (X11; U; Unix; en-US) "
205d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		     "AppleWebKit/537.15 (KHTML, like Gecko) "
206d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		     "hs20-client/1.0", NULL);
207d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	g_object_set(G_OBJECT(settings), "auto-load-images", TRUE, NULL);
208d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
209d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	webkit_web_view_load_uri(view, url);
210d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
211d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gtk_main();
212d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	gtk_widget_destroy(ctx.win);
213d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	while (gtk_events_pending())
214d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		gtk_main_iteration();
215d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
216d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	free(ctx.hover_link);
217d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	free(ctx.title);
218d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return ctx.success;
219d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
220