gpu: Tweak Android WebGL test expectations
[chromium-blink-merge.git] / ui / gfx / gtk_native_view_id_manager.cc
blob07e1ed4c81df7230f81f56886b7e8fb25282c8c1
1 // Copyright (c) 2012 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.
5 #include "ui/gfx/gtk_native_view_id_manager.h"
7 #include <gdk/gdkx.h>
8 #include <gtk/gtk.h>
10 #include "base/logging.h"
11 #include "base/memory/singleton.h"
12 #include "base/rand_util.h"
13 #include "ui/base/gtk/gdk_x_compat.h"
14 #include "ui/base/gtk/gtk_compat.h"
15 #include "ui/gfx/gtk_preserve_window.h"
17 // -----------------------------------------------------------------------------
18 // Bounce functions for GTK to callback into a C++ object...
20 void OnRealize(gfx::NativeView widget, void* arg) {
21 GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg);
22 manager->OnRealize(widget);
25 void OnUnrealize(gfx::NativeView widget, void *arg) {
26 GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg);
27 manager->OnUnrealize(widget);
30 static void OnDestroy(GtkObject* obj, void* arg) {
31 GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg);
32 manager->OnDestroy(reinterpret_cast<GtkWidget*>(obj));
35 // -----------------------------------------------------------------------------
38 // -----------------------------------------------------------------------------
39 // Public functions...
41 GtkNativeViewManager::GtkNativeViewManager() {
44 GtkNativeViewManager::~GtkNativeViewManager() {
47 // static
48 GtkNativeViewManager* GtkNativeViewManager::GetInstance() {
49 return Singleton<GtkNativeViewManager>::get();
52 gfx::NativeViewId GtkNativeViewManager::GetIdForWidget(gfx::NativeView widget) {
53 // This is just for unit tests:
54 if (!widget)
55 return 0;
57 base::AutoLock locked(lock_);
59 std::map<gfx::NativeView, gfx::NativeViewId>::const_iterator i =
60 native_view_to_id_.find(widget);
62 if (i != native_view_to_id_.end())
63 return i->second;
65 gfx::NativeViewId new_id =
66 static_cast<gfx::NativeViewId>(base::RandUint64());
67 while (id_to_info_.find(new_id) != id_to_info_.end())
68 new_id = static_cast<gfx::NativeViewId>(base::RandUint64());
70 NativeViewInfo info;
71 info.widget = widget;
72 if (gtk_widget_get_realized(widget)) {
73 GdkWindow *gdk_window = gtk_widget_get_window(widget);
74 DCHECK(gdk_window);
75 info.x_window_id = GDK_WINDOW_XID(gdk_window);
78 native_view_to_id_[widget] = new_id;
79 id_to_info_[new_id] = info;
81 g_signal_connect(widget, "realize", G_CALLBACK(::OnRealize), this);
82 g_signal_connect(widget, "unrealize", G_CALLBACK(::OnUnrealize), this);
83 g_signal_connect(widget, "destroy", G_CALLBACK(::OnDestroy), this);
85 return new_id;
88 bool GtkNativeViewManager::GetXIDForId(XID* output, gfx::NativeViewId id) {
89 base::AutoLock locked(lock_);
91 std::map<gfx::NativeViewId, NativeViewInfo>::const_iterator i =
92 id_to_info_.find(id);
94 if (i == id_to_info_.end())
95 return false;
97 *output = i->second.x_window_id;
98 return true;
101 bool GtkNativeViewManager::GetNativeViewForId(gfx::NativeView* output,
102 gfx::NativeViewId id) {
103 base::AutoLock locked(lock_);
105 std::map<gfx::NativeViewId, NativeViewInfo>::const_iterator i =
106 id_to_info_.find(id);
108 if (i == id_to_info_.end())
109 return false;
111 *output = i->second.widget;
112 return true;
115 bool GtkNativeViewManager::GetPermanentXIDForId(XID* output,
116 gfx::NativeViewId id) {
117 base::AutoLock locked(lock_);
119 std::map<gfx::NativeViewId, NativeViewInfo>::iterator i =
120 id_to_info_.find(id);
122 if (i == id_to_info_.end())
123 return false;
125 // We only return permanent XIDs for widgets that allow us to guarantee that
126 // the XID will not change.
127 DCHECK(GTK_IS_PRESERVE_WINDOW(i->second.widget));
128 GtkPreserveWindow* widget =
129 reinterpret_cast<GtkPreserveWindow*>(i->second.widget);
130 gtk_preserve_window_set_preserve(widget, TRUE);
132 *output = GDK_WINDOW_XID(gtk_widget_get_window(i->second.widget));
134 // Update the reference count on the permanent XID.
135 PermanentXIDInfo info;
136 info.widget = widget;
137 info.ref_count = 1;
138 std::pair<std::map<XID, PermanentXIDInfo>::iterator, bool> ret =
139 perm_xid_to_info_.insert(std::make_pair(*output, info));
141 if (!ret.second) {
142 DCHECK(ret.first->second.widget == widget);
143 ret.first->second.ref_count++;
146 return true;
149 bool GtkNativeViewManager::AddRefPermanentXID(XID xid) {
150 base::AutoLock locked(lock_);
152 std::map<XID, PermanentXIDInfo>::iterator i =
153 perm_xid_to_info_.find(xid);
155 if (i == perm_xid_to_info_.end())
156 return false;
158 i->second.ref_count++;
160 return true;
163 void GtkNativeViewManager::ReleasePermanentXID(XID xid) {
164 base::AutoLock locked(lock_);
166 std::map<XID, PermanentXIDInfo>::iterator i =
167 perm_xid_to_info_.find(xid);
169 if (i == perm_xid_to_info_.end())
170 return;
172 if (i->second.ref_count > 1) {
173 i->second.ref_count--;
174 } else {
175 if (i->second.widget) {
176 gtk_preserve_window_set_preserve(i->second.widget, FALSE);
177 } else {
178 GdkWindow* window = reinterpret_cast<GdkWindow*>(
179 gdk_x11_window_lookup_for_display(gdk_display_get_default(), xid));
180 DCHECK(window);
181 gdk_window_destroy(window);
183 perm_xid_to_info_.erase(i);
187 // -----------------------------------------------------------------------------
190 // -----------------------------------------------------------------------------
191 // Private functions...
193 gfx::NativeViewId GtkNativeViewManager::GetWidgetId(gfx::NativeView widget) {
194 lock_.AssertAcquired();
196 std::map<gfx::NativeView, gfx::NativeViewId>::const_iterator i =
197 native_view_to_id_.find(widget);
199 CHECK(i != native_view_to_id_.end());
200 return i->second;
203 void GtkNativeViewManager::OnRealize(gfx::NativeView widget) {
204 base::AutoLock locked(lock_);
206 const gfx::NativeViewId id = GetWidgetId(widget);
207 std::map<gfx::NativeViewId, NativeViewInfo>::iterator i =
208 id_to_info_.find(id);
210 CHECK(i != id_to_info_.end());
212 GdkWindow* gdk_window = gtk_widget_get_window(widget);
213 CHECK(gdk_window);
214 i->second.x_window_id = GDK_WINDOW_XID(gdk_window);
217 void GtkNativeViewManager::OnUnrealize(gfx::NativeView widget) {
218 base::AutoLock locked(lock_);
220 const gfx::NativeViewId id = GetWidgetId(widget);
221 std::map<gfx::NativeViewId, NativeViewInfo>::iterator i =
222 id_to_info_.find(id);
224 CHECK(i != id_to_info_.end());
227 void GtkNativeViewManager::OnDestroy(gfx::NativeView widget) {
228 base::AutoLock locked(lock_);
230 std::map<gfx::NativeView, gfx::NativeViewId>::iterator i =
231 native_view_to_id_.find(widget);
232 CHECK(i != native_view_to_id_.end());
234 std::map<gfx::NativeViewId, NativeViewInfo>::iterator j =
235 id_to_info_.find(i->second);
236 CHECK(j != id_to_info_.end());
238 // If the XID is supposed to outlive the widget, mark it
239 // in the lookup table.
240 if (GTK_IS_PRESERVE_WINDOW(widget) &&
241 gtk_preserve_window_get_preserve(
242 reinterpret_cast<GtkPreserveWindow*>(widget))) {
243 std::map<XID, PermanentXIDInfo>::iterator k =
244 perm_xid_to_info_.find(GDK_WINDOW_XID(gtk_widget_get_window(widget)));
246 if (k != perm_xid_to_info_.end())
247 k->second.widget = NULL;
250 native_view_to_id_.erase(i);
251 id_to_info_.erase(j);
254 // -----------------------------------------------------------------------------