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