summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/renderer_host/render_message_filter.cc23
-rw-r--r--content/browser/renderer_host/render_message_filter.h19
-rw-r--r--content/browser/renderer_host/render_message_filter_gtk.cc150
-rw-r--r--content/browser/renderer_host/render_widget_host.cc7
-rw-r--r--content/browser/renderer_host/render_widget_host.h7
-rw-r--r--content/browser/renderer_host/render_widget_host_gtk.cc86
-rw-r--r--content/content_browser.gypi1
-rw-r--r--ui/gfx/gtk_native_view_id_manager.cc17
-rw-r--r--ui/gfx/gtk_native_view_id_manager.h12
9 files changed, 133 insertions, 189 deletions
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index 9b0d75e..dd3f0cd 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -304,13 +304,6 @@ RenderMessageFilter::~RenderMessageFilter() {
void RenderMessageFilter::OverrideThreadForMessage(const IPC::Message& message,
BrowserThread::ID* thread) {
switch (message.type()) {
-#if defined(USE_X11)
- case ViewHostMsg_GetScreenInfo::ID:
- case ViewHostMsg_GetWindowRect::ID:
- case ViewHostMsg_GetRootWindowRect::ID:
- *thread = BrowserThread::BACKGROUND_X11;
- break;
-#endif
// Can't load plugins on IO thread.
case ViewHostMsg_GetPlugins::ID:
// The PluginService::GetPluginInfo may need to load the plugins. Don't do
@@ -327,15 +320,16 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_EX(RenderMessageFilter, message, *message_was_ok)
- // On Linux we need to dispatch these messages to the UI2 thread
- // because we cannot make X calls from the IO thread. Mac
- // doesn't have windowed plug-ins so we handle the messages in
- // the UI thread. On Windows, we intercept the messages and
- // handle them directly.
-#if !defined(OS_MACOSX)
+#if defined(OS_WIN)
+ // On Windows, we handle these on the IO thread to avoid a deadlock with
+ // plugins. On non-Windows systems, we need to handle them on the UI
+ // thread.
IPC_MESSAGE_HANDLER(ViewHostMsg_GetScreenInfo, OnGetScreenInfo)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetWindowRect, OnGetWindowRect)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetRootWindowRect, OnGetRootWindowRect)
+
+ // This hack is Windows-specific.
+ IPC_MESSAGE_HANDLER(ViewHostMsg_PreCacheFont, OnPreCacheFont)
#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_GenerateRoutingID, OnGenerateRoutingID)
@@ -351,9 +345,6 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message,
#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(ViewHostMsg_LoadFont, OnLoadFont)
#endif
-#if defined(OS_WIN) // This hack is Windows-specific.
- IPC_MESSAGE_HANDLER(ViewHostMsg_PreCacheFont, OnPreCacheFont)
-#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_GetPlugins, OnGetPlugins)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetPluginInfo, OnGetPluginInfo)
IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl)
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h
index f9d183d..08741b6 100644
--- a/content/browser/renderer_host/render_message_filter.h
+++ b/content/browser/renderer_host/render_message_filter.h
@@ -135,19 +135,20 @@ class RenderMessageFilter : public BrowserMessageFilter {
uint32* font_id);
#endif
-#if defined(OS_WIN) // This hack is Windows-specific.
- // Cache fonts for the renderer. See RenderMessageFilter::OnPreCacheFont
- // implementation for more details.
- void OnPreCacheFont(LOGFONT font);
-#endif
-
-#if !defined(OS_MACOSX)
- // Not handled in the IO thread on Mac.
+#if defined(OS_WIN)
+ // On Windows, we handle these on the IO thread to avoid a deadlock with
+ // plugins. On non-Windows systems, we need to handle them on the UI thread.
void OnGetScreenInfo(gfx::NativeViewId window,
WebKit::WebScreenInfo* results);
void OnGetWindowRect(gfx::NativeViewId window, gfx::Rect* rect);
void OnGetRootWindowRect(gfx::NativeViewId window, gfx::Rect* rect);
+
+ // This hack is Windows-specific.
+ // Cache fonts for the renderer. See RenderMessageFilter::OnPreCacheFont
+ // implementation for more details.
+ void OnPreCacheFont(LOGFONT font);
#endif
+
void OnGetPlugins(bool refresh,
std::vector<webkit::npapi::WebPluginInfo>* plugins);
void OnGetPluginInfo(int routing_id,
@@ -173,7 +174,7 @@ class RenderMessageFilter : public BrowserMessageFilter {
void OnCheckNotificationPermission(const GURL& source_url,
int* permission_level);
-// Used to ask the browser to allocate a block of shared memory for the
+ // Used to ask the browser to allocate a block of shared memory for the
// renderer to send back data in, since shared memory can't be created
// in the renderer on POSIX due to the sandbox.
void OnAllocateSharedMemoryBuffer(uint32 buffer_size,
diff --git a/content/browser/renderer_host/render_message_filter_gtk.cc b/content/browser/renderer_host/render_message_filter_gtk.cc
deleted file mode 100644
index 4612734..0000000
--- a/content/browser/renderer_host/render_message_filter_gtk.cc
+++ /dev/null
@@ -1,150 +0,0 @@
-// 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 <dlfcn.h>
-
-#include "content/browser/renderer_host/render_message_filter.h"
-
-#include "content/browser/browser_thread.h"
-#include "content/common/view_messages.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/x11/WebScreenInfoFactory.h"
-#include "ui/base/clipboard/clipboard.h"
-#include "ui/base/x/x11_util.h"
-#include "ui/gfx/gtk_native_view_id_manager.h"
-
-#if !defined(OS_CHROMEOS)
-// We want to obey the alphabetical order for including header files, but
-// #define macros in X11 header files affect chrome header files
-// (e.g. Success), so include Xinerama.h here. We don't include Xinerama.h on
-// Chrome OS since the X server for Chrome OS does not support the extension.
-#include <X11/extensions/Xinerama.h>
-#endif // OS_CHROMEOS
-
-using WebKit::WebScreenInfo;
-using WebKit::WebScreenInfoFactory;
-
-namespace {
-
-// Return the top-level parent of the given window. Called on the
-// BACKGROUND_X11 thread.
-XID GetTopLevelWindow(XID window) {
- bool parent_is_root;
- XID parent_window;
-
- if (!ui::GetWindowParent(&parent_window, &parent_is_root, window))
- return 0;
- if (parent_is_root)
- return window;
-
- return GetTopLevelWindow(parent_window);
-}
-
-gfx::Rect GetWindowRectFromView(gfx::NativeViewId view) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::BACKGROUND_X11));
- // This is called to get the x, y offset (in screen coordinates) of the given
- // view and its width and height.
- gfx::Rect rect;
- XID window;
-
- base::AutoLock lock(GtkNativeViewManager::GetInstance()->unrealize_lock());
- if (GtkNativeViewManager::GetInstance()->GetXIDForId(&window, view)) {
- if (window) {
- int x, y;
- unsigned width, height;
- if (ui::GetWindowGeometry(&x, &y, &width, &height, window))
- rect = gfx::Rect(x, y, width, height);
- }
- }
- return rect;
-}
-
-} // namespace
-
-// We get null window_ids passed into the two functions below; please see
-// http://crbug.com/9060 for more details.
-void RenderMessageFilter::OnGetScreenInfo(gfx::NativeViewId view,
- WebKit::WebScreenInfo* results) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::BACKGROUND_X11));
- Display* display = ui::GetSecondaryDisplay();
-
- *results = WebScreenInfoFactory::screenInfo(display,
- ui::GetDefaultScreen(display));
-
-#if !defined(OS_CHROMEOS)
- // First check if we can use Xinerama.
- XineramaScreenInfo* screen_info = NULL;
- int screen_num = 0;
- void* xinerama_lib = dlopen("libXinerama.so.1", RTLD_LAZY);
- if (xinerama_lib) {
- // Prototypes for Xinerama functions.
- typedef Bool (*XineramaIsActiveFunction)(Display* display);
- typedef XineramaScreenInfo*
- (*XineramaQueryScreensFunction)(Display* display, int* num);
-
- XineramaIsActiveFunction is_active = (XineramaIsActiveFunction)
- dlsym(xinerama_lib, "XineramaIsActive");
-
- XineramaQueryScreensFunction query_screens = (XineramaQueryScreensFunction)
- dlsym(xinerama_lib, "XineramaQueryScreens");
-
- // Get the number of screens via Xinerama
- if (is_active && query_screens && is_active(display))
- screen_info = query_screens(display, &screen_num);
-
- if (screen_info) {
- // We can use Xinerama information. Calculate the intersect rect size
- // between window rect and screen rect, and choose the biggest size.
- gfx::Rect rect = GetWindowRectFromView(view);
- int max_intersect_index = 0;
- for (int i = 0, max_intersect_size = 0; i < screen_num; ++i) {
- gfx::Rect screen_rect(screen_info[i].x_org, screen_info[i].y_org,
- screen_info[i].width, screen_info[i].height);
- gfx::Rect intersect_rect = screen_rect.Intersect(rect);
- int intersect_size = intersect_rect.width() * intersect_rect.height();
- if (intersect_size > max_intersect_size) {
- max_intersect_size = intersect_size;
- max_intersect_index = i;
- }
- }
- XineramaScreenInfo& target_screen = screen_info[max_intersect_index];
- results->rect = WebKit::WebRect(target_screen.x_org,
- target_screen.y_org,
- target_screen.width,
- target_screen.height);
- results->availableRect = results->rect;
-
- XFree(screen_info);
- }
- }
-#endif // OS_CHROMEOS
-}
-
-void RenderMessageFilter::OnGetWindowRect(gfx::NativeViewId view,
- gfx::Rect* rect) {
- *rect = GetWindowRectFromView(view);
-}
-
-void RenderMessageFilter::OnGetRootWindowRect(gfx::NativeViewId view,
- gfx::Rect* rect) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::BACKGROUND_X11));
- // This is called to get the screen coordinates and size of the browser
- // window itself.
- *rect = gfx::Rect();
- XID window;
-
- base::AutoLock lock(GtkNativeViewManager::GetInstance()->unrealize_lock());
- if (GtkNativeViewManager::GetInstance()->GetXIDForId(&window, view)) {
- if (window) {
- const XID toplevel = GetTopLevelWindow(window);
- if (toplevel) {
- int x, y;
- unsigned width, height;
- if (ui::GetWindowGeometry(&x, &y, &width, &height, toplevel))
- *rect = gfx::Rect(x, y, width, height);
- }
- }
- }
-}
diff --git a/content/browser/renderer_host/render_widget_host.cc b/content/browser/renderer_host/render_widget_host.cc
index 30ad1b0..670e50f 100644
--- a/content/browser/renderer_host/render_widget_host.cc
+++ b/content/browser/renderer_host/render_widget_host.cc
@@ -170,10 +170,12 @@ bool RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) {
OnMsgImeCancelComposition)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidActivateAcceleratedCompositing,
OnMsgDidActivateAcceleratedCompositing)
-#if defined(OS_MACOSX)
+#if defined(OS_POSIX)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetScreenInfo, OnMsgGetScreenInfo)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetWindowRect, OnMsgGetWindowRect)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetRootWindowRect, OnMsgGetRootWindowRect)
+#endif
+#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged,
OnMsgPluginFocusChanged)
IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme,
@@ -188,7 +190,8 @@ bool RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) {
OnAcceleratedSurfaceSetTransportDIB)
IPC_MESSAGE_HANDLER(ViewHostMsg_AcceleratedSurfaceBuffersSwapped,
OnAcceleratedSurfaceBuffersSwapped)
-#elif defined(TOOLKIT_USES_GTK)
+#endif
+#if defined(TOOLKIT_USES_GTK)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreatePluginContainer,
OnMsgCreatePluginContainer)
IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyPluginContainer,
diff --git a/content/browser/renderer_host/render_widget_host.h b/content/browser/renderer_host/render_widget_host.h
index a275b58..e610958 100644
--- a/content/browser/renderer_host/render_widget_host.h
+++ b/content/browser/renderer_host/render_widget_host.h
@@ -460,11 +460,13 @@ class RenderWidgetHost : public IPC::Channel::Listener,
void OnMsgDidActivateAcceleratedCompositing(bool activated);
-#if defined(OS_MACOSX)
+#if defined(OS_POSIX)
void OnMsgGetScreenInfo(gfx::NativeViewId view,
WebKit::WebScreenInfo* results);
void OnMsgGetWindowRect(gfx::NativeViewId window_id, gfx::Rect* results);
void OnMsgGetRootWindowRect(gfx::NativeViewId window_id, gfx::Rect* results);
+#endif
+#if defined(OS_MACOSX)
void OnMsgPluginFocusChanged(bool focused, int plugin_id);
void OnMsgStartPluginIme();
void OnAllocateFakePluginWindowHandle(bool opaque,
@@ -481,7 +483,8 @@ class RenderWidgetHost : public IPC::Channel::Listener,
TransportDIB::Handle transport_dib);
void OnAcceleratedSurfaceBuffersSwapped(gfx::PluginWindowHandle window,
uint64 surface_id);
-#elif defined(OS_POSIX)
+#endif
+#if defined(TOOLKIT_USES_GTK)
void OnMsgCreatePluginContainer(gfx::PluginWindowHandle id);
void OnMsgDestroyPluginContainer(gfx::PluginWindowHandle id);
#endif
diff --git a/content/browser/renderer_host/render_widget_host_gtk.cc b/content/browser/renderer_host/render_widget_host_gtk.cc
index e378edf..b7dd333 100644
--- a/content/browser/renderer_host/render_widget_host_gtk.cc
+++ b/content/browser/renderer_host/render_widget_host_gtk.cc
@@ -4,7 +4,93 @@
#include "content/browser/renderer_host/render_widget_host.h"
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include "base/synchronization/lock.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/x11/WebScreenInfoFactory.h"
+#include "ui/gfx/gtk_native_view_id_manager.h"
+#include "ui/gfx/rect.h"
+
+using WebKit::WebScreenInfo;
+using WebKit::WebScreenInfoFactory;
+
+// We get a null |view| passed into this function please see
+// http://crbug.com/9060 for more details.
+void RenderWidgetHost::OnMsgGetScreenInfo(gfx::NativeViewId view,
+ WebScreenInfo* results) {
+ GtkWidget* widget = NULL;
+ GdkWindow* gdk_window = NULL;
+ if (GtkNativeViewManager::GetInstance()->GetNativeViewForId(
+ &widget, view) && widget) {
+ gdk_window = widget->window;
+ } else {
+ GdkDisplay* display = gdk_display_get_default();
+ gdk_window = gdk_display_get_window_at_pointer(display, NULL, NULL);
+ }
+ if (!gdk_window)
+ return;
+ GdkScreen* screen = gdk_drawable_get_screen(gdk_window);
+ *results = WebScreenInfoFactory::screenInfo(
+ gdk_x11_drawable_get_xdisplay(gdk_window),
+ gdk_x11_screen_get_screen_number(screen));
+
+ // TODO(tony): We should move this code into WebScreenInfoFactory.
+ int monitor_number = gdk_screen_get_monitor_at_window(screen, gdk_window);
+ GdkRectangle monitor_rect;
+ gdk_screen_get_monitor_geometry(screen, monitor_number, &monitor_rect);
+ results->rect = WebKit::WebRect(monitor_rect.x, monitor_rect.y,
+ monitor_rect.width, monitor_rect.height);
+ // TODO(tony): Should we query _NET_WORKAREA to get the workarea?
+ results->availableRect = results->rect;
+}
+
+// We get null window_ids passed into this function please see
+// http://crbug.com/9060 for more details.
+void RenderWidgetHost::OnMsgGetWindowRect(gfx::NativeViewId window_id,
+ gfx::Rect* results) {
+ GtkWidget* widget = NULL;
+ if (!GtkNativeViewManager::GetInstance()->GetNativeViewForId(
+ &widget, window_id) || !widget) {
+ return;
+ }
+ GdkWindow* gdk_window = widget->window;
+ if (!gdk_window)
+ return;
+ GdkRectangle window_rect;
+ gdk_window_get_origin(gdk_window, &window_rect.x, &window_rect.y);
+ gdk_drawable_get_size(gdk_window, &window_rect.width, &window_rect.height);
+ *results = window_rect;
+}
+
+// We get null window_ids passed into this function please see
+// http://crbug.com/9060 for more details.
+void RenderWidgetHost::OnMsgGetRootWindowRect(gfx::NativeViewId window_id,
+ gfx::Rect* results) {
+ GtkWidget* widget = NULL;
+ if (!GtkNativeViewManager::GetInstance()->GetNativeViewForId(
+ &widget, window_id) || !widget) {
+ return;
+ }
+ GtkWidget* toplevel = gtk_widget_get_toplevel(widget);
+ if (!toplevel)
+ return;
+
+ GdkRectangle frame_extents;
+ GdkWindow* gdk_window = toplevel->window;
+ if (!gdk_window)
+ return;
+ gdk_window_get_frame_extents(gdk_window, &frame_extents);
+ int width = 0;
+ int height = 0;
+ gdk_drawable_get_size(gdk_window, &width, &height);
+ // Although we return a rect, this is actually two pairs of data: The
+ // position of the top left corner of the window and the size of the window
+ // not including the window decorations.
+ *results = gfx::Rect(frame_extents.x, frame_extents.y, width, height);
+}
void RenderWidgetHost::OnMsgCreatePluginContainer(gfx::PluginWindowHandle id) {
// TODO(piman): view_ can only be NULL with delayed view creation in
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index bfc92d0..8da029e 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -238,7 +238,6 @@
'browser/renderer_host/redirect_to_file_resource_handler.h',
'browser/renderer_host/render_message_filter.cc',
'browser/renderer_host/render_message_filter.h',
- 'browser/renderer_host/render_message_filter_gtk.cc',
'browser/renderer_host/render_message_filter_win.cc',
'browser/renderer_host/render_process_host.cc',
'browser/renderer_host/render_process_host.h',
diff --git a/ui/gfx/gtk_native_view_id_manager.cc b/ui/gfx/gtk_native_view_id_manager.cc
index d2a3699..14105f8 100644
--- a/ui/gfx/gtk_native_view_id_manager.cc
+++ b/ui/gfx/gtk_native_view_id_manager.cc
@@ -86,7 +86,7 @@ bool GtkNativeViewManager::GetXIDForId(XID* output, gfx::NativeViewId id) {
base::AutoLock locked(lock_);
std::map<gfx::NativeViewId, NativeViewInfo>::const_iterator i =
- id_to_info_.find(id);
+ id_to_info_.find(id);
if (i == id_to_info_.end())
return false;
@@ -95,6 +95,20 @@ bool GtkNativeViewManager::GetXIDForId(XID* output, gfx::NativeViewId id) {
return true;
}
+bool GtkNativeViewManager::GetNativeViewForId(gfx::NativeView* output,
+ gfx::NativeViewId id) {
+ base::AutoLock locked(lock_);
+
+ std::map<gfx::NativeViewId, NativeViewInfo>::const_iterator i =
+ id_to_info_.find(id);
+
+ if (i == id_to_info_.end())
+ return false;
+
+ *output = i->second.widget;
+ return true;
+}
+
bool GtkNativeViewManager::GetPermanentXIDForId(XID* output,
gfx::NativeViewId id) {
base::AutoLock locked(lock_);
@@ -197,7 +211,6 @@ void GtkNativeViewManager::OnRealize(gfx::NativeView widget) {
}
void GtkNativeViewManager::OnUnrealize(gfx::NativeView widget) {
- base::AutoLock unrealize_locked(unrealize_lock_);
base::AutoLock locked(lock_);
const gfx::NativeViewId id = GetWidgetId(widget);
diff --git a/ui/gfx/gtk_native_view_id_manager.h b/ui/gfx/gtk_native_view_id_manager.h
index 6ea16a2..6b544ff 100644
--- a/ui/gfx/gtk_native_view_id_manager.h
+++ b/ui/gfx/gtk_native_view_id_manager.h
@@ -61,6 +61,11 @@ class GtkNativeViewManager {
// |*xid| is set to 0.
bool GetXIDForId(XID* xid, gfx::NativeViewId id);
+ // May be called from the UI thread:
+ //
+ // Same as GetXIDForId except it returns the NativeView (GtkWidget*).
+ bool GetNativeViewForId(gfx::NativeView* xid, gfx::NativeViewId id);
+
// Must be called from the UI thread because we may need the associated
// widget to create a window.
//
@@ -90,8 +95,6 @@ class GtkNativeViewManager {
void OnUnrealize(gfx::NativeView widget);
void OnDestroy(gfx::NativeView widget);
- base::Lock& unrealize_lock() { return unrealize_lock_; }
-
private:
// This object is a singleton:
GtkNativeViewManager();
@@ -107,11 +110,6 @@ class GtkNativeViewManager {
gfx::NativeViewId GetWidgetId(gfx::NativeView id);
- // This lock can be used to block GTK from unrealizing windows. This is needed
- // when the BACKGROUND_X11 thread is using a window obtained via GetXIDForId,
- // and can't allow the X11 resource to be deleted.
- base::Lock unrealize_lock_;
-
// protects native_view_to_id_ and id_to_info_
base::Lock lock_;