<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[212517] trunk/Tools</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/212517">212517</a></dd>
<dt>Author</dt> <dd>achristensen@apple.com</dd>
<dt>Date</dt> <dd>2017-02-16 18:15:35 -0800 (Thu, 16 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Unreviewed, rolling out <a href="http://trac.webkit.org/projects/webkit/changeset/212514">r212514</a>.
https://bugs.webkit.org/show_bug.cgi?id=168489

broke test runner (Requested by alexchristensen on #webkit).

Reverted changeset:

&quot;Remove EFL-specific files in Tools.&quot;
http://trac.webkit.org/changeset/212514

Patch by Commit Queue &lt;commit-queue@webkit.org&gt; on 2017-02-16</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/Tools/ImageDiff/efl/</li>
<li><a href="#trunkToolsImageDiffeflImageDiffcpp">trunk/Tools/ImageDiff/efl/ImageDiff.cpp</a></li>
<li>trunk/Tools/MiniBrowser/efl/</li>
<li><a href="#trunkToolsMiniBrowsereflCMakeListstxt">trunk/Tools/MiniBrowser/efl/CMakeLists.txt</a></li>
<li><a href="#trunkToolsMiniBrowsereflmainc">trunk/Tools/MiniBrowser/efl/main.c</a></li>
<li><a href="#trunkToolsScriptsrunefltests">trunk/Tools/Scripts/run-efl-tests</a></li>
<li><a href="#trunkToolsScriptsupdatewebkitefllibs">trunk/Tools/Scripts/update-webkitefl-libs</a></li>
<li><a href="#trunkToolsScriptswebkitpyporteflpy">trunk/Tools/Scripts/webkitpy/port/efl.py</a></li>
<li><a href="#trunkToolsScriptswebkitpyportefl_unittestpy">trunk/Tools/Scripts/webkitpy/port/efl_unittest.py</a></li>
<li>trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/</li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2eflWKViewClientWebProcessCallbackscpp">trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2eflWKViewClientWebProcessCallbacks_Bundlecpp">trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks_Bundle.cpp</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2eflWKViewScrollTocpp">trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewScrollTo.cpp</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2eflscrollTohtml">trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/scrollTo.html</a></li>
<li>trunk/Tools/TestWebKitAPI/efl/</li>
<li><a href="#trunkToolsTestWebKitAPIeflInjectedBundleControllercpp">trunk/Tools/TestWebKitAPI/efl/InjectedBundleController.cpp</a></li>
<li><a href="#trunkToolsTestWebKitAPIeflPlatformUtilitiescpp">trunk/Tools/TestWebKitAPI/efl/PlatformUtilities.cpp</a></li>
<li><a href="#trunkToolsTestWebKitAPIeflPlatformWebViewcpp">trunk/Tools/TestWebKitAPI/efl/PlatformWebView.cpp</a></li>
<li><a href="#trunkToolsTestWebKitAPIeflmaincpp">trunk/Tools/TestWebKitAPI/efl/main.cpp</a></li>
<li>trunk/Tools/WebKitTestRunner/InjectedBundle/efl/</li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleeflActivateFontsEflcpp">trunk/Tools/WebKitTestRunner/InjectedBundle/efl/ActivateFontsEfl.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleeflFontManagementcpp">trunk/Tools/WebKitTestRunner/InjectedBundle/efl/FontManagement.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleeflFontManagementh">trunk/Tools/WebKitTestRunner/InjectedBundle/efl/FontManagement.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleeflInjectedBundleEflcpp">trunk/Tools/WebKitTestRunner/InjectedBundle/efl/InjectedBundleEfl.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleeflTestRunnerEflcpp">trunk/Tools/WebKitTestRunner/InjectedBundle/efl/TestRunnerEfl.cpp</a></li>
<li>trunk/Tools/WebKitTestRunner/efl/</li>
<li><a href="#trunkToolsWebKitTestRunnereflEventSenderProxyEflcpp">trunk/Tools/WebKitTestRunner/efl/EventSenderProxyEfl.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnereflPlatformWebViewEflcpp">trunk/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnereflTestControllerEflcpp">trunk/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnereflmaincpp">trunk/Tools/WebKitTestRunner/efl/main.cpp</a></li>
<li>trunk/Tools/efl/</li>
<li><a href="#trunkToolseflinstalldependencies">trunk/Tools/efl/install-dependencies</a></li>
<li><a href="#trunkToolsefljhbuildoptionalmodules">trunk/Tools/efl/jhbuild-optional.modules</a></li>
<li><a href="#trunkToolsefljhbuildmodules">trunk/Tools/efl/jhbuild.modules</a></li>
<li><a href="#trunkToolsefljhbuildrc">trunk/Tools/efl/jhbuildrc</a></li>
<li>trunk/Tools/efl/patches/</li>
<li><a href="#trunkToolseflpatchesevasfixbuildwithgiflib5patch">trunk/Tools/efl/patches/evas-fix-build-with-giflib5.patch</a></li>
<li><a href="#trunkToolseflpatchesfontconfigC11requiresaspacebetweenliteralandidentifierpatch">trunk/Tools/efl/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch</a></li>
<li><a href="#trunkToolseflpatchesgstlibavpatch">trunk/Tools/efl/patches/gst-libav.patch</a></li>
<li><a href="#trunkToolseflpatchesgstpluginsbasertprtcpbufferfixtypoinenumpatch">trunk/Tools/efl/patches/gst-plugins-base-rtp-rtcpbuffer-fix-typo-in-enum.patch</a></li>
<li><a href="#trunkToolseflpatchesgstpluginsgoodRevertqtdemuxexposestreamswithfirstmoofforfrpatch">trunk/Tools/efl/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch</a></li>
<li><a href="#trunkToolseflpatchesgstpluginsgoodusethetfdtdecodetimepatch">trunk/Tools/efl/patches/gst-plugins-good-use-the-tfdt-decode-time.patch</a></li>
<li><a href="#trunkToolseflpatchesopenwebrtcgstpluginsclangwarningfixpatch">trunk/Tools/efl/patches/openwebrtc-gst-plugins-clang-warning-fix.patch</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (212516 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2017-02-17 01:54:10 UTC (rev 212516)
+++ trunk/Tools/ChangeLog        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2017-02-16  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r212514.
+        https://bugs.webkit.org/show_bug.cgi?id=168489
+
+        broke test runner (Requested by alexchristensen on #webkit).
+
+        Reverted changeset:
+
+        &quot;Remove EFL-specific files in Tools.&quot;
+        http://trac.webkit.org/changeset/212514
+
</ins><span class="cx"> 2017-02-16  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Remove EFL-specific files in Tools.
</span></span></pre></div>
<a id="trunkToolsImageDiffeflImageDiffcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/ImageDiff/efl/ImageDiff.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ImageDiff/efl/ImageDiff.cpp                                (rev 0)
+++ trunk/Tools/ImageDiff/efl/ImageDiff.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,365 @@
</span><ins>+/*
+ * Copyright (C) 2009 Zan Dobersek &lt;zandobersek@gmail.com&gt;
+ * Copyright (C) 2010 Igalia S.L.
+ * Copyright (C) 2011 ProFUSION Embedded Systems
+ * Copyright (C) 2011 Samsung Electronics
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. (&quot;Apple&quot;) nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+
+#include &lt;Ecore.h&gt;
+#include &lt;Ecore_Evas.h&gt;
+#include &lt;Evas.h&gt;
+#include &lt;algorithm&gt;
+#include &lt;cmath&gt;
+#include &lt;cstdio&gt;
+#include &lt;cstdlib&gt;
+#include &lt;getopt.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;unistd.h&gt;
+#include &lt;wtf/StdLibExtras.h&gt;
+#include &lt;wtf/efl/UniquePtrEfl.h&gt;
+
+enum PixelComponent {
+    Red,
+    Green,
+    Blue,
+    Alpha
+};
+
+static EflUniquePtr&lt;Ecore_Evas&gt; gEcoreEvas;
+static double gTolerance = 0;
+
+static void abortWithErrorMessage(const char* errorMessage);
+
+static unsigned char* pixelFromImageData(unsigned char* imageData, int rowStride, int x, int y)
+{
+    return imageData + (y * rowStride) + (x &lt;&lt; 2);
+}
+
+static Evas_Object* differenceImageFromDifferenceBuffer(Evas* evas, unsigned char* buffer, int width, int height)
+{
+    Evas_Object* image = evas_object_image_filled_add(evas);
+    if (!image)
+        abortWithErrorMessage(&quot;could not create difference image&quot;);
+
+    evas_object_image_size_set(image, width, height);
+    evas_object_image_colorspace_set(image, EVAS_COLORSPACE_ARGB8888);
+
+    unsigned char* diffPixels = static_cast&lt;unsigned char*&gt;(evas_object_image_data_get(image, EINA_TRUE));
+    const int rowStride = evas_object_image_stride_get(image);
+    for (int x = 0; x &lt; width; x++) {
+        for (int y = 0; y &lt; height; y++) {
+            unsigned char* diffPixel = pixelFromImageData(diffPixels, rowStride, x, y);
+            diffPixel[Red] = diffPixel[Green] = diffPixel[Blue] = *buffer++;
+            diffPixel[Alpha] = 0xff;
+        }
+    }
+
+    evas_object_image_data_set(image, diffPixels);
+
+    return image;
+}
+
+static float computeDistanceBetweenPixelComponents(unsigned char actualComponent, unsigned char baseComponent)
+{
+    return (actualComponent - baseComponent) / std::max&lt;float&gt;(255 - baseComponent, baseComponent);
+}
+
+static float computeDistanceBetweenPixelComponents(unsigned char* actualPixel, unsigned char* basePixel, PixelComponent component)
+{
+    return computeDistanceBetweenPixelComponents(actualPixel[component], basePixel[component]);
+}
+
+static float calculatePixelDifference(unsigned char* basePixel, unsigned char* actualPixel)
+{
+    const float red = computeDistanceBetweenPixelComponents(actualPixel, basePixel, Red);
+    const float green = computeDistanceBetweenPixelComponents(actualPixel, basePixel, Green);
+    const float blue = computeDistanceBetweenPixelComponents(actualPixel, basePixel, Blue);
+    const float alpha = computeDistanceBetweenPixelComponents(actualPixel, basePixel, Alpha);
+    return sqrtf(red * red + green * green + blue * blue + alpha * alpha) / 2.0f;
+}
+
+static float calculateDifference(Evas_Object* baselineImage, Evas_Object* actualImage, EflUniquePtr&lt;Evas_Object&gt;&amp; differenceImage)
+{
+    int width, height, baselineWidth, baselineHeight;
+    evas_object_image_size_get(actualImage, &amp;width, &amp;height);
+    evas_object_image_size_get(baselineImage, &amp;baselineWidth, &amp;baselineHeight);
+
+    if (width != baselineWidth || height != baselineHeight) {
+        printf(&quot;Error, test and reference image have different sizes.\n&quot;);
+        return 100; // Completely different.
+    }
+
+    auto diffBuffer = std::make_unique&lt;unsigned char[]&gt;(width * height);
+    if (!diffBuffer)
+        abortWithErrorMessage(&quot;could not create difference buffer&quot;);
+
+    const int actualRowStride = evas_object_image_stride_get(actualImage);
+    const int baseRowStride = evas_object_image_stride_get(baselineImage);
+    unsigned numberOfDifferentPixels = 0;
+    float totalDistance = 0;
+    float maxDistance = 0;
+    unsigned char* actualPixels = static_cast&lt;unsigned char*&gt;(evas_object_image_data_get(actualImage, EINA_FALSE));
+    unsigned char* basePixels = static_cast&lt;unsigned char*&gt;(evas_object_image_data_get(baselineImage, EINA_FALSE));
+    unsigned char* currentDiffPixel = diffBuffer.get();
+
+    for (int x = 0; x &lt; width; x++) {
+        for (int y = 0; y &lt; height; y++) {
+            unsigned char* actualPixel = pixelFromImageData(actualPixels, actualRowStride, x, y);
+            unsigned char* basePixel = pixelFromImageData(basePixels, baseRowStride, x, y);
+
+            const float distance = calculatePixelDifference(basePixel, actualPixel);
+            *currentDiffPixel++ = static_cast&lt;unsigned char&gt;(distance * 255.0f);
+
+            if (distance &gt;= 1.0f / 255.0f) {
+                ++numberOfDifferentPixels;
+                totalDistance += distance;
+                maxDistance = std::max&lt;float&gt;(maxDistance, distance);
+            }
+        }
+    }
+
+    // When using evas_object_image_data_get(), a complementary evas_object_data_set() must be
+    // issued to balance the reference count, even if the image hasn't been changed.
+    evas_object_image_data_set(baselineImage, basePixels);
+    evas_object_image_data_set(actualImage, actualPixels);
+
+    // Compute the difference as a percentage combining both the number of
+    // different pixels and their difference amount i.e. the average distance
+    // over the entire image
+    float difference = 0;
+    if (numberOfDifferentPixels)
+        difference = 100.0f * totalDistance / (height * width);
+    if (difference &lt;= gTolerance)
+        difference = 0;
+    else {
+        difference = roundf(difference * 100.0f) / 100.0f;
+        difference = std::max(difference, 0.01f); // round to 2 decimal places
+
+        differenceImage = EflUniquePtr&lt;Evas_Object&gt;(differenceImageFromDifferenceBuffer(evas_object_evas_get(baselineImage), diffBuffer.get(), width, height));
+    }
+
+    return difference;
+}
+
+static int getTemporaryFile(char *fileName, size_t fileNameLength)
+{
+    char* tempDirectory = getenv(&quot;TMPDIR&quot;);
+    if (!tempDirectory)
+        tempDirectory = getenv(&quot;TEMP&quot;);
+
+    if (tempDirectory)
+        snprintf(fileName, fileNameLength, &quot;%s/ImageDiffXXXXXX.png&quot;, tempDirectory);
+    else {
+#if __linux__
+        strcpy(fileName, &quot;/dev/shm/ImageDiffXXXXXX.png&quot;);
+        const int fileDescriptor = mkstemps(fileName, sizeof(&quot;.png&quot;) - 1);
+        if (fileDescriptor &gt;= 0)
+            return fileDescriptor;
+#endif // __linux__
+
+        strcpy(fileName, &quot;ImageDiffXXXXXX.png&quot;);
+    }
+
+    return mkstemps(fileName, sizeof(&quot;.png&quot;) - 1);
+}
+
+static void printImage(Evas_Object* image)
+{
+    char fileName[PATH_MAX];
+
+    const int tempImageFd = getTemporaryFile(fileName, PATH_MAX);
+    if (tempImageFd == -1)
+        abortWithErrorMessage(&quot;could not create temporary file&quot;);
+
+    evas_render(evas_object_evas_get(image));
+
+    if (evas_object_image_save(image, fileName, 0, 0)) {
+        struct stat fileInfo;
+        if (!stat(fileName, &amp;fileInfo)) {
+            printf(&quot;Content-Length: %ld\n&quot;, fileInfo.st_size);
+            fflush(stdout);
+
+            unsigned char buffer[2048];
+            ssize_t bytesRead;
+            while ((bytesRead = read(tempImageFd, buffer, sizeof(buffer))) &gt; 0) {
+                ssize_t bytesWritten = 0;
+                ssize_t count;
+                do {
+                    if ((count = write(1, buffer + bytesWritten, bytesRead - bytesWritten)) &lt;= 0)
+                        break;
+                    bytesWritten += count;
+                } while (bytesWritten &lt; bytesRead);
+            }
+        }
+    }
+    close(tempImageFd);
+    unlink(fileName);
+}
+
+static void printImageDifferences(Evas_Object* baselineImage, Evas_Object* actualImage)
+{
+    EflUniquePtr&lt;Evas_Object&gt; differenceImage;
+    const float difference = calculateDifference(baselineImage, actualImage, differenceImage);
+
+    if (difference &gt; 0.0f) {
+        if (differenceImage)
+            printImage(differenceImage.get());
+
+        printf(&quot;diff: %01.2f%% failed\n&quot;, difference);
+    } else
+        printf(&quot;diff: %01.2f%% passed\n&quot;, difference);
+}
+
+static void resizeEcoreEvasIfNeeded(Evas_Object* image)
+{
+    int newWidth, newHeight;
+    evas_object_image_size_get(image, &amp;newWidth, &amp;newHeight);
+
+    int currentWidth, currentHeight;
+    ecore_evas_screen_geometry_get(gEcoreEvas.get(), 0, 0, &amp;currentWidth, &amp;currentHeight);
+
+    if (newWidth &gt; currentWidth)
+        currentWidth = newWidth;
+    if (newHeight &gt; currentHeight)
+        currentHeight = newHeight;
+
+    ecore_evas_resize(gEcoreEvas.get(), currentWidth, currentHeight);
+}
+
+static EflUniquePtr&lt;Evas_Object&gt; readImageFromStdin(Evas* evas, long imageSize)
+{
+    auto imageBuffer = std::make_unique&lt;unsigned char[]&gt;(imageSize);
+    if (!imageBuffer)
+        abortWithErrorMessage(&quot;cannot allocate image&quot;);
+
+    const size_t bytesRead = fread(imageBuffer.get(), 1, imageSize, stdin);
+    if (!bytesRead)
+        return nullptr;
+
+    Evas_Object* image = evas_object_image_filled_add(evas);
+    evas_object_image_colorspace_set(image, EVAS_COLORSPACE_ARGB8888);
+    evas_object_image_memfile_set(image, imageBuffer.get(), bytesRead, 0, 0);
+
+    resizeEcoreEvasIfNeeded(image);
+
+    return EflUniquePtr&lt;Evas_Object&gt;(image);
+}
+
+static bool parseCommandLineOptions(int argc, char** argv)
+{
+    static const option options[] = {
+        { &quot;tolerance&quot;, required_argument, 0, 't' },
+        { 0, 0, 0, 0 }
+    };
+    int option;
+
+    while ((option = getopt_long(argc, (char* const*)argv, &quot;t:&quot;, options, 0)) != -1) {
+        switch (option) {
+        case 't':
+            gTolerance = atof(optarg);
+            break;
+        case '?':
+        case ':':
+            return false;
+        }
+    }
+
+    return true;
+}
+
+static void shutdownEfl()
+{
+    ecore_evas_shutdown();
+    ecore_shutdown();
+    evas_shutdown();
+}
+
+static void abortWithErrorMessage(const char* errorMessage)
+{
+    shutdownEfl();
+
+    printf(&quot;Error, %s.\n&quot;, errorMessage);
+    exit(EXIT_FAILURE);
+}
+
+static Evas* initEfl()
+{
+    evas_init();
+    ecore_init();
+    ecore_evas_init();
+
+    gEcoreEvas = EflUniquePtr&lt;Ecore_Evas&gt;(ecore_evas_buffer_new(1, 1));
+    Evas* evas = ecore_evas_get(gEcoreEvas.get());
+    if (!evas)
+        abortWithErrorMessage(&quot;could not create Ecore_Evas buffer&quot;);
+
+    return evas;
+}
+
+int main(int argc, char* argv[])
+{
+    if (!parseCommandLineOptions(argc, argv))
+        return EXIT_FAILURE;
+
+    Evas* evas = initEfl();
+
+    EflUniquePtr&lt;Evas_Object&gt; actualImage;
+    EflUniquePtr&lt;Evas_Object&gt; baselineImage;
+
+    char buffer[2048];
+    while (fgets(buffer, sizeof(buffer), stdin)) {
+        char* contentLengthStart = strstr(buffer, &quot;Content-Length: &quot;);
+        if (!contentLengthStart)
+            continue;
+        long imageSize;
+        if (sscanf(contentLengthStart, &quot;Content-Length: %ld&quot;, &amp;imageSize) == 1) {
+            if (imageSize &lt;= 0)
+                abortWithErrorMessage(&quot;image size must be specified&quot;);
+
+            if (!actualImage)
+                actualImage = readImageFromStdin(evas, imageSize);
+            else if (!baselineImage) {
+                baselineImage = readImageFromStdin(evas, imageSize);
+
+                printImageDifferences(baselineImage.get(), actualImage.get());
+
+                actualImage.reset();
+                baselineImage.reset();
+            }
+        }
+
+        fflush(stdout);
+    }
+
+    gEcoreEvas = nullptr; // Make sure ecore_evas_free is called before the EFL are shut down
+
+    shutdownEfl();
+    return EXIT_SUCCESS;
+}
</ins></span></pre></div>
<a id="trunkToolsMiniBrowsereflCMakeListstxt"></a>
<div class="addfile"><h4>Added: trunk/Tools/MiniBrowser/efl/CMakeLists.txt (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/MiniBrowser/efl/CMakeLists.txt                                (rev 0)
+++ trunk/Tools/MiniBrowser/efl/CMakeLists.txt        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,70 @@
</span><ins>+set(MiniBrowser_DIR &quot;${TOOLS_DIR}/MiniBrowser/efl&quot;)
+
+# Elementary is needed to build MiniBrowser
+find_package(Eldbus ${EFL_REQUIRED_VERSION} ${EFL_CONFIG_MODE})
+find_package(Elementary ${EFL_REQUIRED_VERSION} ${EFL_CONFIG_MODE})
+find_package(Ethumb ${EFL_REQUIRED_VERSION} ${EFL_CONFIG_MODE})
+find_package(EthumbClient ${EFL_REQUIRED_VERSION} ${EFL_CONFIG_MODE})
+
+set(MiniBrowser_SOURCES
+    ${MiniBrowser_DIR}/main.c
+)
+
+set(MiniBrowser_INCLUDE_DIRECTORIES
+    ${DERIVED_SOURCES_WEBKIT2_DIR}/include
+    ${WEBKIT2_DIR}/UIProcess/API/efl
+    ${WEBKIT2_DIR}
+    ${CMAKE_SOURCE_DIR}/Source
+)
+
+set(MiniBrowser_SYSTEM_INCLUDE_DIRECTORIES
+    ${CAIRO_INCLUDE_DIRS}
+    ${ECORE_INCLUDE_DIRS}
+    ${ECORE_EVAS_INCLUDE_DIRS}
+    ${ECORE_CON_INCLUDE_DIRS}
+    ${ECORE_FILE_INCLUDE_DIRS}
+    ${ECORE_IMF_INCLUDE_DIRS}
+    ${ECORE_INPUT_INCLUDE_DIRS}
+    ${EDJE_INCLUDE_DIRS}
+    ${EET_INCLUDE_DIRS}
+    ${EO_INCLUDE_DIRS}
+    ${DBUS_INCLUDE_DIRS}
+    ${EFREET_INCLUDE_DIRS}
+    ${EINA_INCLUDE_DIRS}
+    ${ELDBUS_INCLUDE_DIRS}
+    ${ELEMENTARY_INCLUDE_DIRS}
+    ${ETHUMB_INCLUDE_DIRS}
+    ${ETHUMB_CLIENT_INCLUDE_DIRS}
+    ${EVAS_INCLUDE_DIRS}
+)
+
+set(MiniBrowser_LIBRARIES
+    JavaScriptCore
+    WebCore
+    WebKit2
+    ${CAIRO_LIBRARIES}
+    ${ECORE_LIBRARIES}
+    ${ECORE_EVAS_LIBRARIES}
+    ${ECORE_FILE_LIBRARIES}
+    ${EDJE_LIBRARIES}
+    ${EET_LIBRARIES}
+    ${EINA_LIBRARIES}
+    ${ELEMENTARY_LIBRARIES}
+    ${EO_LIBRARIES}
+    ${EVAS_LIBRARIES}
+    ${FONTCONFIG_LIBRARIES}
+    ${GLIB_LIBRARIES}
+    ${GLIB_GTHREAD_LIBRARIES}
+    ${LIBSOUP_LIBRARIES}
+    ${LIBXML2_LIBRARIES}
+    ${LIBXSLT_LIBRARIES} -lm
+    ${OPENGL_LIBRARIES}
+    ${SQLITE_LIBRARIES}
+)
+
+if (ELEMENTARY_FOUND)
+    include_directories(${MiniBrowser_INCLUDE_DIRECTORIES})
+    include_directories(SYSTEM ${MiniBrowser_SYSTEM_INCLUDE_DIRECTORIES})
+    add_executable(MiniBrowser ${MiniBrowser_SOURCES})
+    target_link_libraries(MiniBrowser ${MiniBrowser_LIBRARIES})
+endif ()
</ins></span></pre></div>
<a id="trunkToolsMiniBrowsereflmainc"></a>
<div class="addfile"><h4>Added: trunk/Tools/MiniBrowser/efl/main.c (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/MiniBrowser/efl/main.c                                (rev 0)
+++ trunk/Tools/MiniBrowser/efl/main.c        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,2536 @@
</span><ins>+/*
+ * Copyright (C) 2012 Samsung Electronics
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include &quot;EWebKit2.h&quot;
+#include &lt;Ecore.h&gt;
+#include &lt;Ecore_Evas.h&gt;
+#include &lt;Ecore_Getopt.h&gt;
+#include &lt;Eet.h&gt;
+#include &lt;Eina.h&gt;
+#include &lt;Elementary.h&gt;
+#include &lt;Evas.h&gt;
+
+extern int efreet_cache_update;
+
+static const char DEFAULT_URL[] = &quot;http://www.ewebkit.org/&quot;;
+static const char APP_NAME[] = &quot;EFL MiniBrowser&quot;;
+static const char JAVASCRIPT_SCHEME[] = &quot;javascript:&quot;;
+static const char FILE_SCHEME[] = &quot;file://&quot;;
+static const char HTTP_SCHEME[] = &quot;http://&quot;;
+static const int TOOL_BAR_ICON_SIZE = 24;
+static const int TOOL_BAR_BUTTON_SIZE = 32;
+static const int SEARCH_FIELD_SIZE = 200;
+static const int SEARCH_BUTTON_SIZE = 30;
+static const int MAX_SEARCH_COUNT = 1000;
+static const double TOOLTIP_DELAY_SECONDS = 1.0;
+static const double LONGPRESS_INTERVAL_SECONDS = 1.5;
+static const double LIST_ITEM_HEIGHT = 24.35;
+
+static Eina_List *windows = NULL;
+static char *evas_engine_name = NULL;
+static char *user_agent_string = NULL;
+static char *extensions_path = NULL;
+static char *background_color_string = NULL;
+static Eina_Bool encoding_detector_enabled = EINA_FALSE;
+static Eina_Bool frame_flattening_enabled = EINA_FALSE;
+static Eina_Bool local_storage_enabled = EINA_TRUE;
+static Eina_Bool offline_web_application_cache_enabled = EINA_TRUE;
+static Eina_Bool fullscreen_enabled = EINA_FALSE;
+static Eina_Bool spell_checking_enabled = EINA_FALSE;
+static Eina_Bool web_security_enabled = EINA_TRUE;
+static Eina_Bool touch_events_enabled = EINA_FALSE;
+static Eina_Bool fixed_layout_enabled = EINA_TRUE;
+static Eina_Bool separated_process_enabled = EINA_FALSE;
+static Eina_Bool longpress_enabled = EINA_FALSE;
+static int window_width = 1000;
+static int window_height = 800;
+static int color_picker_width = 350;
+static int color_picker_height = 500;
+static int search_flags = EWK_FIND_OPTIONS_SHOW_HIGHLIGHT | EWK_FIND_OPTIONS_WRAP_AROUND | EWK_FIND_OPTIONS_CASE_INSENSITIVE;
+/* Default value of device_pixel_ratio is '0' so that we don't set custom device
+ * scale factor unless it's required by the User. */
+static double device_pixel_ratio = 0;
+static Eina_Bool legacy_behavior_enabled = EINA_FALSE;
+
+#define DEFAULT_ZOOM_LEVEL 5 // Set default zoom level to 1.0 (index 5 on zoomLevels).
+// The zoom values are chosen to be like in Mozilla Firefox 3.
+const static float zoomLevels[] = {0.3, 0.5, 0.67, 0.8, 0.9, 1.0, 1.1, 1.2, 1.33, 1.5, 1.7, 2.0, 2.4, 3.0};
+static int _log_domain_id = -1;
+
+#define INFO(...) EINA_LOG_DOM_INFO(_log_domain_id, __VA_ARGS__)
+#define ERROR(...) EINA_LOG_DOM_ERR(_log_domain_id, __VA_ARGS__)
+
+static Eina_Bool
+zoom_level_set(Evas_Object *webview, int level)
+{
+   if (level &lt; 0  || level &gt;= sizeof(zoomLevels) / sizeof(float))
+     return EINA_FALSE;
+
+   return ewk_view_page_zoom_set(webview, zoomLevels[level]);
+}
+
+static Ewk_View_Smart_Class *miniBrowserViewSmartClass()
+{
+   static Ewk_View_Smart_Class ewkViewClass = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION(&quot;MiniBrowser_View&quot;);
+   return &amp;ewkViewClass;
+}
+
+typedef struct _Tooltip_Information {
+   Ecore_Timer *show_timer;
+   Eina_Bool activated;
+   Eina_Bool text_set;
+   Eina_Bool shown;
+} Tooltip_Information;
+
+typedef struct _Color_Selector {
+   Ewk_Color_Picker *ewk_picker;
+   Evas_Object *elm_selector;
+   Evas_Object *elm_selector_window;
+} Color_Selector;
+
+typedef struct _Browser_Window {
+   Evas_Object *elm_window;
+   Evas_Object *ewk_view;
+   Evas_Object *horizontal_layout;
+   Evas_Object *vertical_layout;
+   Evas_Object *url_bar;
+   Evas_Object *back_button;
+   Evas_Object *forward_button;
+   struct {
+     Evas_Object *elm_menu;
+     Ewk_Popup_Menu *ewk_menu;
+    } popup;
+   struct {
+     Evas_Object *search_bar;
+     Evas_Object *search_field;
+     Evas_Object *search_field_count;
+     Evas_Object *backward_button;
+     Evas_Object *forward_button;
+     Evas_Object *search_case_check_box;
+     Evas_Object *search_word_start_check_box;
+     Evas_Object *close_button;
+   } search;
+   struct {
+     Evas_Object *history_box;
+     Evas_Object *history_list;
+     Eina_List *history_list_items;
+   } history;
+   int current_zoom_level;
+   Tooltip_Information tooltip;
+   Color_Selector color_selector;
+   struct {
+     Evas_Object *elm_menu;
+     Ewk_Context_Menu *ewk_menu;
+   } context_menu;
+} Browser_Window;
+
+typedef struct _File_Selector_Data {
+   Browser_Window* parent;
+   Evas_Object *elm_window;
+   Ewk_File_Chooser_Request *request;
+} File_Selector_Data;
+
+typedef struct _Auth_Data {
+   Evas_Object *popup;
+   Ewk_Auth_Request *request;
+   Evas_Object *username_entry;
+   Evas_Object *password_entry;
+} Auth_Data;
+
+static const Ecore_Getopt options = {
+   &quot;MiniBrowser&quot;,
+   &quot;%prog [options] [url]&quot;,
+   &quot;0.0.1&quot;,
+   &quot;(C)2012 Samsung Electronics\n (C)2012 Intel Corporation\n&quot;,
+   &quot;&quot;,
+   &quot;Test Web Browser using the Enlightenment Foundation Libraries (EFL) port of WebKit2&quot;,
+   EINA_TRUE, {
+     ECORE_GETOPT_STORE_STR
+         ('e', &quot;engine&quot;, &quot;Ecore-evas engine to use.&quot;),
+     ECORE_GETOPT_STORE_STR
+         ('s', &quot;window-size&quot;, &quot;Window size in following format (width)x(height).&quot;),
+     ECORE_GETOPT_STORE_STR
+         ('u', &quot;user-agent&quot;, &quot;User agent to set.&quot;),
+     ECORE_GETOPT_STORE_STR
+         ('x', &quot;extensions-path&quot;, &quot;The path which extensions are stored.&quot;),
+     ECORE_GETOPT_STORE_DOUBLE
+         ('r', &quot;device-pixel-ratio&quot;, &quot;Ratio between the CSS units and device pixels.&quot;),
+     ECORE_GETOPT_CALLBACK_NOARGS
+         ('E', &quot;list-engines&quot;, &quot;List ecore-evas engines.&quot;,
+          ecore_getopt_callback_ecore_evas_list_engines, NULL),
+     ECORE_GETOPT_STORE_DEF_BOOL
+         ('c', &quot;encoding-detector&quot;, &quot;Enable/disable encoding detector.&quot;, EINA_FALSE),
+     ECORE_GETOPT_STORE_STR
+         ('C', &quot;background-color&quot;, &quot;Background color of page. ex) -C=255:255:255:255&quot;),
+     ECORE_GETOPT_STORE_DEF_BOOL
+         ('f', &quot;flattening&quot;, &quot;Enable/disable frame flattening.&quot;, EINA_FALSE),
+     ECORE_GETOPT_STORE_DEF_BOOL
+         ('l', &quot;local-storage&quot;, &quot;Enable/disable HTML5 local storage.&quot;, EINA_TRUE),
+     ECORE_GETOPT_STORE_DEF_BOOL
+         ('o', &quot;offline-web-application-cache&quot;, &quot;Enable/disable offline web application cache.&quot;, EINA_TRUE),
+     ECORE_GETOPT_STORE_DEF_BOOL
+         ('F', &quot;full-screen&quot;, &quot;Start in full-screen.&quot;, EINA_FALSE),
+     ECORE_GETOPT_STORE_DEF_BOOL
+         ('t', &quot;text-checking&quot;, &quot;Enable/disable text spell checking.&quot;, EINA_FALSE),
+     ECORE_GETOPT_STORE_DEF_BOOL
+         ('T', &quot;touch-events&quot;, &quot;Enable/disable touch events.&quot;, EINA_FALSE),
+     ECORE_GETOPT_STORE_DEF_BOOL
+         ('L', &quot;fixed-layout&quot;, &quot;Enable/disable fixed layout.&quot;, EINA_TRUE),
+     ECORE_GETOPT_STORE_DEF_STR
+         ('p', &quot;policy-cookies&quot;, &quot;Cookies policy:\n  always - always accept,\n  never - never accept,\n  no-third-party - don't accept third-party cookies.&quot;, &quot;no-third-party&quot;),
+     ECORE_GETOPT_STORE_DEF_BOOL
+         ('w', &quot;web-security&quot;, &quot;enable/disable web security.&quot;, EINA_TRUE),
+     ECORE_GETOPT_STORE_DEF_BOOL
+         ('S', &quot;separate-process&quot;, &quot;Create new window in separated web process.&quot;, EINA_FALSE),
+     ECORE_GETOPT_VERSION
+         ('V', &quot;version&quot;),
+     ECORE_GETOPT_COPYRIGHT
+         ('R', &quot;copyright&quot;),
+     ECORE_GETOPT_HELP
+         ('h', &quot;help&quot;),
+     ECORE_GETOPT_SENTINEL
+   }
+};
+
+static Eina_Stringshare *_file_entry_dialog_show(Browser_Window *window, const char *label_tag, const char *default_text);
+static Browser_Window *window_create(Ewk_View_Configuration* configuration, int width, int height);
+static Ewk_View_Configuration* configuration();
+
+static Browser_Window *window_find_with_ewk_view(Evas_Object *ewk_view)
+{
+   Eina_List *l;
+   void *data;
+
+   if (!ewk_view)
+     return NULL;
+
+   EINA_LIST_FOREACH(windows, l, data) {
+     Browser_Window *window = (Browser_Window *)data;
+     if (window-&gt;ewk_view == ewk_view)
+       return window;
+   }
+   return NULL;
+}
+
+static Eina_Bool
+_tooltip_show(void *user_data)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   window-&gt;tooltip.show_timer = NULL;
+   elm_object_tooltip_show(window-&gt;elm_window);
+   window-&gt;tooltip.shown = EINA_TRUE;
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+window_tooltip_hide(Browser_Window *window)
+{
+   if (window-&gt;tooltip.show_timer) {
+     ecore_timer_del(window-&gt;tooltip.show_timer);
+     window-&gt;tooltip.show_timer = NULL;
+   }
+
+   if (window-&gt;tooltip.shown) {
+     elm_object_tooltip_hide(window-&gt;elm_window);
+     window-&gt;tooltip.shown = EINA_FALSE;
+   }
+}
+
+static void
+window_tooltip_update(Browser_Window *window)
+{
+   window_tooltip_hide(window);
+
+   if (window-&gt;tooltip.activated &amp;&amp; window-&gt;tooltip.text_set)
+     window-&gt;tooltip.show_timer = ecore_timer_add(TOOLTIP_DELAY_SECONDS, _tooltip_show, window);
+}
+
+static void
+_mouse_in_cb(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   window-&gt;tooltip.activated = EINA_TRUE;
+   window_tooltip_update(window);
+}
+
+static void
+_mouse_move_cb(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info)
+{
+   window_tooltip_update((Browser_Window *)user_data);
+}
+
+static void
+_mouse_out_cb(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   window-&gt;tooltip.activated = EINA_FALSE;
+   window_tooltip_update(window);
+}
+
+static void
+_mouse_wheel_cb(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   const Evas_Modifier *mod = evas_key_modifier_get(e);
+   Evas_Event_Mouse_Wheel *ev = (Evas_Event_Mouse_Wheel *)event_info;
+   Eina_Bool shiftPressed = evas_key_modifier_is_set(mod, &quot;Shift&quot;);
+   Eina_Bool ctrlPressed = evas_key_modifier_is_set(mod, &quot;Control&quot;);
+
+   if (!shiftPressed &amp;&amp; !ctrlPressed)
+     return;
+
+   /* navigate history or zoom web page based on mouse wheel scroll action with shift or control key */
+   if (shiftPressed) {
+     if (ev-&gt;z == -1 &amp;&amp; ewk_view_forward_possible(ewk_view)) {
+       ewk_view_forward(ewk_view);
+       elm_object_disabled_set(window-&gt;forward_button, !ewk_view_forward_possible(ewk_view));
+     } else if (ev-&gt;z == 1 &amp;&amp; ewk_view_back_possible(ewk_view)) {
+       ewk_view_back(ewk_view);
+       elm_object_disabled_set(window-&gt;back_button, !ewk_view_back_possible(ewk_view));
+     }
+   } else if (ctrlPressed) {
+     if (ev-&gt;z == -1 &amp;&amp; zoom_level_set(ewk_view, window-&gt;current_zoom_level + 1)) {
+       window-&gt;current_zoom_level++;
+       INFO(&quot;Zoom in (Ctrl + 'scroll up') was pressed, zoom level became %.2f&quot;, zoomLevels[window-&gt;current_zoom_level]);
+     } else if (ev-&gt;z == 1 &amp;&amp; zoom_level_set(ewk_view, window-&gt;current_zoom_level - 1)) {
+       window-&gt;current_zoom_level--;
+       INFO(&quot;Zoom out (Ctrl + 'scroll down') was pressed, zoom level became %.2f&quot;, zoomLevels[window-&gt;current_zoom_level]);
+     }
+   }
+}
+
+static void
+_window_resize_cb(void *user_data, Evas *e, Evas_Object *elm_window, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   if (!window) {
+     ERROR(&quot;Window is NULL.&quot;);
+     return;
+   }
+
+   if (window-&gt;context_menu.ewk_menu)
+     ewk_context_menu_hide(window-&gt;context_menu.ewk_menu);
+   if (window-&gt;popup.ewk_menu)
+     ewk_popup_menu_close(window-&gt;popup.ewk_menu);
+   if (window-&gt;popup.elm_menu)
+     elm_menu_close(window-&gt;popup.elm_menu);
+}
+
+static void
+update_view_favicon(Browser_Window *window, Evas_Object *icon)
+{
+   /* Remove previous icon from URL bar */
+   Evas_Object *old_icon = elm_object_part_content_unset(window-&gt;url_bar, &quot;icon&quot;);
+   if (old_icon) {
+     evas_object_unref(old_icon);
+     evas_object_del(old_icon);
+   }
+
+   /* Show new icon in URL bar */
+   if (icon) {
+     evas_object_size_hint_min_set(icon, 32, 32);
+     elm_object_part_content_set(window-&gt;url_bar, &quot;icon&quot;, icon);
+     evas_object_ref(icon);
+   }
+}
+
+static void
+_icon_changed_cb(Ewk_Favicon_Database *database, const char *url, void *user_data)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   Evas_Object *ewk_view = window-&gt;ewk_view;
+
+   if (strcmp(url, ewk_view_url_get(ewk_view)))
+     return;
+
+   Evas_Object *favicon = ewk_favicon_database_icon_get(database, url, evas_object_evas_get(ewk_view));
+   update_view_favicon(window, favicon);
+
+   if (favicon)
+     evas_object_unref(favicon);
+}
+
+static void window_free(Browser_Window *window)
+{
+   evas_object_event_callback_del(window-&gt;ewk_view, EVAS_CALLBACK_MOUSE_IN, _mouse_in_cb);
+   evas_object_event_callback_del(window-&gt;ewk_view, EVAS_CALLBACK_MOUSE_OUT, _mouse_out_cb);
+   evas_object_event_callback_del(window-&gt;ewk_view, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move_cb);
+   evas_object_event_callback_del(window-&gt;ewk_view, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb);
+
+   evas_object_event_callback_del(window-&gt;elm_window, EVAS_CALLBACK_RESIZE, _window_resize_cb);
+
+   ewk_favicon_database_icon_change_callback_del(ewk_context_favicon_database_get(ewk_view_context_get(window-&gt;ewk_view)), _icon_changed_cb);
+
+   evas_object_del(window-&gt;ewk_view);
+   /* The elm_win will take care of freeing its children */
+   evas_object_del(window-&gt;elm_window);
+
+   if (window-&gt;tooltip.show_timer)
+     ecore_timer_del(window-&gt;tooltip.show_timer);
+
+   if (window-&gt;color_selector.elm_selector_window)
+     evas_object_del(window-&gt;color_selector.elm_selector_window);
+
+   free(window);
+}
+
+static void window_close(Browser_Window *window)
+{
+   windows = eina_list_remove(windows, window);
+   window_free(window);
+
+   if (!windows)
+     elm_exit();
+}
+
+static void
+search_icon_show(Browser_Window *window)
+{
+   Evas_Object *icon = elm_icon_add(window-&gt;elm_window);
+   elm_icon_standard_set(icon, &quot;edit-find&quot;);
+   elm_object_part_content_set(window-&gt;search.search_field, &quot;icon&quot;, icon);
+   evas_object_size_hint_min_set(icon, 20, 20);
+   evas_object_size_hint_max_set(icon, 20, 20);
+   elm_entry_icon_visible_set(window-&gt;search.search_field, EINA_TRUE);
+   evas_object_show(icon);
+}
+
+static void
+search_box_show(Browser_Window *window)
+{
+   evas_object_size_hint_min_set(window-&gt;search.search_bar, SEARCH_FIELD_SIZE + 2 * SEARCH_BUTTON_SIZE, SEARCH_BUTTON_SIZE);
+
+   search_icon_show(window);
+   evas_object_show(window-&gt;search.search_bar);
+   evas_object_show(window-&gt;search.search_field);
+   evas_object_show(window-&gt;search.search_field_count);
+   evas_object_show(window-&gt;search.backward_button);
+   evas_object_show(window-&gt;search.forward_button);
+   evas_object_show(window-&gt;search.search_case_check_box);
+   evas_object_show(window-&gt;search.search_word_start_check_box);
+   evas_object_show(window-&gt;search.close_button);
+
+   /* Grab focus from the view */
+   evas_object_focus_set(window-&gt;ewk_view, EINA_FALSE);
+   elm_object_focus_set(window-&gt;search.search_field, EINA_TRUE);
+}
+
+static void
+search_box_hide(Browser_Window *window)
+{
+   ewk_view_text_find_highlight_clear(window-&gt;ewk_view);
+
+   evas_object_size_hint_min_set(window-&gt;search.search_bar, SEARCH_FIELD_SIZE + 2 * SEARCH_BUTTON_SIZE, 0);
+   evas_object_hide(window-&gt;search.search_bar);
+   evas_object_hide(window-&gt;search.search_field);
+   evas_object_hide(window-&gt;search.search_field_count);
+   evas_object_hide(window-&gt;search.backward_button);
+   evas_object_hide(window-&gt;search.forward_button);
+   evas_object_hide(window-&gt;search.search_case_check_box);
+   evas_object_hide(window-&gt;search.search_word_start_check_box);
+   evas_object_hide(window-&gt;search.close_button);
+
+   /* Give focus back to the view */
+   elm_object_focus_set(window-&gt;search.search_field, EINA_FALSE);
+   evas_object_focus_set(window-&gt;ewk_view, EINA_TRUE);
+}
+
+static void
+history_list_hide(Browser_Window *window)
+{
+   /* Hide history list */
+   evas_object_hide(window-&gt;history.history_box);
+   evas_object_hide(window-&gt;history.history_list);
+
+   /* Dereference the list items and clear the history list */
+   void *data;
+   EINA_LIST_FREE(window-&gt;history.history_list_items, data) {
+       ewk_object_unref(data);
+   }
+
+   elm_genlist_clear(window-&gt;history.history_list);
+
+   /* Give focus back to the view */
+   elm_object_focus_set(window-&gt;history.history_box, EINA_FALSE);
+   elm_object_focus_set(window-&gt;history.history_list, EINA_FALSE);
+   evas_object_focus_set(window-&gt;ewk_view, EINA_TRUE);
+
+   /* Reset flags */
+   longpress_enabled = EINA_FALSE;
+}
+
+static void save_page_contents_callback(Ewk_Page_Contents_Type type, const char *data, void *user_data)
+{
+   Eet_File *ef;
+   Eina_Stringshare *fileName = (Eina_Stringshare *)user_data;
+
+   if (!eina_str_has_extension(fileName, &quot;.mht&quot;)) {
+     Eina_Strbuf *fileNameWithMht = eina_strbuf_new();
+     eina_strbuf_append_printf(fileNameWithMht, &quot;%s.mht&quot;, fileName);
+     ef = eet_open(eina_strbuf_string_get(fileNameWithMht), EET_FILE_MODE_WRITE);
+     INFO(&quot;Saving file to: %s&quot;, eina_strbuf_string_get(fileNameWithMht));
+     eina_strbuf_free(fileNameWithMht);
+   } else {
+     ef = eet_open(fileName, EET_FILE_MODE_WRITE);
+     INFO(&quot;Saving file to: %s&quot;, fileName);
+   }
+
+   if (!ef) {
+     ERROR(&quot;Could not create File&quot;);
+     return;
+   }
+
+   eet_write(ef, &quot;MHTML data&quot;, data, strlen(data), 0 /* compress */);
+   eet_close(ef);
+   INFO(&quot;SUCCESS: saved.&quot;);
+
+   eina_stringshare_del(fileName);
+}
+
+static void
+script_execute_callback(Evas_Object *ewk_view, const char *return_value, void *user_data)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   Eina_Strbuf *text_buffer = eina_strbuf_new();
+
+   if (return_value) {
+     eina_strbuf_append(text_buffer, return_value);
+     INFO(&quot;selected text is: %s&quot;, eina_strbuf_string_get(text_buffer));
+     elm_entry_entry_set(window-&gt;search.search_field, eina_strbuf_string_get(text_buffer));
+   }
+   eina_strbuf_free(text_buffer);
+   search_box_show(window);
+}
+
+static void
+toggle_window_fullscreen(Browser_Window *window, Eina_Bool isFullScreen)
+{
+   if (isFullScreen) {
+     evas_object_hide(window-&gt;horizontal_layout);
+     elm_box_unpack(window-&gt;vertical_layout, window-&gt;horizontal_layout);
+     elm_win_fullscreen_set(window-&gt;elm_window, EINA_TRUE);
+   } else {
+     elm_win_fullscreen_set(window-&gt;elm_window, EINA_FALSE);
+     elm_box_pack_start(window-&gt;vertical_layout, window-&gt;horizontal_layout);
+      evas_object_show(window-&gt;horizontal_layout);
+   }
+}
+
+static void
+_key_down_cb(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   Evas_Event_Key_Down *ev = (Evas_Event_Key_Down*) event_info;
+
+   static const char *encodings[] = {
+     &quot;ISO-8859-1&quot;,
+     &quot;UTF-8&quot;,
+     NULL
+   };
+   static int currentEncoding = -1;
+   const Evas_Modifier *mod = evas_key_modifier_get(e);
+   Eina_Bool ctrlPressed = evas_key_modifier_is_set(mod, &quot;Control&quot;);
+   Eina_Bool altPressed = evas_key_modifier_is_set(mod, &quot;Alt&quot;);
+   Eina_Bool shiftPressed = evas_key_modifier_is_set(mod, &quot;Shift&quot;);
+
+   if (!strcmp(ev-&gt;key, &quot;Left&quot;) &amp;&amp; altPressed) {
+     INFO(&quot;Back (Alt+Left) was pressed&quot;);
+     if (!ewk_view_back(ewk_view))
+       INFO(&quot;Back ignored: No back history&quot;);
+   } else if (!strcmp(ev-&gt;key, &quot;Right&quot;) &amp;&amp; altPressed) {
+     INFO(&quot;Forward (Alt+Right) was pressed&quot;);
+     if (!ewk_view_forward(ewk_view))
+       INFO(&quot;Forward ignored: No forward history&quot;);
+   } else if (!strcmp(ev-&gt;key, &quot;Home&quot;) &amp;&amp; altPressed) {
+     INFO(&quot;Home (Alt+Home) was pressed&quot;);
+     ewk_view_url_set(window-&gt;ewk_view, DEFAULT_URL);
+   } else if (!strcmp(ev-&gt;key, &quot;F3&quot;)) {
+     currentEncoding = (currentEncoding + 1) % (sizeof(encodings) / sizeof(encodings[0]));
+     INFO(&quot;Set encoding (F3) pressed. New encoding to %s&quot;, encodings[currentEncoding]);
+     ewk_view_custom_encoding_set(ewk_view, encodings[currentEncoding]);
+   } else if ((!strcmp(ev-&gt;key, &quot;F5&quot;) &amp;&amp; ctrlPressed) || (!strcmp(ev-&gt;key, &quot;r&quot;) &amp;&amp; (shiftPressed &amp; ctrlPressed))) {
+     INFO(&quot;Reload ignoring cache (Ctrl+F5 or Ctrl+Shift+r) was pressed, reloading and bypassing cache...&quot;);
+     ewk_view_reload_bypass_cache(ewk_view);
+   } else if (!strcmp(ev-&gt;key, &quot;F5&quot;) || (!strcmp(ev-&gt;key, &quot;r&quot;) &amp;&amp; ctrlPressed)) {
+     INFO(&quot;Reload (F5 or Ctrl+r) was pressed, reloading...&quot;);
+     ewk_view_reload(ewk_view);
+   } else if (!strcmp(ev-&gt;key, &quot;F6&quot;)) {
+     INFO(&quot;Stop (F6) was pressed, stop loading.&quot;);
+     ewk_view_stop(ewk_view);
+   } else if (!strcmp(ev-&gt;key, &quot;F7&quot;)) {
+     Ewk_Pagination_Mode mode =  ewk_view_pagination_mode_get(ewk_view);
+     mode = (mode + 1) % (EWK_PAGINATION_MODE_BOTTOM_TO_TOP + 1);
+     if (ewk_view_pagination_mode_set(ewk_view, mode))
+       INFO(&quot;Change Pagination Mode (F7) was pressed, changed to: %d&quot;, mode);
+     else
+       INFO(&quot;Change Pagination Mode (F7) was pressed, but NOT changed!&quot;);
+   } else if (!strcmp(ev-&gt;key, &quot;F11&quot;)) {
+     INFO(&quot;Fullscreen (F11) was pressed, toggling window/fullscreen.&quot;);
+     toggle_window_fullscreen(window, !elm_win_fullscreen_get(window-&gt;elm_window));
+   } else if (!strcmp(ev-&gt;key, &quot;n&quot;) &amp;&amp; ctrlPressed) {
+     INFO(&quot;Create new window (Ctrl+n) was pressed.&quot;);
+     Browser_Window *window = window_create(configuration(), 0, 0);
+     ewk_view_url_set(window-&gt;ewk_view, DEFAULT_URL);
+     // 0 equals default width and height.
+     windows = eina_list_append(windows, window);
+   } else if (!strcmp(ev-&gt;key, &quot;i&quot;) &amp;&amp; ctrlPressed) {
+     INFO(&quot;Show Inspector (Ctrl+i) was pressed.&quot;);
+     ewk_view_inspector_show(ewk_view);
+   } else if (!strcmp(ev-&gt;key, &quot;f&quot;) &amp;&amp; ctrlPressed) {
+     INFO(&quot;Show Search Box (Ctrl+f) was pressed.&quot;);
+     const char get_data_script[] = &quot;window.getSelection().toString();&quot;;
+     ewk_view_script_execute(ewk_view, get_data_script, script_execute_callback, (void*)(window));
+   } else if (!strcmp(ev-&gt;key, &quot;Escape&quot;)) {
+     if (evas_object_visible_get(window-&gt;search.search_bar))
+       search_box_hide(window);
+     else if (evas_object_visible_get(window-&gt;history.history_box))
+       history_list_hide(window);
+     else if (elm_win_fullscreen_get(window-&gt;elm_window))
+       ewk_view_fullscreen_exit(ewk_view);
+     else
+       ewk_view_stop(ewk_view);
+   } else if (ctrlPressed &amp;&amp; (!strcmp(ev-&gt;key, &quot;minus&quot;) || !strcmp(ev-&gt;key, &quot;KP_Subtract&quot;))) {
+     if (zoom_level_set(ewk_view, window-&gt;current_zoom_level - 1))
+       window-&gt;current_zoom_level--;
+     INFO(&quot;Zoom out (Ctrl + '-') was pressed, zoom level became %.2f&quot;, zoomLevels[window-&gt;current_zoom_level]);
+   } else if (ctrlPressed &amp;&amp; (!strcmp(ev-&gt;key, &quot;equal&quot;) || !strcmp(ev-&gt;key, &quot;KP_Add&quot;))) {
+     if (zoom_level_set(ewk_view, window-&gt;current_zoom_level + 1))
+       window-&gt;current_zoom_level++;
+     INFO(&quot;Zoom in (Ctrl + '+') was pressed, zoom level became %.2f&quot;, zoomLevels[window-&gt;current_zoom_level]);
+   } else if (ctrlPressed &amp;&amp; !strcmp(ev-&gt;key, &quot;0&quot;)) {
+     if (zoom_level_set(ewk_view, DEFAULT_ZOOM_LEVEL))
+       window-&gt;current_zoom_level = DEFAULT_ZOOM_LEVEL;
+     INFO(&quot;Zoom to default (Ctrl + '0') was pressed, zoom level became %.2f&quot;, zoomLevels[window-&gt;current_zoom_level]);
+   } else if (ctrlPressed &amp;&amp; !strcmp(ev-&gt;key, &quot;s&quot;)) {
+     Eina_Strbuf *default_file = eina_strbuf_new();
+     const char *home_path = getenv(&quot;HOME&quot;);
+     const char *title = ewk_view_title_get(window-&gt;ewk_view);
+     eina_strbuf_append_printf(default_file, &quot;%s/%s.mht&quot;, home_path ? home_path : &quot;/home&quot;, title ? title : &quot;title&quot;);
+     INFO(&quot;Pressed (CTRL + S) : Saving Current Page.&quot;);
+     Eina_Stringshare *save_file_name = _file_entry_dialog_show(window, &quot;SAVE&quot;, eina_strbuf_string_get(default_file));
+     if (!save_file_name)
+       return;
+     ewk_view_page_contents_get(ewk_view, EWK_PAGE_CONTENTS_TYPE_MHTML, save_page_contents_callback, (void *)save_file_name);
+     eina_strbuf_free(default_file);
+   } else if (ctrlPressed &amp;&amp; !strcmp(ev-&gt;key, &quot;l&quot;)) {
+     const char *home_path =  getenv(&quot;HOME&quot;);
+     Eina_Stringshare *open_file_name = _file_entry_dialog_show(window, &quot;LOAD&quot;, home_path ? home_path : &quot;/home&quot;);
+     if (!open_file_name)
+       return;
+     Eina_Strbuf *uri_path = eina_strbuf_new();
+     eina_strbuf_append_printf(uri_path, &quot;%s%s&quot;, FILE_SCHEME, open_file_name);
+     INFO(&quot;pressed (CTRL + L) : Loading Page %s&quot;, eina_strbuf_string_get(uri_path));
+     ewk_view_url_set(ewk_view, eina_strbuf_string_get(uri_path));
+     eina_strbuf_free(uri_path);
+     eina_stringshare_del(open_file_name);
+   }
+}
+
+static void
+view_focus_set(Browser_Window *window, Eina_Bool focus)
+{
+   /* We steal focus away from elm's focus model and start to do things
+    * manually here, so elm now has no clue what's up. Tell elm that its
+    * toplevel widget is to be unfocused so elm gives up the focus */
+   elm_object_focus_set(elm_object_top_widget_get(window-&gt;elm_window), EINA_FALSE);
+   evas_object_focus_set(window-&gt;ewk_view, focus);
+}
+
+static void
+_mouse_down_cb(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *)event_info;
+
+   /* Clear selection from the URL bar */
+   elm_entry_select_none(window-&gt;url_bar);
+
+   if (longpress_enabled)
+     history_list_hide(window);
+   if (ev-&gt;button == 1)
+     view_focus_set(window, EINA_TRUE);
+   else if (ev-&gt;button == 2)
+     view_focus_set(window, !evas_object_focus_get(ewk_view));
+}
+
+static void
+title_set(Evas_Object *elm_window, const char *title, int progress)
+{
+   Eina_Strbuf *buffer;
+
+   if (!title || !*title) {
+     elm_win_title_set(elm_window, APP_NAME);
+     return;
+   }
+
+   buffer = eina_strbuf_new();
+   if (progress &lt; 100)
+     eina_strbuf_append_printf(buffer, &quot;%s (%d%%) - %s&quot;, title, progress, APP_NAME);
+   else
+     eina_strbuf_append_printf(buffer, &quot;%s - %s&quot;, title, APP_NAME);
+
+   elm_win_title_set(elm_window, eina_strbuf_string_get(buffer));
+   eina_strbuf_free(buffer);
+}
+
+static void
+_title_changed_cb(void *user_data, Evas_Object *ewk_view, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   const char *title = (const char *)event_info;
+
+   title_set(window-&gt;elm_window, title, 100);
+}
+
+static void
+_url_changed_cb(void *user_data, Evas_Object *ewk_view, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   const char *url = ewk_view_url_get(window-&gt;ewk_view);
+   char *converted_url = elm_entry_utf8_to_markup(url);
+   elm_entry_entry_set(window-&gt;url_bar, converted_url);
+
+   _icon_changed_cb(ewk_context_favicon_database_get(ewk_view_context_get(ewk_view)), url, user_data);
+
+   free(converted_url);
+
+   search_box_hide(window);
+}
+
+static void
+_back_forward_list_changed_cb(void *user_data, Evas_Object *ewk_view, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   /* Update navigation buttons state */
+   elm_object_disabled_set(window-&gt;back_button, !ewk_view_back_possible(ewk_view));
+   elm_object_disabled_set(window-&gt;forward_button, !ewk_view_forward_possible(ewk_view));
+}
+
+static void
+_progress_cb(void *user_data, Evas_Object *ewk_view, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   double progress = *(double *)event_info;
+
+   title_set(window-&gt;elm_window, ewk_view_title_get(window-&gt;ewk_view), progress * 100);
+}
+
+static void
+_error_cb(void *user_data, Evas_Object *ewk_view, void *event_info)
+{
+   Eina_Strbuf *buffer;
+   const Ewk_Error *error = (const Ewk_Error *)event_info;
+
+   /* This is a cancellation, do not display the error page */
+   if (ewk_error_cancellation_get(error))
+     return;
+
+   buffer = eina_strbuf_new();
+   eina_strbuf_append_printf(buffer,
+     &quot;&lt;html&gt;&lt;body&gt;&lt;div style=\&quot;color:#ff0000\&quot;&gt;ERROR!&lt;/div&gt;&lt;br&gt;&lt;div&gt;Code: %d&lt;br&gt;Description: %s&lt;br&gt;URL: %s&lt;/div&gt;&lt;/body&lt;/html&gt;&quot;,
+     ewk_error_code_get(error), ewk_error_description_get(error), ewk_error_url_get(error));
+
+   ewk_view_html_string_load(ewk_view, eina_strbuf_string_get(buffer), 0, ewk_error_url_get(error));
+   eina_strbuf_free(buffer);
+}
+
+static void
+_download_request_cb(Ewk_Download_Job *download, void *user_data)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   Eina_Strbuf *destination_path = eina_strbuf_new();
+
+   const char *home_path = getenv(&quot;HOME&quot;);
+   Eina_Stringshare *save_file_path = _file_entry_dialog_show(window, &quot;DOWNLOAD&quot;, home_path ? home_path : &quot;/tmp&quot;);
+
+   if (save_file_path)
+     eina_strbuf_append_printf(destination_path, &quot;%s&quot;, save_file_path);
+   else
+     eina_strbuf_append(destination_path, &quot;/tmp&quot;);
+
+   const char *suggested_name = ewk_download_job_suggested_filename_get(download);
+   if (suggested_name &amp;&amp; *suggested_name)
+     eina_strbuf_append_printf(destination_path, &quot;/%s&quot;, suggested_name);
+   else {
+     // Generate a unique file name since no name was suggested.
+     eina_strbuf_append(destination_path, &quot;/downloaded-file.XXXXXX&quot;);
+     char *url = NULL;
+     url = eina_strbuf_string_steal(destination_path);
+     if (mkstemp(url) == -1) {
+       ERROR(&quot;Could not generate a unique file name.&quot;);
+       return;
+     }
+     eina_strbuf_append(destination_path, url);
+   }
+
+   ewk_download_job_destination_set(download, eina_strbuf_string_get(destination_path));
+   INFO(&quot;Downloading: %s&quot;, eina_strbuf_string_get(destination_path));
+   eina_strbuf_free(destination_path);
+   eina_stringshare_del(save_file_path);
+}
+
+static void _filepicker_parent_deletion_cb(void *user_data, Evas *evas, Evas_Object *elm_window, void *event);
+
+static void close_file_picker(File_Selector_Data *fs_data)
+{
+   evas_object_event_callback_del(fs_data-&gt;parent-&gt;elm_window, EVAS_CALLBACK_DEL, _filepicker_parent_deletion_cb);
+   evas_object_del(fs_data-&gt;elm_window);
+   ewk_object_unref(fs_data-&gt;request);
+   free(fs_data);
+}
+
+static void
+_filepicker_parent_deletion_cb(void *user_data, Evas *evas, Evas_Object *elm_window, void *event)
+{
+   close_file_picker((File_Selector_Data *)user_data);
+}
+
+static void
+_filepicker_deletion_cb(void *user_data, Evas_Object *elm_window, void *event_info)
+{
+   close_file_picker((File_Selector_Data *)user_data);
+}
+
+static void
+_fileselector_done_cb(void *user_data, Evas_Object *file_selector, void *event_info)
+{
+   File_Selector_Data *fs_data = (File_Selector_Data *)user_data;
+
+   const char *selected = (const char *)event_info;
+   if (selected &amp;&amp; *selected)
+     ewk_file_chooser_request_file_choose(fs_data-&gt;request, selected);
+
+   close_file_picker(fs_data);
+}
+
+static void
+_file_chooser_request_cb(void *user_data, Evas_Object *ewk_view, void *event_info)
+{
+   Evas_Object *bg;
+   Browser_Window *window = (Browser_Window *)user_data;
+   Ewk_File_Chooser_Request *request = (Ewk_File_Chooser_Request *)event_info;
+
+   // Show basic file picker which does not currently support multiple files
+   // or MIME type filtering.
+   Evas_Object *elm_window = elm_win_add(window-&gt;elm_window, &quot;file-picker-window&quot;, ELM_WIN_DIALOG_BASIC);
+   elm_win_title_set(elm_window, &quot;File picker&quot;);
+   elm_win_modal_set(elm_window, EINA_TRUE);
+
+   bg = elm_bg_add(elm_window);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(elm_window, bg);
+   evas_object_show(bg);
+
+   File_Selector_Data *fs_data = (File_Selector_Data *)malloc(sizeof(File_Selector_Data));
+   fs_data-&gt;parent = window;
+   fs_data-&gt;elm_window = elm_window;
+   fs_data-&gt;request = ewk_object_ref(request);
+   evas_object_smart_callback_add(elm_window, &quot;delete,request&quot;, _filepicker_deletion_cb, fs_data);
+   evas_object_event_callback_add(window-&gt;elm_window, EVAS_CALLBACK_DEL, _filepicker_parent_deletion_cb, fs_data);
+
+   Evas_Object *file_selector = elm_fileselector_add(elm_window);
+   const char *home_path = getenv(&quot;HOME&quot;);
+   elm_fileselector_path_set(file_selector, home_path ? home_path : &quot;/home&quot;);
+   evas_object_size_hint_weight_set(file_selector, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(elm_window, file_selector);
+   evas_object_show(file_selector);
+
+   evas_object_smart_callback_add(file_selector, &quot;done&quot;, _fileselector_done_cb, fs_data);
+
+   int x, y, width, height;
+   evas_object_geometry_get(window-&gt;elm_window, &amp;x, &amp;y, &amp;width, &amp;height);
+
+   int picker_x = x + width / 2 - color_picker_width / 2;
+   int picker_y = y + height / 2 - color_picker_height / 2;
+   evas_object_geometry_set(window-&gt;color_selector.elm_selector_window, picker_x, picker_y,
+     color_picker_width, color_picker_height);
+}
+
+static void
+_download_finished_cb(Ewk_Download_Job *download, void *user_data)
+{
+   INFO(&quot;Download finished: %s&quot;,  ewk_download_job_destination_get(download));
+}
+
+static void
+_download_failed_cb(Ewk_Download_Job_Error *download_error, void *user_data)
+{
+   Ewk_Error *error = download_error-&gt;error;
+
+   INFO(&quot;Download failed! Error code: %d, Error description: %s, Error URL: %s&quot;, ewk_error_code_get(error), ewk_error_description_get(error), ewk_error_url_get(error));
+}
+
+static void
+_color_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   int r, g, b, a;
+
+   elm_colorselector_color_get(obj, &amp;r, &amp;g, &amp;b, &amp;a);
+   evas_object_color_set(data, r, g, b, a);
+}
+
+static void
+_color_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   int r, g, b, a;
+   Elm_Object_Item *color_item = (Elm_Object_Item *)event_info;
+
+   elm_colorselector_palette_item_color_get(color_item, &amp;r, &amp;g, &amp;b, &amp;a);
+   evas_object_color_set(data, r, g, b, a);
+}
+
+static void
+_color_picker_ok_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   int r, g, b, a;
+   Color_Selector *color_selector = (Color_Selector *)data;
+
+   elm_colorselector_color_get(color_selector-&gt;elm_selector, &amp;r, &amp;g, &amp;b, &amp;a);
+   ewk_color_picker_color_set(color_selector-&gt;ewk_picker, r, g, b, a);
+}
+
+static void
+_color_picker_cancel_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   int r, g, b, a;
+
+   ewk_color_picker_color_get(data, &amp;r, &amp;g, &amp;b, &amp;a);
+   ewk_color_picker_color_set(data, r, g, b, a);
+}
+
+static Eina_Bool
+_color_picker_dismiss_cb(Ewk_View_Smart_Data *sd)
+{
+   Browser_Window *window = window_find_with_ewk_view(sd-&gt;self);
+
+   evas_object_del(window-&gt;color_selector.elm_selector_window);
+   window-&gt;color_selector.elm_selector_window = NULL;
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_color_picker_request_cb(Ewk_View_Smart_Data *sd, Ewk_Color_Picker *color_picker)
+{
+   int r, g, b, a;
+   Evas_Object *background, *rect, *box, *button_box, *rect_frame, *cs_frame, *ok_button, *cancel_button;
+
+   Browser_Window *window = window_find_with_ewk_view(sd-&gt;self);
+   window-&gt;color_selector.elm_selector_window = elm_win_add(window-&gt;elm_window, &quot;color selector&quot;, ELM_WIN_BASIC);
+   window-&gt;color_selector.ewk_picker = color_picker;
+
+   elm_win_title_set(window-&gt;color_selector.elm_selector_window, &quot;Color selector&quot;);
+
+   /* Show color view */
+   background = elm_bg_add(window-&gt;color_selector.elm_selector_window);
+   evas_object_size_hint_weight_set(background, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(window-&gt;color_selector.elm_selector_window, background);
+   evas_object_show(background);
+
+   box = elm_box_add(window-&gt;color_selector.elm_selector_window);
+   evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(window-&gt;color_selector.elm_selector_window, box);
+   evas_object_show(box);
+
+   rect_frame = elm_frame_add(window-&gt;color_selector.elm_selector_window);
+   evas_object_size_hint_weight_set(rect_frame, EVAS_HINT_EXPAND, 0.3);
+   evas_object_size_hint_align_set(rect_frame, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_object_text_set(rect_frame, &quot;Color View&quot;);
+   elm_box_pack_end(box, rect_frame);
+   evas_object_show(rect_frame);
+
+   rect = evas_object_rectangle_add(evas_object_evas_get(window-&gt;color_selector.elm_selector_window));
+   elm_object_content_set(rect_frame, rect);
+   ewk_color_picker_color_get(window-&gt;color_selector.ewk_picker, &amp;r, &amp;g, &amp;b, &amp;a);
+   evas_object_color_set(rect, r, g, b, a);
+   evas_object_show(rect);
+
+   /* Show color selector */
+   cs_frame = elm_frame_add(window-&gt;color_selector.elm_selector_window);
+   evas_object_size_hint_weight_set(cs_frame, EVAS_HINT_EXPAND, 0.7);
+   evas_object_size_hint_align_set(cs_frame, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_object_text_set(cs_frame, &quot;Color Selector&quot;);
+   elm_box_pack_end(box, cs_frame);
+   evas_object_show(cs_frame);
+
+   window-&gt;color_selector.elm_selector = elm_colorselector_add(window-&gt;color_selector.elm_selector_window);
+   elm_object_content_set(cs_frame, window-&gt;color_selector.elm_selector);
+   evas_object_show(window-&gt;color_selector.elm_selector);
+
+   /* OK, Cancel Buttons */
+   button_box = elm_box_add(window-&gt;color_selector.elm_selector_window);
+   elm_box_horizontal_set(button_box, EINA_TRUE);
+   evas_object_size_hint_min_set(button_box, 200, 50);
+   elm_box_pack_end(box, button_box);
+   evas_object_show(button_box);
+
+   ok_button = elm_button_add(window-&gt;color_selector.elm_selector_window);
+   elm_object_text_set(ok_button, &quot;OK&quot;);
+   elm_box_pack_end(button_box, ok_button);
+   evas_object_show(ok_button);
+
+   cancel_button = elm_button_add(window-&gt;color_selector.elm_selector_window);
+   elm_object_text_set(cancel_button, &quot;Cancel&quot;);
+   elm_box_pack_end(button_box, cancel_button);
+   evas_object_show(cancel_button);
+
+   evas_object_smart_callback_add(ok_button, &quot;clicked&quot;, _color_picker_ok_clicked_cb, &amp;(window-&gt;color_selector));
+   evas_object_smart_callback_add(cancel_button, &quot;clicked&quot;, _color_picker_cancel_clicked_cb,
+     window-&gt;color_selector.ewk_picker);
+   evas_object_smart_callback_add(window-&gt;color_selector.elm_selector_window, &quot;delete,request&quot;,
+     _color_picker_cancel_clicked_cb, window-&gt;color_selector.ewk_picker);
+   evas_object_smart_callback_add(window-&gt;color_selector.elm_selector, &quot;changed&quot;, _color_changed_cb, rect);
+   evas_object_smart_callback_add(window-&gt;color_selector.elm_selector, &quot;color,item,selected&quot;, _color_item_selected_cb,
+     rect);
+
+   int x, y, width, height;
+   evas_object_geometry_get(window-&gt;elm_window, &amp;x, &amp;y, &amp;width, &amp;height);
+
+   elm_win_center(window-&gt;color_selector.elm_selector_window, EINA_TRUE, EINA_TRUE);
+   evas_object_resize(window-&gt;color_selector.elm_selector_window, 350, 500);
+   evas_object_show(window-&gt;color_selector.elm_selector_window);
+
+   return EINA_TRUE;
+}
+
+static int
+quit(Eina_Bool success, const char *msg)
+{
+   if (msg)
+     success ? INFO(&quot;%s&quot;, msg) : ERROR(&quot;%s&quot;, msg);
+
+   ewk_object_unref(configuration());
+   ewk_shutdown();
+   elm_shutdown();
+   eina_log_domain_unregister(_log_domain_id);
+
+   if (!success)
+     return EXIT_FAILURE;
+
+   return EXIT_SUCCESS;
+}
+
+static Eina_Bool
+has_scheme(const char *url)
+{
+   return !!strstr(url, &quot;://&quot;);
+}
+
+static char *
+url_from_user_input(const char *arg)
+{
+   /* If it is already a URL, return the argument as is. */
+   if (has_scheme(arg) || eina_str_has_prefix(arg, JAVASCRIPT_SCHEME) || !strcasecmp(arg, &quot;about:blank&quot;))
+     return strdup(arg);
+
+   Eina_Strbuf *buf = eina_strbuf_manage_new(eina_file_path_sanitize(arg));
+
+   /* Check if the path exists. */
+   if (ecore_file_exists(eina_strbuf_string_get(buf))) {
+     /* File exists, convert local path to a URL. */
+     eina_strbuf_prepend(buf, FILE_SCHEME);
+   } else {
+     /* The path does not exist, convert it to a URL by
+        prepending http:// scheme:
+        www.google.com -&gt; http://www.google.com */
+     eina_strbuf_string_free(buf);
+     eina_strbuf_append_printf(buf, &quot;%s%s&quot;, HTTP_SCHEME, arg);
+   }
+   char *url = eina_strbuf_string_steal(buf);
+   eina_strbuf_free(buf);
+
+   return url;
+}
+
+static Eina_Bool
+url_load_from_user_input(Evas_Object *ewk_view, const char *url)
+{
+   if (!ewk_view || !url)
+     return EINA_FALSE;
+
+   if (eina_str_has_prefix(url, JAVASCRIPT_SCHEME))
+     return ewk_view_script_execute(ewk_view, strstr(url, JAVASCRIPT_SCHEME), 0, 0);
+
+   return ewk_view_url_set(ewk_view, url);
+}
+
+static void
+_url_bar_activated_cb(void *user_data, Evas_Object *url_bar, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   const char *markup_url = elm_entry_entry_get(url_bar);
+   char *user_url = elm_entry_markup_to_utf8(markup_url);
+   char *url = url_from_user_input(user_url);
+   url_load_from_user_input(window-&gt;ewk_view, url);
+
+   free(user_url);
+   free(url);
+
+   /* Give focus back to the view */
+   view_focus_set(window, EINA_TRUE);
+}
+
+static void
+_url_bar_clicked_cb(void *user_data, Evas_Object *url_bar, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   /* Grab focus from the view */
+   evas_object_focus_set(window-&gt;ewk_view, EINA_FALSE);
+   elm_object_focus_set(url_bar, EINA_TRUE);
+}
+
+static void
+_search_field_aborted_cb(void *user_data, Evas_Object *search_field, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   search_box_hide(window);
+
+   /* Give focus back to the view */
+   view_focus_set(window, EINA_TRUE);
+}
+
+static void
+_search_field_activated_cb(void *user_data, Evas_Object *search_field, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   const char *markup_text = elm_entry_entry_get(search_field);
+   char *text = elm_entry_markup_to_utf8(markup_text);
+   ewk_view_text_find(window-&gt;ewk_view, text, search_flags, MAX_SEARCH_COUNT);
+   free(text);
+
+   /* Grab focus from the view */
+   evas_object_focus_set(window-&gt;ewk_view, EINA_FALSE);
+   elm_object_focus_set(search_field, EINA_TRUE);
+}
+
+static void
+_search_field_clicked_cb(void *user_data, Evas_Object *search_field, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   /* Grab focus from the view */
+   evas_object_focus_set(window-&gt;ewk_view, EINA_FALSE);
+   elm_object_focus_set(search_field, EINA_TRUE);
+}
+
+static void
+_back_button_clicked_cb(void *user_data, Evas_Object *back_button, void *event_info)
+{
+   if (longpress_enabled)
+     return;
+
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   ewk_view_back(window-&gt;ewk_view);
+   /* Update back button state */
+   elm_object_disabled_set(back_button, !ewk_view_back_possible(window-&gt;ewk_view));
+}
+
+static void
+_forward_button_clicked_cb(void *user_data, Evas_Object *forward_button, void *event_info)
+{
+   if (longpress_enabled)
+     return;
+
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   ewk_view_forward(window-&gt;ewk_view);
+   /* Update forward button state */
+   elm_object_disabled_set(forward_button, !ewk_view_forward_possible(window-&gt;ewk_view));
+}
+
+static void
+_search_backward_button_clicked_cb(void *user_data, Evas_Object *search_backward_button, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   char *text = elm_entry_markup_to_utf8(elm_entry_entry_get(window-&gt;search.search_field));
+   ewk_view_text_find(window-&gt;ewk_view, text, search_flags | EWK_FIND_OPTIONS_BACKWARDS, MAX_SEARCH_COUNT);
+   free(text);
+}
+
+static void
+_search_forward_button_clicked_cb(void *user_data, Evas_Object *search_forward_button, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   char *text = elm_entry_markup_to_utf8(elm_entry_entry_get(window-&gt;search.search_field));
+   ewk_view_text_find(window-&gt;ewk_view, text, search_flags, MAX_SEARCH_COUNT);
+   free(text);
+}
+
+static void
+_search_case_option_changed(void *user_data, Evas_Object *search_case_check_box, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   char *text = elm_entry_markup_to_utf8(elm_entry_entry_get(window-&gt;search.search_field));
+
+   /* Bit toggle the case sensitive flag */
+   search_flags = search_flags ^ EWK_FIND_OPTIONS_CASE_INSENSITIVE;
+
+   ewk_view_text_find(window-&gt;ewk_view, text, search_flags, MAX_SEARCH_COUNT);
+   free(text);
+}
+
+static void
+_search_word_start_option_changed_cb(void *user_data, Evas_Object *search_word_start_check_box, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   char *text = elm_entry_markup_to_utf8(elm_entry_entry_get(window-&gt;search.search_field));
+
+   /* Bit toggle the word start flag */
+   search_flags = search_flags ^ EWK_FIND_OPTIONS_AT_WORD_STARTS;
+
+   ewk_view_text_find(window-&gt;ewk_view, text, search_flags, MAX_SEARCH_COUNT);
+   free(text);
+}
+
+static void
+_search_close_button_clicked_cb(void *user_data, Evas_Object *search_close_button, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   search_box_hide(window);
+}
+
+static void
+_refresh_button_clicked_cb(void *user_data, Evas_Object *refresh_button, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   Evas *evas = evas_object_evas_get(refresh_button);
+   Eina_Bool ctrlPressed = evas_key_modifier_is_set(evas_key_modifier_get(evas), &quot;Control&quot;);
+   if (ctrlPressed) {
+     INFO(&quot;Reloading and bypassing cache...&quot;);
+     ewk_view_reload_bypass_cache(window-&gt;ewk_view);
+   } else {
+     INFO(&quot;Reloading...&quot;);
+     ewk_view_reload(window-&gt;ewk_view);
+   }
+}
+
+static void
+_stop_button_clicked_cb(void *user_data, Evas_Object *stop_button, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   INFO(&quot;Stop was Pressed. Aborting load...&quot;);
+   ewk_view_stop(window-&gt;ewk_view);
+}
+
+static char *
+list_item_label_get(void *data, Evas_Object *obj, const char *part)
+{
+   int len = strlen((char *)data);
+   char *buf = (char *)malloc(sizeof(char) * (len + 1));
+   snprintf(buf, len + 1, &quot;%s&quot;, (char *)data);
+   return buf;
+}
+
+static void
+_list_item_select_cb(void *user_data, Evas_Object *obj, void *event_info)
+{
+   Browser_Window *window = evas_object_data_get(obj, &quot;Browser_Window&quot;);
+   ewk_view_navigate_to(window-&gt;ewk_view, user_data);
+   history_list_hide(window);
+   evas_object_data_del(obj, &quot;Browser_Window&quot;);
+}
+
+static void
+navigation_button_longpress_process(void *user_data, Eina_Bool forward_navigation_enabled)
+{
+   if (longpress_enabled)
+     return;
+
+   longpress_enabled = EINA_TRUE;
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   Ewk_Back_Forward_List *list = ewk_view_back_forward_list_get(window-&gt;ewk_view);
+   const Eina_List *l;
+   void *data;
+   static Elm_Genlist_Item_Class *list_item = NULL;
+   const char *title = NULL;
+   int item_count;
+   int x;
+   int y;
+   int width;
+   int height;
+   size_t index;
+
+   evas_object_data_set(window-&gt;history.history_list, &quot;Browser_Window&quot;, window);
+
+   if (forward_navigation_enabled)
+     window-&gt;history.history_list_items = ewk_back_forward_list_forward_items_copy(list);
+   else
+     window-&gt;history.history_list_items = ewk_back_forward_list_back_items_copy(list);
+
+   if (!list_item) {
+     list_item = elm_genlist_item_class_new();
+     list_item-&gt;item_style = &quot;default&quot;;
+     list_item-&gt;func.text_get = list_item_label_get;
+     list_item-&gt;func.content_get = NULL;
+     list_item-&gt;func.state_get = NULL;
+     list_item-&gt;func.del = NULL;
+   }
+
+   item_count = eina_list_count(window-&gt;history.history_list_items);
+   INFO(&quot;navigation_button_longpress_process : Item count = %d forward_navigation_enabled = %d&quot;, item_count, forward_navigation_enabled);
+
+   EINA_LIST_FOREACH(window-&gt;history.history_list_items, l, data) {
+     title = ewk_back_forward_list_item_title_get(data);
+     INFO(&quot; title = %s&quot;, title);
+     elm_genlist_item_append(window-&gt;history.history_list, list_item, (void *)(title), NULL, ELM_GENLIST_ITEM_NONE, _list_item_select_cb, data);
+   }
+
+   if (item_count &gt; 0) {
+     evas_object_geometry_get(window-&gt;elm_window, &amp;x, &amp;y, &amp;width, &amp;height);
+     elm_list_go(window-&gt;history.history_list);
+     evas_object_resize(window-&gt;history.history_box , width / 3 , LIST_ITEM_HEIGHT * item_count);
+
+     if (forward_navigation_enabled) {
+       evas_object_move(window-&gt;history.history_box , x + TOOL_BAR_BUTTON_SIZE + 1, y + TOOL_BAR_BUTTON_SIZE);
+       evas_object_move(window-&gt;history.history_list , x + TOOL_BAR_BUTTON_SIZE + 1, y + TOOL_BAR_BUTTON_SIZE);
+     } else {
+       evas_object_move(window-&gt;history.history_box , x, y + TOOL_BAR_BUTTON_SIZE);
+       evas_object_move(window-&gt;history.history_list , x, y + TOOL_BAR_BUTTON_SIZE);
+     }
+
+     elm_genlist_mode_set(window-&gt;history.history_list, ELM_LIST_COMPRESS);
+     evas_object_show(window-&gt;history.history_box);
+     evas_object_show(window-&gt;history.history_list);
+     evas_object_focus_set(window-&gt;ewk_view, EINA_FALSE);
+     elm_object_focus_set(window-&gt;history.history_list, EINA_TRUE);
+   } else
+     longpress_enabled = EINA_FALSE;
+}
+
+static void
+_forward_button_longpress_cb(void *user_data, Evas_Object *forward_button, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   navigation_button_longpress_process(user_data, EINA_TRUE);
+   elm_object_disabled_set(forward_button, !ewk_view_back_possible(window-&gt;ewk_view));
+}
+
+static void
+_back_button_longpress_cb(void *user_data, Evas_Object *back_button, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   navigation_button_longpress_process(user_data, EINA_FALSE);
+   elm_object_disabled_set(back_button, !ewk_view_back_possible(window-&gt;ewk_view));
+}
+
+static void
+_ok_clicked_cb(void *user_data, Evas_Object *obj, void *event_info)
+{
+   Eina_Bool *confirmed = (Eina_Bool *)user_data;
+   *confirmed = EINA_TRUE;
+}
+
+static Eina_Stringshare *
+_file_entry_dialog_show(Browser_Window *window, const char *label_tag, const char *default_text)
+{
+   Evas_Object *file_popup = elm_popup_add(window-&gt;elm_window);
+   evas_object_size_hint_weight_set(file_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(file_popup);
+
+   Evas_Object *vbox = elm_box_add(file_popup);
+   evas_object_size_hint_weight_set(vbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(vbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_object_content_set(file_popup, vbox);
+   evas_object_show(vbox);
+
+   Evas_Object *label = elm_label_add(window-&gt;elm_window);
+   elm_object_text_set(label, label_tag);
+   evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(label, EVAS_HINT_FILL, 0.5);
+   evas_object_color_set(label, 23, 45, 67, 142);
+   elm_box_pack_end(vbox, label);
+   evas_object_show(label);
+
+   Evas_Object *fs_entry = elm_fileselector_entry_add(file_popup);
+   elm_fileselector_is_save_set(fs_entry, EINA_TRUE);
+   evas_object_size_hint_align_set(fs_entry, EVAS_HINT_FILL, 0);
+   elm_fileselector_path_set(fs_entry, default_text);
+   elm_object_text_set(fs_entry, &quot;FileChooser&quot;);
+   elm_box_pack_end(vbox, fs_entry);
+   evas_object_show(fs_entry);
+
+   Evas_Object *hbox = elm_box_add(file_popup);
+   evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_horizontal_set(hbox, EINA_TRUE);
+   evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(vbox, hbox);
+   evas_object_show(hbox);
+
+   Eina_Bool ok = EINA_FALSE;
+   Evas_Object *ok_button = elm_button_add(file_popup);
+   elm_object_text_set(ok_button, &quot;OK&quot;);
+   evas_object_smart_callback_add(ok_button, &quot;clicked&quot;, _ok_clicked_cb, &amp;ok);
+   elm_box_pack_end(hbox, ok_button);
+   evas_object_show(ok_button);
+
+   Eina_Bool cancel = EINA_FALSE;
+   Evas_Object *cancel_button = elm_button_add(file_popup);
+   elm_object_text_set(cancel_button, &quot;Cancel&quot;);
+   evas_object_smart_callback_add(cancel_button, &quot;clicked&quot;, _ok_clicked_cb, &amp;cancel);
+   elm_box_pack_end(hbox, cancel_button);
+   evas_object_show(cancel_button);
+
+   while (ok != EINA_TRUE &amp;&amp; cancel != EINA_TRUE)
+    ecore_main_loop_iterate();
+
+   Eina_Stringshare *file_path = ok ? eina_stringshare_add(elm_fileselector_path_get(fs_entry)) : NULL;
+   evas_object_del(file_popup);
+   return file_path;
+}
+
+static void
+_javascript_alert_cb(Ewk_View_Smart_Data *smartData, const char *message)
+{
+   Browser_Window *window = window_find_with_ewk_view(smartData-&gt;self);
+
+   Evas_Object *alert_popup = elm_popup_add(window-&gt;elm_window);
+   evas_object_size_hint_weight_set(alert_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_object_text_set(alert_popup, message);
+   elm_object_part_text_set(alert_popup, &quot;title,text&quot;, &quot;Alert&quot;);
+
+   /* Popup buttons */
+   Eina_Bool ok = EINA_FALSE;
+   Evas_Object *button = elm_button_add(alert_popup);
+   elm_object_text_set(button, &quot;OK&quot;);
+   elm_object_part_content_set(alert_popup, &quot;button1&quot;, button);
+   evas_object_smart_callback_add(button, &quot;clicked&quot;, _ok_clicked_cb, &amp;ok);
+   elm_object_focus_set(button, EINA_TRUE);
+   evas_object_show(alert_popup);
+
+   while (ok != EINA_TRUE)
+      ecore_main_loop_iterate();
+
+   evas_object_del(alert_popup);
+}
+
+static Eina_Bool
+_javascript_confirm_cb(Ewk_View_Smart_Data *smartData, const char *message)
+{
+   Browser_Window *window = window_find_with_ewk_view(smartData-&gt;self);
+
+   Evas_Object *confirm_popup = elm_popup_add(window-&gt;elm_window);
+   evas_object_size_hint_weight_set(confirm_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_object_text_set(confirm_popup, message);
+   elm_object_part_text_set(confirm_popup, &quot;title,text&quot;, &quot;Confirmation&quot;);
+
+   /* Popup buttons */
+   Eina_Bool cancel = EINA_FALSE;
+   Evas_Object *cancel_button = elm_button_add(confirm_popup);
+   elm_object_text_set(cancel_button, &quot;Cancel&quot;);
+   elm_object_part_content_set(confirm_popup, &quot;button1&quot;, cancel_button);
+   evas_object_smart_callback_add(cancel_button, &quot;clicked&quot;, _ok_clicked_cb, &amp;cancel);
+   Evas_Object *ok_button = elm_button_add(confirm_popup);
+   Eina_Bool ok = EINA_FALSE;
+   elm_object_text_set(ok_button, &quot;OK&quot;);
+   elm_object_part_content_set(confirm_popup, &quot;button2&quot;, ok_button);
+   evas_object_smart_callback_add(ok_button, &quot;clicked&quot;, _ok_clicked_cb, &amp;ok);
+   elm_object_focus_set(ok_button, EINA_TRUE);
+   evas_object_show(confirm_popup);
+
+   while (cancel != EINA_TRUE &amp;&amp; ok != EINA_TRUE)
+      ecore_main_loop_iterate();
+
+   evas_object_del(confirm_popup);
+
+   return ok;
+}
+
+static const char *
+_javascript_prompt_cb(Ewk_View_Smart_Data *smartData, const char *message, const char *default_value)
+{
+   Browser_Window *window = window_find_with_ewk_view(smartData-&gt;self);
+
+   Evas_Object *prompt_popup = elm_popup_add(window-&gt;elm_window);
+   evas_object_size_hint_weight_set(prompt_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_object_part_text_set(prompt_popup, &quot;title,text&quot;, &quot;Prompt&quot;);
+
+   /* Popup Content */
+   Evas_Object *box = elm_box_add(window-&gt;elm_window);
+   elm_box_padding_set(box, 0, 4);
+   evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_show(box);
+
+   Evas_Object *prompt = elm_label_add(window-&gt;elm_window);
+   elm_object_text_set(prompt, message);
+   evas_object_size_hint_weight_set(prompt, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(prompt, EVAS_HINT_FILL, 0.5);
+   elm_box_pack_end(box, prompt);
+   evas_object_show(prompt);
+
+   Evas_Object *entry = elm_entry_add(window-&gt;elm_window);
+   elm_entry_scrollable_set(entry, EINA_TRUE);
+   elm_entry_single_line_set(entry, EINA_TRUE);
+   elm_entry_text_style_user_push(entry, &quot;DEFAULT='font_size=18'&quot;);
+   elm_entry_entry_set(entry, default_value ? default_value : &quot;&quot;);
+   elm_entry_select_all(entry);
+   evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, 0.5);
+   elm_box_pack_end(box, entry);
+   elm_object_focus_set(entry, EINA_TRUE);
+   evas_object_show(entry);
+
+   elm_object_content_set(prompt_popup, box);
+
+   /* Popup buttons */
+   Eina_Bool cancel = EINA_FALSE;
+   Evas_Object *cancel_button = elm_button_add(prompt_popup);
+   elm_object_text_set(cancel_button, &quot;Cancel&quot;);
+   elm_object_part_content_set(prompt_popup, &quot;button1&quot;, cancel_button);
+   evas_object_smart_callback_add(cancel_button, &quot;clicked&quot;, _ok_clicked_cb, &amp;cancel);
+   Eina_Bool ok = EINA_FALSE;
+   Evas_Object *ok_button = elm_button_add(prompt_popup);
+   elm_object_text_set(ok_button, &quot;OK&quot;);
+   elm_object_part_content_set(prompt_popup, &quot;button2&quot;, ok_button);
+   evas_object_smart_callback_add(ok_button, &quot;clicked&quot;, _ok_clicked_cb, &amp;ok);
+   evas_object_show(prompt_popup);
+
+   while (cancel != EINA_TRUE &amp;&amp; ok != EINA_TRUE)
+      ecore_main_loop_iterate();
+
+   /* The return string need to be stringshared */
+   const char *prompt_text = ok ? eina_stringshare_add(elm_entry_entry_get(entry)) : NULL;
+   evas_object_del(prompt_popup);
+
+   return prompt_text;
+}
+
+static Eina_Bool
+_javascript_before_unload_confirm_cb(Ewk_View_Smart_Data *smartData, const char *message)
+{
+   return _javascript_confirm_cb(smartData, &quot;Will you leave this page?&quot;);
+}
+
+static void
+_popup_menu_item_clicked_cb(void *user_data, Evas_Object *obj, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   Elm_Object_Item *item = (Elm_Object_Item *)event_info;
+
+   INFO(&quot;Selected popup menu index: %u&quot;, elm_menu_item_index_get(item));
+   ewk_popup_menu_selected_index_set(window-&gt;popup.ewk_menu, elm_menu_item_index_get(item));
+
+   // Close popup menu.
+   ewk_popup_menu_close(window-&gt;popup.ewk_menu);
+}
+
+static void
+popup_menu_populate(Evas_Object *elm_menu, Ewk_Popup_Menu *ewk_menu, void *user_data)
+{
+   const Eina_List* ewk_items = ewk_popup_menu_items_get(ewk_menu);
+
+   void *data;
+   const Eina_List *l;
+   EINA_LIST_FOREACH(ewk_items, l, data) {
+     Ewk_Popup_Menu_Item *ewk_item = (Ewk_Popup_Menu_Item *)data;
+     switch (ewk_popup_menu_item_type_get(ewk_item)) {
+     case EWK_POPUP_MENU_SEPARATOR:
+       elm_menu_item_separator_add(elm_menu, NULL);
+       break;
+     case EWK_POPUP_MENU_ITEM:
+       if (ewk_popup_menu_item_is_label_get(ewk_item)) {
+         Elm_Object_Item *item = elm_menu_item_add(elm_menu, NULL, NULL, ewk_popup_menu_item_text_get(ewk_item), NULL, NULL);
+         elm_object_item_disabled_set(item, EINA_TRUE);
+       } else {
+         Elm_Object_Item *item = elm_menu_item_add(elm_menu, NULL, NULL, ewk_popup_menu_item_text_get(ewk_item), _popup_menu_item_clicked_cb, user_data);
+         const char *tooltip_text = ewk_popup_menu_item_tooltip_get(ewk_item);
+         if (tooltip_text &amp;&amp; tooltip_text[0] != '\0')
+           elm_object_item_tooltip_text_set(item, tooltip_text);
+         elm_object_item_disabled_set(item, !ewk_popup_menu_item_enabled_get(ewk_item));
+         elm_menu_item_selected_set(item, ewk_popup_menu_item_selected_get(ewk_item));
+       }
+       break;
+     default:
+       INFO(&quot;Unrecognized popup menu item type!&quot;);
+       break;
+     }
+   }
+}
+
+static Eina_Bool
+_popup_menu_show(Ewk_View_Smart_Data *smartData, Eina_Rectangle rect, Ewk_Text_Direction text_direction, double page_scale_factor, Ewk_Popup_Menu *ewk_menu)
+{
+   Browser_Window *window = window_find_with_ewk_view(smartData-&gt;self);
+
+   if (window-&gt;popup.elm_menu)
+     evas_object_del(window-&gt;popup.elm_menu);
+
+   window-&gt;popup.elm_menu = elm_menu_add(window-&gt;elm_window);
+   window-&gt;popup.ewk_menu = ewk_menu;
+
+   popup_menu_populate(window-&gt;popup.elm_menu, ewk_menu, window);
+
+   INFO(&quot;Showing popup menu at (%d, %d)&quot;, rect.x, rect.y);
+   elm_menu_move(window-&gt;popup.elm_menu, rect.x, rect.y);
+   evas_object_show(window-&gt;popup.elm_menu);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_popup_menu_hide(Ewk_View_Smart_Data *smartData)
+{
+   Browser_Window *window = window_find_with_ewk_view(smartData-&gt;self);
+
+   if (!window-&gt;popup.elm_menu)
+     return EINA_FALSE;
+
+   elm_menu_close(window-&gt;popup.elm_menu);
+   window-&gt;popup.ewk_menu = NULL;
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_window_geometry_get(Ewk_View_Smart_Data *sd, Evas_Coord *x, Evas_Coord *y, Evas_Coord *width, Evas_Coord *height)
+{
+   Browser_Window *window = window_find_with_ewk_view(sd-&gt;self);
+
+   evas_object_geometry_get(window-&gt;elm_window, x, y, width, height);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_window_geometry_set(Ewk_View_Smart_Data *sd, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height)
+{
+   Browser_Window *window = window_find_with_ewk_view(sd-&gt;self);
+
+   evas_object_move(window-&gt;elm_window, x, y);
+   evas_object_resize(window-&gt;elm_window, width, height);
+
+   return EINA_TRUE;
+}
+
+typedef struct {
+   Evas_Object *ewk_view;
+   Evas_Object *permission_popup;
+} PermissionData;
+
+static void
+_fullscreen_accept_cb(void *user_data, Evas_Object *obj, void *event_info)
+{
+   PermissionData *permission_data = (PermissionData *)user_data;
+   Browser_Window *window = window_find_with_ewk_view(permission_data-&gt;ewk_view);
+
+   elm_win_resize_object_del(window-&gt;elm_window, permission_data-&gt;permission_popup);
+   evas_object_del(permission_data-&gt;permission_popup);
+   evas_object_focus_set(permission_data-&gt;ewk_view, EINA_TRUE);
+   free(permission_data);
+}
+
+static void
+_fullscreen_deny_cb(void *user_data, Evas_Object *obj, void *event_info)
+{
+   PermissionData *permission_data = (PermissionData *)user_data;
+   Browser_Window *window = window_find_with_ewk_view(permission_data-&gt;ewk_view);
+
+   ewk_view_fullscreen_exit(permission_data-&gt;ewk_view);
+   elm_win_resize_object_del(window-&gt;elm_window, permission_data-&gt;permission_popup);
+   evas_object_del(permission_data-&gt;permission_popup);
+   evas_object_focus_set(permission_data-&gt;ewk_view, EINA_TRUE);
+   free(permission_data);
+}
+
+static Eina_Bool
+_fullscreen_enter_cb(Ewk_View_Smart_Data *sd, Ewk_Security_Origin *origin)
+{
+   Browser_Window *window = window_find_with_ewk_view(sd-&gt;self);
+
+   /* Go fullscreen */
+   toggle_window_fullscreen(window, EINA_TRUE);
+
+   /* Show user popup */
+   Evas_Object *permission_popup = elm_popup_add(window-&gt;elm_window);
+   evas_object_size_hint_weight_set(permission_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+   Eina_Strbuf *message = eina_strbuf_new();
+   eina_strbuf_append_printf(message, &quot;%s is now fullscreen.&lt;br&gt;Press ESC at any time to exit fullscreen.&lt;br&gt;Allow fullscreen?&quot;, ewk_security_origin_host_get(origin));
+   elm_object_text_set(permission_popup, eina_strbuf_string_get(message));
+   eina_strbuf_free(message);
+   elm_object_part_text_set(permission_popup, &quot;title,text&quot;, &quot;Fullscreen Permission&quot;);
+
+   /* Popup buttons */
+   PermissionData *permission_data = (PermissionData *)malloc(sizeof(PermissionData));
+   permission_data-&gt;ewk_view = window-&gt;ewk_view;
+   permission_data-&gt;permission_popup = permission_popup;
+   Evas_Object *accept_button = elm_button_add(permission_popup);
+   elm_object_text_set(accept_button, &quot;Accept&quot;);
+   elm_object_part_content_set(permission_popup, &quot;button1&quot;, accept_button);
+   evas_object_smart_callback_add(accept_button, &quot;clicked&quot;, _fullscreen_accept_cb, permission_data);
+
+   Evas_Object *deny_button = elm_button_add(permission_popup);
+   elm_object_text_set(deny_button, &quot;Deny&quot;);
+   elm_object_part_content_set(permission_popup, &quot;button2&quot;, deny_button);
+   evas_object_smart_callback_add(deny_button, &quot;clicked&quot;, _fullscreen_deny_cb, permission_data);
+   elm_win_resize_object_add(window-&gt;elm_window, permission_popup);
+   evas_object_show(permission_popup);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool _fullscreen_exit_cb(Ewk_View_Smart_Data *sd)
+{
+   Browser_Window *window = window_find_with_ewk_view(sd-&gt;self);
+
+   toggle_window_fullscreen(window, EINA_FALSE);
+
+   return EINA_TRUE;
+}
+
+static Evas_Object *
+_window_create_cb(Ewk_View_Smart_Data *smartData, Ewk_View_Configuration* configuration, const Ewk_Window_Features *window_features)
+{
+   int x = 0;
+   int y = 0;
+   int width = 0;
+   int height = 0;
+
+   ewk_window_features_geometry_get(window_features, &amp;x, &amp;y, &amp;width, &amp;height);
+
+   if (!width)
+     width = window_width;
+
+   if (!height)
+     height = window_height;
+
+   Browser_Window *window = window_create(configuration, width, height);
+   Evas_Object *new_view = window-&gt;ewk_view;
+
+   windows = eina_list_append(windows, window);
+
+   INFO(&quot;minibrowser: location(%d,%d) size=(%d,%d)&quot;, x, y, width, height);
+
+   return new_view;
+}
+
+static void
+_window_close_cb(Ewk_View_Smart_Data *smartData)
+{
+   Browser_Window *window = window_find_with_ewk_view(smartData-&gt;self);
+   window_close(window);
+}
+
+static void
+_context_menu_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   if (!data) {
+     ERROR(&quot;Context menu callback data is NULL.&quot;);
+     return;
+   }
+
+   Ewk_Context_Menu_Item *ewk_item = (Ewk_Context_Menu_Item *)data;
+   INFO(&quot;Selected context menu item: %s.&quot;, ewk_context_menu_item_title_get(ewk_item));
+   ewk_context_menu_item_select(ewk_context_menu_item_parent_menu_get(ewk_item), ewk_item);
+   ewk_context_menu_hide(ewk_context_menu_item_parent_menu_get(ewk_item));
+}
+
+static void
+context_menu_populate(Evas_Object* context_menu, Ewk_Context_Menu *ewk_menu, Elm_Object_Item *parent_item)
+{
+   if (!context_menu || !ewk_menu) {
+     ERROR(&quot;Necessary objects are NULL.&quot;);
+     return;
+   }
+
+   const Eina_List *list = ewk_context_menu_items_get(ewk_menu);
+   const Eina_List *l;
+   void *data;
+
+   Ewk_Context_Menu_Item *ewk_item;
+   Elm_Object_Item *elm_menu_item;
+   Evas_Object *elm_check_item;
+
+   EINA_LIST_FOREACH(list, l, data) {
+     ewk_item = (Ewk_Context_Menu_Item *)data;
+     switch (ewk_context_menu_item_type_get(ewk_item)) {
+     case EWK_ACTION_TYPE:
+       elm_menu_item = elm_menu_item_add(context_menu, parent_item, NULL, ewk_context_menu_item_title_get(ewk_item), _context_menu_item_selected_cb, ewk_item);
+       break;
+     case EWK_CHECKABLE_ACTION_TYPE:
+       elm_check_item = elm_check_add(context_menu);
+       elm_menu_item = elm_menu_item_add(context_menu, parent_item, NULL, ewk_context_menu_item_title_get(ewk_item), _context_menu_item_selected_cb, ewk_item);
+       elm_object_item_content_set(elm_menu_item, elm_check_item);
+       elm_check_state_set(elm_check_item, ewk_context_menu_item_checked_get(ewk_item));
+       break;
+     case EWK_SUBMENU_TYPE:
+       elm_menu_item = elm_menu_item_add(context_menu, parent_item, NULL, ewk_context_menu_item_title_get(ewk_item), NULL, ewk_item);
+       if (elm_menu_item)
+         context_menu_populate(context_menu, ewk_context_menu_item_submenu_get(ewk_item), elm_menu_item);
+       break;
+     default:
+       continue;
+     }
+     elm_object_item_disabled_set(elm_menu_item, !ewk_context_menu_item_enabled_get(ewk_item));
+   }
+}
+
+static Eina_Bool
+_context_menu_show(Ewk_View_Smart_Data *sd, Evas_Coord x, Evas_Coord y, Ewk_Context_Menu *menu)
+{
+   Browser_Window *window = window_find_with_ewk_view(sd-&gt;self);
+
+   if (!window || !menu) {
+     ERROR(&quot;Necessary objects are NULL.&quot;);
+     return EINA_FALSE;
+   }
+
+   window-&gt;context_menu.elm_menu = elm_menu_add(window-&gt;elm_window);
+
+   if (!window-&gt;context_menu.elm_menu) {
+     ERROR(&quot;Could not create menu widget.&quot;);
+     return EINA_FALSE;
+   }
+
+   window-&gt;context_menu.ewk_menu = menu;
+
+   context_menu_populate(window-&gt;context_menu.elm_menu, menu, NULL);
+
+   INFO(&quot;Showing context menu at (%d, %d).&quot;, x, y);
+   elm_menu_move(window-&gt;context_menu.elm_menu, x, y);
+   evas_object_show(window-&gt;context_menu.elm_menu);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_context_menu_hide(Ewk_View_Smart_Data *sd)
+{
+   Browser_Window *window = window_find_with_ewk_view(sd-&gt;self);
+
+   if (!window || !window-&gt;context_menu.elm_menu) {
+     ERROR(&quot;Necessary objects are NULL.&quot;);
+     return EINA_FALSE;
+   }
+
+   elm_menu_close(window-&gt;context_menu.elm_menu);
+   evas_object_del(window-&gt;context_menu.elm_menu);
+   window-&gt;context_menu.elm_menu = NULL;
+   window-&gt;context_menu.ewk_menu = NULL;
+
+   return EINA_TRUE;
+}
+
+static void
+auth_popup_close(Auth_Data *auth_data)
+{
+   ewk_object_unref(auth_data-&gt;request);
+   evas_object_del(auth_data-&gt;popup);
+   free(auth_data);
+}
+
+static void
+_auth_cancel_cb(void *user_data, Evas_Object *obj, void *event_info)
+{
+   Auth_Data *auth_data = (Auth_Data *)user_data;
+
+   ewk_auth_request_cancel(auth_data-&gt;request);
+
+   auth_popup_close(auth_data);
+}
+
+static void
+_auth_ok_cb(void *user_data, Evas_Object *obj, void *event_info)
+{
+   Auth_Data *auth_data = (Auth_Data *)user_data;
+
+   const char *username = elm_entry_entry_get(auth_data-&gt;username_entry);
+   const char *password = elm_entry_entry_get(auth_data-&gt;password_entry);
+   ewk_auth_request_authenticate(auth_data-&gt;request, username, password);
+
+   auth_popup_close(auth_data);
+}
+
+static void
+_authentication_request_cb(void *user_data, Evas_Object *obj, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   Ewk_Auth_Request *request = ewk_object_ref((Ewk_Auth_Request *)event_info);
+
+   Auth_Data *auth_data = (Auth_Data *)malloc(sizeof(Auth_Data));
+   auth_data-&gt;request = request;
+
+   Evas_Object *auth_popup = elm_popup_add(window-&gt;elm_window);
+   auth_data-&gt;popup = auth_popup;
+   evas_object_size_hint_weight_set(auth_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_object_part_text_set(auth_popup, &quot;title,text&quot;, &quot;Authentication Required&quot;);
+
+   /* Popup Content */
+   Evas_Object *vbox = elm_box_add(auth_popup);
+   elm_box_padding_set(vbox, 0, 4);
+   evas_object_size_hint_weight_set(vbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(vbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_object_content_set(auth_popup, vbox);
+   evas_object_show(vbox);
+
+   /* Authentication message */
+   Evas_Object *label = elm_label_add(auth_popup);
+   elm_label_line_wrap_set(label, ELM_WRAP_WORD);
+   Eina_Strbuf *auth_text = eina_strbuf_new();
+   const char *host = ewk_auth_request_host_get(request);
+   const char *realm = ewk_auth_request_realm_get(request);
+   eina_strbuf_append_printf(auth_text, &quot;A username and password are being requested by %s. The site says: \&quot;%s\&quot;&quot;, host, realm ? realm : &quot;&quot;);
+   elm_object_text_set(label, eina_strbuf_string_get(auth_text));
+   eina_strbuf_free(auth_text);
+   evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(vbox, label);
+   evas_object_show(label);
+
+   /* Credential table */
+   Evas_Object *table = elm_table_add(auth_popup);
+   elm_table_padding_set(table, 2, 2);
+   elm_table_homogeneous_set(table, EINA_TRUE);
+   evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(vbox, table);
+   evas_object_show(table);
+
+   /* Username row */
+   Evas_Object *username_label = elm_label_add(auth_popup);
+   elm_object_text_set(username_label, &quot;Username:&quot;);
+   evas_object_size_hint_weight_set(username_label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(username_label, 1, EVAS_HINT_FILL);
+   elm_table_pack(table, username_label, 0, 0, 1, 1);
+   evas_object_show(username_label);
+
+   Evas_Object *username_entry = elm_entry_add(auth_popup);
+   auth_data-&gt;username_entry = username_entry;
+   elm_entry_scrollable_set(username_entry, EINA_TRUE);
+   elm_entry_single_line_set(username_entry, EINA_TRUE);
+   elm_entry_text_style_user_push(username_entry, &quot;DEFAULT='font_size=18'&quot;);
+   const char *suggested_username = ewk_auth_request_suggested_username_get(request);
+   elm_entry_entry_set(username_entry, suggested_username ? suggested_username : &quot;&quot;);
+   evas_object_size_hint_weight_set(username_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(username_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(table, username_entry, 1, 0, 2, 1);
+   elm_object_focus_set(username_entry, EINA_TRUE);
+   evas_object_show(username_entry);
+
+   /* Password row */
+   Evas_Object *password_label = elm_label_add(auth_popup);
+   elm_object_text_set(password_label, &quot;Password:&quot;);
+   evas_object_size_hint_weight_set(password_label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(password_label, 1, EVAS_HINT_FILL);
+   elm_table_pack(table, password_label, 0, 1, 1, 1);
+   evas_object_show(password_label);
+
+   Evas_Object *password_entry = elm_entry_add(auth_popup);
+   auth_data-&gt;password_entry = password_entry;
+   elm_entry_scrollable_set(password_entry, EINA_TRUE);
+   elm_entry_single_line_set(password_entry, EINA_TRUE);
+   elm_entry_password_set(password_entry, EINA_TRUE);
+   elm_entry_text_style_user_push(password_entry, &quot;DEFAULT='font_size=18'&quot;);
+   evas_object_size_hint_weight_set(password_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(password_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(table, password_entry, 1, 1, 2, 1);
+   evas_object_show(password_entry);
+
+   /* Popup buttons */
+   Evas_Object *cancel_button = elm_button_add(auth_popup);
+   elm_object_text_set(cancel_button, &quot;Cancel&quot;);
+   elm_object_part_content_set(auth_popup, &quot;button1&quot;, cancel_button);
+   evas_object_smart_callback_add(cancel_button, &quot;clicked&quot;, _auth_cancel_cb, auth_data);
+   Evas_Object *ok_button = elm_button_add(auth_popup);
+   elm_object_text_set(ok_button, &quot;OK&quot;);
+   elm_object_part_content_set(auth_popup, &quot;button2&quot;, ok_button);
+   evas_object_smart_callback_add(ok_button, &quot;clicked&quot;, _auth_ok_cb, auth_data);
+   evas_object_show(auth_popup);
+}
+
+static void
+_search_text_found_cb(void *user_data, Evas_Object *obj, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   const int *match_count = (const int *)(event_info);
+
+   if (*match_count) {
+     Eina_Strbuf *search_text = eina_strbuf_new();
+     eina_strbuf_append_printf(search_text, &quot;  %d  Matches Found &quot; , *match_count);
+     elm_object_text_set(window-&gt;search.search_field_count, eina_strbuf_string_get(search_text));
+     eina_strbuf_free(search_text);
+   } else
+     elm_object_text_set(window-&gt;search.search_field_count, &quot; No Matches Found&quot;);
+
+   evas_object_focus_set(window-&gt;ewk_view, EINA_FALSE);
+   elm_object_focus_set(window-&gt;search.search_field_count, EINA_FALSE);
+   elm_object_focus_set(window-&gt;search.search_field, EINA_TRUE);
+}
+
+static void
+_tooltip_text_set(void *user_data, Evas_Object *obj, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   const char *message = (const char*)event_info;
+
+   elm_object_tooltip_text_set(window-&gt;elm_window, message);
+   window-&gt;tooltip.text_set = EINA_TRUE;
+   window_tooltip_update(window);
+}
+
+static void
+_tooltip_text_unset(void *user_data, Evas_Object *obj, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   window_tooltip_hide(window);
+   elm_object_tooltip_unset(window-&gt;elm_window);
+   window-&gt;tooltip.text_set = EINA_FALSE;
+}
+
+static void
+_navigation_policy_decision_cb(void *user_data, Evas_Object *obj, void *event_info)
+{
+   Ewk_Navigation_Policy_Decision *decision = (Ewk_Navigation_Policy_Decision *)event_info;
+
+   if (ewk_navigation_policy_mouse_button_get(decision) == EWK_EVENT_MOUSE_BUTTON_MIDDLE) {
+     Browser_Window *window = window_create(NULL, 0, 0);
+     ewk_view_url_set(window-&gt;ewk_view, ewk_url_request_url_get(ewk_navigation_policy_request_get(decision)));
+     windows = eina_list_append(windows, window);
+     INFO(&quot;Mouse middle button pressed, open link in new window&quot;);
+
+     ewk_navigation_policy_decision_reject(decision);
+   }
+}
+
+static void
+_search_button_clicked_cb(void *user_data, Evas_Object *home_button, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   search_box_show(window);
+}
+
+static void
+_home_button_clicked_cb(void *user_data, Evas_Object *home_button, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+
+   ewk_view_url_set(window-&gt;ewk_view, DEFAULT_URL);
+}
+
+static void
+_window_deletion_cb(void *user_data, Evas_Object *elm_window, void *event_info)
+{
+   Browser_Window *window = (Browser_Window *)user_data;
+   ewk_view_try_close(window-&gt;ewk_view);
+}
+
+static Evas_Object *
+_create_toolbar_button(Evas_Object *elm_window, const char *icon_name)
+{
+   Evas_Object *button = elm_button_add(elm_window);
+
+   Evas_Object *icon = elm_icon_add(elm_window);
+   elm_icon_standard_set(icon, icon_name);
+   evas_object_size_hint_max_set(icon, TOOL_BAR_ICON_SIZE, TOOL_BAR_ICON_SIZE);
+   evas_object_color_set(icon, 0, 255, 255, 255);
+   evas_object_show(icon);
+   elm_object_part_content_set(button, &quot;icon&quot;, icon);
+   evas_object_size_hint_min_set(button, TOOL_BAR_BUTTON_SIZE, TOOL_BAR_BUTTON_SIZE);
+
+   return button;
+}
+
+static Browser_Window *window_create(Ewk_View_Configuration* configuration, int width, int height)
+{
+   Browser_Window *window = calloc(1, sizeof(Browser_Window));
+   if (!window) {
+     ERROR(&quot;Could not create browser window.&quot;);
+     return NULL;
+   }
+
+   /* Initialize tooltip information */
+   window-&gt;tooltip.show_timer = NULL;
+   window-&gt;tooltip.activated = EINA_FALSE;
+   window-&gt;tooltip.text_set = EINA_FALSE;
+   window-&gt;tooltip.shown = EINA_FALSE;
+
+   /* Create window */
+   window-&gt;elm_window = elm_win_add(NULL, &quot;minibrowser-window&quot;, ELM_WIN_BASIC);
+   elm_win_title_set(window-&gt;elm_window, APP_NAME);
+   evas_object_smart_callback_add(window-&gt;elm_window, &quot;delete,request&quot;, _window_deletion_cb, window);
+
+   /* Create window background */
+   Evas_Object *bg = elm_bg_add(window-&gt;elm_window);
+   elm_bg_color_set(bg, 193, 192, 191);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(window-&gt;elm_window, bg);
+   evas_object_show(bg);
+
+   /* Create conformant widget. */
+   Evas_Object *conformant = elm_conformant_add(window-&gt;elm_window);
+   evas_object_size_hint_weight_set(conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(window-&gt;elm_window, conformant);
+   evas_object_show(conformant);
+
+   /* Create vertical layout */
+   window-&gt;vertical_layout = elm_box_add(window-&gt;elm_window);
+   elm_object_content_set(conformant, window-&gt;vertical_layout);
+   elm_box_padding_set(window-&gt;vertical_layout, 0, 2);
+   evas_object_size_hint_weight_set(window-&gt;vertical_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(window-&gt;vertical_layout);
+
+   /* Create horizontal layout for top bar */
+   window-&gt;horizontal_layout = elm_box_add(window-&gt;elm_window);
+   elm_box_horizontal_set(window-&gt;horizontal_layout, EINA_TRUE);
+   evas_object_size_hint_weight_set(window-&gt;horizontal_layout, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(window-&gt;horizontal_layout, EVAS_HINT_FILL, 0.0);
+   elm_box_pack_end(window-&gt;vertical_layout, window-&gt;horizontal_layout);
+   evas_object_show(window-&gt;horizontal_layout);
+
+   /* Create Back button */
+   window-&gt;back_button = _create_toolbar_button(window-&gt;elm_window, &quot;arrow_left&quot;);
+   evas_object_smart_callback_add(window-&gt;back_button, &quot;clicked&quot;, _back_button_clicked_cb, window);
+   evas_object_smart_callback_add(window-&gt;back_button, &quot;repeated&quot;, _back_button_longpress_cb, window);
+   elm_object_tooltip_text_set(window-&gt;back_button, &quot;Click to go back, longpress to see session history&quot;);
+   elm_object_tooltip_window_mode_set(window-&gt;back_button, EINA_TRUE);
+   elm_object_disabled_set(window-&gt;back_button, EINA_TRUE);
+   evas_object_size_hint_weight_set(window-&gt;back_button, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(window-&gt;back_button, 0.0, 0.5);
+   elm_box_pack_end(window-&gt;horizontal_layout, window-&gt;back_button);
+   evas_object_show(window-&gt;back_button);
+
+   /* Create Forward button */
+   window-&gt;forward_button = _create_toolbar_button(window-&gt;elm_window, &quot;arrow_right&quot;);
+   evas_object_smart_callback_add(window-&gt;forward_button, &quot;clicked&quot;, _forward_button_clicked_cb, window);
+   evas_object_smart_callback_add(window-&gt;forward_button, &quot;repeated&quot;, _forward_button_longpress_cb, window);
+   elm_object_tooltip_text_set(window-&gt;forward_button, &quot;Click to go forward, longpress to see session history&quot;);
+   elm_object_tooltip_window_mode_set(window-&gt;forward_button, EINA_TRUE);
+   elm_object_disabled_set(window-&gt;forward_button, EINA_TRUE);
+   evas_object_size_hint_weight_set(window-&gt;forward_button, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(window-&gt;forward_button, 0.0, 0.5);
+   elm_box_pack_end(window-&gt;horizontal_layout, window-&gt;forward_button);
+   evas_object_show(window-&gt;forward_button);
+
+   /* Create Search button */
+   Evas_Object *search_button = _create_toolbar_button(window-&gt;elm_window, &quot;toolbar/search&quot;);
+   evas_object_smart_callback_add(search_button, &quot;clicked&quot;, _search_button_clicked_cb, window);
+   elm_object_tooltip_text_set(search_button, &quot;Find text&quot;);
+   elm_object_tooltip_window_mode_set(search_button, EINA_TRUE);
+   evas_object_size_hint_weight_set(search_button, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(search_button, 1.0, 0.5);
+   elm_box_pack_end(window-&gt;horizontal_layout, search_button);
+   evas_object_show(search_button);
+
+   /* Create URL bar */
+   window-&gt;url_bar = elm_entry_add(window-&gt;elm_window);
+   elm_entry_scrollable_set(window-&gt;url_bar, EINA_TRUE);
+   elm_scroller_policy_set(window-&gt;url_bar, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+   elm_entry_single_line_set(window-&gt;url_bar, EINA_TRUE);
+   elm_entry_cnp_mode_set(window-&gt;url_bar, ELM_CNP_MODE_PLAINTEXT);
+   elm_entry_text_style_user_push(window-&gt;url_bar, &quot;DEFAULT='font_size=18'&quot;);
+   evas_object_smart_callback_add(window-&gt;url_bar, &quot;activated&quot;, _url_bar_activated_cb, window);
+   evas_object_smart_callback_add(window-&gt;url_bar, &quot;clicked&quot;, _url_bar_clicked_cb, window);
+   evas_object_size_hint_weight_set(window-&gt;url_bar, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(window-&gt;url_bar, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(window-&gt;horizontal_layout, window-&gt;url_bar);
+   evas_object_show(window-&gt;url_bar);
+
+   /* Create Refresh button */
+   Evas_Object *refresh_button = _create_toolbar_button(window-&gt;elm_window, &quot;refresh&quot;);
+   evas_object_smart_callback_add(refresh_button, &quot;clicked&quot;, _refresh_button_clicked_cb, window);
+   elm_object_tooltip_text_set(refresh_button, &quot;Reload page&quot;);
+   elm_object_tooltip_window_mode_set(refresh_button, EINA_TRUE);
+   evas_object_size_hint_weight_set(refresh_button, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(refresh_button, 1.0, 0.5);
+   elm_box_pack_end(window-&gt;horizontal_layout, refresh_button);
+   evas_object_show(refresh_button);
+
+   /* Create Stop button */
+   Evas_Object *stop_button = _create_toolbar_button(window-&gt;elm_window, &quot;close&quot;);
+   evas_object_smart_callback_add(stop_button, &quot;clicked&quot;, _stop_button_clicked_cb, window);
+   elm_object_tooltip_text_set(stop_button, &quot;Stop page load&quot;);
+   elm_object_tooltip_window_mode_set(stop_button, EINA_TRUE);
+   evas_object_size_hint_weight_set(stop_button, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(stop_button, 1.0, 0.5);
+   elm_box_pack_end(window-&gt;horizontal_layout, stop_button);
+   evas_object_show(stop_button);
+
+   /* Create Home button */
+   Evas_Object *home_button = _create_toolbar_button(window-&gt;elm_window, &quot;home&quot;);
+   evas_object_smart_callback_add(home_button, &quot;clicked&quot;, _home_button_clicked_cb, window);
+   elm_object_tooltip_text_set(home_button, &quot;Home page&quot;);
+   elm_object_tooltip_window_mode_set(home_button, EINA_TRUE);
+   evas_object_size_hint_weight_set(home_button, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(home_button, 1.0, 0.5);
+   elm_box_pack_end(window-&gt;horizontal_layout, home_button);
+   evas_object_show(home_button);
+
+   /* Create Search bar */
+   window-&gt;search.search_bar = elm_box_add(window-&gt;elm_window);
+   elm_box_horizontal_set(window-&gt;search.search_bar, EINA_TRUE);
+   evas_object_size_hint_min_set(window-&gt;search.search_bar, SEARCH_FIELD_SIZE + 2 * SEARCH_BUTTON_SIZE, 0);
+   evas_object_size_hint_align_set(window-&gt;search.search_bar, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(window-&gt;vertical_layout, window-&gt;search.search_bar);
+
+   /* Create Search field */
+   window-&gt;search.search_field = elm_entry_add(window-&gt;elm_window);
+   elm_entry_scrollable_set(window-&gt;search.search_field, EINA_TRUE);
+   elm_scroller_policy_set(window-&gt;search.search_field, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+   elm_entry_single_line_set(window-&gt;search.search_field, EINA_TRUE);
+   elm_entry_cnp_mode_set(window-&gt;search.search_field, ELM_CNP_MODE_PLAINTEXT);
+   elm_entry_text_style_user_push(window-&gt;search.search_field, &quot;DEFAULT='font_size=14'&quot;);
+   evas_object_smart_callback_add(window-&gt;search.search_field, &quot;activated&quot;, _search_field_activated_cb, window);
+   evas_object_smart_callback_add(window-&gt;search.search_field, &quot;changed&quot;, _search_field_activated_cb, window);
+   evas_object_smart_callback_add(window-&gt;search.search_field, &quot;aborted&quot;, _search_field_aborted_cb, window);
+   evas_object_smart_callback_add(window-&gt;search.search_field, &quot;clicked&quot;, _search_field_clicked_cb, window);
+   evas_object_size_hint_weight_set(window-&gt;search.search_field, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(window-&gt;search.search_field, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(window-&gt;search.search_bar, window-&gt;search.search_field);
+
+   /* Create Search backward button */
+   window-&gt;search.backward_button = _create_toolbar_button(window-&gt;elm_window, &quot;arrow_up&quot;);
+   evas_object_smart_callback_add(window-&gt;search.backward_button, &quot;clicked&quot;, _search_backward_button_clicked_cb, window);
+   elm_object_disabled_set(window-&gt;search.backward_button, EINA_FALSE);
+   evas_object_size_hint_weight_set(window-&gt;search.backward_button, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(window-&gt;search.backward_button, 1.0, 0.5);
+   evas_object_size_hint_min_set(window-&gt;search.backward_button, SEARCH_BUTTON_SIZE, SEARCH_BUTTON_SIZE);
+   elm_box_pack_end(window-&gt;search.search_bar, window-&gt;search.backward_button);
+
+   /* Create Search forwardward button */
+   window-&gt;search.forward_button = _create_toolbar_button(window-&gt;elm_window, &quot;arrow_down&quot;);
+   evas_object_smart_callback_add(window-&gt;search.forward_button, &quot;clicked&quot;, _search_forward_button_clicked_cb, window);
+   elm_object_disabled_set(window-&gt;search.forward_button, EINA_FALSE);
+   evas_object_size_hint_weight_set(window-&gt;search.forward_button, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(window-&gt;search.forward_button, 1.0, 0.5);
+   evas_object_size_hint_min_set(window-&gt;search.forward_button, SEARCH_BUTTON_SIZE, SEARCH_BUTTON_SIZE);
+   elm_box_pack_end(window-&gt;search.search_bar, window-&gt;search.forward_button);
+
+   /* Create Search count field */
+   window-&gt;search.search_field_count = elm_label_add(window-&gt;elm_window);
+   evas_object_size_hint_weight_set(window-&gt;search.search_field_count, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(window-&gt;search.search_field_count, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_object_text_set(window-&gt;search.search_field_count, &quot;&quot;);
+   elm_box_pack_end(window-&gt;search.search_bar, window-&gt;search.search_field_count);
+
+   /* Create Search Case Sensitive Option check box */
+   window-&gt;search.search_case_check_box = elm_check_add(window-&gt;elm_window);
+   elm_object_text_set(window-&gt;search.search_case_check_box, &quot;Case Sensitive&quot;);
+   evas_object_smart_callback_add(window-&gt;search.search_case_check_box, &quot;changed&quot;, _search_case_option_changed, window);
+   elm_box_pack_end(window-&gt;search.search_bar, window-&gt;search.search_case_check_box);
+
+   /* Create Search Word Start Option check box */
+   window-&gt;search.search_word_start_check_box = elm_check_add(window-&gt;elm_window);
+   elm_object_text_set(window-&gt;search.search_word_start_check_box, &quot;Only Word Start&quot;);
+   evas_object_smart_callback_add(window-&gt;search.search_word_start_check_box, &quot;changed&quot;, _search_word_start_option_changed_cb, window);
+   elm_box_pack_end(window-&gt;search.search_bar, window-&gt;search.search_word_start_check_box);
+
+   /* Create Search close button */
+   window-&gt;search.close_button = _create_toolbar_button(window-&gt;elm_window, &quot;close&quot;);
+   evas_object_smart_callback_add(window-&gt;search.close_button, &quot;clicked&quot;, _search_close_button_clicked_cb, window);
+   elm_object_disabled_set(window-&gt;search.close_button, EINA_FALSE);
+   evas_object_size_hint_weight_set(window-&gt;search.close_button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(window-&gt;search.close_button, 1.0, 0.5);
+   evas_object_size_hint_min_set(window-&gt;search.close_button, SEARCH_BUTTON_SIZE, SEARCH_BUTTON_SIZE);
+   elm_box_pack_end(window-&gt;search.search_bar, window-&gt;search.close_button);
+
+   /* Create history box */
+   window-&gt;history.history_box = elm_box_add(window-&gt;elm_window);
+   evas_object_size_hint_aspect_set(window-&gt;history.history_box, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   evas_object_size_hint_weight_set(window-&gt;history.history_box, EVAS_HINT_EXPAND , EVAS_HINT_EXPAND);
+
+   /* Create history list */
+   window-&gt;history.history_list = elm_genlist_add(window-&gt;elm_window);
+   evas_object_size_hint_weight_set(window-&gt;history.history_list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(window-&gt;history.history_list, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_win_resize_object_add(window-&gt;elm_window, window-&gt;history.history_box);
+   elm_box_pack_end(window-&gt;history.history_box, window-&gt;history.history_list);
+
+   /* Create ewk_view */
+   Ewk_View_Smart_Class *ewkViewClass = miniBrowserViewSmartClass();
+   ewkViewClass-&gt;run_javascript_alert = _javascript_alert_cb;
+   ewkViewClass-&gt;run_javascript_confirm = _javascript_confirm_cb;
+   ewkViewClass-&gt;run_javascript_prompt = _javascript_prompt_cb;
+   ewkViewClass-&gt;run_javascript_before_unload_confirm = _javascript_before_unload_confirm_cb;
+   ewkViewClass-&gt;window_geometry_get = _window_geometry_get;
+   ewkViewClass-&gt;window_geometry_set = _window_geometry_set;
+   ewkViewClass-&gt;fullscreen_enter = _fullscreen_enter_cb;
+   ewkViewClass-&gt;fullscreen_exit = _fullscreen_exit_cb;
+   ewkViewClass-&gt;window_create = _window_create_cb;
+   ewkViewClass-&gt;window_close = _window_close_cb;
+   ewkViewClass-&gt;popup_menu_show = _popup_menu_show;
+   ewkViewClass-&gt;popup_menu_hide = _popup_menu_hide;
+   ewkViewClass-&gt;context_menu_show = _context_menu_show;
+   ewkViewClass-&gt;context_menu_hide = _context_menu_hide;
+   ewkViewClass-&gt;input_picker_color_request = _color_picker_request_cb;
+   ewkViewClass-&gt;input_picker_color_dismiss = _color_picker_dismiss_cb;
+
+   Evas *evas = evas_object_evas_get(window-&gt;elm_window);
+   Evas_Smart *smart = evas_smart_class_new(&amp;ewkViewClass-&gt;sc);
+   window-&gt;ewk_view = ewk_view_add_with_configuration(evas, smart, configuration);
+
+   Ewk_Context *context = ewk_view_context_get(window-&gt;ewk_view);
+   ewk_favicon_database_icon_change_callback_add(ewk_context_favicon_database_get(context), _icon_changed_cb, window);
+
+   ewk_view_theme_set(window-&gt;ewk_view, DEFAULT_THEME_DIR &quot;/default.edj&quot;);
+   if (device_pixel_ratio)
+     ewk_view_device_pixel_ratio_set(window-&gt;ewk_view, (float)device_pixel_ratio);
+   ewk_view_user_agent_set(window-&gt;ewk_view, user_agent_string);
+   ewk_view_layout_fixed_set(window-&gt;ewk_view, fixed_layout_enabled);
+
+   if (touch_events_enabled) {
+     ewk_view_touch_events_enabled_set(window-&gt;ewk_view, EINA_TRUE);
+     ewk_view_mouse_events_enabled_set(window-&gt;ewk_view, EINA_FALSE);
+   }
+
+   if (background_color_string) {
+     int red, green, blue, alpha;
+
+     if (sscanf(background_color_string, &quot;%d:%d:%d:%d&quot;, &amp;red, &amp;green, &amp;blue, &amp;alpha))
+       ewk_view_bg_color_set(window-&gt;ewk_view, red, green, blue, alpha);
+   }
+
+   /* Set the zoom level to default */
+   window-&gt;current_zoom_level = DEFAULT_ZOOM_LEVEL;
+
+   elm_win_fullscreen_set(window-&gt;elm_window, fullscreen_enabled);
+
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;authentication,request&quot;, _authentication_request_cb, window);
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;file,chooser,request&quot;, _file_chooser_request_cb, window);
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;load,error&quot;, _error_cb, window);
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;load,provisional,failed&quot;, _error_cb, window);
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;load,progress&quot;, _progress_cb, window);
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;title,changed&quot;, _title_changed_cb, window);
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;url,changed&quot;, _url_changed_cb, window);
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;back,forward,list,changed&quot;, _back_forward_list_changed_cb, window);
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;text,found&quot;, _search_text_found_cb, window);
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;tooltip,text,set&quot;, _tooltip_text_set, window);
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;tooltip,text,unset&quot;, _tooltip_text_unset, window);
+   evas_object_smart_callback_add(window-&gt;ewk_view, &quot;policy,decision,navigation&quot;, _navigation_policy_decision_cb, window);
+
+   evas_object_event_callback_add(window-&gt;ewk_view, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, window);
+   evas_object_event_callback_add(window-&gt;ewk_view, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down_cb, window);
+
+   evas_object_size_hint_weight_set(window-&gt;ewk_view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(window-&gt;ewk_view, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_before(window-&gt;vertical_layout, window-&gt;ewk_view, window-&gt;search.search_bar);
+   evas_object_show(window-&gt;ewk_view);
+
+   evas_object_resize(window-&gt;elm_window, width ? width : window_width, height ? height : window_height);
+   evas_object_show(window-&gt;elm_window);
+   search_box_hide(window);
+
+   view_focus_set(window, EINA_TRUE);
+   // Prevent window from stealing web view's focus on start up.
+   elm_object_focus_allow_set(window-&gt;elm_window, EINA_FALSE);
+
+   evas_object_event_callback_add(window-&gt;ewk_view, EVAS_CALLBACK_MOUSE_IN, _mouse_in_cb, window);
+   evas_object_event_callback_add(window-&gt;ewk_view, EVAS_CALLBACK_MOUSE_OUT, _mouse_out_cb, window);
+   evas_object_event_callback_add(window-&gt;ewk_view, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move_cb, window);
+   evas_object_event_callback_add(window-&gt;ewk_view, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb, window);
+   evas_object_event_callback_add(window-&gt;elm_window, EVAS_CALLBACK_RESIZE, _window_resize_cb, window);
+
+   elm_button_autorepeat_set(window-&gt;back_button, EINA_TRUE);
+   elm_button_autorepeat_set(window-&gt;forward_button, EINA_TRUE);
+   elm_button_autorepeat_initial_timeout_set(window-&gt;back_button, LONGPRESS_INTERVAL_SECONDS);
+   elm_button_autorepeat_initial_timeout_set(window-&gt;forward_button, LONGPRESS_INTERVAL_SECONDS);
+
+   return window;
+}
+
+static Ewk_View_Configuration* configuration()
+{
+    static Ewk_View_Configuration* default_configuration = 0;
+
+    if (default_configuration)
+      return default_configuration;
+
+    default_configuration = ewk_view_configuration_new();
+
+    Ewk_Settings* settings = ewk_view_configuration_settings_get(default_configuration);
+    ewk_settings_file_access_from_file_urls_allowed_set(settings, EINA_TRUE);
+    ewk_settings_encoding_detector_enabled_set(settings, encoding_detector_enabled);
+    ewk_settings_frame_flattening_enabled_set(settings, frame_flattening_enabled);
+    ewk_settings_local_storage_enabled_set(settings, local_storage_enabled);
+    ewk_settings_offline_web_application_cache_enabled_set(settings, offline_web_application_cache_enabled);
+    INFO(&quot;HTML5 local storage is %s for this view.&quot;, local_storage_enabled ? &quot;enabled&quot; : &quot;disabled&quot;);
+    ewk_settings_developer_extras_enabled_set(settings, EINA_TRUE);
+    ewk_settings_preferred_minimum_contents_width_set(settings, 0);
+    ewk_text_checker_continuous_spell_checking_enabled_set(spell_checking_enabled);
+    ewk_settings_web_security_enabled_set(settings, web_security_enabled);
+
+    return default_configuration;
+}
+
+static Ewk_Cookie_Accept_Policy
+parse_cookies_policy(const char *input_string)
+{
+   if (!strcmp(input_string, &quot;always&quot;))
+     return EWK_COOKIE_ACCEPT_POLICY_ALWAYS;
+   if (!strcmp(input_string, &quot;never&quot;))
+     return EWK_COOKIE_ACCEPT_POLICY_NEVER;
+   if (strcmp(input_string, &quot;no-third-party&quot;))
+     INFO(&quot;Unrecognized type for cookies policy: %s.&quot;, input_string);
+   return EWK_COOKIE_ACCEPT_POLICY_NO_THIRD_PARTY;
+}
+
+static void
+parse_window_size(const char *input_string, int *width, int *height)
+{
+   static const unsigned max_length = 4;
+   int parsed_width;
+   int parsed_height;
+   char **arr;
+   unsigned elements;
+
+   arr = eina_str_split_full(input_string, &quot;x&quot;, 0, &amp;elements);
+
+   if (elements == 2 &amp;&amp; (strlen(arr[0]) &lt;= max_length) &amp;&amp; (strlen(arr[1]) &lt;= max_length)) {
+     parsed_width = atoi(arr[0]);
+     if (width &amp;&amp; parsed_width)
+       *width = parsed_width;
+
+     parsed_height = atoi(arr[1]);
+     if (height &amp;&amp; parsed_height)
+       *height = parsed_height;
+   }
+
+   free(arr[0]);
+   free(arr);
+}
+
+EAPI_MAIN int
+elm_main(int argc, char *argv[])
+{
+   int args = 1;
+   unsigned char quitOption = 0;
+   Browser_Window *window;
+   char *window_size_string = NULL;
+   char *cookies_policy_string = NULL;
+
+   Ecore_Getopt_Value values[] = {
+     ECORE_GETOPT_VALUE_STR(evas_engine_name),
+     ECORE_GETOPT_VALUE_STR(window_size_string),
+     ECORE_GETOPT_VALUE_STR(user_agent_string),
+     ECORE_GETOPT_VALUE_STR(extensions_path),
+     ECORE_GETOPT_VALUE_DOUBLE(device_pixel_ratio),
+     ECORE_GETOPT_VALUE_BOOL(quitOption),
+     ECORE_GETOPT_VALUE_BOOL(encoding_detector_enabled),
+     ECORE_GETOPT_VALUE_STR(background_color_string),
+     ECORE_GETOPT_VALUE_BOOL(frame_flattening_enabled),
+     ECORE_GETOPT_VALUE_BOOL(local_storage_enabled),
+     ECORE_GETOPT_VALUE_BOOL(offline_web_application_cache_enabled),
+     ECORE_GETOPT_VALUE_BOOL(fullscreen_enabled),
+     ECORE_GETOPT_VALUE_BOOL(spell_checking_enabled),
+     ECORE_GETOPT_VALUE_BOOL(touch_events_enabled),
+     ECORE_GETOPT_VALUE_BOOL(fixed_layout_enabled),
+     ECORE_GETOPT_VALUE_STR(cookies_policy_string),
+     ECORE_GETOPT_VALUE_BOOL(web_security_enabled),
+     ECORE_GETOPT_VALUE_BOOL(separated_process_enabled),
+     ECORE_GETOPT_VALUE_BOOL(quitOption),
+     ECORE_GETOPT_VALUE_BOOL(quitOption),
+     ECORE_GETOPT_VALUE_BOOL(quitOption),
+     ECORE_GETOPT_VALUE_NONE
+   };
+
+   efreet_cache_update = 0;
+
+   if (!ewk_init())
+     return EXIT_FAILURE;
+
+   _log_domain_id = eina_log_domain_register(&quot;minibrowser&quot;, EINA_COLOR_YELLOW);
+
+   ewk_view_smart_class_set(miniBrowserViewSmartClass());
+
+   ecore_app_args_set(argc, (const char **) argv);
+   args = ecore_getopt_parse(&amp;options, values, argc, argv);
+
+   if (args &lt; 0)
+     return quit(EINA_FALSE, &quot;Could not parse options.&quot;);
+
+   if (quitOption)
+     return quit(EINA_TRUE, NULL);
+
+   if (evas_engine_name)
+     elm_config_accel_preference_set(evas_engine_name);
+   else {
+     evas_engine_name = &quot;opengl:depth24:stencil8&quot;;
+     elm_config_accel_preference_set(evas_engine_name);
+   }
+
+   Ewk_Context *context = ewk_context_default_get();
+
+   if (separated_process_enabled)
+     ewk_context_web_process_count_limit_set(context, 0);
+
+   // Enable favicon database.
+   ewk_context_favicon_database_directory_set(context, NULL);
+
+   // Use a proper cache model.
+   ewk_context_cache_model_set(context, EWK_CACHE_MODEL_PRIMARY_WEBBROWSER);
+
+   if (cookies_policy_string) {
+     Ewk_Cookie_Accept_Policy cookie_policy = parse_cookies_policy(cookies_policy_string);
+     ewk_cookie_manager_accept_policy_set(ewk_context_cookie_manager_get(context), cookie_policy);
+
+     if (cookie_policy == EWK_COOKIE_ACCEPT_POLICY_ALWAYS) {
+       const char cookie_storage_directory[] = &quot;/tmp/ewebkit2_minibrowser_cookie/&quot;;
+       mkdir(cookie_storage_directory, S_IRWXU);
+       char storage_name[64];
+       snprintf(storage_name, sizeof(storage_name), &quot;%stxt-cookie&quot;, cookie_storage_directory);
+       ewk_cookie_manager_persistent_storage_set(ewk_context_cookie_manager_get(context), storage_name, EWK_COOKIE_PERSISTENT_STORAGE_TEXT);
+     }
+   }
+
+   if (window_size_string)
+     parse_window_size(window_size_string, &amp;window_width, &amp;window_height);
+
+   window = window_create(configuration(), 0, 0);
+   if (!window)
+     return quit(EINA_FALSE, &quot;Could not create browser window.&quot;);
+
+   // Set callbacks for download events.
+   ewk_context_download_callbacks_set(context, _download_request_cb, _download_failed_cb, 0, _download_finished_cb, window);
+
+   if (args &lt; argc) {
+     char *url = url_from_user_input(argv[args]);
+     url_load_from_user_input(window-&gt;ewk_view, url);
+     free(url);
+   } else
+     ewk_view_url_set(window-&gt;ewk_view, DEFAULT_URL);
+
+   windows = eina_list_append(windows, window);
+
+   elm_run();
+
+   return quit(EINA_TRUE, NULL);
+}
+ELM_MAIN()
+
</ins></span></pre></div>
<a id="trunkToolsScriptsrunefltests"></a>
<div class="addfile"><h4>Added: trunk/Tools/Scripts/run-efl-tests (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/run-efl-tests                                (rev 0)
+++ trunk/Tools/Scripts/run-efl-tests        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+#!/usr/bin/perl -w
+# Copyright (C) 2012 Intel Corporation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+my $xvfb_display = &quot;:55&quot;;
+
+my $xvfb_pid = fork();
+exit(1) if not defined $xvfb_pid;
+
+# Tell CTest to dump gtest output in case of failure.
+$ENV{CTEST_OUTPUT_ON_FAILURE} = &quot;1&quot;;
+$ENV{DISPLAY} = $xvfb_display;
+
+if ($xvfb_pid == 0) {
+    # Start Xvfb
+    my @xvfb_args = ( &quot;Xvfb $xvfb_display -screen 0 800x600x24 -nolisten tcp &gt; /dev/null 2&gt;&amp;1&quot; );
+    exec(@xvfb_args);
+} else {
+    setConfiguration();
+
+    # Manually add this for jhbuildWrapperPrefixIfNeeded().
+    push(@ARGV, &quot;--efl&quot;);
+
+    my $returnCode = exitStatus(generateBuildSystemFromCMakeProject(undef, cmakeBasedPortArguments()));
+    exit($returnCode) if $returnCode;
+
+    $returnCode = exitStatus(buildCMakeGeneratedProject(&quot;test&quot;));
+
+    # Kill Xvfb
+    kill(15, $xvfb_pid);
+
+    exit($returnCode);
+}
+
</ins><span class="cx">Property changes on: trunk/Tools/Scripts/run-efl-tests
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkToolsScriptsupdatewebkitefllibs"></a>
<div class="addfile"><h4>Added: trunk/Tools/Scripts/update-webkitefl-libs (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/update-webkitefl-libs                                (rev 0)
+++ trunk/Tools/Scripts/update-webkitefl-libs        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+#!/usr/bin/perl -w
+# Copyright (C) 2012 Intel Corporation
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+my $scriptsDir = relativeScriptsDir();
+system(&quot;perl&quot;, &quot;$scriptsDir/update-webkit-libs-jhbuild&quot;, &quot;--efl&quot;, @ARGV) == 0 or die $!;
</ins><span class="cx">Property changes on: trunk/Tools/Scripts/update-webkitefl-libs
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkToolsScriptswebkitpyporteflpy"></a>
<div class="addfile"><h4>Added: trunk/Tools/Scripts/webkitpy/port/efl.py (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/efl.py                                (rev 0)
+++ trunk/Tools/Scripts/webkitpy/port/efl.py        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,146 @@
</span><ins>+# Copyright (C) 2011 ProFUSION Embedded Systems. All rights reserved.
+# Copyright (C) 2011 Samsung Electronics. All rights reserved.
+# Copyright (C) 2012 Intel Corporation
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+&quot;&quot;&quot;WebKit Efl implementation of the Port interface.&quot;&quot;&quot;
+
+import os
+
+from webkitpy.common.system import path
+from webkitpy.layout_tests.models.test_configuration import TestConfiguration
+from webkitpy.port.base import Port
+from webkitpy.port.pulseaudio_sanitizer import PulseAudioSanitizer
+from webkitpy.port.xorgdriver import XorgDriver
+from webkitpy.port.xvfbdriver import XvfbDriver
+from webkitpy.port.linux_get_crash_log import GDBCrashLogGenerator
+
+
+class EflPort(Port):
+    port_name = 'efl'
+
+    def __init__(self, *args, **kwargs):
+        super(EflPort, self).__init__(*args, **kwargs)
+
+        self._jhbuild_wrapper = [self.path_from_webkit_base('Tools', 'jhbuild', 'jhbuild-wrapper'), '--efl', 'run']
+
+        self.set_option_default('wrapper', ' '.join(self._jhbuild_wrapper))
+        self.webprocess_cmd_prefix = self.get_option('webprocess_cmd_prefix')
+
+        self._pulseaudio_sanitizer = PulseAudioSanitizer()
+
+    def _port_flag_for_scripts(self):
+        return &quot;--efl&quot;
+
+    def setup_test_run(self, device_class=None):
+        super(EflPort, self).setup_test_run(device_class)
+        self._pulseaudio_sanitizer.unload_pulseaudio_module()
+
+    def setup_environ_for_server(self, server_name=None):
+        env = super(EflPort, self).setup_environ_for_server(server_name)
+
+        # If DISPLAY environment variable is unset in the system
+        # e.g. on build bot, remove DISPLAY variable from the dictionary
+        if not 'DISPLAY' in os.environ:
+            del env['DISPLAY']
+
+        if 'ACCESSIBILITY_EAIL_LIBRARY_PATH' in os.environ:
+            env['ACCESSIBILITY_EAIL_LIBRARY_PATH'] = os.environ['ACCESSIBILITY_EAIL_LIBRARY_PATH']
+
+        env['TEST_RUNNER_INJECTED_BUNDLE_FILENAME'] = self._build_path('lib', 'libTestRunnerInjectedBundle.so')
+        env['TEST_RUNNER_PLUGIN_PATH'] = self._build_path('lib', 'plugins')
+
+        # Silence GIO warnings about using the &quot;memory&quot; GSettings backend.
+        env['GSETTINGS_BACKEND'] = 'memory'
+
+        if self.webprocess_cmd_prefix:
+            env['WEB_PROCESS_CMD_PREFIX'] = self.webprocess_cmd_prefix
+
+        return env
+
+    def default_timeout_ms(self):
+        # Tests run considerably slower under gdb
+        # or valgrind.
+        if self.get_option('webprocess_cmd_prefix'):
+            return 350 * 1000
+        return super(EflPort, self).default_timeout_ms()
+
+    def clean_up_test_run(self):
+        super(EflPort, self).clean_up_test_run()
+        self._pulseaudio_sanitizer.restore_pulseaudio_module()
+
+    def _generate_all_test_configurations(self):
+        return [TestConfiguration(version=self._version, architecture='x86', build_type=build_type) for build_type in self.ALL_BUILD_TYPES]
+
+    def _driver_class(self):
+        if os.environ.get(&quot;USE_NATIVE_XDISPLAY&quot;):
+            return XorgDriver
+        return XvfbDriver
+
+    def _path_to_driver(self):
+        return self._build_path('bin', self.driver_name())
+
+    def _path_to_image_diff(self):
+        return self._build_path('bin', 'ImageDiff')
+
+    def _image_diff_command(self, *args, **kwargs):
+        return self._jhbuild_wrapper + super(EflPort, self)._image_diff_command(*args, **kwargs)
+
+    def _path_to_webcore_library(self):
+        static_path = self._build_path('lib', 'libwebcore_efl.a')
+        dyn_path = self._build_path('lib', 'libwebcore_efl.so')
+        return static_path if self._filesystem.exists(static_path) else dyn_path
+
+    def _search_paths(self):
+        search_paths = []
+        search_paths.append(self.port_name)
+        search_paths.append('wk2')
+        return search_paths
+
+    def default_baseline_search_path(self):
+        return map(self._webkit_baseline_path, self._search_paths())
+
+    def _port_specific_expectations_files(self):
+        # FIXME: We should be able to use the default algorithm here.
+        return list(reversed([self._filesystem.join(self._webkit_baseline_path(p), 'TestExpectations') for p in self._search_paths()]))
+
+    def show_results_html_file(self, results_filename):
+        self._run_script(&quot;run-minibrowser&quot;, [path.abspath_to_uri(self.host.platform, results_filename)])
+
+    def check_sys_deps(self, needs_http):
+        return super(EflPort, self).check_sys_deps(needs_http) and self._driver_class().check_driver(self)
+
+    def build_webkit_command(self, build_style=None):
+        command = super(EflPort, self).build_webkit_command(build_style)
+        command.extend([&quot;--efl&quot;, &quot;--update-efl&quot;])
+        command.append(super(EflPort, self).make_args())
+        return command
+
+    def _get_crash_log(self, name, pid, stdout, stderr, newer_than):
+        return GDBCrashLogGenerator(name, pid, newer_than, self._filesystem, self._path_to_driver).generate_crash_log(stdout, stderr)
+
+    def test_expectations_file_position(self):
+        # EFL port baseline search path is efl -&gt; wk2 -&gt; generic (as efl-wk2 and efl baselines are merged), so port test expectations file is at third to last position.
+        return 2
</ins></span></pre></div>
<a id="trunkToolsScriptswebkitpyportefl_unittestpy"></a>
<div class="addfile"><h4>Added: trunk/Tools/Scripts/webkitpy/port/efl_unittest.py (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/efl_unittest.py                                (rev 0)
+++ trunk/Tools/Scripts/webkitpy/port/efl_unittest.py        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+# Copyright (C) 2011 ProFUSION Embedded Systems. All rights reserved.
+# Copyright (C) 2011 Samsung Electronics. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#    * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import unittest
+
+from webkitpy.common.system.executive_mock import MockExecutive
+from webkitpy.common.system.outputcapture import OutputCapture
+from webkitpy.port.efl import EflPort
+from webkitpy.port.pulseaudio_sanitizer_mock import PulseAudioSanitizerMock
+from webkitpy.port import port_testcase
+
+
+class EflPortTest(port_testcase.PortTestCase):
+    port_name = 'efl'
+    port_maker = EflPort
+
+    # Additionally mocks out the PulseAudioSanitizer methods.
+    def make_port(self, host=None, port_name=None, options=None, os_name=None, os_version=None, **kwargs):
+        port = super(EflPortTest, self).make_port(host, port_name, options, os_name, os_version, **kwargs)
+        port._pulseaudio_sanitizer = PulseAudioSanitizerMock()
+        return port
+
+    def test_show_results_html_file(self):
+        port = self.make_port()
+        port._executive = MockExecutive(should_log=True)
+        expected_logs = &quot;MOCK run_command: ['Tools/Scripts/run-minibrowser', '--release', '--efl', 'file://test.html'], cwd=/mock-checkout\n&quot;
+        OutputCapture().assert_outputs(self, port.show_results_html_file, [&quot;test.html&quot;], expected_logs=expected_logs)
+
+    def test_get_crash_log(self):
+        # This function tested in linux_get_crash_log_unittest.py
+        pass
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2eflWKViewClientWebProcessCallbackscpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,126 @@
</span><ins>+/*
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;ewk_view_private.h&quot;
+#include &quot;PlatformUtilities.h&quot;
+#include &quot;PlatformWebView.h&quot;
+#include &quot;Test.h&quot;
+#include &quot;WKView.h&quot;
+#include &lt;WebKit/WKRetainPtr.h&gt;
+
+namespace TestWebKitAPI {
+
+struct TestStatesData {
+    TestStatesData(WKViewRef view, WKURLRef url)
+        : view(view)
+        , url(url)
+        , didFinishLoad(false)
+        , didCrash(false)
+        , didRelaunch(false)
+    {
+    }
+
+    WKViewRef view;
+    WKURLRef url;
+    bool didFinishLoad;
+    bool didCrash;
+    bool didRelaunch;
+};
+
+static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void* clientInfo)
+{
+    TestStatesData* states = const_cast&lt;TestStatesData*&gt;(static_cast&lt;const TestStatesData*&gt;(clientInfo));
+    states-&gt;didFinishLoad = true;
+}
+
+static void setPageLoaderClient(WKPageRef page, const void* clientInfo)
+{
+    WKPageLoaderClientV3 loaderClient;
+    memset(&amp;loaderClient, 0, sizeof(loaderClient));
+
+    loaderClient.base.version = 3;
+    loaderClient.base.clientInfo = clientInfo;
+    loaderClient.didFinishLoadForFrame = didFinishLoadForFrame;
+
+    WKPageSetPageLoaderClient(page, &amp;loaderClient.base);
+}
+
+void webProcessCrashed(WKViewRef view, WKURLRef url, const void* clientInfo)
+{
+    TestStatesData* states = const_cast&lt;TestStatesData*&gt;(static_cast&lt;const TestStatesData*&gt;(clientInfo));
+
+    EXPECT_EQ(states-&gt;view, view);
+    EXPECT_TRUE(WKURLIsEqual(url, states-&gt;url));
+
+    states-&gt;didCrash = true;
+}
+
+void webProcessDidRelaunch(WKViewRef view, const void* clientInfo)
+{
+    TestStatesData* states = const_cast&lt;TestStatesData*&gt;(static_cast&lt;const TestStatesData*&gt;(clientInfo));
+
+    EXPECT_EQ(states-&gt;view, view);
+
+    states-&gt;didRelaunch = true;
+}
+
+static void setViewClient(WKViewRef view, const void* clientInfo)
+{
+    WKViewClientV0 viewClient;
+    memset(&amp;viewClient, 0, sizeof(WKViewClientV0));
+
+    viewClient.base.version = 0;
+    viewClient.base.clientInfo = clientInfo;
+    viewClient.webProcessCrashed = webProcessCrashed;
+    viewClient.webProcessDidRelaunch = webProcessDidRelaunch;
+
+    WKViewSetViewClient(view, &amp;viewClient.base);
+}
+
+TEST(WebKit2, WKViewClientWebProcessCallbacks)
+{
+    WKRetainPtr&lt;WKContextRef&gt; context = adoptWK(Util::createContextForInjectedBundleTest(&quot;WKViewClientWebProcessCallbacksTest&quot;));
+    WKRetainPtr&lt;WKURLRef&gt; url(AdoptWK, Util::createURLForResource(&quot;simple&quot;, &quot;html&quot;));
+
+    PlatformWebView view(context.get());
+    WKViewRef wkView = EWKViewGetWKView(view.platformView());
+
+    TestStatesData states = TestStatesData(wkView, url.get());
+
+    setPageLoaderClient(view.page(), &amp;states);
+    setViewClient(wkView, &amp;states);
+
+    WKPageLoadURL(view.page(), url.get());
+    Util::run(&amp;states.didFinishLoad);
+
+    WKContextPostMessageToInjectedBundle(context.get(), Util::toWK(&quot;Crash&quot;).get(), 0);
+    Util::run(&amp;states.didCrash);
+
+    WKPageReload(view.page());
+    Util::run(&amp;states.didRelaunch);
+}
+
+} // namespace TestWebKitAPI
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2eflWKViewClientWebProcessCallbacks_Bundlecpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks_Bundle.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks_Bundle.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks_Bundle.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+/*
+ * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;InjectedBundleTest.h&quot;
+#include &lt;WebKit/WKRetainPtr.h&gt;
+
+namespace TestWebKitAPI {
+
+class WKViewClientWebProcessCallbacksTest : public InjectedBundleTest {
+public:
+    WKViewClientWebProcessCallbacksTest(const std::string&amp; identifier);
+
+private:
+    virtual void didReceiveMessage(WKBundleRef, WKStringRef messageName, WKTypeRef messageBody);
+};
+
+static InjectedBundleTest::Register&lt;WKViewClientWebProcessCallbacksTest&gt; registrar(&quot;WKViewClientWebProcessCallbacksTest&quot;);
+
+WKViewClientWebProcessCallbacksTest::WKViewClientWebProcessCallbacksTest(const std::string&amp; identifier)
+    : InjectedBundleTest(identifier)
+{
+}
+
+void WKViewClientWebProcessCallbacksTest::didReceiveMessage(WKBundleRef, WKStringRef messageName, WKTypeRef)
+{
+    if (!WKStringIsEqualToUTF8CString(messageName, &quot;Crash&quot;))
+        return;
+
+    // Simulating a crash
+    abort();
+}
+
+} // namespace TestWebKitAPI
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2eflWKViewScrollTocpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewScrollTo.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewScrollTo.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewScrollTo.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+/*
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+
+#include &quot;ewk_view_private.h&quot;
+#include &quot;PlatformUtilities.h&quot;
+#include &quot;PlatformWebView.h&quot;
+#include &lt;WebKit/WKContext.h&gt;
+#include &lt;WebKit/WKRetainPtr.h&gt;
+#include &quot;Test.h&quot;
+
+namespace TestWebKitAPI {
+
+static bool finishedLoad = false;
+
+static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*)
+{
+    finishedLoad = true;
+}
+
+TEST(WebKit2, WKViewScrollTo)
+{
+    WKRetainPtr&lt;WKContextRef&gt; context(AdoptWK, WKContextCreate());
+    PlatformWebView webView(context.get());
+    WKRetainPtr&lt;WKViewRef&gt; view = EWKViewGetWKView(webView.platformView());
+
+    WKPageSetUseFixedLayout(webView.page(), true);
+
+    WKPageLoaderClientV0 loaderClient;
+    memset(&amp;loaderClient, 0, sizeof(loaderClient));
+    loaderClient.base.version = 0;
+    loaderClient.didFinishLoadForFrame = didFinishLoadForFrame;
+    WKPageSetPageLoaderClient(webView.page(), &amp;loaderClient.base);
+
+    WKViewClientV0 viewClient;
+    memset(&amp;viewClient, 0, sizeof(viewClient));
+    viewClient.base.version = 0;
+    viewClient.didChangeContentsPosition = 0;
+    WKViewSetViewClient(view.get(), &amp;viewClient.base);
+
+    // Load page.
+    WKRetainPtr&lt;WKURLRef&gt; url(AdoptWK, Util::createURLForResource(&quot;efl/scrollTo&quot;, &quot;html&quot;));
+    WKPageLoadURL(webView.page(), url.get());
+    Util::run(&amp;finishedLoad);
+
+    WKPoint currentPagePosition = WKViewGetContentPosition(view.get());
+    EXPECT_EQ(100, currentPagePosition.x);
+    EXPECT_EQ(300, currentPagePosition.y);
+}
+
+} // TestWebKitAPI
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2eflscrollTohtml"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/scrollTo.html (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/scrollTo.html                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2/efl/scrollTo.html        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+&lt;html&gt;
+&lt;body style=&quot;width:2000px;height:2000px;&quot;&gt;
+scrollTo Test
+&lt;script&gt;
+window.scrollTo(100, 300);
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPIeflInjectedBundleControllercpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/efl/InjectedBundleController.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/efl/InjectedBundleController.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/efl/InjectedBundleController.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;InjectedBundleController.h&quot;
+
+#include &lt;wtf/Assertions.h&gt;
+
+namespace TestWebKitAPI {
+
+void InjectedBundleController::platformInitialize()
+{
+    WTFInstallReportBacktraceOnCrashHook();
+}
+
+} // namespace TestWebKitAPI
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPIeflPlatformUtilitiescpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/efl/PlatformUtilities.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/efl/PlatformUtilities.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/efl/PlatformUtilities.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;PlatformUtilities.h&quot;
+
+#include &lt;Ecore.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;unistd.h&gt;
+
+namespace TestWebKitAPI {
+
+namespace Util {
+
+void run(bool* done)
+{
+    while (!*done)
+        ecore_main_loop_iterate();
+}
+
+void sleep(double seconds)
+{
+    usleep(seconds * 1000000);
+}
+
+WKURLRef createURLForResource(const char* resource, const char* extension)
+{
+    char url[PATH_MAX];
+
+    snprintf(url, sizeof(url), &quot;file://%s/%s.%s&quot;, TEST_WEBKIT2_RESOURCES_DIR, resource, extension);
+
+    return WKURLCreateWithUTF8CString(url);
+}
+
+WKStringRef createInjectedBundlePath()
+{
+    return WKStringCreateWithUTF8CString(TEST_INJECTED_BUNDLE_PATH);
+}
+
+WKURLRef URLForNonExistentResource()
+{
+    return WKURLCreateWithUTF8CString(&quot;file:///does-not-exist.html&quot;);
+}
+
+WKRetainPtr&lt;WKStringRef&gt; MIMETypeForWKURLResponse(WKURLResponseRef wkResponse)
+{
+    return adoptWK(WKURLResponseCopyMIMEType(wkResponse));
+}
+
+} // namespace Util
+
+} // namespace TestWebKitAPI
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPIeflPlatformWebViewcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/efl/PlatformWebView.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/efl/PlatformWebView.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/efl/PlatformWebView.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,126 @@
</span><ins>+/*
+ * Copyright (C) 2012, 2014 Samsung Electronics
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+
+#include &quot;ewk_main.h&quot;
+#include &quot;ewk_view_private.h&quot;
+#include &quot;PlatformWebView.h&quot;
+#include &quot;EWebKit2.h&quot;
+#include &lt;WebKit/WKAPICast.h&gt;
+#include &lt;WebKit/WKPageConfigurationRef.h&gt;
+#include &lt;WebKit/WKRetainPtr.h&gt;
+#include &lt;WebKit/WKViewEfl.h&gt;
+#include &lt;Ecore_Evas.h&gt;
+
+extern bool useX11Window;
+
+using namespace WebKit;
+
+namespace TestWebKitAPI {
+
+static Ecore_Evas* createEcoreEvas()
+{
+    Ecore_Evas* ecoreEvas;
+#if defined(HAVE_ECORE_X)
+    ecoreEvas = ecore_evas_new(&quot;opengl_x11&quot;, 0, 0, 800, 600, 0);
+    // Graceful fallback to software rendering if evas_gl engine is not available.
+    if (!ecoreEvas)
+#endif
+    ecoreEvas = ecore_evas_new(0, 0, 0, 800, 600, 0);
+
+    ASSERT(ecoreEvas);
+
+    ecore_evas_show(ecoreEvas);
+
+    return ecoreEvas;
+}
+
+static void onWebProcessCrashed(void*, Evas_Object*, void* eventInfo)
+{
+    bool* handled = static_cast&lt;bool*&gt;(eventInfo);
+    *handled = true;
+}
+
+PlatformWebView::PlatformWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef)
+{
+    m_window = createEcoreEvas();
+
+    WKRetainPtr&lt;WKPageConfigurationRef&gt; pageConfiguration = adoptWK(WKPageConfigurationCreate());
+    WKPageConfigurationSetContext(pageConfiguration.get(), contextRef);
+    WKPageConfigurationSetPageGroup(pageConfiguration.get(), pageGroupRef);
+
+    m_view = EWKViewCreate(pageConfiguration.get(), ecore_evas_get(m_window), /* smart */ 0);
+
+    WKRetainPtr&lt;WKStringRef&gt; wkTheme = adoptWK(WKStringCreateWithUTF8CString(DEFAULT_THEME_DIR &quot;/default.edj&quot;));
+    WKViewSetThemePath(EWKViewGetWKView(m_view), wkTheme.get());
+
+    evas_object_smart_callback_add(m_view, &quot;webprocess,crashed&quot;, onWebProcessCrashed, 0);
+    resizeTo(600, 800);
+}
+
+PlatformWebView::~PlatformWebView()
+{
+    evas_object_del(m_view);
+
+    ecore_evas_free(m_window);
+}
+
+void PlatformWebView::resizeTo(unsigned width, unsigned height)
+{
+    evas_object_resize(m_view, width, height);
+}
+
+WKPageRef PlatformWebView::page() const
+{
+    return WKViewGetPage(EWKViewGetWKView(m_view));
+}
+
+void PlatformWebView::simulateSpacebarKeyPress()
+{
+    Evas* evas = evas_object_evas_get(m_view);
+    evas_object_focus_set(m_view, true);
+    evas_event_feed_key_down(evas, &quot;space&quot;, &quot;space&quot;, &quot; &quot;, 0, 0, 0);
+    evas_event_feed_key_up(evas, &quot;space&quot;, &quot;space&quot;, &quot; &quot;, 0, 1, 0);
+}
+
+void PlatformWebView::simulateMouseMove(unsigned x, unsigned y)
+{
+    Evas* evas = evas_object_evas_get(m_view);
+    evas_object_show(m_view);
+    evas_event_feed_mouse_move(evas, x, y, 0, 0);
+}
+
+void PlatformWebView::simulateRightClick(unsigned x, unsigned y)
+{
+    Evas* evas = evas_object_evas_get(m_view);
+    evas_object_show(m_view);
+    evas_event_feed_mouse_move(evas, x, y, 0, 0);
+    evas_event_feed_mouse_down(evas, 3, EVAS_BUTTON_NONE, 0, 0);
+    evas_event_feed_mouse_up(evas, 3, EVAS_BUTTON_NONE, 0, 0);
+}
+
+} // namespace TestWebKitAPI
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPIeflmaincpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/efl/main.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/efl/main.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/efl/main.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+/*
+ * Copyright (C) 2012 Samsung Electronics
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;TestsController.h&quot;
+#include &lt;getopt.h&gt;
+#include &lt;EWebKit2.h&gt;
+#include &lt;wtf/Assertions.h&gt;
+
+bool useX11Window = false;
+
+static bool checkForUseX11WindowArgument(int argc, char** argv)
+{
+    int hasUseX11Window = 0;
+
+    static const option options[] = {
+        {&quot;useX11Window&quot;, no_argument, &amp;hasUseX11Window, 1},
+        {0, 0, 0, 0}
+    };
+
+    while (getopt_long(argc, argv, &quot;&quot;, options, 0) != -1) { }
+
+    return hasUseX11Window;
+}
+
+int main(int argc, char** argv)
+{
+    WTFInstallReportBacktraceOnCrashHook();
+    setenv(&quot;WEBKIT_EXEC_PATH&quot;, WEBKIT_EXEC_PATH, false);
+
+    if (!ewk_init())
+        return EXIT_FAILURE;
+
+    useX11Window = checkForUseX11WindowArgument(argc, argv);
+
+    int returnCode = TestWebKitAPI::TestsController::singleton().run(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE;
+
+    ewk_shutdown();
+
+    return returnCode;
+}
</ins></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleeflActivateFontsEflcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/WebKitTestRunner/InjectedBundle/efl/ActivateFontsEfl.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/efl/ActivateFontsEfl.cpp                                (rev 0)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/efl/ActivateFontsEfl.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;ActivateFonts.h&quot;
+
+#include &quot;FontManagement.h&quot;
+
+namespace WTR {
+
+void activateFonts()
+{
+    addFontsToEnvironment();
+}
+
+} // namespace WTR
</ins></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleeflFontManagementcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/WebKitTestRunner/InjectedBundle/efl/FontManagement.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/efl/FontManagement.cpp                                (rev 0)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/efl/FontManagement.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,140 @@
</span><ins>+/*
+ * Copyright (C) 2011 ProFUSION Embedded Systems
+ * Copyright (C) 2011 Samsung Electronics
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;FontManagement.h&quot;
+
+#include &lt;Ecore_File.h&gt;
+#include &lt;cstdio&gt;
+#include &lt;fontconfig/fontconfig.h&gt;
+#include &lt;wtf/Vector.h&gt;
+#include &lt;wtf/text/CString.h&gt;
+#include &lt;wtf/text/StringBuilder.h&gt;
+
+static CString buildPath(const char* base, const char* first, ...)
+{
+    va_list ap;
+    StringBuilder result;
+    result.append(base);
+
+    if (const char* current = first) {
+        va_start(ap, first);
+        do {
+            result.append('/');
+            result.append(current);
+        } while ((current = va_arg(ap, const char*)));
+        va_end(ap);
+    }
+
+    return result.toString().utf8();
+}
+
+static Vector&lt;CString&gt; getCoreFontFiles()
+{
+    Vector&lt;CString&gt; fontFilePaths;
+
+    // Ahem is used by many layout tests.
+    fontFilePaths.append(CString(FONTS_CONF_DIR &quot;/AHEM____.TTF&quot;));
+    // A font with no valid Fontconfig encoding to test https://bugs.webkit.org/show_bug.cgi?id=47452
+    fontFilePaths.append(CString(FONTS_CONF_DIR &quot;/FontWithNoValidEncoding.fon&quot;));
+
+    for (int i = 1; i &lt;= 9; i++) {
+        char fontPath[EINA_PATH_MAX];
+        snprintf(fontPath, EINA_PATH_MAX - 1, FONTS_CONF_DIR &quot;/../../fonts/WebKitWeightWatcher%i00.ttf&quot;, i);
+        fontFilePaths.append(CString(fontPath));
+    }
+
+    return fontFilePaths;
+}
+
+static void addFontDirectory(const CString&amp; fontDirectory, FcConfig* config)
+{
+    const char* fontPath = fontDirectory.data();
+    if (!fontPath || !FcConfigAppFontAddDir(config, reinterpret_cast&lt;const FcChar8*&gt;(fontPath)))
+        fprintf(stderr, &quot;Could not add font directory %s!\n&quot;, fontPath);
+}
+
+static void addFontFiles(const Vector&lt;CString&gt;&amp; fontFiles, FcConfig* config)
+{
+    Vector&lt;CString&gt;::const_iterator it, end = fontFiles.end();
+    for (it = fontFiles.begin(); it != end; ++it) {
+        const char* filePath = (*it).data();
+        if (!FcConfigAppFontAddFile(config, reinterpret_cast&lt;const FcChar8*&gt;(filePath)))
+            fprintf(stderr, &quot;Could not load font at %s!\n&quot;, filePath);
+    }
+}
+
+static CString getCustomBuildDir()
+{
+    if (const char* userChosenBuildDir = getenv(&quot;WEBKIT_OUTPUTDIR&quot;)) {
+        if (ecore_file_is_dir(userChosenBuildDir))
+            return userChosenBuildDir;
+        fprintf(stderr, &quot;WEBKIT_OUTPUTDIR set to '%s', but path doesn't exist.\n&quot;, userChosenBuildDir);
+    }
+
+    return CString();
+}
+
+static CString getPlatformFontsPath()
+{
+    CString customBuildDir = getCustomBuildDir();
+    if (!customBuildDir.isNull()) {
+        CString fontsPath = buildPath(customBuildDir.data(), &quot;DependenciesEFL&quot;, &quot;Root&quot;, &quot;webkitgtk-test-fonts&quot;, 0);
+        if (!ecore_file_exists(fontsPath.data()))
+            fprintf(stderr, &quot;WEBKIT_OUTPUTDIR set to '%s', but could not local test fonts.\n&quot;, customBuildDir.data());
+        return fontsPath;
+    }
+
+    CString fontsPath = CString(DOWNLOADED_FONTS_DIR);
+    if (ecore_file_exists(fontsPath.data()))
+        return fontsPath;
+
+    fprintf(stderr, &quot;Could not locate tests fonts, try setting WEBKIT_OUTPUTDIR.\n&quot;);
+    return CString();
+}
+
+void addFontsToEnvironment()
+{
+    FcInit();
+
+    // Load our configuration file, which sets up proper aliases for family
+    // names like sans, serif and monospace.
+    FcConfig* config = FcConfigCreate();
+    const char* fontConfigFilename = FONTS_CONF_DIR &quot;/fonts.conf&quot;;
+    if (!FcConfigParseAndLoad(config, reinterpret_cast&lt;const FcChar8*&gt;(fontConfigFilename), true)) {
+        fprintf(stderr, &quot;Couldn't load font configuration file from: %s\n&quot;, fontConfigFilename);
+        exit(1);
+    }
+
+    addFontFiles(getCoreFontFiles(), config);
+    addFontDirectory(getPlatformFontsPath(), config);
+
+    if (!FcConfigSetCurrent(config)) {
+        fprintf(stderr, &quot;Could not set the current font configuration!\n&quot;);
+        exit(1);
+    }
+}
+
</ins></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleeflFontManagementh"></a>
<div class="addfile"><h4>Added: trunk/Tools/WebKitTestRunner/InjectedBundle/efl/FontManagement.h (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/efl/FontManagement.h                                (rev 0)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/efl/FontManagement.h        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+/*
+ * Copyright (C) 2011 ProFUSION Embedded Systems
+ * Copyright (C) 2011 Samsung Electronics
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FontManagement_h
+#define FontManagement_h
+
+void addFontsToEnvironment();
+
+#endif // FontManagement_h
</ins></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleeflInjectedBundleEflcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/WebKitTestRunner/InjectedBundle/efl/InjectedBundleEfl.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/efl/InjectedBundleEfl.cpp                                (rev 0)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/efl/InjectedBundleEfl.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;InjectedBundle.h&quot;
+
+#include &lt;wtf/Assertions.h&gt;
+
+namespace WTR {
+
+void InjectedBundle::platformInitialize(WKTypeRef)
+{
+    WTFInstallReportBacktraceOnCrashHook();
+}
+
+} // namespace WTR
</ins></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleeflTestRunnerEflcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/WebKitTestRunner/InjectedBundle/efl/TestRunnerEfl.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/efl/TestRunnerEfl.cpp                                (rev 0)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/efl/TestRunnerEfl.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;TestRunner.h&quot;
+
+#include &quot;InjectedBundle.h&quot;
+#include &lt;Ecore.h&gt;
+#include &lt;JavaScriptCore/OpaqueJSString.h&gt;
+#include &lt;WebCore/EflInspectorUtilities.h&gt;
+#include &lt;wtf/text/CString.h&gt;
+#include &lt;wtf/text/StringBuilder.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WTR {
+
+static Eina_Bool waitToDumpWatchdogTimerCallback(void*)
+{
+    InjectedBundle::singleton().testRunner()-&gt;waitToDumpWatchdogTimerFired();
+    return false;
+}
+
+void TestRunner::platformInitialize()
+{
+    m_waitToDumpWatchdogTimer = 0;
+}
+
+void TestRunner::invalidateWaitToDumpWatchdogTimer()
+{
+    if (!m_waitToDumpWatchdogTimer)
+        return;
+
+    ecore_timer_del(m_waitToDumpWatchdogTimer);
+    m_waitToDumpWatchdogTimer = 0;
+}
+
+void TestRunner::initializeWaitToDumpWatchdogTimerIfNeeded()
+{
+    if (m_waitToDumpWatchdogTimer)
+        return;
+
+    m_waitToDumpWatchdogTimer = ecore_timer_loop_add(m_timeout / 1000.0, waitToDumpWatchdogTimerCallback, 0);
+}
+
+JSRetainPtr&lt;JSStringRef&gt; TestRunner::pathToLocalResource(JSStringRef url)
+{
+    String requestedUrl(url-&gt;characters(), url-&gt;length());
+    String resourceRoot;
+    String requestedRoot;
+
+    if (requestedUrl.find(&quot;LayoutTests&quot;) != notFound) {
+        // If the URL contains LayoutTests we need to remap that to
+        // LOCAL_RESOURCE_ROOT which is the path of the LayoutTests directory
+        // within the WebKit source tree.
+        requestedRoot = &quot;/tmp/LayoutTests&quot;;
+        resourceRoot = getenv(&quot;LOCAL_RESOURCE_ROOT&quot;);
+    } else if (requestedUrl.find(&quot;tmp&quot;) != notFound) {
+        // If the URL is a child of /tmp we need to convert it to be a child
+        // DUMPRENDERTREE_TEMP replace tmp with DUMPRENDERTREE_TEMP
+        requestedRoot = &quot;/tmp&quot;;
+        resourceRoot = getenv(&quot;DUMPRENDERTREE_TEMP&quot;);
+    }
+
+    size_t indexOfRootStart = requestedUrl.reverseFind(requestedRoot);
+    size_t indexOfSeparatorAfterRoot = indexOfRootStart + requestedRoot.length();
+    String fullPathToUrl = &quot;file://&quot; + resourceRoot + requestedUrl.substring(indexOfSeparatorAfterRoot);
+
+    return JSStringCreateWithUTF8CString(fullPathToUrl.utf8().data());
+}
+
+JSRetainPtr&lt;JSStringRef&gt; TestRunner::inspectorTestStubURL()
+{
+    StringBuilder builder;
+    builder.append(&quot;file://&quot;);
+    builder.append(WebCore::inspectorResourcePath());
+    builder.appendLiteral(&quot;/TestStub.html&quot;);
+
+    return JSStringCreateWithUTF8CString(builder.toString().utf8().data());
+}
+
+} // namespace WTR
</ins></span></pre></div>
<a id="trunkToolsWebKitTestRunnereflEventSenderProxyEflcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/WebKitTestRunner/efl/EventSenderProxyEfl.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/efl/EventSenderProxyEfl.cpp                                (rev 0)
+++ trunk/Tools/WebKitTestRunner/efl/EventSenderProxyEfl.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,572 @@
</span><ins>+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Zan Dobersek &lt;zandobersek@gmail.com&gt;
+ * Copyright (C) 2009 Holger Hans Peter Freyther
+ * Copyright (C) 2010 Igalia S.L.
+ * Copyright (C) 2011 ProFUSION Embedded Systems
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;EventSenderProxy.h&quot;
+
+#include &quot;NotImplemented.h&quot;
+#include &quot;PlatformWebView.h&quot;
+#include &quot;TestController.h&quot;
+
+#include &lt;Ecore.h&gt;
+#include &lt;Ecore_Evas.h&gt;
+#include &lt;unistd.h&gt;
+#include &lt;wtf/StdLibExtras.h&gt;
+#include &lt;wtf/text/CString.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WTR {
+
+static const char* modifierNames[] = { &quot;Shift&quot;, &quot;Control&quot;, &quot;Alt&quot;, &quot;Meta&quot; };
+
+enum WTREventType {
+    WTREventTypeNone = 0,
+    WTREventTypeMouseDown,
+    WTREventTypeMouseUp,
+    WTREventTypeMouseMove,
+    WTREventTypeMouseScrollBy,
+    WTREventTypeLeapForward
+};
+
+enum EvasMouseButton {
+    EvasMouseButtonNone = 0,
+    EvasMouseButtonLeft,
+    EvasMouseButtonMiddle,
+    EvasMouseButtonRight
+};
+
+// Key event location code defined in DOM Level 3.
+enum KeyLocationCode {
+    DOMKeyLocationStandard      = 0x00,
+    DOMKeyLocationLeft          = 0x01,
+    DOMKeyLocationRight         = 0x02,
+    DOMKeyLocationNumpad        = 0x03
+};
+
+struct WTREvent {
+    WTREventType eventType;
+    unsigned delay;
+    WKEventModifiers modifiers;
+    int button;
+    int horizontal;
+    int vertical;
+
+    WTREvent()
+        : eventType(WTREventTypeNone)
+        , delay(0)
+        , modifiers(0)
+        , button(-1)
+        , horizontal(-1)
+        , vertical(-1)
+    {
+    }
+
+    WTREvent(WTREventType eventType, unsigned delay, WKEventModifiers modifiers, int button)
+        : eventType(eventType)
+        , delay(delay)
+        , modifiers(modifiers)
+        , button(button)
+        , horizontal(-1)
+        , vertical(-1)
+    {
+    }
+};
+
+struct KeyEventInfo : public RefCounted&lt;KeyEventInfo&gt; {
+    KeyEventInfo(const CString&amp; keyName, const CString&amp; keyString)
+        : keyName(keyName)
+        , keyString(keyString)
+    {
+    }
+
+    const CString keyName;
+    const CString keyString;
+};
+
+static unsigned evasMouseButton(unsigned button)
+{
+    // The common case involves converting from a WKEventMouseButton (which
+    // starts at -1) to an EvasMouseButton (which a starts at 0). The special
+    // case for button 3 exists because of fast/events/mouse-click-events.html,
+    // which tests whether a 4th mouse button behaves as the middle one.
+    if (button &lt;= kWKEventMouseButtonRightButton)
+        return button + 1;
+    if (button == kWKEventMouseButtonRightButton + 1)
+        return EvasMouseButtonMiddle;
+    return EvasMouseButtonNone;
+}
+
+static void setEvasModifiers(Evas* evas, WKEventModifiers wkModifiers)
+{
+    for (unsigned modifier = 0; modifier &lt; (sizeof(modifierNames) / sizeof(char*)); ++modifier) {
+        if (wkModifiers &amp; (1 &lt;&lt; modifier))
+            evas_key_modifier_on(evas, modifierNames[modifier]);
+        else
+            evas_key_modifier_off(evas, modifierNames[modifier]);
+    }
+}
+
+static void dispatchMouseDownEvent(Evas* evas, unsigned button, WKEventModifiers wkModifiers, int clickCount)
+{
+    Evas_Button_Flags buttonFlags = EVAS_BUTTON_NONE;
+    if (clickCount == 3)
+        buttonFlags = EVAS_BUTTON_TRIPLE_CLICK;
+    else if (clickCount == 2)
+        buttonFlags = EVAS_BUTTON_DOUBLE_CLICK;
+
+    setEvasModifiers(evas, wkModifiers);
+    evas_event_feed_mouse_down(evas, button, buttonFlags, 0, 0);
+    setEvasModifiers(evas, 0);
+}
+
+static void dispatchMouseUpEvent(Evas* evas, unsigned button, WKEventModifiers wkModifiers)
+{
+    setEvasModifiers(evas, wkModifiers);
+    evas_event_feed_mouse_up(evas, button, EVAS_BUTTON_NONE, 0, 0);
+    setEvasModifiers(evas, 0);
+}
+
+static void dispatchMouseMoveEvent(Evas* evas, int x, int y)
+{
+    evas_event_feed_mouse_move(evas, x, y, 0, 0);
+}
+
+static void dispatchMouseScrollByEvent(Evas* evas, int horizontal, int vertical)
+{
+    if (horizontal)
+        evas_event_feed_mouse_wheel(evas, 1, horizontal, 0, 0);
+
+    if (vertical)
+        evas_event_feed_mouse_wheel(evas, 0, vertical, 0, 0);
+}
+
+static const RefPtr&lt;KeyEventInfo&gt; keyPadName(WKStringRef keyRef)
+{
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;leftArrow&quot;))
+        return adoptRef(new KeyEventInfo(&quot;KP_Left&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;rightArrow&quot;))
+        return adoptRef(new KeyEventInfo(&quot;KP_Right&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;upArrow&quot;))
+        return adoptRef(new KeyEventInfo(&quot;KP_Up&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;downArrow&quot;))
+        return adoptRef(new KeyEventInfo(&quot;KP_Down&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;pageUp&quot;))
+        return adoptRef(new KeyEventInfo(&quot;KP_Prior&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;pageDown&quot;))
+        return adoptRef(new KeyEventInfo(&quot;KP_Next&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;home&quot;))
+        return adoptRef(new KeyEventInfo(&quot;KP_Home&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;end&quot;))
+        return adoptRef(new KeyEventInfo(&quot;KP_End&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;insert&quot;))
+        return adoptRef(new KeyEventInfo(&quot;KP_Insert&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;delete&quot;))
+        return adoptRef(new KeyEventInfo(&quot;KP_Delete&quot;, &quot;&quot;));
+
+    size_t bufferSize = WKStringGetMaximumUTF8CStringSize(keyRef);
+    auto buffer = std::make_unique&lt;char[]&gt;(bufferSize);
+    WKStringGetUTF8CString(keyRef, buffer.get(), bufferSize);
+    return adoptRef(new KeyEventInfo(buffer.get(), buffer.get()));
+}
+
+static const RefPtr&lt;KeyEventInfo&gt; keyName(WKStringRef keyRef)
+{
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;leftArrow&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Left&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;rightArrow&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Right&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;upArrow&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Up&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;downArrow&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Down&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;pageUp&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Prior&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;pageDown&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Next&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;home&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Home&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;end&quot;))
+        return adoptRef(new KeyEventInfo(&quot;End&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;insert&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Insert&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;delete&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Delete&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;printScreen&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Print&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;menu&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Menu&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;leftControl&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Control_L&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;rightControl&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Control_R&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;leftShift&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Shift_L&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;rightShift&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Shift_R&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;leftAlt&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Alt_L&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;rightAlt&quot;))
+        return adoptRef(new KeyEventInfo(&quot;Alt_R&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F1&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F1&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F2&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F2&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F3&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F3&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F4&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F4&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F5&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F5&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F6&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F6&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F7&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F7&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F8&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F8&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F9&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F9&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F10&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F10&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F11&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F11&quot;, &quot;&quot;));
+    if (WKStringIsEqualToUTF8CString(keyRef, &quot;F12&quot;))
+        return adoptRef(new KeyEventInfo(&quot;F12&quot;, &quot;&quot;));
+
+    size_t bufferSize = WKStringGetMaximumUTF8CStringSize(keyRef);
+    auto buffer = std::make_unique&lt;char[]&gt;(bufferSize);
+    WKStringGetUTF8CString(keyRef, buffer.get(), bufferSize);
+    char charCode = buffer.get()[0];
+
+    if (charCode == '\n' || charCode == '\r')
+        return adoptRef(new KeyEventInfo(&quot;Return&quot;, &quot;\r&quot;));
+    if (charCode == '\t')
+        return adoptRef(new KeyEventInfo(&quot;Tab&quot;, &quot;\t&quot;));
+    if (charCode == '\x8')
+        return adoptRef(new KeyEventInfo(&quot;BackSpace&quot;, &quot;\x8&quot;));
+    if (charCode == ' ')
+        return adoptRef(new KeyEventInfo(&quot;space&quot;, &quot; &quot;));
+
+    return adoptRef(new KeyEventInfo(buffer.get(), buffer.get()));
+}
+
+EventSenderProxy::EventSenderProxy(TestController* testController)
+    : m_testController(testController)
+    , m_time(0)
+    , m_leftMouseButtonDown(false)
+    , m_clickCount(0)
+    , m_clickTime(0)
+    , m_clickButton(kWKEventMouseButtonNoButton)
+    , m_mouseButton(kWKEventMouseButtonNoButton)
+#if ENABLE(TOUCH_EVENTS)
+    , m_touchPoints(0)
+#endif
+{
+}
+
+EventSenderProxy::~EventSenderProxy()
+{
+#if ENABLE(TOUCH_EVENTS)
+    clearTouchPoints();
+#endif
+}
+
+void EventSenderProxy::updateClickCountForButton(int button)
+{
+    if (m_time - m_clickTime &lt; 1 &amp;&amp; m_position == m_clickPosition &amp;&amp; button == m_clickButton) {
+        ++m_clickCount;
+        m_clickTime = m_time;
+        return;
+    }
+
+    m_clickCount = 1;
+    m_clickTime = m_time;
+    m_clickPosition = m_position;
+    m_clickButton = button;
+}
+
+void EventSenderProxy::dispatchEvent(const WTREvent&amp; event)
+{
+    Evas* evas = evas_object_evas_get(m_testController-&gt;mainWebView()-&gt;platformView());
+
+    if (event.eventType == WTREventTypeMouseDown)
+        dispatchMouseDownEvent(evas, event.button, event.modifiers, m_clickCount);
+    else if (event.eventType == WTREventTypeMouseUp)
+        dispatchMouseUpEvent(evas, event.button, event.modifiers);
+    else if (event.eventType == WTREventTypeMouseMove)
+        dispatchMouseMoveEvent(evas, static_cast&lt;int&gt;(m_position.x), static_cast&lt;int&gt;(m_position.y));
+    else if (event.eventType == WTREventTypeMouseScrollBy)
+        dispatchMouseScrollByEvent(evas, event.horizontal, event.vertical);
+}
+
+void EventSenderProxy::replaySavedEvents()
+{
+    while (!m_eventQueue.isEmpty()) {
+        WTREvent event = m_eventQueue.takeFirst();
+        if (event.delay)
+            usleep(event.delay * 1000);
+
+        dispatchEvent(event);
+    }
+}
+
+void EventSenderProxy::sendOrQueueEvent(const WTREvent&amp; event)
+{
+    if (m_eventQueue.isEmpty() || !m_eventQueue.last().delay) {
+        dispatchEvent(event);
+        return;
+    }
+
+    m_eventQueue.append(event);
+    replaySavedEvents();
+}
+
+void EventSenderProxy::mouseDown(unsigned button, WKEventModifiers wkModifiers)
+{
+    if (m_mouseButton == button)
+        return;
+
+    m_mouseButton = button;
+    updateClickCountForButton(button);
+
+    sendOrQueueEvent(WTREvent(WTREventTypeMouseDown, 0, wkModifiers, evasMouseButton(button)));
+}
+
+void EventSenderProxy::mouseUp(unsigned button, WKEventModifiers wkModifiers)
+{
+    sendOrQueueEvent(WTREvent(WTREventTypeMouseUp, 0, wkModifiers, evasMouseButton(button)));
+
+    if (m_mouseButton == button)
+        m_mouseButton = kWKEventMouseButtonNoButton;
+
+    m_clickPosition = m_position;
+    m_clickTime = currentEventTime();
+}
+
+void EventSenderProxy::mouseMoveTo(double x, double y)
+{
+    m_position.x = x;
+    m_position.y = y;
+
+    sendOrQueueEvent(WTREvent(WTREventTypeMouseMove, 0, 0, kWKEventMouseButtonNoButton));
+}
+
+void EventSenderProxy::mouseScrollBy(int horizontal, int vertical)
+{
+    WTREvent event(WTREventTypeMouseScrollBy, 0, 0, kWKEventMouseButtonNoButton);
+    // We need to invert scrolling values since in EFL negative z value means that
+    // canvas is scrolling down
+    event.horizontal = -horizontal;
+    event.vertical = -vertical;
+    sendOrQueueEvent(event);
+}
+
+void EventSenderProxy::continuousMouseScrollBy(int horizontal, int vertical, bool paged)
+{
+    notImplemented();
+}
+
+void EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases(int x, int y, int /*phase*/, int /*momentum*/)
+{
+    // EFL does not have the concept of wheel gesture phases or momentum. Just relay to
+    // the mouse wheel handler.
+    mouseScrollBy(x, y);
+}
+
+void EventSenderProxy::swipeGestureWithWheelAndMomentumPhases(int, int, int, int)
+{
+    notImplemented();
+}
+
+void EventSenderProxy::leapForward(int milliseconds)
+{
+    if (m_eventQueue.isEmpty())
+        m_eventQueue.append(WTREvent(WTREventTypeLeapForward, milliseconds, 0, kWKEventMouseButtonNoButton));
+
+    m_time += milliseconds / 1000.0;
+}
+
+void EventSenderProxy::keyDown(WKStringRef keyRef, WKEventModifiers wkModifiers, unsigned location)
+{
+    const RefPtr&lt;KeyEventInfo&gt; keyEventInfo = (location == DOMKeyLocationNumpad) ? keyPadName(keyRef) : keyName(keyRef);
+    if (!keyEventInfo)
+        return;
+
+    const char* keyName = keyEventInfo-&gt;keyName.data();
+    const char* keyString = keyEventInfo-&gt;keyString.data();
+
+    // Enforce 'Shift' modifier for caps.
+    if ((strlen(keyName) == 1) &amp;&amp; (keyName[0] &gt;= 'A' &amp;&amp; keyName[0] &lt;= 'Z'))
+        wkModifiers |= kWKEventModifiersShiftKey;
+
+    Evas* evas = evas_object_evas_get(m_testController-&gt;mainWebView()-&gt;platformView());
+
+    int eventIndex = 0;
+    // Mimic the emacs ctrl-o binding by inserting a paragraph
+    // separator and then putting the cursor back to its original
+    // position. Allows us to pass emacs-ctrl-o.html
+    if ((wkModifiers &amp; kWKEventModifiersControlKey) &amp;&amp; !strcmp(keyName, &quot;o&quot;)) {
+        setEvasModifiers(evas, 0);
+        evas_event_feed_key_down(evas, &quot;Return&quot;, &quot;Return&quot;, &quot;\r&quot;, 0, eventIndex++, 0);
+        evas_event_feed_key_up(evas, &quot;Return&quot;, &quot;Return&quot;, &quot;\r&quot;, 0, eventIndex++, 0);
+        wkModifiers = 0;
+        keyName = &quot;Left&quot;;
+        keyString = 0;
+    }
+
+    setEvasModifiers(evas, wkModifiers);
+    evas_event_feed_key_down(evas, keyName, keyName, keyString, 0, eventIndex++, 0);
+    evas_event_feed_key_up(evas, keyName, keyName, keyString, 0, eventIndex++, 0);
+    setEvasModifiers(evas, 0);
+}
+
+#if ENABLE(TOUCH_EVENTS)
+void EventSenderProxy::sendTouchEvent(Ewk_Touch_Event_Type eventType)
+{
+    ASSERT(m_touchPoints);
+
+    Evas_Object* ewkView = m_testController-&gt;mainWebView()-&gt;platformView();
+    ewk_view_feed_touch_event(ewkView, eventType, m_touchPoints, evas_key_modifier_get(evas_object_evas_get(ewkView)));
+
+    Eina_List* list;
+    Eina_List* listNext;
+    void* data;
+    EINA_LIST_FOREACH_SAFE(m_touchPoints, list, listNext, data) {
+         Ewk_Touch_Point* touchPoint = static_cast&lt;Ewk_Touch_Point*&gt;(data);
+         ASSERT(touchPoint);
+
+         if ((touchPoint-&gt;state == EVAS_TOUCH_POINT_UP) || (touchPoint-&gt;state == EVAS_TOUCH_POINT_CANCEL)) {
+             delete touchPoint;
+             m_touchPoints = eina_list_remove_list(m_touchPoints, list);
+         } else
+             touchPoint-&gt;state = EVAS_TOUCH_POINT_STILL;
+     }
+}
+
+void EventSenderProxy::addTouchPoint(int x, int y)
+{
+    int id = 0;
+    if (m_touchPoints) {
+        Eina_List* last = eina_list_last(m_touchPoints);
+        Ewk_Touch_Point* touchPoint = static_cast&lt;Ewk_Touch_Point*&gt;(eina_list_data_get(last));
+        ASSERT(touchPoint);
+
+        id = touchPoint-&gt;id + 1;
+    }
+
+    Ewk_Touch_Point* touchPoint = new Ewk_Touch_Point;
+    touchPoint-&gt;id = id;
+    touchPoint-&gt;x = x;
+    touchPoint-&gt;y = y;
+    touchPoint-&gt;state = EVAS_TOUCH_POINT_DOWN;
+
+    m_touchPoints = eina_list_append(m_touchPoints, touchPoint);
+}
+
+void EventSenderProxy::updateTouchPoint(int index, int x, int y)
+{
+    ASSERT(index &gt;= 0 &amp;&amp; index &lt; eina_list_count(m_touchPoints));
+
+    Ewk_Touch_Point* touchPoint = static_cast&lt;Ewk_Touch_Point*&gt;(eina_list_nth(m_touchPoints, index));
+    ASSERT(touchPoint);
+
+    touchPoint-&gt;x = x;
+    touchPoint-&gt;y = y;
+    touchPoint-&gt;state = EVAS_TOUCH_POINT_MOVE;
+}
+
+void EventSenderProxy::setTouchModifier(WKEventModifiers modifier, bool enable)
+{
+    Evas_Object* ewkView = m_testController-&gt;mainWebView()-&gt;platformView();
+
+    for (unsigned index = 0; index &lt; (sizeof(modifierNames) / sizeof(char*)); ++index) {
+        if (modifier &amp; (1 &lt;&lt; index)) {
+            if (enable)
+                evas_key_modifier_on(evas_object_evas_get(ewkView), modifierNames[index]);
+            else
+                evas_key_modifier_off(evas_object_evas_get(ewkView), modifierNames[index]);
+        }
+    }
+}
+
+void EventSenderProxy::touchStart()
+{
+    sendTouchEvent(EWK_TOUCH_START);
+}
+
+void EventSenderProxy::touchMove()
+{
+    sendTouchEvent(EWK_TOUCH_MOVE);
+}
+
+void EventSenderProxy::touchEnd()
+{
+    sendTouchEvent(EWK_TOUCH_END);
+}
+
+void EventSenderProxy::touchCancel()
+{
+    sendTouchEvent(EWK_TOUCH_CANCEL);
+}
+
+void EventSenderProxy::clearTouchPoints()
+{
+    void* data = 0;
+    EINA_LIST_FREE(m_touchPoints, data)
+        delete static_cast&lt;Ewk_Touch_Point*&gt;(data);
+}
+
+void EventSenderProxy::releaseTouchPoint(int index)
+{
+    ASSERT(index &gt;= 0 &amp;&amp; index &lt; eina_list_count(m_touchPoints));
+
+    Ewk_Touch_Point* touchPoint = static_cast&lt;Ewk_Touch_Point*&gt;(eina_list_nth(m_touchPoints, index));
+    ASSERT(touchPoint);
+
+    touchPoint-&gt;state = EVAS_TOUCH_POINT_UP;
+}
+
+void EventSenderProxy::cancelTouchPoint(int index)
+{
+    ASSERT(index &gt;= 0 &amp;&amp; index &lt; eina_list_count(m_touchPoints));
+
+    Ewk_Touch_Point* touchPoint = static_cast&lt;Ewk_Touch_Point*&gt;(eina_list_nth(m_touchPoints, index));
+    ASSERT(touchPoint);
+
+    touchPoint-&gt;state = EVAS_TOUCH_POINT_CANCEL;
+}
+
+void EventSenderProxy::setTouchPointRadius(int radiusX, int radiusY)
+{
+    notImplemented();
+}
+
+#endif
+
+}
</ins></span></pre></div>
<a id="trunkToolsWebKitTestRunnereflPlatformWebViewEflcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp                                (rev 0)
+++ trunk/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,175 @@
</span><ins>+/*
+ * Copyright (C) 2012 Samsung Electronics
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;ewk_view_private.h&quot;
+#include &quot;PlatformWebView.h&quot;
+
+#include &quot;EWebKit2.h&quot;
+#include &lt;Ecore_Evas.h&gt;
+#include &lt;WebCore/RefPtrCairo.h&gt;
+#include &lt;WebKit/WKImageCairo.h&gt;
+#include &lt;WebKit/WKViewEfl.h&gt;
+#include &lt;cairo.h&gt;
+
+using namespace WebKit;
+
+namespace WTR {
+
+static Ecore_Evas* initEcoreEvas()
+{
+    Ecore_Evas* ecoreEvas = 0;
+#if defined(HAVE_ECORE_X)
+    const char* engine = &quot;opengl_x11&quot;;
+    ecoreEvas = ecore_evas_new(engine, 0, 0, 800, 600, 0);
+    // Graceful fallback to software rendering if evas_gl engine is not available.
+    if (!ecoreEvas)
+#endif
+    ecoreEvas = ecore_evas_new(0, 0, 0, 800, 600, 0);
+
+    if (!ecoreEvas)
+        return 0;
+
+    ecore_evas_title_set(ecoreEvas, &quot;EFL WebKitTestRunner&quot;);
+    ecore_evas_show(ecoreEvas);
+
+    return ecoreEvas;
+}
+
+PlatformWebView::PlatformWebView(WKPageConfigurationRef configuration, const TestOptions&amp; options)
+    : m_options(options)
+{
+    WKRetainPtr&lt;WKStringRef&gt; useFixedLayoutKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;UseFixedLayout&quot;));
+    m_usingFixedLayout = options.useFixedLayout;
+
+    m_window = initEcoreEvas();
+
+    m_view = EWKViewCreate(configuration, ecore_evas_get(m_window), /* smart */ 0);
+
+    WKPageSetUseFixedLayout(WKViewGetPage(EWKViewGetWKView(m_view)), m_usingFixedLayout);
+
+    if (m_usingFixedLayout)
+        resizeTo(800, 600);
+
+    ewk_view_theme_set(m_view, DEFAULT_THEME_DIR &quot;/default.edj&quot;);
+    m_windowIsKey = false;
+    evas_object_show(m_view);
+}
+
+PlatformWebView::~PlatformWebView()
+{
+    evas_object_del(m_view);
+
+    ecore_evas_free(m_window);
+}
+
+void PlatformWebView::setWindowIsKey(bool isKey)
+{
+    m_windowIsKey = isKey;
+}
+
+void PlatformWebView::resizeTo(unsigned width, unsigned height, WebViewSizingMode)
+{
+    // FIXME: Don't we need to resize the window too?
+    evas_object_resize(m_view, width, height);
+}
+
+WKPageRef PlatformWebView::page()
+{
+    return WKViewGetPage(EWKViewGetWKView(m_view));
+}
+
+void PlatformWebView::focus()
+{
+    // In a few cases, an iframe might receive focus from JavaScript and Evas is not aware of it at all
+    // (WebCoreSupport::focusedFrameChanged() does not emit any notification). We then manually remove the
+    // focus from the view to make the call give focus to evas_object_focus_set(..., true) to be effectful.
+    if (WKPageGetFocusedFrame(page()) != WKPageGetMainFrame(page()))
+        evas_object_focus_set(m_view, false);
+    evas_object_focus_set(m_view, true);
+}
+
+WKRect PlatformWebView::windowFrame()
+{
+    int x, y, width, height;
+
+    ecore_evas_request_geometry_get(m_window, &amp;x, &amp;y, &amp;width, &amp;height);
+
+    return WKRectMake(x, y, width, height);
+}
+
+void PlatformWebView::setWindowFrame(WKRect frame, WebViewSizingMode)
+{
+    ecore_evas_move_resize(m_window, frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
+    evas_object_resize(m_view, frame.size.width, frame.size.height);
+}
+
+void PlatformWebView::addChromeInputField()
+{
+}
+
+void PlatformWebView::removeChromeInputField()
+{
+}
+
+void PlatformWebView::addToWindow()
+{
+}
+
+void PlatformWebView::removeFromWindow()
+{
+}
+
+void PlatformWebView::makeWebViewFirstResponder()
+{
+}
+
+void PlatformWebView::changeWindowScaleIfNeeded(float)
+{
+}
+
+WKRetainPtr&lt;WKImageRef&gt; PlatformWebView::windowSnapshotImage()
+{
+    int width;
+    int height;
+    ecore_evas_geometry_get(m_window, 0, 0, &amp;width, &amp;height);
+    ASSERT(width &gt; 0 &amp;&amp; height &gt; 0);
+
+    return adoptWK(WKViewCreateSnapshot(EWKViewGetWKView(m_view)));
+}
+
+bool PlatformWebView::viewSupportsOptions(const TestOptions&amp; options) const
+{
+    if (m_options.useFixedLayout != options.useFixedLayout)
+        return false;
+
+    return true;
+}
+
+void PlatformWebView::didInitializeClients()
+{
+}
+
+void PlatformWebView::setNavigationGesturesEnabled(bool)
+{
+}
+
+} // namespace WTR
+
</ins></span></pre></div>
<a id="trunkToolsWebKitTestRunnereflTestControllerEflcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp                                (rev 0)
+++ trunk/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,166 @@
</span><ins>+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;TestController.h&quot;
+
+#include &quot;PlatformWebView.h&quot;
+#include &quot;TestInvocation.h&quot;
+#include &lt;Ecore.h&gt;
+#include &lt;Evas.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;unistd.h&gt;
+#include &lt;wtf/Platform.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WTR {
+
+static Ecore_Timer* timer = 0;
+
+static Eina_Bool timerFired(void*)
+{
+    timer = 0;
+    ecore_main_loop_quit();
+    return ECORE_CALLBACK_CANCEL;
+}
+
+void TestController::notifyDone()
+{
+    if (!timer)
+        return;
+
+    ecore_timer_del(timer);
+    timer = 0;
+    ecore_main_loop_quit();
+}
+
+void TestController::platformInitialize()
+{
+    const char* isDebugging = getenv(&quot;WEB_PROCESS_CMD_PREFIX&quot;);
+    if (isDebugging &amp;&amp; *isDebugging) {
+        m_useWaitToDumpWatchdogTimer = false;
+        m_forceNoTimeout = true;
+    }
+}
+
+WKPreferencesRef TestController::platformPreferences()
+{
+    return WKPageGroupGetPreferences(m_pageGroup.get());
+}
+
+void TestController::platformDestroy()
+{
+}
+
+void TestController::platformRunUntil(bool&amp; condition, double timeout)
+{
+    if (timeout &lt;= 0) {
+        // Never timeout if we are debugging or not meant to timeout.
+        while (!condition)
+            ecore_main_loop_iterate();
+
+        return;
+    }
+    timer = ecore_timer_loop_add(timeout, timerFired, 0);
+    ecore_main_loop_begin();
+}
+
+static const char* getEnvironmentVariableOrExit(const char* variableName)
+{
+    const char* value = getenv(variableName);
+    if (!value) {
+        fprintf(stderr, &quot;%s environment variable not found\n&quot;, variableName);
+        exit(0);
+    }
+
+    return value;
+}
+
+void TestController::initializeInjectedBundlePath()
+{
+    const char* bundlePath = getEnvironmentVariableOrExit(&quot;TEST_RUNNER_INJECTED_BUNDLE_FILENAME&quot;);
+    m_injectedBundlePath.adopt(WKStringCreateWithUTF8CString(bundlePath));
+}
+
+void TestController::initializeTestPluginDirectory()
+{
+    const char* pluginPath = getEnvironmentVariableOrExit(&quot;TEST_RUNNER_PLUGIN_PATH&quot;);
+    m_testPluginDirectory.adopt(WKStringCreateWithUTF8CString(pluginPath));
+}
+
+void TestController::platformInitializeContext()
+{
+}
+
+void TestController::setHidden(bool hidden)
+{
+    PlatformWKView view = mainWebView()-&gt;platformView();
+
+    if (!view) {
+        fprintf(stderr, &quot;ERROR: view is null.\n&quot;);
+        return;
+    }
+
+    if (hidden)
+        evas_object_hide(view);
+    else
+        evas_object_show(view);
+}
+
+void TestController::runModal(PlatformWebView*)
+{
+    // FIXME: Need to implement this to test showModalDialog.
+}
+
+const char* TestController::platformLibraryPathForTesting()
+{
+    return 0;
+}
+
+static bool pathContains(const std::string&amp; pathOrURL, const char* substring)
+{
+    String path(pathOrURL.c_str());
+    return path.contains(substring); // Case-insensitive.
+}
+
+static bool shouldUseFixedLayout(const std::string&amp; pathOrURL)
+{
+#if USE(COORDINATED_GRAPHICS)
+    if (pathContains(pathOrURL, &quot;sticky/&quot;) || pathContains(pathOrURL, &quot;sticky\\&quot;))
+        return true;
+#endif
+    return false;
+}
+
+void TestController::updatePlatformSpecificTestOptionsForTest(TestOptions&amp; testOptions, const std::string&amp; pathOrURL) const
+{
+    testOptions.useFixedLayout |= shouldUseFixedLayout(pathOrURL);
+}
+
+void TestController::platformConfigureViewForTest(const TestInvocation&amp;)
+{
+    WKPageSetApplicationNameForUserAgent(mainWebView()-&gt;page(), WKStringCreateWithUTF8CString(&quot;WebKitTestRunnerEFL&quot;));
+}
+
+void TestController::platformResetPreferencesToConsistentValues()
+{
+}
+
+} // namespace WTR
</ins></span></pre></div>
<a id="trunkToolsWebKitTestRunnereflmaincpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/WebKitTestRunner/efl/main.cpp (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/efl/main.cpp                                (rev 0)
+++ trunk/Tools/WebKitTestRunner/efl/main.cpp        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include &quot;config.h&quot;
+
+#include &quot;EWebKit2.h&quot;
+#include &quot;TestController.h&quot;
+#include &lt;wtf/Assertions.h&gt;
+#include &lt;stdlib.h&gt;
+
+#ifdef HAVE_ECORE_X
+#include &lt;X11/Xlib.h&gt;
+#include &lt;X11/extensions/Xext.h&gt;
+
+static int dummyExtensionErrorHandler(Display*, _Xconst char*, _Xconst char*)
+{
+    return 0;
+}
+#endif
+
+int main(int argc, char** argv)
+{
+    WTFInstallReportBacktraceOnCrashHook();
+
+#ifdef HAVE_ECORE_X
+    XSetExtensionErrorHandler(dummyExtensionErrorHandler);
+#endif
+
+    if (!ewk_init())
+        return 1;
+
+    {
+        // Test controller has own ptr containing WebView and WebView must be deleted
+        // before its evas object is deleted. Call of ewk_shutdown() leads to evas objects deletion.
+
+        WTR::TestController controller(argc, const_cast&lt;const char**&gt;(argv));
+    }
+
+    ewk_shutdown();
+
+    return 0;
+}
+
</ins></span></pre></div>
<a id="trunkToolseflinstalldependencies"></a>
<div class="addfile"><h4>Added: trunk/Tools/efl/install-dependencies (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/efl/install-dependencies                                (rev 0)
+++ trunk/Tools/efl/install-dependencies        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,135 @@
</span><ins>+#!/bin/bash
+
+# This script needs to be run with root rights.
+if [ $UID -ne 0 ]; then
+    sudo $0
+    exit 0
+fi
+
+function printNotSupportedMessageAndExit() {
+    echo
+    echo &quot;Currently this script only works for distributions supporting apt-get.&quot;
+    echo &quot;Please add support for your distribution.&quot;
+    echo
+    exit 1
+}
+
+function checkCmakeVersion() {
+    CMAKE_VERSION=`cmake --version`
+
+    VERSION=`echo &quot;$CMAKE_VERSION&quot; | awk '{split($3,num,&quot;.&quot;);
+    if (!(num[1]&gt;2 || num[2]&gt;8 || num[3]&gt;=10))
+        printf $3}'`
+
+    if [ -n &quot;${VERSION}&quot; ]; then
+        echo &quot;Warning: CMake version detected (${VERSION}) is lower then 2.8.10.&quot;
+        echo &quot;  This will probably cause errors, as older version didn't support CMAKE_NINJA_FORCE_RESPONSE_FILE,&quot;
+        echo &quot;  which is needed now for building. (look at: https://lists.webkit.org/pipermail/webkit-gtk/2014-March/001809.html )&quot;
+        echo &quot;&quot;
+
+        if [ -f &quot;/etc/issue&quot; ]; then
+            ubuntu_version=`cat /etc/issue`
+            if [[ $ubuntu_version == *Ubuntu\ 12.04* ]]; then
+                echo &quot;  For Ubuntu 12.04 or 12.10 You might consider adding ppa from https://launchpad.net/~kalakris/+archive/ubuntu/cmake&quot;
+            fi
+        fi
+    fi
+}
+
+function checkInstaller {
+    # apt-get - Debian based distributions
+    apt-get --version &amp;&gt; /dev/null
+    if [ $? -eq 0 ]; then
+        installDependenciesWithApt
+        checkCmakeVersion;
+        exit 0
+    fi
+
+    printNotSupportedMessageAndExit
+}
+
+# If the package $1 is available, prints it. Otherwise prints $2.
+# Useful for handling when a package is renamed on new versions of Debian/Ubuntu.
+function aptIfElse {
+    if apt-cache show $1 &amp;&gt;/dev/null; then
+        echo $1
+    else
+        echo $2
+    fi
+}
+
+function installDependenciesWithApt {
+    # These are dependencies necessary for building WebKitEFL.
+    apt-get install \
+        bison \
+        cmake \
+        doxygen \
+        flex \
+        g++ \
+        geoclue-2.0 \
+        gperf \
+        gtk-doc-tools \
+        libatk1.0-dev \
+        libdbus-1-dev \
+        libedit-dev \
+        libenchant-dev \
+        libespeak-dev \
+        libfaad-dev \
+        libffi-dev \
+        libfreetype6-dev \
+        $(aptIfElse libgcrypt20-dev libgcrypt11-dev) \
+        $(aptIfElse libgeoclue-2-dev libgeoclue-dev) \
+        libgif-dev \
+        libgl1-mesa-dev \
+        libgpg-error-dev \
+        libhyphen-dev \
+        libicu-dev \
+        libjpeg-dev \
+        libjson-glib-dev \
+        liblua5.1-0-dev \
+        libluajit-5.1-dev \
+        libmpg123-dev \
+        liborc-0.4-dev \
+        libosmesa6-dev \
+        libp11-kit-dev \
+        $(aptIfElse libpng-dev libpng12-dev) \
+        libpoppler-cpp-dev \
+        libpulse-dev \
+        libraw-dev \
+        librsvg2-dev \
+        libspectre-dev \
+        libsqlite3-dev \
+        libssl-dev \
+        libtheora-dev \
+        libtiff5-dev \
+        libudev-dev \
+        libvorbis-dev \
+        libwebp-dev \
+        libxcomposite-dev \
+        libxcursor-dev \
+        libxinerama-dev \
+        libxrandr-dev \
+        libxrender-dev \
+        libxss-dev \
+        libxt-dev \
+        libxtst-dev \
+        ninja-build \
+        ragel \
+        ruby \
+        subversion \
+        x11proto-print-dev
+
+    # These are dependencies necessary for building WebKitEFL and not available on ARM64.
+    apt-get install \
+        luajit
+
+    # These are dependencies necessary for running tests.
+    apt-get install \
+        apache2 \
+        $(aptIfElse libapache2-mod-php7.0 libapache2-mod-php5) \
+        libruby \
+        xvfb
+}
+
+checkInstaller
+
</ins><span class="cx">Property changes on: trunk/Tools/efl/install-dependencies
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkToolsefljhbuildoptionalmodules"></a>
<div class="addfile"><h4>Added: trunk/Tools/efl/jhbuild-optional.modules (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/efl/jhbuild-optional.modules                                (rev 0)
+++ trunk/Tools/efl/jhbuild-optional.modules        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot;?&gt;
+&lt;!DOCTYPE moduleset SYSTEM &quot;moduleset.dtd&quot;&gt;
+&lt;?xml-stylesheet type=&quot;text/xsl&quot; href=&quot;moduleset.xsl&quot;?&gt;
+&lt;moduleset&gt;
+
+  &lt;repository type=&quot;tarball&quot; name=&quot;ftp.gnome.org&quot;
+      href=&quot;http://ftp.gnome.org&quot;/&gt;
+
+  &lt;autotools id=&quot;at-spi2-core&quot;
+          autogenargs=&quot;--disable-introspection&quot;&gt;
+    &lt;branch module=&quot;pub/GNOME/sources/at-spi2-core/2.10/at-spi2-core-2.10.0.tar.xz&quot; version=&quot;2.10.0&quot;
+          repo=&quot;ftp.gnome.org&quot;
+          hash=&quot;sha256:964155c7574220a00e11e1c0d91f2d3017ed603920eb1333ff9cbdb6a22744db&quot;&gt;
+    &lt;/branch&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;glib&quot;/&gt;
+    &lt;/dependencies&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;at-spi2-atk&quot;&gt;
+    &lt;branch module=&quot;pub/GNOME/sources/at-spi2-atk/2.10/at-spi2-atk-2.10.0.tar.xz&quot; version=&quot;2.10.0&quot;
+            repo=&quot;ftp.gnome.org&quot;
+            hash=&quot;sha256:dea7ff2f9bc9bbdb0351112616d738de718b55739cd2511afecac51604c31a94&quot;&gt;
+    &lt;/branch&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;glib&quot;/&gt;
+      &lt;dep package=&quot;atk&quot;/&gt;
+      &lt;dep package=&quot;at-spi2-core&quot;/&gt;
+    &lt;/dependencies&gt;
+  &lt;/autotools&gt;
+
+&lt;/moduleset&gt;
</ins></span></pre></div>
<a id="trunkToolsefljhbuildmodules"></a>
<div class="addfile"><h4>Added: trunk/Tools/efl/jhbuild.modules (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/efl/jhbuild.modules                                (rev 0)
+++ trunk/Tools/efl/jhbuild.modules        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,317 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot;?&gt;
+&lt;!DOCTYPE moduleset SYSTEM &quot;moduleset.dtd&quot;&gt;
+&lt;?xml-stylesheet type=&quot;text/xsl&quot; href=&quot;moduleset.xsl&quot;?&gt;
+&lt;moduleset&gt;
+
+  &lt;metamodule id=&quot;webkitefl-testing-dependencies&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;cairo&quot;/&gt;
+      &lt;dep package=&quot;fonts&quot;/&gt;
+      &lt;dep package=&quot;dicts&quot;/&gt;
+      &lt;dep package=&quot;fontconfig&quot;/&gt;
+      &lt;dep package=&quot;freetype6&quot;/&gt;
+      &lt;dep package=&quot;harfbuzz&quot;/&gt;
+      &lt;dep package=&quot;glib&quot;/&gt;
+      &lt;dep package=&quot;glib-networking&quot;/&gt;
+      &lt;dep package=&quot;libsoup&quot;/&gt;
+      &lt;dep package=&quot;efl&quot;/&gt;
+      &lt;dep package=&quot;libxml2&quot;/&gt;
+      &lt;dep package=&quot;libxslt&quot;/&gt;
+      &lt;dep package=&quot;gstreamer&quot;/&gt;
+      &lt;dep package=&quot;gst-plugins-base&quot;/&gt;
+      &lt;dep package=&quot;gst-plugins-good&quot;/&gt;
+      &lt;dep package=&quot;gst-plugins-bad&quot;/&gt;
+      &lt;dep package=&quot;gst-libav&quot;/&gt;
+      &lt;dep package=&quot;atk&quot;/&gt;
+      &lt;dep package=&quot;openwebrtc&quot;/&gt;
+    &lt;/dependencies&gt;
+  &lt;/metamodule&gt;
+
+  &lt;include href=&quot;jhbuild-optional.modules&quot;/&gt;
+
+  &lt;repository type=&quot;tarball&quot; name=&quot;github.com&quot;
+      href=&quot;https://github.com&quot;/&gt;
+  &lt;repository type=&quot;tarball&quot; name=&quot;sourceware.org&quot;
+      href=&quot;ftp://sourceware.org&quot;/&gt;
+  &lt;repository type=&quot;tarball&quot; name=&quot;ftp.gnome.org&quot;
+      href=&quot;http://ftp.gnome.org&quot;/&gt;
+  &lt;repository type=&quot;git&quot; name=&quot;git.gnome.org&quot;
+      href=&quot;git://git.gnome.org/&quot;/&gt;
+  &lt;repository type=&quot;tarball&quot; name=&quot;cairographics.org&quot;
+      href=&quot;http://cairographics.org&quot;/&gt;
+  &lt;repository type=&quot;tarball&quot; name=&quot;freedesktop.org&quot;
+      href=&quot;http://www.freedesktop.org&quot;/&gt;
+  &lt;repository type=&quot;tarball&quot; name=&quot;nice.freedesktop.org&quot;
+      href=&quot;http://nice.freedesktop.org/&quot;/&gt;
+  &lt;repository type=&quot;tarball&quot; name=&quot;enlightenment.fr&quot;
+      href=&quot;http://git.enlightenment.fr/cgit.cgi/svn/&quot;/&gt;
+  &lt;repository type=&quot;tarball&quot; name=&quot;xmlsoft.org&quot;
+      href=&quot;ftp://xmlsoft.org&quot;/&gt;
+  &lt;repository type=&quot;tarball&quot; name=&quot;download.enlightenment.org&quot;
+      href=&quot;http://download.enlightenment.org&quot;/&gt;
+  &lt;repository type=&quot;tarball&quot; name=&quot;gstreamer&quot;
+      href=&quot;http://gstreamer.freedesktop.org/src/&quot;/&gt;
+
+  &lt;autotools id=&quot;cairo&quot; autogen-sh=&quot;configure&quot;
+             makeargs=&quot;CFLAGS='-fno-lto' CXXFLAGS='-fno-lto' LDFLAGS='-fno-lto'&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;fontconfig&quot;/&gt;
+      &lt;dep package=&quot;pixman&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch module=&quot;releases/cairo-1.14.2.tar.xz&quot; version=&quot;1.14.2&quot;
+            repo=&quot;cairographics.org&quot;
+            hash=&quot;sha256:c919d999ddb1bbbecd4bbe65299ca2abd2079c7e13d224577895afa7005ecceb&quot;
+            md5sum=&quot;e1cdfaf1c6c995c4d4c54e07215b0118&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;!-- FIXME: Pixman 0.32.6 isn't buildable with Clang, but disable-mmx option fixes
+              the build. This workaround can be removed once the original bug is fixed.
+              Details can be found here: https://bugs.webkit.org/show_bug.cgi?id=151441 --&gt;
+  &lt;autotools id=&quot;pixman&quot; autogen-sh=&quot;configure&quot;
+             autogenargs=&quot;--enable-gtk=no --disable-arm-iwmmxt --disable-mmx&quot;&gt;
+    &lt;branch module=&quot;releases/pixman-0.32.6.tar.gz&quot; version=&quot;0.32.6&quot;
+            repo=&quot;cairographics.org&quot;
+            hash=&quot;sha256:3dfed13b8060eadabf0a4945c7045b7793cc7e3e910e748a8bb0f0dc3e794904&quot;
+            md5sum=&quot;3a30859719a41bd0f5cccffbfefdd4c2&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;fonts&quot; supports-non-srcdir-builds=&quot;no&quot;
+             skip-autogen=&quot;true&quot;&gt;
+    &lt;branch module=&quot;mrobinson/webkitgtk-test-fonts/archive/0.0.5.tar.gz&quot; version=&quot;0.0.5&quot;
+            checkoutdir=&quot;webkitgtk-test-fonts&quot;
+            repo=&quot;github.com&quot;
+            hash=&quot;sha256:369aea9e18aa1a234400976c0a8135b9709805ce4b65a3b474a8d0ee0e298f34&quot;
+            md5sum=&quot;39802b485f513842724e6cfd265335bb&quot; size=&quot;22592847&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;dicts&quot; supports-non-srcdir-builds=&quot;no&quot;
+             skip-autogen=&quot;true&quot;&gt;
+    &lt;branch module=&quot;mrobinson/webkitgtk-test-dicts/archive/0.0.1.zip&quot; version=&quot;0.0.1&quot;
+            checkoutdir=&quot;webkitgtk-test-dicts&quot;
+            repo=&quot;github.com&quot;
+            hash=&quot;sha256:6cfc94a7846a0d8f76a7a733f729e8109c6e1d0fbc9e0e8587eb5c3ef9888c24&quot;
+            md5sum=&quot;6bd8d32c157305fc69932ea8d1348723&quot; size=&quot;99299&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;libffi&quot; autogen-sh=&quot;configure&quot;&gt;
+    &lt;branch module=&quot;/pub/libffi/libffi-3.1.tar.gz&quot; version=&quot;3.1&quot;
+             repo=&quot;sourceware.org&quot;
+             hash=&quot;sha256:97feeeadca5e21870fa4433bc953d1b3af3f698d5df8a428f68b73cd60aef6eb&quot;
+             md5sum=&quot;f5898b29bbfd70502831a212d9249d10&quot;/&gt;
+  &lt;/autotools&gt;
+
+  &lt;!-- FIXME: Original download url doesn't work in Korea. So, Bug 133303 changes the url for now.
+             Original download url: http://download.savannah.gnu.org/releases/freetype/freetype-2.4.11.tar.bz2 --&gt;
+  &lt;tarball id=&quot;freetype6&quot;&gt;
+    &lt;source href=&quot;github.com/shivamidow/freetype/raw/master/freetype-2.4.11.tar.bz2&quot; version=&quot;2.4.11&quot;
+            hash=&quot;sha256:ef9d0bcb64647d9e5125dc7534d7ca371c98310fec87677c410f397f71ffbe3f&quot;
+            md5sum=&quot;b93435488942486c8d0ca22e8f768034&quot; /&gt;
+  &lt;/tarball&gt;
+
+  &lt;autotools id=&quot;glib&quot;
+             autogen-sh=&quot;configure&quot;
+             autogenargs=&quot;--disable-dtrace&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;libffi&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch module=&quot;/pub/GNOME/sources/glib/2.41/glib-2.41.2.tar.xz&quot; version=&quot;2.41.2&quot;
+            repo=&quot;ftp.gnome.org&quot;
+            hash=&quot;sha256:da1f7258655f0e196b9304cb9515784634f3797437923e236bb3466348811c96&quot;
+            md5sum=&quot;9636f60e99b98fd0fdb5239f905ac008&quot;/&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;glib-networking&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;glib&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch module=&quot;/pub/GNOME/sources/glib-networking/2.41/glib-networking-2.41.4.tar.xz&quot; version=&quot;2.41.4&quot;
+            repo=&quot;ftp.gnome.org&quot;
+            hash=&quot;sha256:930ad618865dcf81765d0f48cb6f13e22d76203efa59d30604aed0384ce80fd7&quot;
+            md5sum=&quot;f88e163322c0834f9781d6224771ab2e&quot;/&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;libsoup&quot;
+             autogenargs=&quot;--without-gnome --disable-introspection&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;glib-networking&quot;/&gt;
+      &lt;dep package=&quot;libxml2&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch module=&quot;/pub/gnome/sources/libsoup/2.50/libsoup-2.50.0.tar.xz&quot; version=&quot;2.50.0&quot;
+            repo=&quot;ftp.gnome.org&quot;
+            hash=&quot;sha256:1e01365ac4af3817187ea847f9d3588c27eee01fc519a5a7cb212bb78b0f667b&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;fontconfig&quot;
+             autogen-sh=&quot;configure&quot;
+             autogenargs=&quot;--enable-libxml2&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;freetype6&quot;/&gt;
+      &lt;dep package=&quot;libxml2&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch module=&quot;software/fontconfig/release/fontconfig-2.11.1.tar.gz&quot; version=&quot;2.11.1&quot;
+            repo=&quot;freedesktop.org&quot;
+            hash=&quot;sha256:b6b066c7dce3f436fdc0dfbae9d36122b38094f4f53bd8dffd45e195b0540d8d&quot;
+            md5sum=&quot;e75e303b4f7756c2b16203a57ac87eba&quot;/&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;harfbuzz&quot; autogen-sh=&quot;configure&quot;&gt;
+    &lt;branch module=&quot;software/harfbuzz/release/harfbuzz-0.9.35.tar.bz2&quot; version=&quot;0.9.35&quot;
+           checkoutdir=&quot;harfbuzz-0.9.35&quot;
+           repo=&quot;freedesktop.org&quot;
+           hash=&quot;sha256:0aa1a8aba6f502321cf6fef3c9d2c73dde48389c5ed1d3615a7691944c2a06ed&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;efl&quot; autogen-sh=&quot;configure&quot;
+             autogenargs=&quot;--disable-fribidi --disable-audio --disable-libmount --disable-physics --enable-i-really-know-what-i-am-doing-and-that-this-will-probably-break-things-and-i-will-fix-them-myself-and-send-patches-abb&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;fontconfig&quot;/&gt;
+      &lt;dep package=&quot;gstreamer&quot;/&gt;
+      &lt;dep package=&quot;gst-plugins-base&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch module=&quot;rel/libs/efl/efl-1.18.4.tar.gz&quot; version=&quot;1.18.4&quot;
+            repo=&quot;download.enlightenment.org&quot;
+            hash=&quot;sha256:d19669eece770cc09733568c7dfef9870daa0f8b9f613ab76ad14b2f5de20040&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;libxml2&quot;
+             autogen-sh=&quot;configure&quot;
+             autogenargs=&quot;--without-python&quot;&gt;
+    &lt;branch module=&quot;/libxml2/libxml2-2.9.1.tar.gz&quot; version=&quot;2.9.1&quot;
+            repo=&quot;xmlsoft.org&quot;
+            hash=&quot;sha256:fd3c64cb66f2c4ea27e934d275904d92cec494a8e8405613780cbc8a71680fdb&quot;
+            md5sum=&quot;9c0cfef285d5c4a5c80d00904ddab380&quot;/&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;libxslt&quot;&gt;
+    &lt;branch module=&quot;/libxslt/libxslt-1.1.29.tar.gz&quot; version=&quot;1.1.29&quot;
+            repo=&quot;xmlsoft.org&quot;
+            hash=&quot;sha256:b5976e3857837e7617b29f2249ebb5eeac34e249208d31f1fbf7a6ba7a4090ce&quot;/&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;libxml2&quot;/&gt;
+    &lt;/dependencies&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;orc&quot; autogenargs=&quot;--disable-gtk-doc&quot; autogen-sh=&quot;configure&quot;&gt;
+    &lt;branch module=&quot;orc/orc-0.4.17.tar.gz&quot; version=&quot;0.4.17&quot;
+            repo=&quot;gstreamer&quot;
+            hash=&quot;sha256:4fc7cca48c59fff23afee78fb642cdbde001f56401c8f47b95a16578d1d5d7e8&quot;
+            md5sum=&quot;af1bf3dab9e69f3c36f389285e2a12a1&quot;/&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;gstreamer&quot; autogenargs=&quot;--disable-gtk-doc&quot; autogen-sh=&quot;configure&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;orc&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch module=&quot;gstreamer/gstreamer-1.8.0.tar.xz&quot; version=&quot;1.8.0&quot;
+            repo=&quot;gstreamer&quot;
+            hash=&quot;sha256:947a314a212b5d94985d89b43440dbe66b696e12bbdf9a2f78967b98d74abedc&quot;
+            md5sum=&quot;6846d7289ec323c38c49b818171e955a&quot;/&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;gst-plugins-base&quot;
+             autogen-sh=&quot;configure&quot;
+             autogenargs=&quot;--disable-examples --disable-gtk-doc&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;gstreamer&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch module=&quot;gst-plugins-base/gst-plugins-base-1.8.0.tar.xz&quot; version=&quot;1.8.0&quot;
+            repo=&quot;gstreamer&quot;
+            hash=&quot;sha256:abc0acc1d15b4b9c97c65cd9689bd6400081853b9980ea428d3c8572dd791522&quot;
+            md5sum=&quot;20cc8231609318310f2a55f64c86cbb4&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;gst-plugins-good&quot; autogenargs=&quot;--disable-examples --disable-soup --disable-gtk-doc&quot; autogen-sh=&quot;configure&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;gst-plugins-base&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch module=&quot;gst-plugins-good/gst-plugins-good-1.8.0.tar.xz&quot; version=&quot;1.8.0&quot;
+            repo=&quot;gstreamer&quot;
+            hash=&quot;sha256:c20c134d47dbc238d921707a3b66da709c2b4dd89f9d267cec13d1ddf16e9f4d&quot;
+            md5sum=&quot;91ed4649c7c2e43a61f731d144f6f6d0&quot;&gt;
+      &lt;patch file=&quot;gst-plugins-good-use-the-tfdt-decode-time.patch&quot; strip=&quot;1&quot;/&gt;
+      &lt;patch file=&quot;gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch&quot; strip=&quot;1&quot;/&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;gst-plugins-bad&quot; autogenargs=&quot;--disable-examples --disable-gtk-doc&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;gst-plugins-base&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch module=&quot;gst-plugins-bad/gst-plugins-bad-1.8.0.tar.xz&quot; version=&quot;1.8.0&quot;
+            repo=&quot;gstreamer&quot;
+            hash=&quot;sha256:116376dd1085082422e0b21b0ecd3d1cb345c469c58e32463167d4675f4ca90e&quot;
+            md5sum=&quot;1c2d797bb96a81e9ef570c7a0a37203e&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;gst-libav&quot; autogenargs=&quot;--with-libav-extra-configure='--disable-yasm' --disable-gtk-doc&quot; autogen-sh=&quot;configure&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;gst-plugins-base&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch module=&quot;gst-libav/gst-libav-1.8.0.tar.xz&quot; version=&quot;1.8.0&quot;
+            repo=&quot;gstreamer&quot;
+            hash=&quot;sha256:5a1ce28876aee93cb4f3d090f0e807915a5d9bc1325e3480dd302b85aeb4291c&quot;
+            md5sum=&quot;361638fa45466c5050bcde6bfe10fa46&quot;&gt;
+      &lt;patch file=&quot;gst-libav.patch&quot; strip=&quot;1&quot;/&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;atk&quot;
+             autogen-sh=&quot;configure&quot;
+             autogenargs=&quot;--disable-introspection&quot;&gt;
+    &lt;branch module=&quot;pub/GNOME/sources/atk/2.15/atk-2.15.2.tar.xz&quot; version=&quot;2.15.2&quot;
+            repo=&quot;ftp.gnome.org&quot;
+            hash=&quot;sha256:179d15424b8aa3a5726903f0da458de68e0585dfd9d451c6dcfcdb6b7b509cbe&quot;/&gt;
+    &lt;dependencies&gt;
+        &lt;dep package=&quot;glib&quot;/&gt;
+    &lt;/dependencies&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;libusrsctp&quot; supports-non-srcdir-builds=&quot;no&quot; autogen-sh=&quot;./bootstrap; ./configure --disable-warnings-as-errors&quot;&gt;
+    &lt;branch repo=&quot;github.com&quot; module=&quot;sctplab/usrsctp/archive/078ff3252f73327e0ac11d6fd5eff62011f6646e.tar.gz&quot; version=&quot;078ff3252f73327e0ac11d6fd5eff62011f6646e&quot; checkoutdir=&quot;libusrsctp&quot;
+            hash=&quot;sha256:175938887dc7554e000152055c818bdd15dd0e4ccc94ef93e38e9f952ea82edc&quot; size=&quot;648925&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;gst-plugins-openwebrtc&quot; supports-parallel-builds=&quot;no&quot; supports-non-srcdir-builds=&quot;no&quot; autogen-sh=&quot;./autogen.sh; ./configure&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;gst-plugins-base&quot;/&gt;
+      &lt;dep package=&quot;libusrsctp&quot;/&gt;
+    &lt;/dependencies&gt;
+   &lt;branch repo=&quot;github.com&quot; module=&quot;EricssonResearch/openwebrtc-gst-plugins/archive/e359b67484af90f416ea35e301205d2b53c77a14.tar.gz&quot; checkoutdir=&quot;gst-plugins-openwebrtc&quot; version=&quot;gst-plugins-openwebrtc-20150317&quot;
+           hash=&quot;sha256:a456425efb88de39c16a4f8ac4214aaf53157f9df1323f08de375c77f227b6b7&quot;
+           md5sum=&quot;827f13634ffa83cccf1a6312effbceaa&quot; size=&quot;92883&quot;&gt;
+      &lt;patch file=&quot;openwebrtc-gst-plugins-clang-warning-fix.patch&quot; strip=&quot;1&quot;/&gt;
+   &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;libnice&quot; supports-non-srcdir-builds=&quot;no&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;gstreamer&quot;/&gt;
+    &lt;/dependencies&gt;
+    &lt;branch repo=&quot;nice.freedesktop.org&quot; module=&quot;releases/libnice-0.1.13.tar.gz&quot; checkoutdir=&quot;libnice&quot; version=&quot;0.1.13&quot;
+            hash=&quot;sha256:61112d9f3be933a827c8365f20551563953af6718057928f51f487bfe88419e1&quot;
+            md5sum=&quot;3226faeaf48a9150ada00da2e2865959&quot; size=&quot;912374&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+  &lt;autotools id=&quot;openwebrtc&quot; autogenargs=&quot;--enable-bridge=no --enable-owr-gst=yes&quot;&gt;
+    &lt;dependencies&gt;
+      &lt;dep package=&quot;gst-plugins-openwebrtc&quot;/&gt;
+      &lt;dep package=&quot;libnice&quot;/&gt;
+     &lt;/dependencies&gt;
+    &lt;branch repo=&quot;github.com&quot; module=&quot;EricssonResearch/openwebrtc/archive/f511ea1fa79a33fa3d52bfd1c0969c28084aeb35.tar.gz&quot; checkoutdir=&quot;openwebrtc&quot; version=&quot;f511ea1fa79a33fa3d52bfd1c0969c28084aeb35&quot;
+            hash=&quot;sha256:af80b80512b5f5a6b82b4cf43afa28da9c94c86800f6fadd10762361079fb5e3&quot;
+            md5sum=&quot;4555d20821af8f5334f74b4f0327f178&quot; size=&quot;296143&quot;&gt;
+    &lt;/branch&gt;
+  &lt;/autotools&gt;
+
+&lt;/moduleset&gt;
</ins></span></pre></div>
<a id="trunkToolsefljhbuildrc"></a>
<div class="addfile"><h4>Added: trunk/Tools/efl/jhbuildrc (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/efl/jhbuildrc                                (rev 0)
+++ trunk/Tools/efl/jhbuildrc        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+#!/usr/bin/env python
+# Copyright (C) 2011 Igalia S.L.
+# Copyright (C) 2012 Intel Corporation
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+import sys
+import platform
+
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), &quot;../jhbuild&quot;) )
+import jhbuildrc_common
+
+jhbuildrc_common.init(globals(), &quot;efl&quot;) 
+
+addpath('XDG_DATA_DIRS', '/usr/share')
+addpath('XDG_CONFIG_DIRS', '/etc/xdg')
+
+partial_build = False
</ins></span></pre></div>
<a id="trunkToolseflpatchesevasfixbuildwithgiflib5patch"></a>
<div class="addfile"><h4>Added: trunk/Tools/efl/patches/evas-fix-build-with-giflib5.patch (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/efl/patches/evas-fix-build-with-giflib5.patch                                (rev 0)
+++ trunk/Tools/efl/patches/evas-fix-build-with-giflib5.patch        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+Patch from Doug Newgard, available at https://phab.enlightenment.org/D200
+
+diff --git a/src/modules/loaders/gif/evas_image_load_gif.c b/src/modules/loaders/gif/evas_image_load_gif.c
+index 18a6e23..6b6ef3d 100644
+--- a/src/modules/loaders/gif/evas_image_load_gif.c
++++ b/src/modules/loaders/gif/evas_image_load_gif.c
+@@ -700,7 +700,11 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
+         return EINA_FALSE;
+      }

++#if GIFLIB_MAJOR &gt;= 5
++   gif = DGifOpenFileHandle(fd, NULL);
++#else
+    gif = DGifOpenFileHandle(fd);
++#endif
+    if (!gif)
+      {
+         if (fd) close(fd);
+@@ -838,7 +842,11 @@ evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_inde
+         return EINA_FALSE;
+      }

++#if GIFLIB_MAJOR &gt;= 5
++   gif = DGifOpenFileHandle(fd, NULL);
++#else
+    gif = DGifOpenFileHandle(fd);
++#endif
+    if (!gif)
+      {
+         if (fd) close(fd);
+@@ -927,7 +935,11 @@ evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key
+                   return EINA_FALSE;
+                }

++#if GIFLIB_MAJOR &gt;= 5
++             gif = DGifOpenFileHandle(fd, NULL);
++#else
+              gif = DGifOpenFileHandle(fd);
++#endif
+              if (!gif)
+                {
+                   if (fd) close(fd);
+@@ -1000,7 +1012,11 @@ evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, const int
+ #endif
+    if (fd &lt; 0) return -1;

++#if GIFLIB_MAJOR &gt;=5
++   gif = DGifOpenFileHandle(fd, NULL);
++#else
+    gif = DGifOpenFileHandle(fd);
++#endif
+    if (!gif)
+      {
+         if (fd) close(fd);
</ins></span></pre></div>
<a id="trunkToolseflpatchesfontconfigC11requiresaspacebetweenliteralandidentifierpatch"></a>
<div class="addfile"><h4>Added: trunk/Tools/efl/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/efl/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch                                (rev 0)
+++ trunk/Tools/efl/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+From 7069d717e982adcf8e1d300cbd10eec6322a65c9 Mon Sep 17 00:00:00 2001
+From: Akira TAGOH &lt;akira@tagoh.org&gt;
+Date: Sun, 22 Apr 2012 21:40:44 +0900
+Subject: [PATCH] C++11 requires a space between literal and identifier
+
+Reported by Buganini
+---
+ fontconfig/fontconfig.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
+index 0e2ca50..b27ccb5 100644
+--- a/fontconfig/fontconfig.h
++++ b/fontconfig/fontconfig.h
+@@ -112,9 +112,9 @@ typedef int                FcBool;
+ #define FC_DECORATIVE            &quot;decorative&quot;        /* Bool - true if style is a decorative variant */
+ #define FC_LCD_FILTER            &quot;lcdfilter&quot;                /* Int */

+-#define FC_CACHE_SUFFIX                    &quot;.cache-&quot;FC_CACHE_VERSION
+-#define FC_DIR_CACHE_FILE            &quot;fonts.cache-&quot;FC_CACHE_VERSION
+-#define FC_USER_CACHE_FILE            &quot;.fonts.cache-&quot;FC_CACHE_VERSION
++#define FC_CACHE_SUFFIX                    &quot;.cache-&quot; FC_CACHE_VERSION
++#define FC_DIR_CACHE_FILE            &quot;fonts.cache-&quot; FC_CACHE_VERSION
++#define FC_USER_CACHE_FILE            &quot;.fonts.cache-&quot; FC_CACHE_VERSION

+ /* Adjust outline rasterizer */
+ #define FC_CHAR_WIDTH            &quot;charwidth&quot;        /* Int */
+-- 
+1.8.3.2
+
</ins></span></pre></div>
<a id="trunkToolseflpatchesgstlibavpatch"></a>
<div class="addfile"><h4>Added: trunk/Tools/efl/patches/gst-libav.patch (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/efl/patches/gst-libav.patch                                (rev 0)
+++ trunk/Tools/efl/patches/gst-libav.patch        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+--- a/gst-libs/ext/libav/libavcodec/arm/videodsp_armv5te.S
++++ b/gst-libs/ext/libav/libavcodec/arm/videodsp_armv5te.S
+@@ -27,6 +27,7 @@
+         subs            r2,  r2,  #1
+         pld             [r0]
+         add             r0,  r0,  r1
++        it              ne
+         bne             1b
+         bx              lr
+
+--- a/gst-libs/ext/libav/libswresample/arm/audio_convert_neon.S
++++ b/gst-libs/ext/libav/libswresample/arm/audio_convert_neon.S
+@@ -134,6 +134,7 @@ function swri_oldapi_conv_fltp_to_s16_nch_neon, export=1
+         itt             lt
+         ldrlt           r1,  [r1]
+         blt             X(swri_oldapi_conv_flt_to_s16_neon)
++        it              eq
+         beq             X(swri_oldapi_conv_fltp_to_s16_2ch_neon)

+         push            {r4-r8, lr}
</ins></span></pre></div>
<a id="trunkToolseflpatchesgstpluginsbasertprtcpbufferfixtypoinenumpatch"></a>
<div class="addfile"><h4>Added: trunk/Tools/efl/patches/gst-plugins-base-rtp-rtcpbuffer-fix-typo-in-enum.patch (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/efl/patches/gst-plugins-base-rtp-rtcpbuffer-fix-typo-in-enum.patch                                (rev 0)
+++ trunk/Tools/efl/patches/gst-plugins-base-rtp-rtcpbuffer-fix-typo-in-enum.patch        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+From dfc34c58411f50b37b2e1300560ae8a0b6a9a7d4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= &lt;tim@centricular.com&gt;
+Date: Tue, 7 Apr 2015 16:43:59 +0100
+Subject: [PATCH] rtp: rtcpbuffer: fix typo in enum
+
+and in docs. Spotted by Rob Swain.
+---
+ gst-libs/gst/rtp/gstrtcpbuffer.h | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/gst-libs/gst/rtp/gstrtcpbuffer.h b/gst-libs/gst/rtp/gstrtcpbuffer.h
+index b5ff4a1..47378cf 100644
+--- a/gst-libs/gst/rtp/gstrtcpbuffer.h
++++ b/gst-libs/gst/rtp/gstrtcpbuffer.h
+@@ -59,6 +59,9 @@ typedef enum
+   GST_RTCP_TYPE_PSFB    = 206
+ } GstRTCPType;

++/* FIXME 2.0: backwards compatibility define for enum typo */
++#define GST_RTCP_RTPFB_TYPE_RCTP_SR_REQ GST_RTCP_RTPFB_TYPE_RTCP_SR_REQ
++
+ /**
+  * GstRTCPFBType:
+  * @GST_RTCP_FB_TYPE_INVALID: Invalid type
+@@ -66,7 +69,7 @@ typedef enum
+  * @GST_RTCP_RTPFB_TYPE_TMMBR: Temporary Maximum Media Stream Bit Rate Request
+  * @GST_RTCP_RTPFB_TYPE_TMMBN: Temporary Maximum Media Stream Bit Rate
+  *    Notification
+- * @GST_RTCP_RTPFB_TYPE_RTCP_SR_SEQ: Request an SR packet for early
++ * @GST_RTCP_RTPFB_TYPE_RTCP_SR_REQ: Request an SR packet for early
+  *    synchronization
+  * @GST_RTCP_PSFB_TYPE_PLI: Picture Loss Indication
+  * @GST_RTCP_PSFB_TYPE_SLI: Slice Loss Indication
+@@ -89,7 +92,7 @@ typedef enum
+   GST_RTCP_RTPFB_TYPE_TMMBR       = 3,
+   GST_RTCP_RTPFB_TYPE_TMMBN       = 4,
+   /* RTPFB types assigned in RFC 6051 */
+-  GST_RTCP_RTPFB_TYPE_RCTP_SR_REQ = 5,
++  GST_RTCP_RTPFB_TYPE_RTCP_SR_REQ = 5,
+   /* PSFB types */
+   GST_RTCP_PSFB_TYPE_PLI          = 1,
+   GST_RTCP_PSFB_TYPE_SLI          = 2,
+-- 
+2.1.4
+
</ins></span></pre></div>
<a id="trunkToolseflpatchesgstpluginsgoodRevertqtdemuxexposestreamswithfirstmoofforfrpatch"></a>
<div class="addfile"><h4>Added: trunk/Tools/efl/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/efl/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch                                (rev 0)
+++ trunk/Tools/efl/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,133 @@
</span><ins>+From 1a81bd90d4a3e59d6669a0bbfa456f1ed4e5db48 Mon Sep 17 00:00:00 2001
+From: Xabier Rodriguez Calvar &lt;calvaris@igalia.com&gt;
+Date: Thu, 7 Apr 2016 13:57:16 +0200
+Subject: [PATCH] Revert &quot;qtdemux: expose streams with first moof for
+ fragmented format&quot;
+
+This reverts commit d8bb6687ea251570c331038279a43d448167d6ad.
+---
+ gst/isomp4/qtdemux.c | 54 ++++++++++++++++------------------------------------
+ gst/isomp4/qtdemux.h |  1 -
+ 2 files changed, 16 insertions(+), 39 deletions(-)
+
+diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
+index 39be163..9636b4b 100644
+--- a/gst/isomp4/qtdemux.c
++++ b/gst/isomp4/qtdemux.c
+@@ -609,7 +609,6 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
+   qtdemux-&gt;state = QTDEMUX_STATE_INITIAL;
+   qtdemux-&gt;pullbased = FALSE;
+   qtdemux-&gt;posted_redirect = FALSE;
+-  qtdemux-&gt;pending_configure = FALSE;
+   qtdemux-&gt;neededbytes = 16;
+   qtdemux-&gt;todrop = 0;
+   qtdemux-&gt;adapter = gst_adapter_new ();
+@@ -2049,7 +2048,6 @@ gst_qtdemux_reset (GstQTDemux * qtdemux, gboolean hard)
+     gst_caps_replace (&amp;qtdemux-&gt;media_caps, NULL);
+     qtdemux-&gt;timescale = 0;
+     qtdemux-&gt;got_moov = FALSE;
+-    qtdemux-&gt;pending_configure = FALSE;
+   } else if (qtdemux-&gt;mss_mode) {
+     gst_flow_combiner_reset (qtdemux-&gt;flowcombiner);
+     for (n = 0; n &lt; qtdemux-&gt;n_streams; n++)
+@@ -6104,7 +6102,6 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+             &amp;fourcc);
+         if (fourcc == FOURCC_moov) {
+           gint n;
+-          gboolean got_samples = FALSE;

+           /* in usual fragmented setup we could try to scan for more
+            * and end up at the the moov (after mdat) again */
+@@ -6136,27 +6133,19 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+             qtdemux_node_dump (demux, demux-&gt;moov_node);
+             qtdemux_parse_tree (demux);
+             qtdemux_prepare_streams (demux);
++            if (!demux-&gt;got_moov)
++              qtdemux_expose_streams (demux);
++            else {

+-            for (n = 0; n &lt; demux-&gt;n_streams; n++) {
+-              QtDemuxStream *stream = demux-&gt;streams[n];
+-              got_samples |= stream-&gt;stbl_index &gt;= 0;
+-            }
+-            if (!demux-&gt;fragmented || got_samples) {
+-              if (!demux-&gt;got_moov) {
+-                qtdemux_expose_streams (demux);
+-              } else {
+-                for (n = 0; n &lt; demux-&gt;n_streams; n++) {
+-                  QtDemuxStream *stream = demux-&gt;streams[n];
+-                  gst_qtdemux_configure_stream (demux, stream);
+-                }
++              for (n = 0; n &lt; demux-&gt;n_streams; n++) {
++                QtDemuxStream *stream = demux-&gt;streams[n];
++
++                gst_qtdemux_configure_stream (demux, stream);
+               }
+-              gst_qtdemux_check_send_pending_segment (demux);
+-              demux-&gt;pending_configure = FALSE;
+-            } else {
+-              demux-&gt;pending_configure = TRUE;
+             }

+             demux-&gt;got_moov = TRUE;
++            gst_qtdemux_check_send_pending_segment (demux);

+             /* fragmented streams headers shouldn't contain edts atoms */
+             if (!demux-&gt;fragmented) {
+@@ -6175,7 +6164,6 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+             guint64 dist = 0;
+             GstClockTime prev_pts;
+             guint64 prev_offset;
+-            gint n;

+             GST_DEBUG_OBJECT (demux, &quot;Parsing [moof]&quot;);

+@@ -6209,25 +6197,15 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+               ret = GST_FLOW_ERROR;
+               goto done;
+             }
+-            /* in MSS we need to expose the pads after the first moof as we won't get a moov 
+-             * Also, fragmented format need to be exposed if a moov have no valid sample data */
+-            if (demux-&gt;mss_mode || demux-&gt;pending_configure) {
+-              if (!demux-&gt;exposed) {
+-                if (!demux-&gt;pending_newsegment) {
+-                  GstSegment segment;
+-                  gst_segment_init (&amp;segment, GST_FORMAT_TIME);
+-                  GST_DEBUG_OBJECT (demux, &quot;new pending_newsegment&quot;);
+-                  demux-&gt;pending_newsegment = gst_event_new_segment (&amp;segment);
+-                }
+-                qtdemux_expose_streams (demux);
+-              } else {
+-                for (n = 0; n &lt; demux-&gt;n_streams; n++) {
+-                  QtDemuxStream *stream = demux-&gt;streams[n];
+-                  gst_qtdemux_configure_stream (demux, stream);
+-                }
++            /* in MSS we need to expose the pads after the first moof as we won't get a moov */
++            if (demux-&gt;mss_mode &amp;&amp; !demux-&gt;exposed) {
++              if (!demux-&gt;pending_newsegment) {
++                GstSegment segment;
++                gst_segment_init (&amp;segment, GST_FORMAT_TIME);
++                GST_DEBUG_OBJECT (demux, &quot;new pending_newsegment&quot;);
++                demux-&gt;pending_newsegment = gst_event_new_segment (&amp;segment);
+               }
+-              gst_qtdemux_check_send_pending_segment (demux);
+-              demux-&gt;pending_configure = FALSE;
++              qtdemux_expose_streams (demux);
+             }
+           } else {
+             GST_DEBUG_OBJECT (demux, &quot;Discarding [moof]&quot;);
+diff --git a/gst/isomp4/qtdemux.h b/gst/isomp4/qtdemux.h
+index 6061215..ecf0c63 100644
+--- a/gst/isomp4/qtdemux.h
++++ b/gst/isomp4/qtdemux.h
+@@ -89,7 +89,6 @@ struct _GstQTDemux {
+   gboolean posted_redirect;

+   /* push based variables */
+-  gboolean pending_configure;
+   guint neededbytes;
+   guint todrop;
+   GstAdapter *adapter;
+-- 
+2.8.0.rc3
+
</ins></span></pre></div>
<a id="trunkToolseflpatchesgstpluginsgoodusethetfdtdecodetimepatch"></a>
<div class="addfile"><h4>Added: trunk/Tools/efl/patches/gst-plugins-good-use-the-tfdt-decode-time.patch (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/efl/patches/gst-plugins-good-use-the-tfdt-decode-time.patch                                (rev 0)
+++ trunk/Tools/efl/patches/gst-plugins-good-use-the-tfdt-decode-time.patch        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,146 @@
</span><ins>+From 46d3e0faa922643094a5e46a32e4f82f774ae772 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Enrique=20Oca=C3=B1a=20Gonz=C3=A1lez?= &lt;eocanha@igalia.com&gt;
+Date: Tue, 10 Nov 2015 13:09:00 +0100
+Subject: [PATCH] Use the tfdt decode time when it's significantly different
+ than the time in the last sample if always-honor-tfdt is enabled
+
+https://bugzilla.gnome.org/show_bug.cgi?id=754230
+---
+ gst/isomp4/qtdemux.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ gst/isomp4/qtdemux.h |  1 +
+ 2 files changed, 73 insertions(+)
+
+diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
+index 880595e..d8b54f0 100644
+--- a/gst/isomp4/qtdemux.c
++++ b/gst/isomp4/qtdemux.c
+@@ -535,6 +535,11 @@ static void gst_qtdemux_append_protection_system_id (GstQTDemux * qtdemux,
+     const gchar * id);
+ static void qtdemux_gst_structure_free (GstStructure * gststructure);

++static void gst_qtdemux_set_property (GObject * object, guint prop_id,
++    const GValue * value, GParamSpec * spec);
++static void gst_qtdemux_get_property (GObject * object, guint prop_id,
++    GValue * value, GParamSpec * spec);
++
+ static void
+ gst_qtdemux_class_init (GstQTDemuxClass * klass)
+ {
+@@ -546,8 +551,21 @@ gst_qtdemux_class_init (GstQTDemuxClass * klass)

+   parent_class = g_type_class_peek_parent (klass);

++  gobject_class-&gt;set_property = gst_qtdemux_set_property;
++  gobject_class-&gt;get_property = gst_qtdemux_get_property;
++
+   gobject_class-&gt;dispose = gst_qtdemux_dispose;

++ /**
++   * GstQtDemux::always-honor-tfdt:
++   *
++   * Requests the demuxer to respect what the TFDT atom says in order to produce presentation timestamps. Defaults to FALSE.
++   */
++  g_object_class_install_property (gobject_class, PROP_ALWAYS_HONOR_TFDT,
++      g_param_spec_boolean (&quot;always-honor-tfdt&quot;, &quot;Always honor TFDT&quot;,
++          &quot;When enabled, TFDT atom will always be respected in order to produce presentation timestamps&quot;,
++          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
++
+   gstelement_class-&gt;change_state = GST_DEBUG_FUNCPTR (gst_qtdemux_change_state);
+ #if 0
+   gstelement_class-&gt;set_index = GST_DEBUG_FUNCPTR (gst_qtdemux_set_index);
+@@ -611,6 +629,7 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
+   qtdemux-&gt;cenc_aux_info_sizes = NULL;
+   qtdemux-&gt;cenc_aux_sample_count = 0;
+   qtdemux-&gt;protection_system_ids = NULL;
++  qtdemux-&gt;always_honor_tfdt = FALSE;
+   g_queue_init (&amp;qtdemux-&gt;protection_event_queue);
+   gst_segment_init (&amp;qtdemux-&gt;segment, GST_FORMAT_TIME);
+   qtdemux-&gt;flowcombiner = gst_flow_combiner_new ();
+@@ -639,6 +658,42 @@ gst_qtdemux_dispose (GObject * object)
+ }

+ static void
++gst_qtdemux_set_property (GObject * object, guint prop_id,
++    const GValue * value, GParamSpec * pspec)
++{
++  GstQTDemux *qtdemux = GST_QTDEMUX (object);
++
++  switch (prop_id) {
++    case PROP_ALWAYS_HONOR_TFDT:
++      GST_OBJECT_LOCK (qtdemux);
++      qtdemux-&gt;always_honor_tfdt = g_value_get_boolean (value);
++      GST_OBJECT_UNLOCK (qtdemux);
++      break;
++    default:
++      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
++      break;
++  }
++}
++
++static void
++gst_qtdemux_get_property (GObject * object, guint prop_id, GValue * value,
++    GParamSpec * pspec)
++{
++  GstQTDemux *qtdemux = GST_QTDEMUX (object);
++
++  switch (prop_id) {
++    case PROP_ALWAYS_HONOR_TFDT:
++      GST_OBJECT_LOCK (qtdemux);
++      g_value_set_boolean (value, qtdemux-&gt;always_honor_tfdt);
++      GST_OBJECT_UNLOCK (qtdemux);
++      break;
++    default:
++      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
++      break;
++  }
++}
++
++static void
+ gst_qtdemux_post_no_playable_stream_error (GstQTDemux * qtdemux)
+ {
+   if (qtdemux-&gt;posted_redirect) {
+@@ -2995,6 +3050,16 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
+           stream-&gt;samples[stream-&gt;n_samples - 1].timestamp +
+           stream-&gt;samples[stream-&gt;n_samples - 1].duration;

++      /* If we're always honoring TFDT and there's a significative difference
++       * between the decode_ts and the timestamp, prefer decode_ts */
++      if (qtdemux-&gt;always_honor_tfdt == TRUE
++          &amp;&amp; abs (decode_ts - timestamp) &gt;
++          stream-&gt;samples[stream-&gt;n_samples - 1].duration) {
++        GST_INFO_OBJECT (qtdemux,
++            &quot;decode_ts is significantly different from timestamp, using decode_ts&quot;);
++        timestamp = decode_ts;
++      }
++
+       gst_ts = QTSTREAMTIME_TO_GSTTIME (stream, timestamp);
+       GST_INFO_OBJECT (qtdemux, &quot;first sample ts %&quot; GST_TIME_FORMAT
+           &quot; (extends previous samples)&quot;, GST_TIME_ARGS (gst_ts));
+diff --git a/gst/isomp4/qtdemux.h b/gst/isomp4/qtdemux.h
+index 53bd071..ecf0c63 100644
+--- a/gst/isomp4/qtdemux.h
++++ b/gst/isomp4/qtdemux.h
+@@ -154,12 +154,20 @@ struct _GstQTDemux {
+   guint8 *cenc_aux_info_sizes;
+   guint32 cenc_aux_sample_count;

++  gboolean always_honor_tfdt;
+ };

+ struct _GstQTDemuxClass {
+   GstElementClass parent_class;
+ };

++/* props */
++enum
++{
++  PROP_0,
++  PROP_ALWAYS_HONOR_TFDT
++};
++
+ GType gst_qtdemux_get_type (void);

+ G_END_DECLS
+-- 
+2.6.1
+
</ins></span></pre></div>
<a id="trunkToolseflpatchesopenwebrtcgstpluginsclangwarningfixpatch"></a>
<div class="addfile"><h4>Added: trunk/Tools/efl/patches/openwebrtc-gst-plugins-clang-warning-fix.patch (0 => 212517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/efl/patches/openwebrtc-gst-plugins-clang-warning-fix.patch                                (rev 0)
+++ trunk/Tools/efl/patches/openwebrtc-gst-plugins-clang-warning-fix.patch        2017-02-17 02:15:35 UTC (rev 212517)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+diff --git a/gst/videorepair/Makefile.am b/gst/videorepair/Makefile.am
+index 34487b5..34c3887 100644
+--- a/gst/videorepair/Makefile.am
++++ b/gst/videorepair/Makefile.am
+@@ -17,7 +17,7 @@ plugin_LTLIBRARIES = libgstvideorepair.la
+ libgstvideorepair_la_SOURCES = gstvideorepair.c

+ # compiler and linker flags used to compile this plugin, set in configure.ac
+-libgstvideorepair_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) -Wall -Wextra -Werror
++libgstvideorepair_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) -Wall -Wextra
+ libgstvideorepair_la_LIBADD = $(GST_LIBS) -lgstvideo-1.0
+ libgstvideorepair_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+ if !GST_PLUGIN_BUILD_STATIC
</ins></span></pre>
</div>
</div>

</body>
</html>