OLD | NEW |
---|---|
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gfx/gtk_native_view_id_manager.h" | 5 #include "gfx/gtk_native_view_id_manager.h" |
6 | 6 |
7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
8 #include <gdk/gdkx.h> | 8 #include <gdk/gdkx.h> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 gfx::NativeViewId new_id = | 57 gfx::NativeViewId new_id = |
58 static_cast<gfx::NativeViewId>(base::RandUint64()); | 58 static_cast<gfx::NativeViewId>(base::RandUint64()); |
59 while (id_to_info_.find(new_id) != id_to_info_.end()) | 59 while (id_to_info_.find(new_id) != id_to_info_.end()) |
60 new_id = static_cast<gfx::NativeViewId>(base::RandUint64()); | 60 new_id = static_cast<gfx::NativeViewId>(base::RandUint64()); |
61 | 61 |
62 NativeViewInfo info; | 62 NativeViewInfo info; |
63 info.widget = widget; | 63 info.widget = widget; |
64 if (GTK_WIDGET_REALIZED(widget)) { | 64 if (GTK_WIDGET_REALIZED(widget)) { |
65 GdkWindow *gdk_window = widget->window; | 65 GdkWindow *gdk_window = widget->window; |
66 CHECK(gdk_window); | 66 CHECK(gdk_window); |
67 info.x_window_id = GDK_WINDOW_XID(gdk_window); | 67 XID xid = GDK_WINDOW_XID(gdk_window); |
68 info.x_window_id = xid; | |
69 xid_to_native_view_[xid] = widget; | |
68 } | 70 } |
69 | 71 |
70 native_view_to_id_[widget] = new_id; | 72 native_view_to_id_[widget] = new_id; |
71 id_to_info_[new_id] = info; | 73 id_to_info_[new_id] = info; |
72 | 74 |
73 g_signal_connect(widget, "realize", G_CALLBACK(::OnRealize), this); | 75 g_signal_connect(widget, "realize", G_CALLBACK(::OnRealize), this); |
74 g_signal_connect(widget, "unrealize", G_CALLBACK(::OnUnrealize), this); | 76 g_signal_connect(widget, "unrealize", G_CALLBACK(::OnUnrealize), this); |
75 g_signal_connect(widget, "destroy", G_CALLBACK(::OnDestroy), this); | 77 g_signal_connect(widget, "destroy", G_CALLBACK(::OnDestroy), this); |
76 | 78 |
77 return new_id; | 79 return new_id; |
(...skipping 17 matching lines...) Expand all Loading... | |
95 AutoLock locked(lock_); | 97 AutoLock locked(lock_); |
96 | 98 |
97 std::map<gfx::NativeViewId, NativeViewInfo>::iterator i = | 99 std::map<gfx::NativeViewId, NativeViewInfo>::iterator i = |
98 id_to_info_.find(id); | 100 id_to_info_.find(id); |
99 | 101 |
100 if (i == id_to_info_.end()) | 102 if (i == id_to_info_.end()) |
101 return false; | 103 return false; |
102 | 104 |
103 // We only return permanent XIDs for widgets that allow us to guarantee that | 105 // We only return permanent XIDs for widgets that allow us to guarantee that |
104 // the XID will not change. | 106 // the XID will not change. |
105 if (!GTK_IS_PRESERVE_WINDOW(i->second.widget)) | 107 CHECK(GTK_IS_PRESERVE_WINDOW(i->second.widget)); |
piman
2010/11/29 21:59:01
I'm not sure that this CHECK (and other below) rea
jonathan.backer
2010/11/30 13:09:31
Done.
| |
106 return false; | |
107 | 108 |
108 GtkPreserveWindow* widget = | 109 GtkPreserveWindow* widget = |
109 reinterpret_cast<GtkPreserveWindow*>(i->second.widget); | 110 reinterpret_cast<GtkPreserveWindow*>(i->second.widget); |
110 gtk_preserve_window_set_preserve(widget, TRUE); | 111 gtk_preserve_window_set_preserve(widget, TRUE); |
111 | 112 |
112 *output = GDK_WINDOW_XID(i->second.widget->window); | 113 *output = GDK_WINDOW_XID(i->second.widget->window); |
114 | |
115 // It's possible that we were not realized before this call, in which | |
116 // case we must place an entry in the lookup table. | |
117 xid_to_native_view_[*output] = i->second.widget; | |
118 | |
113 return true; | 119 return true; |
114 } | 120 } |
115 | 121 |
122 void GtkNativeViewManager::ReleasePermanentXID(XID xid) { | |
123 AutoLock locked(lock_); | |
124 | |
125 std::map<XID, gfx::NativeView>::iterator i = | |
126 xid_to_native_view_.find(xid); | |
127 | |
128 if (i == xid_to_native_view_.end()) | |
129 return; | |
130 | |
131 if (i->second) { | |
132 CHECK(GTK_IS_PRESERVE_WINDOW(i->second)); | |
133 GtkPreserveWindow* preserve_window = | |
134 reinterpret_cast<GtkPreserveWindow*>(i->second); | |
135 gtk_preserve_window_set_preserve(preserve_window, FALSE); | |
136 } else { | |
137 GdkWindow* window = reinterpret_cast<GdkWindow*>(gdk_xid_table_lookup(xid)); | |
138 CHECK(window); | |
139 gdk_window_destroy(window); | |
140 } | |
141 } | |
142 | |
116 // ----------------------------------------------------------------------------- | 143 // ----------------------------------------------------------------------------- |
117 | 144 |
118 | 145 |
119 // ----------------------------------------------------------------------------- | 146 // ----------------------------------------------------------------------------- |
120 // Private functions... | 147 // Private functions... |
121 | 148 |
122 gfx::NativeViewId GtkNativeViewManager::GetWidgetId(gfx::NativeView widget) { | 149 gfx::NativeViewId GtkNativeViewManager::GetWidgetId(gfx::NativeView widget) { |
123 lock_.AssertAcquired(); | 150 lock_.AssertAcquired(); |
124 | 151 |
125 std::map<gfx::NativeView, gfx::NativeViewId>::const_iterator i = | 152 std::map<gfx::NativeView, gfx::NativeViewId>::const_iterator i = |
126 native_view_to_id_.find(widget); | 153 native_view_to_id_.find(widget); |
127 | 154 |
128 CHECK(i != native_view_to_id_.end()); | 155 CHECK(i != native_view_to_id_.end()); |
129 return i->second; | 156 return i->second; |
130 } | 157 } |
131 | 158 |
132 void GtkNativeViewManager::OnRealize(gfx::NativeView widget) { | 159 void GtkNativeViewManager::OnRealize(gfx::NativeView widget) { |
133 AutoLock locked(lock_); | 160 AutoLock locked(lock_); |
134 | 161 |
135 const gfx::NativeViewId id = GetWidgetId(widget); | 162 const gfx::NativeViewId id = GetWidgetId(widget); |
136 std::map<gfx::NativeViewId, NativeViewInfo>::iterator i = | 163 std::map<gfx::NativeViewId, NativeViewInfo>::iterator i = |
137 id_to_info_.find(id); | 164 id_to_info_.find(id); |
138 | 165 |
139 CHECK(i != id_to_info_.end()); | 166 CHECK(i != id_to_info_.end()); |
140 CHECK(widget->window); | 167 CHECK(widget->window); |
141 | 168 |
142 i->second.x_window_id = GDK_WINDOW_XID(widget->window); | 169 i->second.x_window_id = GDK_WINDOW_XID(widget->window); |
170 | |
171 // See if the XID is already associated with a widget. | |
172 // If so, there had better be a lock on that window. | |
173 XID xid = GDK_WINDOW_XID(widget->window); | |
174 std::map<XID, gfx::NativeView>::iterator j = | |
175 xid_to_native_view_.find(xid); | |
176 | |
177 if (j != xid_to_native_view_.end()) { | |
178 CHECK(GTK_IS_PRESERVE_WINDOW(j->second)); | |
179 GtkPreserveWindow* preserve_window = | |
180 reinterpret_cast<GtkPreserveWindow*>(j->second); | |
181 CHECK(gtk_preserve_window_get_preserve(preserve_window)); | |
182 } else { | |
183 xid_to_native_view_[xid] = widget; | |
piman
2010/11/29 21:59:01
We're effectively doing the lookup into the map tw
jonathan.backer
2010/11/30 13:09:31
Done.
| |
184 } | |
143 } | 185 } |
144 | 186 |
145 void GtkNativeViewManager::OnUnrealize(gfx::NativeView widget) { | 187 void GtkNativeViewManager::OnUnrealize(gfx::NativeView widget) { |
146 AutoLock unrealize_locked(unrealize_lock_); | 188 AutoLock unrealize_locked(unrealize_lock_); |
147 AutoLock locked(lock_); | 189 AutoLock locked(lock_); |
148 | 190 |
149 const gfx::NativeViewId id = GetWidgetId(widget); | 191 const gfx::NativeViewId id = GetWidgetId(widget); |
150 std::map<gfx::NativeViewId, NativeViewInfo>::iterator i = | 192 std::map<gfx::NativeViewId, NativeViewInfo>::iterator i = |
151 id_to_info_.find(id); | 193 id_to_info_.find(id); |
152 | 194 |
153 CHECK(i != id_to_info_.end()); | 195 CHECK(i != id_to_info_.end()); |
154 | 196 |
197 XID xid = i->second.x_window_id; | |
155 i->second.x_window_id = 0; | 198 i->second.x_window_id = 0; |
199 | |
200 // Remove XID from lookup table unless it will be preserved. | |
201 std::map<XID, gfx::NativeView>::iterator j = | |
202 xid_to_native_view_.find(xid); | |
203 | |
204 CHECK(j != xid_to_native_view_.end()); | |
205 if (!GTK_IS_PRESERVE_WINDOW(j->second) || | |
206 !gtk_preserve_window_get_preserve( | |
207 reinterpret_cast<GtkPreserveWindow*>(j->second))) { | |
208 xid_to_native_view_.erase(j); | |
209 } | |
156 } | 210 } |
157 | 211 |
158 void GtkNativeViewManager::OnDestroy(gfx::NativeView widget) { | 212 void GtkNativeViewManager::OnDestroy(gfx::NativeView widget) { |
159 AutoLock locked(lock_); | 213 AutoLock locked(lock_); |
160 | 214 |
161 std::map<gfx::NativeView, gfx::NativeViewId>::iterator i = | 215 std::map<gfx::NativeView, gfx::NativeViewId>::iterator i = |
162 native_view_to_id_.find(widget); | 216 native_view_to_id_.find(widget); |
163 CHECK(i != native_view_to_id_.end()); | 217 CHECK(i != native_view_to_id_.end()); |
164 | 218 |
165 std::map<gfx::NativeViewId, NativeViewInfo>::iterator j = | 219 std::map<gfx::NativeViewId, NativeViewInfo>::iterator j = |
166 id_to_info_.find(i->second); | 220 id_to_info_.find(i->second); |
167 CHECK(j != id_to_info_.end()); | 221 CHECK(j != id_to_info_.end()); |
168 | 222 |
223 // If the XID is supposed to outlive the widget, mark it | |
224 // in the lookup table. | |
225 if (GTK_IS_PRESERVE_WINDOW(widget) && | |
226 gtk_preserve_window_get_preserve( | |
227 reinterpret_cast<GtkPreserveWindow*>(widget))) | |
228 xid_to_native_view_[GDK_WINDOW_XID(widget->window)] = NULL; | |
229 | |
169 native_view_to_id_.erase(i); | 230 native_view_to_id_.erase(i); |
170 id_to_info_.erase(j); | 231 id_to_info_.erase(j); |
171 } | 232 } |
172 | 233 |
173 // ----------------------------------------------------------------------------- | 234 // ----------------------------------------------------------------------------- |
OLD | NEW |