[GTK] Use gdk_screen_get_monitor_workarea() when available for screenAvailableRect()
https://bugs.webkit.org/show_bug.cgi?id=75435

Reviewed by Martin Robinson.

Source/WebCore:

* platform/gtk/GtkVersioning.c:
(getScreenCurrentDesktop):
(getScreenWorkArea):
(gdk_screen_get_monitor_workarea): Implement it when GTK+ < 3.3.6.
* platform/gtk/GtkVersioning.h:
* platform/gtk/PlatformScreenGtk.cpp:
(WebCore::screenAvailableRect): Use
gdk_screen_get_monitor_workarea() instead of our own
implementation.

Source/WebKit/gtk:

* GNUmakefile.am: Make sure unit tests link to X11.

Tools:

* GNUmakefile.am: Make sure DRT links to X11.
* WebKitTestRunner/GNUmakefile.am: Make sure WTR links to X11.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@103929 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 7eeb3b303..c98017f 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,20 @@
+2012-01-03  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Use gdk_screen_get_monitor_workarea() when available for screenAvailableRect()
+        https://bugs.webkit.org/show_bug.cgi?id=75435
+
+        Reviewed by Martin Robinson.
+
+        * platform/gtk/GtkVersioning.c:
+        (getScreenCurrentDesktop):
+        (getScreenWorkArea):
+        (gdk_screen_get_monitor_workarea): Implement it when GTK+ < 3.3.6.
+        * platform/gtk/GtkVersioning.h:
+        * platform/gtk/PlatformScreenGtk.cpp:
+        (WebCore::screenAvailableRect): Use
+        gdk_screen_get_monitor_workarea() instead of our own
+        implementation.
+
 2012-01-02  Kentaro Hara  <haraken@chromium.org>
 
         REGRESSION(r103919): Remove resolve-supplemental.pl from the WebCore target in Xcode
diff --git a/Source/WebCore/platform/gtk/GtkVersioning.c b/Source/WebCore/platform/gtk/GtkVersioning.c
index 537c011..ac2f84c 100644
--- a/Source/WebCore/platform/gtk/GtkVersioning.c
+++ b/Source/WebCore/platform/gtk/GtkVersioning.c
@@ -22,6 +22,11 @@
 
 #include <gtk/gtk.h>
 
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xatom.h>
+#include <gdk/gdkx.h>
+#endif
+
 #if !GTK_CHECK_VERSION(2, 14, 0)
 void gtk_adjustment_set_value(GtkAdjustment* adjusment, gdouble value)
 {
@@ -303,3 +308,74 @@
 }
 #endif // GTK_CHECK_VERSION(2, 22, 0)
 
+#if !GTK_CHECK_VERSION(3, 3, 6)
+#ifdef GDK_WINDOWING_X11
+static int getScreenCurrentDesktop(GdkScreen *screen)
+{
+    Display *display = GDK_DISPLAY_XDISPLAY(gdk_screen_get_display(screen));
+    Window rootWindow = XRootWindow(display, GDK_SCREEN_XNUMBER(screen));
+    Atom currentDesktop = XInternAtom(display, "_NET_CURRENT_DESKTOP", True);
+
+    Atom type;
+    int format;
+    unsigned long itemsCount, bytesAfter;
+    unsigned char *returnedData = NULL;
+    XGetWindowProperty(display, rootWindow, currentDesktop, 0, G_MAXLONG, False, XA_CARDINAL,
+                       &type, &format, &itemsCount, &bytesAfter, &returnedData);
+
+    int workspace = 0;
+    if (type == XA_CARDINAL && format == 32 && itemsCount > 0)
+        workspace = (int)returnedData[0];
+
+    if (returnedData)
+        XFree(returnedData);
+
+    return workspace;
+}
+
+static void getScreenWorkArea(GdkScreen *screen, GdkRectangle *area)
+{
+    Display *display = GDK_DISPLAY_XDISPLAY(gdk_screen_get_display(screen));
+    Atom workArea = XInternAtom(display, "_NET_WORKAREA", True);
+
+    /* Defaults in case of error. */
+    area->x = 0;
+    area->y = 0;
+    area->width = gdk_screen_get_width(screen);
+    area->height = gdk_screen_get_height(screen);
+
+    if (workArea == None)
+        return;
+
+    Window rootWindow = XRootWindow(display, GDK_SCREEN_XNUMBER(screen));
+    Atom type;
+    int format;
+    unsigned long itemsCount, bytesAfter;
+    unsigned char *returnedData = 0;
+    int result = XGetWindowProperty(display, rootWindow, workArea, 0, 4 * 32 /* Max length */, False, AnyPropertyType,
+                                    &type, &format, &itemsCount, &bytesAfter, &returnedData);
+    if (result != Success || type == None || !format || bytesAfter || itemsCount % 4)
+        return;
+
+    int desktop = getScreenCurrentDesktop(screen);
+    long *workAreas = (long *)returnedData;
+    area->x = workAreas[desktop * 4];
+    area->y = workAreas[desktop * 4 + 1];
+    area->width = workAreas[desktop * 4 + 2];
+    area->height = workAreas[desktop * 4 + 3];
+
+    XFree(returnedData);
+}
+#endif // GDK_WINDOWING_X11
+
+void gdk_screen_get_monitor_workarea(GdkScreen *screen, int monitor, GdkRectangle *area)
+{
+    gdk_screen_get_monitor_geometry(screen, monitor, area);
+
+#ifdef GDK_WINDOWING_X11
+    GdkRectangle workArea;
+    getScreenWorkArea(screen, &workArea);
+    gdk_rectangle_intersect(&workArea, area, area);
+#endif
+}
+#endif // GTK_CHECK_VERSION(3, 3, 6)
diff --git a/Source/WebCore/platform/gtk/GtkVersioning.h b/Source/WebCore/platform/gtk/GtkVersioning.h
index 92d03c4..c039ee2 100644
--- a/Source/WebCore/platform/gtk/GtkVersioning.h
+++ b/Source/WebCore/platform/gtk/GtkVersioning.h
@@ -117,6 +117,10 @@
 gboolean g_signal_accumulator_first_wins(GSignalInvocationHint* invocationHint, GValue* returnAccumulator, const GValue* handlerReturn, gpointer data);
 #endif
 
