• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
3  * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in>
4  * Copyright (C) 2006 George Staikos <staikos@kde.org>
5  * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
6  * Copyright (C) 2006 Zack Rusin <zack@kde.org>
7  * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
21  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
28  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include "launcherwindow.h"
34 #include "urlloader.h"
35 
36 WindowOptions windowOptions;
37 
38 
39 #include <QDir>
40 #include <QFile>
41 #include <QFileInfo>
42 #include <QFontDatabase>
43 
44 
45 #if defined(Q_WS_X11)
46 #include <fontconfig/fontconfig.h>
47 #endif
48 
49 
50 #if defined(Q_WS_X11)
51 // Very similar to WebCore::DumpRenderTree::initializeFonts();
52 // Duplicated here so that QtTestBrowser would display contents
53 // with the same fonts as run-webkit-tests/DumpRenderTree.
initTestFonts()54 static void initTestFonts()
55 {
56     static int numFonts = -1;
57 
58     // Some test cases may add or remove application fonts (via @font-face).
59     // Make sure to re-initialize the font set if necessary.
60     FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication);
61     if (appFontSet && numFonts >= 0 && appFontSet->nfont == numFonts)
62         return;
63 
64     QByteArray fontDir = getenv("WEBKIT_TESTFONTS");
65     if (fontDir.isEmpty() || !QDir(fontDir).exists()) {
66         fprintf(stderr,
67                 "\n\n"
68                 "----------------------------------------------------------------------\n"
69                 "WEBKIT_TESTFONTS environment variable is not set correctly.\n"
70                 "This variable has to point to the directory containing the fonts\n"
71                 "you can clone from git://gitorious.org/qtwebkit/testfonts.git\n"
72                 "----------------------------------------------------------------------\n"
73                );
74         exit(1);
75     }
76     // Looks for qt/fonts.conf relative to the directory of the QtTestBrowser
77     // executable.
78     QString configFileString = QCoreApplication::applicationDirPath();
79     configFileString += "/../../../Tools/DumpRenderTree/qt/fonts.conf";
80     QByteArray configFileArray = configFileString.toUtf8();
81     FcConfig* config = FcConfigCreate();
82     if (!FcConfigParseAndLoad (config, (FcChar8*) configFileArray.data(), true))
83         qFatal("Couldn't load font configuration file");
84     if (!FcConfigAppFontAddDir (config, (FcChar8*) fontDir.data()))
85         qFatal("Couldn't add font dir!");
86     FcConfigSetCurrent(config);
87 
88     appFontSet = FcConfigGetFonts(config, FcSetApplication);
89     numFonts = appFontSet->nfont;
90 }
91 #endif
92 
launcherMain(const QApplication & app)93 int launcherMain(const QApplication& app)
94 {
95 #ifdef Q_WS_X11
96     if (windowOptions.useTestFonts)
97         initTestFonts();
98 #endif
99 
100 #ifndef NDEBUG
101     int retVal = app.exec();
102     DumpRenderTreeSupportQt::garbageCollectorCollect();
103     QWebSettings::clearMemoryCaches();
104     return retVal;
105 #else
106     return app.exec();
107 #endif
108 }
109 
110 class LauncherApplication : public QApplication {
111     Q_OBJECT
112 
113 public:
114     LauncherApplication(int& argc, char** argv);
urls() const115     QStringList urls() const { return m_urls; }
isRobotized() const116     bool isRobotized() const { return m_isRobotized; }
robotTimeout() const117     int robotTimeout() const { return m_robotTimeoutSeconds; }
robotExtraTime() const118     int robotExtraTime() const { return m_robotExtraTimeSeconds; }
119 
120 private:
121     void handleUserOptions();
122     void applyDefaultSettings();
123 
124 private:
125     bool m_isRobotized;
126     int m_robotTimeoutSeconds;
127     int m_robotExtraTimeSeconds;
128     QStringList m_urls;
129 };
130 
applyDefaultSettings()131 void LauncherApplication::applyDefaultSettings()
132 {
133     QWebSettings::setMaximumPagesInCache(4);
134 
135     QWebSettings::setObjectCacheCapacities((16*1024*1024) / 8, (16*1024*1024) / 8, 16*1024*1024);
136 
137     QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled, true);
138     QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
139     QWebSettings::enablePersistentStorage();
140 }
141 
LauncherApplication(int & argc,char ** argv)142 LauncherApplication::LauncherApplication(int& argc, char** argv)
143     : QApplication(argc, argv, QApplication::GuiServer)
144     , m_isRobotized(false)
145     , m_robotTimeoutSeconds(0)
146     , m_robotExtraTimeSeconds(0)
147 {
148     // To allow QWebInspector's configuration persistence
149     setOrganizationName("Nokia");
150     setApplicationName("QtTestBrowser");
151     setApplicationVersion("0.1");
152 
153     applyDefaultSettings();
154 
155     handleUserOptions();
156 }
157 
requiresGraphicsView(const QString & option)158 static void requiresGraphicsView(const QString& option)
159 {
160     if (windowOptions.useGraphicsView)
161         return;
162     appQuit(1, QString("%1 only works in combination with the -graphicsbased option").arg(option));
163 }
164 
handleUserOptions()165 void LauncherApplication::handleUserOptions()
166 {
167     QStringList args = arguments();
168     QFileInfo program(args.at(0));
169     QString programName("QtTestBrowser");
170     if (program.exists())
171         programName = program.baseName();
172 
173     QList<QString> updateModes(enumToKeys(QGraphicsView::staticMetaObject,
174             "ViewportUpdateMode", "ViewportUpdate"));
175 
176     if (args.contains("-help")) {
177         qDebug() << "Usage:" << programName.toLatin1().data()
178              << "[-graphicsbased]"
179              << "[-no-compositing]"
180 #if defined(QT_CONFIGURED_WITH_OPENGL)
181              << "[-gl-viewport]"
182              << "[-webgl]"
183 #endif
184              << QString("[-viewport-update-mode %1]").arg(formatKeys(updateModes)).toLatin1().data()
185              << "[-cache-webview]"
186              << "[-maximize]"
187              << "[-show-fps]"
188              << "[-r list]"
189              << "[-robot-timeout seconds]"
190              << "[-robot-extra-time seconds]"
191              << "[-inspector-url location]"
192              << "[-tiled-backing-store]"
193              << "[-resizes-to-contents]"
194              << "[-local-storage-enabled]"
195              << "[-offline-storage-database-enabled]"
196              << "[-offline-web-application-cache-enabled]"
197              << "[-set-offline-storage-default-quota maxSize]"
198 #if defined(Q_WS_X11)
199              << "[-use-test-fonts]"
200 #endif
201              << "[-print-loaded-urls]"
202              << "URLs";
203         appQuit(0);
204     }
205 
206     const bool defaultForAnimations = args.contains("-default-animations");
207     if (args.contains("-graphicsbased") || defaultForAnimations)
208         windowOptions.useGraphicsView = true;
209 
210     if (args.contains("-no-compositing")) {
211         requiresGraphicsView("-no-compositing");
212         windowOptions.useCompositing = false;
213     }
214 
215     if (args.contains("-show-fps")) {
216         requiresGraphicsView("-show-fps");
217         windowOptions.showFrameRate = true;
218     }
219 
220     if (args.contains("-cache-webview") || defaultForAnimations) {
221         requiresGraphicsView("-cache-webview");
222         windowOptions.cacheWebView = true;
223     }
224 
225     if (args.contains("-tiled-backing-store")) {
226         requiresGraphicsView("-tiled-backing-store");
227         windowOptions.useTiledBackingStore = true;
228     }
229 
230     if (args.contains("-resizes-to-contents")) {
231         requiresGraphicsView("-resizes-to-contents");
232         windowOptions.resizesToContents = true;
233     }
234 
235     if (args.contains("-local-storage-enabled"))
236         windowOptions.useLocalStorage = true;
237 
238     if (args.contains("-maximize"))
239         windowOptions.startMaximized = true;
240 
241     if (args.contains("-offline-storage-database-enabled"))
242         windowOptions.useOfflineStorageDatabase = true;
243 
244     if (args.contains("-offline-web-application-cache-enabled"))
245         windowOptions.useOfflineWebApplicationCache = true;
246 
247     int setOfflineStorageDefaultQuotaIndex = args.indexOf("-set-offline-storage-default-quota");
248     if (setOfflineStorageDefaultQuotaIndex != -1) {
249         unsigned int maxSize = takeOptionValue(&args, setOfflineStorageDefaultQuotaIndex).toUInt();
250         windowOptions.offlineStorageDefaultQuotaSize = maxSize;
251     }
252 
253     if (defaultForAnimations)
254         windowOptions.viewportUpdateMode = QGraphicsView::BoundingRectViewportUpdate;
255 
256     QString arg1("-viewport-update-mode");
257     int modeIndex = args.indexOf(arg1);
258     if (modeIndex != -1) {
259         requiresGraphicsView(arg1);
260 
261         QString mode = takeOptionValue(&args, modeIndex);
262         if (mode.isEmpty())
263             appQuit(1, QString("%1 needs a value of one of [%2]").arg(arg1).arg(formatKeys(updateModes)));
264         int idx = updateModes.indexOf(mode);
265         if (idx == -1)
266             appQuit(1, QString("%1 value has to be one of [%2]").arg(arg1).arg(formatKeys(updateModes)));
267 
268         windowOptions.viewportUpdateMode = static_cast<QGraphicsView::ViewportUpdateMode>(idx);
269     }
270 #ifdef QT_CONFIGURED_WITH_OPENGL
271     if (args.contains("-gl-viewport") || defaultForAnimations) {
272         requiresGraphicsView("-gl-viewport");
273         windowOptions.useQGLWidgetViewport = true;
274     }
275 
276     if (args.contains("-webgl")) {
277         requiresGraphicsView("-webgl");
278         windowOptions.useWebGL = true;
279     }
280 #endif
281 
282 #if defined(Q_WS_X11)
283     if (args.contains("-use-test-fonts"))
284         windowOptions.useTestFonts = true;
285 #endif
286 
287     if (args.contains("-print-loaded-urls"))
288         windowOptions.printLoadedUrls = true;
289 
290     QString inspectorUrlArg("-inspector-url");
291     int inspectorUrlIndex = args.indexOf(inspectorUrlArg);
292     if (inspectorUrlIndex != -1)
293        windowOptions.inspectorUrl = takeOptionValue(&args, inspectorUrlIndex);
294 
295     QString remoteInspectorPortArg("-remote-inspector-port");
296     int remoteInspectorPortIndex = args.indexOf(remoteInspectorPortArg);
297     if (remoteInspectorPortIndex != -1)
298         windowOptions.remoteInspectorPort = takeOptionValue(&args, remoteInspectorPortIndex).toInt();
299 
300     int robotIndex = args.indexOf("-r");
301     if (robotIndex != -1) {
302         QString listFile = takeOptionValue(&args, robotIndex);
303         if (listFile.isEmpty())
304             appQuit(1, "-r needs a list file to start in robotized mode");
305         if (!QFile::exists(listFile))
306             appQuit(1, "The list file supplied to -r does not exist.");
307 
308         m_isRobotized = true;
309         m_urls = QStringList(listFile);
310     } else {
311         int lastArg = args.lastIndexOf(QRegExp("^-.*"));
312         m_urls = (lastArg != -1) ? args.mid(++lastArg) : args.mid(1);
313     }
314 
315     int robotTimeoutIndex = args.indexOf("-robot-timeout");
316     if (robotTimeoutIndex != -1)
317         m_robotTimeoutSeconds = takeOptionValue(&args, robotTimeoutIndex).toInt();
318 
319     int robotExtraTimeIndex = args.indexOf("-robot-extra-time");
320     if (robotExtraTimeIndex != -1)
321         m_robotExtraTimeSeconds = takeOptionValue(&args, robotExtraTimeIndex).toInt();
322 }
323 
324 
main(int argc,char ** argv)325 int main(int argc, char **argv)
326 {
327     LauncherApplication app(argc, argv);
328 
329     if (app.isRobotized()) {
330         LauncherWindow* window = new LauncherWindow();
331         UrlLoader loader(window->page()->mainFrame(), app.urls().at(0), app.robotTimeout(), app.robotExtraTime());
332         loader.loadNext();
333         window->show();
334         return launcherMain(app);
335     }
336 
337     QStringList urls = app.urls();
338 
339     if (urls.isEmpty()) {
340         QString defaultIndexFile = QString("%1/%2").arg(QDir::homePath()).arg(QLatin1String("index.html"));
341         if (QFile(defaultIndexFile).exists())
342             urls.append(QString("file://") + defaultIndexFile);
343         else
344             urls.append("");
345     }
346 
347     LauncherWindow* window = 0;
348     foreach (QString url, urls) {
349         LauncherWindow* newWindow;
350         if (!window)
351             newWindow = window = new LauncherWindow(&windowOptions);
352         else
353             newWindow = window->newWindow();
354 
355         newWindow->load(url);
356     }
357 
358     window->show();
359     return launcherMain(app);
360 }
361 
362 #include "main.moc"
363