1/* 2 * Copyright (C) 2012 Igalia S.L. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20#include "config.h" 21#include "WebKitAuthenticationDialog.h" 22 23#include "AuthenticationDecisionListener.h" 24#include "WebKitAuthenticationRequestPrivate.h" 25#include "WebKitCredentialPrivate.h" 26#include "WebKitPrivate.h" 27#include "WebKitWebView.h" 28 29using namespace WebKit; 30 31struct _WebKitAuthenticationDialogPrivate { 32 GRefPtr<WebKitAuthenticationRequest> request; 33 GtkWidget* authWidget; 34 GtkWidget* defaultButton; 35 unsigned long authenticationCancelledID; 36 GRefPtr<GtkStyleContext> styleContext; 37}; 38 39WEBKIT_DEFINE_TYPE(WebKitAuthenticationDialog, webkit_authentication_dialog, GTK_TYPE_EVENT_BOX) 40 41static void okButtonClicked(GtkButton*, WebKitAuthenticationDialog* authDialog) 42{ 43 WebKitAuthenticationDialogPrivate* priv = authDialog->priv; 44 WebKitCredential* credential = webkitCredentialCreate(webkitAuthenticationWidgetCreateCredential(WEBKIT_AUTHENTICATION_WIDGET(priv->authWidget))); 45 webkit_authentication_request_authenticate(priv->request.get(), credential); 46 webkit_credential_free(credential); 47 gtk_widget_destroy(GTK_WIDGET(authDialog)); 48} 49 50static void cancelButtonClicked(GtkButton*, WebKitAuthenticationDialog* authDialog) 51{ 52 webkit_authentication_request_authenticate(authDialog->priv->request.get(), 0); 53 gtk_widget_destroy(GTK_WIDGET(authDialog)); 54} 55 56static void authenticationCancelled(WebKitAuthenticationRequest*, WebKitAuthenticationDialog* authDialog) 57{ 58 gtk_widget_destroy(GTK_WIDGET(authDialog)); 59} 60 61static void webkitAuthenticationDialogInitialize(WebKitAuthenticationDialog* authDialog, CredentialStorageMode credentialStorageMode) 62{ 63 GtkWidget* frame = gtk_frame_new(0); 64 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); 65 66 GtkWidget* vBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); 67 gtk_container_set_border_width(GTK_CONTAINER(vBox), 5); 68 69 GtkWidget* buttonBox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); 70 gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END); 71 gtk_container_set_border_width(GTK_CONTAINER(buttonBox), 5); 72 gtk_box_set_spacing(GTK_BOX(buttonBox), 6); 73 74 GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); 75 g_signal_connect(button, "clicked", G_CALLBACK(cancelButtonClicked), authDialog); 76 gtk_box_pack_end(GTK_BOX(buttonBox), button, FALSE, TRUE, 0); 77 gtk_widget_show(button); 78 79 button = gtk_button_new_from_stock(GTK_STOCK_OK); 80 authDialog->priv->defaultButton = button; 81 g_signal_connect(button, "clicked", G_CALLBACK(okButtonClicked), authDialog); 82 gtk_widget_set_can_default(button, TRUE); 83 gtk_box_pack_end(GTK_BOX(buttonBox), button, FALSE, TRUE, 0); 84 gtk_widget_show(button); 85 86 authDialog->priv->authWidget = webkitAuthenticationWidgetNew(webkitAuthenticationRequestGetAuthenticationChallenge(authDialog->priv->request.get())->core(), credentialStorageMode); 87 gtk_box_pack_start(GTK_BOX(vBox), authDialog->priv->authWidget, TRUE, TRUE, 0); 88 gtk_widget_show(authDialog->priv->authWidget); 89 90 gtk_box_pack_end(GTK_BOX(vBox), buttonBox, FALSE, TRUE, 0); 91 gtk_widget_show(buttonBox); 92 93 gtk_container_add(GTK_CONTAINER(frame), vBox); 94 gtk_widget_show(vBox); 95 96 gtk_container_add(GTK_CONTAINER(authDialog), frame); 97 gtk_widget_show(frame); 98 99 authDialog->priv->authenticationCancelledID = g_signal_connect(authDialog->priv->request.get(), "cancelled", G_CALLBACK(authenticationCancelled), authDialog); 100} 101 102static gboolean webkitAuthenticationDialogDraw(GtkWidget* widget, cairo_t* cr) 103{ 104 WebKitAuthenticationDialogPrivate* priv = WEBKIT_AUTHENTICATION_DIALOG(widget)->priv; 105 106 gtk_style_context_save(priv->styleContext.get()); 107 gtk_style_context_add_class(priv->styleContext.get(), GTK_STYLE_CLASS_BACKGROUND); 108 gtk_render_background(priv->styleContext.get(), cr, 0, 0, gtk_widget_get_allocated_width(widget), gtk_widget_get_allocated_height(widget)); 109 gtk_style_context_restore(priv->styleContext.get()); 110 111 GTK_WIDGET_CLASS(webkit_authentication_dialog_parent_class)->draw(widget, cr); 112 113 return FALSE; 114} 115 116static void webkitAuthenticationDialogMap(GtkWidget* widget) 117{ 118 WebKitAuthenticationDialogPrivate* priv = WEBKIT_AUTHENTICATION_DIALOG(widget)->priv; 119 gtk_widget_grab_default(priv->defaultButton); 120 121 GTK_WIDGET_CLASS(webkit_authentication_dialog_parent_class)->map(widget); 122} 123 124static void webkitAuthenticationDialogConstructed(GObject* object) 125{ 126 G_OBJECT_CLASS(webkit_authentication_dialog_parent_class)->constructed(object); 127 128 WebKitAuthenticationDialogPrivate* priv = WEBKIT_AUTHENTICATION_DIALOG(object)->priv; 129 priv->styleContext = adoptGRef(gtk_style_context_new()); 130 GtkWidgetPath* path = gtk_widget_path_new(); 131 gtk_widget_path_append_type(path, GTK_TYPE_WINDOW); 132 gtk_style_context_set_path(priv->styleContext.get(), path); 133 gtk_widget_path_free(path); 134} 135 136static void webkitAuthenticationDialogDispose(GObject* object) 137{ 138 WebKitAuthenticationDialogPrivate* priv = WEBKIT_AUTHENTICATION_DIALOG(object)->priv; 139 if (priv->authenticationCancelledID) { 140 g_signal_handler_disconnect(priv->request.get(), priv->authenticationCancelledID); 141 priv->authenticationCancelledID = 0; 142 } 143 144 G_OBJECT_CLASS(webkit_authentication_dialog_parent_class)->dispose(object); 145} 146 147static void webkit_authentication_dialog_class_init(WebKitAuthenticationDialogClass* klass) 148{ 149 GObjectClass* objectClass = G_OBJECT_CLASS(klass); 150 objectClass->constructed = webkitAuthenticationDialogConstructed; 151 objectClass->dispose = webkitAuthenticationDialogDispose; 152 153 GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(klass); 154 widgetClass->draw = webkitAuthenticationDialogDraw; 155 widgetClass->map = webkitAuthenticationDialogMap; 156} 157 158GtkWidget* webkitAuthenticationDialogNew(WebKitAuthenticationRequest* request, CredentialStorageMode mode) 159{ 160 WebKitAuthenticationDialog* authDialog = WEBKIT_AUTHENTICATION_DIALOG(g_object_new(WEBKIT_TYPE_AUTHENTICATION_DIALOG, NULL)); 161 authDialog->priv->request = request; 162 webkitAuthenticationDialogInitialize(authDialog, mode); 163 return GTK_WIDGET(authDialog); 164} 165