2 * Hotspot 2.0 client - Web browser using WebKit
3 * Copyright (c) 2013, Qualcomm Atheros, Inc.
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
10 #include <webkit/webkit.h>
16 struct browser_context
{
24 static void win_cb_destroy(GtkWidget
*win
, struct browser_context
*ctx
)
26 wpa_printf(MSG_DEBUG
, "BROWSER:%s", __func__
);
31 static void browser_update_title(struct browser_context
*ctx
)
35 if (ctx
->hover_link
) {
36 gtk_window_set_title(GTK_WINDOW(ctx
->win
), ctx
->hover_link
);
40 if (ctx
->progress
== 100) {
41 gtk_window_set_title(GTK_WINDOW(ctx
->win
),
42 ctx
->title
? ctx
->title
:
43 "Hotspot 2.0 client");
47 snprintf(buf
, sizeof(buf
), "[%d%%] %s", ctx
->progress
,
48 ctx
->title
? ctx
->title
: "Hotspot 2.0 client");
49 gtk_window_set_title(GTK_WINDOW(ctx
->win
), buf
);
53 static void view_cb_notify_progress(WebKitWebView
*view
, GParamSpec
*pspec
,
54 struct browser_context
*ctx
)
56 ctx
->progress
= 100 * webkit_web_view_get_progress(view
);
57 wpa_printf(MSG_DEBUG
, "BROWSER:%s progress=%d", __func__
,
59 browser_update_title(ctx
);
63 static void view_cb_notify_load_status(WebKitWebView
*view
, GParamSpec
*pspec
,
64 struct browser_context
*ctx
)
66 int status
= webkit_web_view_get_load_status(view
);
67 wpa_printf(MSG_DEBUG
, "BROWSER:%s load-status=%d uri=%s",
68 __func__
, status
, webkit_web_view_get_uri(view
));
72 static void view_cb_resource_request_starting(WebKitWebView
*view
,
73 WebKitWebFrame
*frame
,
74 WebKitWebResource
*res
,
75 WebKitNetworkRequest
*req
,
76 WebKitNetworkResponse
*resp
,
77 struct browser_context
*ctx
)
79 const gchar
*uri
= webkit_network_request_get_uri(req
);
80 wpa_printf(MSG_DEBUG
, "BROWSER:%s uri=%s", __func__
, uri
);
81 if (g_str_has_suffix(uri
, "/favicon.ico"))
82 webkit_network_request_set_uri(req
, "about:blank");
83 if (g_str_has_prefix(uri
, "osu://")) {
84 ctx
->success
= atoi(uri
+ 6);
87 if (g_str_has_prefix(uri
, "http://localhost:12345")) {
89 * This is used as a special trigger to indicate that the
90 * user exchange has been completed.
98 static gboolean
view_cb_mime_type_policy_decision(
99 WebKitWebView
*view
, WebKitWebFrame
*frame
, WebKitNetworkRequest
*req
,
100 gchar
*mime
, WebKitWebPolicyDecision
*policy
,
101 struct browser_context
*ctx
)
103 wpa_printf(MSG_DEBUG
, "BROWSER:%s mime=%s", __func__
, mime
);
105 if (!webkit_web_view_can_show_mime_type(view
, mime
)) {
106 webkit_web_policy_decision_download(policy
);
114 static gboolean
view_cb_download_requested(WebKitWebView
*view
,
116 struct browser_context
*ctx
)
119 uri
= webkit_download_get_uri(dl
);
120 wpa_printf(MSG_DEBUG
, "BROWSER:%s uri=%s", __func__
, uri
);
125 static void view_cb_hovering_over_link(WebKitWebView
*view
, gchar
*title
,
126 gchar
*uri
, struct browser_context
*ctx
)
128 wpa_printf(MSG_DEBUG
, "BROWSER:%s title=%s uri=%s", __func__
, title
,
130 os_free(ctx
->hover_link
);
132 ctx
->hover_link
= os_strdup(uri
);
134 ctx
->hover_link
= NULL
;
136 browser_update_title(ctx
);
140 static void view_cb_title_changed(WebKitWebView
*view
, WebKitWebFrame
*frame
,
142 struct browser_context
*ctx
)
144 wpa_printf(MSG_DEBUG
, "BROWSER:%s title=%s", __func__
, title
);
146 ctx
->title
= os_strdup(title
);
147 browser_update_title(ctx
);
151 int hs20_web_browser(const char *url
)
156 WebKitWebSettings
*settings
;
157 struct browser_context ctx
;
159 memset(&ctx
, 0, sizeof(ctx
));
160 if (!gtk_init_check(NULL
, NULL
))
163 s
= webkit_get_default_session();
164 g_object_set(G_OBJECT(s
), "ssl-ca-file",
165 "/etc/ssl/certs/ca-certificates.crt", NULL
);
166 g_object_set(G_OBJECT(s
), "ssl-strict", FALSE
, NULL
);
168 ctx
.win
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
169 gtk_window_set_role(GTK_WINDOW(ctx
.win
), "Hotspot 2.0 client");
170 gtk_window_set_default_size(GTK_WINDOW(ctx
.win
), 800, 600);
172 scroll
= gtk_scrolled_window_new(NULL
, NULL
);
173 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll
),
174 GTK_POLICY_NEVER
, GTK_POLICY_NEVER
);
176 g_signal_connect(G_OBJECT(ctx
.win
), "destroy",
177 G_CALLBACK(win_cb_destroy
), &ctx
);
179 view
= WEBKIT_WEB_VIEW(webkit_web_view_new());
180 g_signal_connect(G_OBJECT(view
), "notify::progress",
181 G_CALLBACK(view_cb_notify_progress
), &ctx
);
182 g_signal_connect(G_OBJECT(view
), "notify::load-status",
183 G_CALLBACK(view_cb_notify_load_status
), &ctx
);
184 g_signal_connect(G_OBJECT(view
), "resource-request-starting",
185 G_CALLBACK(view_cb_resource_request_starting
), &ctx
);
186 g_signal_connect(G_OBJECT(view
), "mime-type-policy-decision-requested",
187 G_CALLBACK(view_cb_mime_type_policy_decision
), &ctx
);
188 g_signal_connect(G_OBJECT(view
), "download-requested",
189 G_CALLBACK(view_cb_download_requested
), &ctx
);
190 g_signal_connect(G_OBJECT(view
), "hovering-over-link",
191 G_CALLBACK(view_cb_hovering_over_link
), &ctx
);
192 g_signal_connect(G_OBJECT(view
), "title-changed",
193 G_CALLBACK(view_cb_title_changed
), &ctx
);
195 gtk_container_add(GTK_CONTAINER(scroll
), GTK_WIDGET(view
));
196 gtk_container_add(GTK_CONTAINER(ctx
.win
), GTK_WIDGET(scroll
));
198 gtk_widget_grab_focus(GTK_WIDGET(view
));
199 gtk_widget_show_all(ctx
.win
);
201 settings
= webkit_web_view_get_settings(view
);
202 g_object_set(G_OBJECT(settings
), "user-agent",
203 "Mozilla/5.0 (X11; U; Unix; en-US) "
204 "AppleWebKit/537.15 (KHTML, like Gecko) "
205 "hs20-client/1.0", NULL
);
206 g_object_set(G_OBJECT(settings
), "auto-load-images", TRUE
, NULL
);
208 webkit_web_view_load_uri(view
, url
);
211 gtk_widget_destroy(ctx
.win
);
212 while (gtk_events_pending())
213 gtk_main_iteration();
215 free(ctx
.hover_link
);