+#if !GTK_CHECK_VERSION(3, 3, 6)
+void gdk_screen_get_monitor_workarea(GdkScreen *, int monitor, GdkRectangle *area);
+#endif
+
 G_END_DECLS
 
 #endif // GtkVersioning_h
diff --git a/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
index 6150b90..93228c3 100644
--- a/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
+++ b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp
@@ -39,11 +39,6 @@
 
 #include <gtk/gtk.h>
 
-#if PLATFORM(X11)
-#include <gdk/gdkx.h>
-#include <X11/Xatom.h>
-#endif
-
 namespace WebCore {
 
 static GtkWidget* getToplevel(GtkWidget* widget)
@@ -134,7 +129,6 @@
     if (!widget)
         return FloatRect();
 
-#if PLATFORM(X11)
     GtkWidget* container = GTK_WIDGET(widget->root()->hostWindow()->platformPageClient());
     if (container && !gtk_widget_get_realized(container))
         return screenRect(widget);
@@ -143,34 +137,13 @@
     if (!screen)
         return FloatRect();
 
-    GdkWindow* rootWindow = gdk_screen_get_root_window(screen);
-    GdkDisplay* display = gdk_window_get_display(rootWindow);
-    Atom xproperty = gdk_x11_get_xatom_by_name_for_display(display, "_NET_WORKAREA");
+    gint monitor = container ? gdk_screen_get_monitor_at_window(screen, gtk_widget_get_window(container)) : 0;
 
-    Atom retType;
-    int retFormat;
-    long *workAreaPos = NULL;
-    unsigned long retNItems;
-    unsigned long retAfter;
-    int xRes = XGetWindowProperty(GDK_DISPLAY_XDISPLAY(display), GDK_WINDOW_XWINDOW(rootWindow), xproperty,
-        0, 4, FALSE, XA_CARDINAL, &retType, &retFormat, &retNItems, &retAfter, (guchar**)&workAreaPos);
+    GdkRectangle workArea;
+    gdk_screen_get_monitor_workarea(screen, monitor, &workArea);
 
-    FloatRect rect;
-    if (xRes == Success && workAreaPos != NULL && retType == XA_CARDINAL && retNItems == 4 && retFormat == 32) {
-        rect = FloatRect(workAreaPos[0], workAreaPos[1], workAreaPos[2], workAreaPos[3]);
-        // rect contains the available space in the whole screen not just in the monitor
-        // containing the widget, so we intersect it with the monitor rectangle.
-        rect.intersect(screenRect(widget));
-    } else
-        rect = screenRect(widget);
+    return FloatRect(workArea.x, workArea.y, workArea.width, workArea.height);
 
-    if (workAreaPos)
-        XFree(workAreaPos);
-
-    return rect;
-#else
-    return screenRect(widget);
-#endif
 }
 
 } // namespace WebCore
diff --git a/Source/WebKit/gtk/ChangeLog b/Source/WebKit/gtk/ChangeLog
index eb9cd2e4..61fcf55 100644
--- a/Source/WebKit/gtk/ChangeLog
+++ b/Source/WebKit/gtk/ChangeLog
@@ -1,3 +1,12 @@
+2012-01-03  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Use gdk_screen_get_monitor_workarea() when available for screenAvailableRect()
+        https://bugs.webkit.org/show_bug.cgi?id=75435
+
+        Reviewed by Martin Robinson.
+
+        * GNUmakefile.am: Make sure unit tests link to X11.
+
 2011-12-20  Yuta Kitamura  <yutak@chromium.org>
 
         [GTK] Change default WebSocket protocol to the latest one
diff --git a/Source/WebKit/gtk/GNUmakefile.am b/Source/WebKit/gtk/GNUmakefile.am
index 38dd279..786a27b 100644
--- a/Source/WebKit/gtk/GNUmakefile.am
+++ b/Source/WebKit/gtk/GNUmakefile.am
@@ -420,7 +420,9 @@
 	$(javascriptcore_cppflags) \
 	$(GLIB_CFLAGS) \
 	$(GTK_CFLAGS) \
-	$(LIBSOUP_CFLAGS)
+	$(LIBSOUP_CFLAGS) \
+	$(XRENDER_LIBS) \
+	$(XT_LIBS)
 
 webkit_tests_ldadd = \
 	libjavascriptcoregtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \