e96e1784846e72f21fcf0cd0b3a13250bcb81555
[WebKit-https.git] / Source / WebKit / gtk / webkit / webkitglobals.cpp
1 /*
2  * Copyright (C) 2007 Holger Hans Peter Freyther
3  * Copyright (C) 2008, 2010 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22 #include "webkitglobals.h"
23
24 #include "ApplicationCacheStorage.h"
25 #include "Chrome.h"
26 #include "FrameNetworkingContextGtk.h"
27 #include "GOwnPtr.h"
28 #include "GRefPtr.h"
29 #include "IconDatabase.h"
30 #include "Logging.h"
31 #include "MemoryCache.h"
32 #include "Page.h"
33 #include "PageCache.h"
34 #include "PageGroup.h"
35 #include "TextEncodingRegistry.h"
36 #include "Pasteboard.h"
37 #include "PasteboardHelperGtk.h"
38 #include "ResourceHandle.h"
39 #include "ResourceHandleClient.h"
40 #include "ResourceHandleInternal.h"
41 #include "ResourceResponse.h"
42 #include "webkitapplicationcache.h"
43 #include "webkitglobalsprivate.h"
44 #include "webkiticondatabase.h"
45 #include "webkitsoupauthdialog.h"
46 #include "webkitspellchecker.h"
47 #include "webkitspellcheckerenchant.h"
48 #include "webkitwebdatabase.h"
49 #include "webkitwebplugindatabaseprivate.h"
50 #include <libintl.h>
51 #include <runtime/InitializeThreading.h>
52 #include <stdlib.h>
53 #include <wtf/MainThread.h>
54
55 static WebKitCacheModel cacheModel = WEBKIT_CACHE_MODEL_DEFAULT;
56
57 using namespace WebCore;
58
59 /**
60  * SECTION:webkit
61  * @short_description: Global functions controlling WebKit
62  *
63  * WebKit manages many resources which are not related to specific
64  * views. These functions relate to cross-view limits, such as cache
65  * sizes, database quotas, and the HTTP session management.
66  */
67
68 /**
69  * webkit_get_default_session:
70  *
71  * Retrieves the default #SoupSession used by all web views.
72  * Note that the session features are added by WebKit on demand,
73  * so if you insert your own #SoupCookieJar before any network
74  * traffic occurs, WebKit will use it instead of the default.
75  *
76  * Return value: (transfer none): the default #SoupSession
77  *
78  * Since: 1.1.1
79  */
80 SoupSession* webkit_get_default_session ()
81 {
82     webkitInit();
83     return ResourceHandle::defaultSession();
84 }
85
86 /**
87  * webkit_set_cache_model:
88  * @cache_model: a #WebKitCacheModel
89  *
90  * Specifies a usage model for WebViews, which WebKit will use to
91  * determine its caching behavior. All web views follow the cache
92  * model. This cache model determines the RAM and disk space to use
93  * for caching previously viewed content .
94  *
95  * Research indicates that users tend to browse within clusters of
96  * documents that hold resources in common, and to revisit previously
97  * visited documents. WebKit and the frameworks below it include
98  * built-in caches that take advantage of these patterns,
99  * substantially improving document load speed in browsing
100  * situations. The WebKit cache model controls the behaviors of all of
101  * these caches, including various WebCore caches.
102  *
103  * Browsers can improve document load speed substantially by
104  * specifying WEBKIT_CACHE_MODEL_WEB_BROWSER. Applications without a
105  * browsing interface can reduce memory usage substantially by
106  * specifying WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER. Default value is
107  * WEBKIT_CACHE_MODEL_WEB_BROWSER.
108  *
109  * Since: 1.1.18
110  */
111 void webkit_set_cache_model(WebKitCacheModel model)
112 {
113     webkitInit();
114
115     if (cacheModel == model)
116         return;
117
118     // FIXME: Add disk cache handling when soup has the API
119     guint cacheTotalCapacity;
120     guint cacheMinDeadCapacity;
121     guint cacheMaxDeadCapacity;
122     gdouble deadDecodedDataDeletionInterval;
123     guint pageCacheCapacity;
124
125     // FIXME: The Mac port calculates these values based on the amount of physical memory that's
126     // installed on the system. Currently these values match the Mac port for users with more than
127     // 512 MB and less than 1024 MB of physical memory.
128     switch (model) {
129     case WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER:
130         pageCacheCapacity = 0;
131         cacheTotalCapacity = 0; // FIXME: The Mac port actually sets this to larger than 0.
132         cacheMinDeadCapacity = 0;
133         cacheMaxDeadCapacity = 0;
134         deadDecodedDataDeletionInterval = 0;
135         break;
136     case WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER:
137         pageCacheCapacity = 2;
138         cacheTotalCapacity = 16 * 1024 * 1024;
139         cacheMinDeadCapacity = cacheTotalCapacity / 8;
140         cacheMaxDeadCapacity = cacheTotalCapacity / 4;
141         deadDecodedDataDeletionInterval = 0;
142         break;
143     case WEBKIT_CACHE_MODEL_WEB_BROWSER:
144         // Page cache capacity (in pages). Comment from Mac port:
145         // (Research indicates that value / page drops substantially after 3 pages.)
146         pageCacheCapacity = 3;
147         cacheTotalCapacity = 32 * 1024 * 1024;
148         cacheMinDeadCapacity = cacheTotalCapacity / 4;
149         cacheMaxDeadCapacity = cacheTotalCapacity / 2;
150         deadDecodedDataDeletionInterval = 60;
151         break;
152     default:
153         g_return_if_reached();
154     }
155
156     memoryCache()->setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity);
157     memoryCache()->setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval);
158     pageCache()->setCapacity(pageCacheCapacity);
159     cacheModel = model;
160 }
161
162 /**
163  * webkit_get_cache_model:
164  *
165  * Returns the current cache model. For more information about this
166  * value check the documentation of the function
167  * webkit_set_cache_model().
168  *
169  * Return value: the current #WebKitCacheModel
170  *
171  * Since: 1.1.18
172  */
173 WebKitCacheModel webkit_get_cache_model()
174 {
175     webkitInit();
176     return cacheModel;
177 }
178
179 /**
180  * webkit_get_web_plugin_database:
181  *
182  * Returns the current #WebKitWebPluginDatabase with information about
183  * all the plugins WebKit knows about in this instance.
184  *
185  * Return value: (transfer none): the current #WebKitWebPluginDatabase
186  *
187  * Since: 1.3.8
188  */
189 WebKitWebPluginDatabase* webkit_get_web_plugin_database()
190 {
191     static WebKitWebPluginDatabase* database = 0;
192
193     webkitInit();
194
195     if (!database)
196         database = webkit_web_plugin_database_new();
197
198     return database;
199 }
200
201
202 static GtkWidget* currentToplevelCallback(WebKitSoupAuthDialog* feature, SoupMessage* message, gpointer userData)
203 {
204     gpointer messageData = g_object_get_data(G_OBJECT(message), "resourceHandle");
205     if (!messageData)
206         return NULL;
207
208     ResourceHandle* handle = static_cast<ResourceHandle*>(messageData);
209     if (!handle)
210         return NULL;
211
212     ResourceHandleInternal* d = handle->getInternal();
213     if (!d)
214         return NULL;
215
216     WebKit::FrameNetworkingContextGtk* context = static_cast<WebKit::FrameNetworkingContextGtk*>(d->m_context.get());
217     if (!context)
218         return NULL;
219
220     if (!context->coreFrame())
221         return NULL;
222
223     GtkWidget* toplevel =  gtk_widget_get_toplevel(GTK_WIDGET(context->coreFrame()->page()->chrome()->platformPageClient()));
224     if (gtk_widget_is_toplevel(toplevel))
225         return toplevel;
226     else
227         return NULL;
228 }
229
230 /**
231  * webkit_get_icon_database:
232  *
233  * Returns the #WebKitIconDatabase providing access to website icons.
234  *
235  * Return value: (transfer none): the current #WebKitIconDatabase
236  *
237  * Since: 1.3.13
238  */
239 WebKitIconDatabase* webkit_get_icon_database()
240 {
241     webkitInit();
242
243     static WebKitIconDatabase* database = 0;
244     if (!database)
245         database = WEBKIT_ICON_DATABASE(g_object_new(WEBKIT_TYPE_ICON_DATABASE, NULL));
246
247     return database;
248 }
249
250 static GRefPtr<WebKitSpellChecker> textChecker = 0;
251
252 static void webkitExit()
253 {
254     g_object_unref(webkit_get_default_session());
255     textChecker = 0;
256 }
257
258 /**
259  * webkit_get_text_checker:
260  *
261  * Returns: the #WebKitSpellChecker used by WebKit, or %NULL if spell
262  * checking is not enabled
263  *
264  * Since: 1.5.1
265  **/
266 GObject* webkit_get_text_checker()
267 {
268     webkitInit();
269
270 #if ENABLE(SPELLCHECK)
271     if (!textChecker)
272         textChecker = adoptGRef(WEBKIT_SPELL_CHECKER(g_object_new(WEBKIT_TYPE_SPELL_CHECKER_ENCHANT, NULL)));
273 #endif
274
275     return G_OBJECT(textChecker.get());
276 }
277
278 /**
279  * webkit_set_text_checker:
280  * @checker: a #WebKitSpellChecker or %NULL
281  *
282  * Sets @checker as the spell checker to be used by WebKit. The API
283  * accepts GObject since in the future we might accept objects
284  * implementing multiple interfaces (for example, spell checking and
285  * grammar checking).
286  *
287  * Since: 1.5.1
288  **/
289 void webkit_set_text_checker(GObject* checker)
290 {
291     g_return_if_fail(!checker || WEBKIT_IS_SPELL_CHECKER(checker));
292
293     webkitInit();
294
295     // We need to do this because we need the cast, and casting NULL
296     // is not kosher.
297     textChecker = checker ? WEBKIT_SPELL_CHECKER(checker) : 0;
298 }
299
300 void webkitInit()
301 {
302     static bool isInitialized = false;
303     if (isInitialized)
304         return;
305     isInitialized = true;
306
307     bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
308     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
309
310     JSC::initializeThreading();
311     WTF::initializeMainThread();
312
313     WebCore::initializeLoggingChannelsIfNecessary();
314
315     // We make sure the text codecs have been initialized, because
316     // that may only be done by the main thread.
317     atomicCanonicalTextEncodingName("UTF-8");
318
319     GOwnPtr<gchar> databaseDirectory(g_build_filename(g_get_user_data_dir(), "webkit", "databases", NULL));
320     webkit_set_web_database_directory_path(databaseDirectory.get());
321
322     GOwnPtr<gchar> cacheDirectory(g_build_filename(g_get_user_cache_dir(), "webkitgtk", "applications", NULL));
323     WebCore::cacheStorage().setCacheDirectory(cacheDirectory.get());
324
325     PageGroup::setShouldTrackVisitedLinks(true);
326
327     GOwnPtr<gchar> iconDatabasePath(g_build_filename(g_get_user_data_dir(), "webkit", "icondatabase", NULL));
328     webkit_icon_database_set_path(webkit_get_icon_database(), iconDatabasePath.get());
329
330     SoupSession* session = webkit_get_default_session();
331
332     SoupSessionFeature* authDialog = static_cast<SoupSessionFeature*>(g_object_new(WEBKIT_TYPE_SOUP_AUTH_DIALOG, NULL));
333     g_signal_connect(authDialog, "current-toplevel", G_CALLBACK(currentToplevelCallback), NULL);
334     soup_session_add_feature(session, authDialog);
335     g_object_unref(authDialog);
336
337     SoupSessionFeature* sniffer = static_cast<SoupSessionFeature*>(g_object_new(SOUP_TYPE_CONTENT_SNIFFER, NULL));
338     soup_session_add_feature(session, sniffer);
339     g_object_unref(sniffer);
340
341     soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER);
342
343     atexit(webkitExit);
344 }