Index: chrome/browser/ui/monitor_info_provider_gtk.cc |
diff --git a/chrome/browser/ui/monitor_info_provider_gtk.cc b/chrome/browser/ui/monitor_info_provider_gtk.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f85650b75422e082c5cfc68b9748e0cf40f6c4e8 |
--- /dev/null |
+++ b/chrome/browser/ui/monitor_info_provider_gtk.cc |
@@ -0,0 +1,110 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/ui/monitor_info_provider.h" |
+ |
+#include <gtk/gtk.h> |
+ |
+#include "base/compiler_specific.h" |
+#include "base/logging.h" |
+ |
+namespace { |
+ |
+class MonitorInfoProviderGtk : public MonitorInfoProvider { |
+ public: |
+ MonitorInfoProviderGtk(); |
+ virtual ~MonitorInfoProviderGtk(); |
+ |
+ // Overridden from MonitorInfoProvider: |
+ virtual gfx::Rect GetPrimaryMonitorWorkArea() const OVERRIDE; |
+ virtual gfx::Rect GetPrimaryMonitorBounds() const OVERRIDE; |
+ virtual gfx::Rect GetMonitorWorkAreaMatching( |
+ const gfx::Rect& match_rect) const OVERRIDE; |
+ virtual void UpdateWorkAreas() OVERRIDE; |
+ |
+ private: |
+ // Get the available screen space as a gfx::Rect, or return false if |
+ // if it's unavailable (i.e. the window manager doesn't support |
+ // retrieving this). |
+ // TODO(thestig) Use _NET_CURRENT_DESKTOP here as well? |
+ bool GetScreenWorkArea(gfx::Rect* out_rect) const; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MonitorInfoProviderGtk); |
+}; |
+ |
+MonitorInfoProviderGtk::MonitorInfoProviderGtk() { |
+} |
+ |
+MonitorInfoProviderGtk::~MonitorInfoProviderGtk() { |
+} |
+ |
+gfx::Rect MonitorInfoProviderGtk::GetPrimaryMonitorWorkArea() const { |
+ gfx::Rect rect; |
+ if (GetScreenWorkArea(&rect)) |
+ return rect.Intersect(GetPrimaryMonitorBounds()); |
+ |
+ // Return the best we've got. |
+ return GetPrimaryMonitorBounds(); |
+} |
+ |
+gfx::Rect MonitorInfoProviderGtk::GetPrimaryMonitorBounds() const { |
+ GdkScreen* screen = gdk_screen_get_default(); |
+ GdkRectangle rect; |
+ gdk_screen_get_monitor_geometry(screen, 0, &rect); |
+ return gfx::Rect(rect); |
+} |
+ |
+gfx::Rect MonitorInfoProviderGtk::GetMonitorWorkAreaMatching( |
+ const gfx::Rect& match_rect) const { |
+ // TODO(thestig) Implement multi-monitor support. |
+ return GetPrimaryMonitorWorkArea(); |
+} |
+ |
+void MonitorInfoProviderGtk::UpdateWorkAreas() { |
+ // TODO(thestig) Implement multi-monitor support. |
+ work_areas_.clear(); |
+ work_areas_.push_back(GetPrimaryMonitorBounds()); |
+} |
+ |
+bool MonitorInfoProviderGtk::GetScreenWorkArea(gfx::Rect* out_rect) const { |
+ gboolean ok; |
+ guchar* raw_data = NULL; |
+ gint data_len = 0; |
+ ok = gdk_property_get(gdk_get_default_root_window(), // a gdk window |
+ gdk_atom_intern("_NET_WORKAREA", FALSE), // property |
+ gdk_atom_intern("CARDINAL", FALSE), // property type |
+ 0, // byte offset into property |
+ 0xff, // property length to retrieve |
+ false, // delete property after retrieval? |
+ NULL, // returned property type |
+ NULL, // returned data format |
+ &data_len, // returned data len |
+ &raw_data); // returned data |
+ if (!ok) |
+ return false; |
+ |
+ // We expect to get four longs back: x, y, width, height. |
+ if (data_len < static_cast<gint>(4 * sizeof(glong))) { |
+ NOTREACHED(); |
+ g_free(raw_data); |
+ return false; |
+ } |
+ |
+ glong* data = reinterpret_cast<glong*>(raw_data); |
+ gint x = data[0]; |
+ gint y = data[1]; |
+ gint width = data[2]; |
+ gint height = data[3]; |
+ g_free(raw_data); |
+ |
+ out_rect->SetRect(x, y, width, height); |
+ return true; |
+} |
+ |
+} // namespace |
+ |
+// static |
+MonitorInfoProvider* MonitorInfoProvider::Create() { |
+ return new MonitorInfoProviderGtk(); |
+} |