OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/ui/monitor_info_provider.h" |
| 6 |
| 7 #include <gtk/gtk.h> |
| 8 |
| 9 #include "base/compiler_specific.h" |
| 10 #include "base/logging.h" |
| 11 |
| 12 namespace { |
| 13 |
| 14 class MonitorInfoProviderGtk : public MonitorInfoProvider { |
| 15 public: |
| 16 MonitorInfoProviderGtk(); |
| 17 virtual ~MonitorInfoProviderGtk(); |
| 18 |
| 19 // Overridden from MonitorInfoProvider: |
| 20 virtual gfx::Rect GetPrimaryMonitorWorkArea() const OVERRIDE; |
| 21 virtual gfx::Rect GetPrimaryMonitorBounds() const OVERRIDE; |
| 22 virtual gfx::Rect GetMonitorWorkAreaMatching( |
| 23 const gfx::Rect& match_rect) const OVERRIDE; |
| 24 virtual void UpdateWorkAreas() OVERRIDE; |
| 25 |
| 26 private: |
| 27 // Get the available screen space as a gfx::Rect, or return false if |
| 28 // if it's unavailable (i.e. the window manager doesn't support |
| 29 // retrieving this). |
| 30 // TODO(thestig) Use _NET_CURRENT_DESKTOP here as well? |
| 31 bool GetScreenWorkArea(gfx::Rect* out_rect) const; |
| 32 |
| 33 DISALLOW_COPY_AND_ASSIGN(MonitorInfoProviderGtk); |
| 34 }; |
| 35 |
| 36 MonitorInfoProviderGtk::MonitorInfoProviderGtk() { |
| 37 } |
| 38 |
| 39 MonitorInfoProviderGtk::~MonitorInfoProviderGtk() { |
| 40 } |
| 41 |
| 42 gfx::Rect MonitorInfoProviderGtk::GetPrimaryMonitorWorkArea() const { |
| 43 gfx::Rect rect; |
| 44 if (GetScreenWorkArea(&rect)) |
| 45 return rect.Intersect(GetPrimaryMonitorBounds()); |
| 46 |
| 47 // Return the best we've got. |
| 48 return GetPrimaryMonitorBounds(); |
| 49 } |
| 50 |
| 51 gfx::Rect MonitorInfoProviderGtk::GetPrimaryMonitorBounds() const { |
| 52 GdkScreen* screen = gdk_screen_get_default(); |
| 53 GdkRectangle rect; |
| 54 gdk_screen_get_monitor_geometry(screen, 0, &rect); |
| 55 return gfx::Rect(rect); |
| 56 } |
| 57 |
| 58 gfx::Rect MonitorInfoProviderGtk::GetMonitorWorkAreaMatching( |
| 59 const gfx::Rect& match_rect) const { |
| 60 // TODO(thestig) Implement multi-monitor support. |
| 61 return GetPrimaryMonitorWorkArea(); |
| 62 } |
| 63 |
| 64 void MonitorInfoProviderGtk::UpdateWorkAreas() { |
| 65 // TODO(thestig) Implement multi-monitor support. |
| 66 work_areas_.clear(); |
| 67 work_areas_.push_back(GetPrimaryMonitorBounds()); |
| 68 } |
| 69 |
| 70 bool MonitorInfoProviderGtk::GetScreenWorkArea(gfx::Rect* out_rect) const { |
| 71 gboolean ok; |
| 72 guchar* raw_data = NULL; |
| 73 gint data_len = 0; |
| 74 ok = gdk_property_get(gdk_get_default_root_window(), // a gdk window |
| 75 gdk_atom_intern("_NET_WORKAREA", FALSE), // property |
| 76 gdk_atom_intern("CARDINAL", FALSE), // property type |
| 77 0, // byte offset into property |
| 78 0xff, // property length to retrieve |
| 79 false, // delete property after retrieval? |
| 80 NULL, // returned property type |
| 81 NULL, // returned data format |
| 82 &data_len, // returned data len |
| 83 &raw_data); // returned data |
| 84 if (!ok) |
| 85 return false; |
| 86 |
| 87 // We expect to get four longs back: x, y, width, height. |
| 88 if (data_len < static_cast<gint>(4 * sizeof(glong))) { |
| 89 NOTREACHED(); |
| 90 g_free(raw_data); |
| 91 return false; |
| 92 } |
| 93 |
| 94 glong* data = reinterpret_cast<glong*>(raw_data); |
| 95 gint x = data[0]; |
| 96 gint y = data[1]; |
| 97 gint width = data[2]; |
| 98 gint height = data[3]; |
| 99 g_free(raw_data); |
| 100 |
| 101 out_rect->SetRect(x, y, width, height); |
| 102 return true; |
| 103 } |
| 104 |
| 105 } // namespace |
| 106 |
| 107 // static |
| 108 MonitorInfoProvider* MonitorInfoProvider::Create() { |
| 109 return new MonitorInfoProviderGtk(); |
| 110 } |
OLD | NEW |