OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/renderer_host/render_widget_host_view_views.h" | 5 #include "chrome/browser/renderer_host/render_widget_host_view_views.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/string_number_conversions.h" | 14 #include "base/string_number_conversions.h" |
15 #include "base/task.h" | 15 #include "base/task.h" |
16 #include "base/time.h" | 16 #include "base/time.h" |
| 17 #include "chrome/browser/renderer_host/backing_store_skia.h" |
17 #include "chrome/browser/renderer_host/backing_store_x.h" | 18 #include "chrome/browser/renderer_host/backing_store_x.h" |
18 #include "chrome/browser/renderer_host/render_widget_host.h" | 19 #include "chrome/browser/renderer_host/render_widget_host.h" |
19 #include "chrome/common/native_web_keyboard_event.h" | 20 #include "chrome/common/native_web_keyboard_event.h" |
20 #include "chrome/common/render_messages.h" | 21 #include "chrome/common/render_messages.h" |
21 #include "chrome/common/result_codes.h" | 22 #include "chrome/common/result_codes.h" |
22 #include "third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFact
ory.h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFact
ory.h" |
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
24 #include "ui/base/keycodes/keyboard_code_conversion_gtk.h" | 25 #include "ui/base/keycodes/keyboard_code_conversion_gtk.h" |
25 #include "ui/base/l10n/l10n_util.h" | 26 #include "ui/base/l10n/l10n_util.h" |
26 #include "ui/base/x/x11_util.h" | 27 #include "ui/base/x/x11_util.h" |
27 #include "ui/gfx/canvas.h" | 28 #include "ui/gfx/canvas.h" |
| 29 #include "ui/gfx/canvas_skia.h" |
28 #include "views/events/event.h" | 30 #include "views/events/event.h" |
29 #include "views/ime/ime_context.h" | 31 #include "views/ime/ime_context.h" |
30 #include "views/widget/widget.h" | 32 #include "views/widget/widget.h" |
31 #include "views/widget/widget_gtk.h" | 33 #include "views/widget/widget_gtk.h" |
32 | 34 |
33 static const int kMaxWindowWidth = 4000; | 35 static const int kMaxWindowWidth = 4000; |
34 static const int kMaxWindowHeight = 4000; | 36 static const int kMaxWindowHeight = 4000; |
35 static const char* kRenderWidgetHostViewKey = "__RENDER_WIDGET_HOST_VIEW__"; | 37 static const char kRenderWidgetHostViewKey[] = "__RENDER_WIDGET_HOST_VIEW__"; |
| 38 static const char kBackingStoreSkiaSwitch[] = "use-backing-store-skia"; |
36 | 39 |
37 // Copied from third_party/WebKit/Source/WebCore/page/EventHandler.cpp | 40 // Copied from third_party/WebKit/Source/WebCore/page/EventHandler.cpp |
38 // | 41 // |
39 // Match key code of composition keydown event on windows. | 42 // Match key code of composition keydown event on windows. |
40 // IE sends VK_PROCESSKEY which has value 229; | 43 // IE sends VK_PROCESSKEY which has value 229; |
41 // | 44 // |
42 // Please refer to following documents for detals: | 45 // Please refer to following documents for detals: |
43 // - Virtual-Key Codes | 46 // - Virtual-Key Codes |
44 // http://msdn.microsoft.com/en-us/library/ms645540(VS.85).aspx | 47 // http://msdn.microsoft.com/en-us/library/ms645540(VS.85).aspx |
45 // - How the IME System Works | 48 // - How the IME System Works |
46 // http://msdn.microsoft.com/en-us/library/cc194848.aspx | 49 // http://msdn.microsoft.com/en-us/library/cc194848.aspx |
47 // - ImmGetVirtualKey Function | 50 // - ImmGetVirtualKey Function |
48 // http://msdn.microsoft.com/en-us/library/dd318570(VS.85).aspx | 51 // http://msdn.microsoft.com/en-us/library/dd318570(VS.85).aspx |
49 static const int kCompositionEventKeyCode = 229; | 52 static const int kCompositionEventKeyCode = 229; |
50 | 53 |
51 using WebKit::WebInputEventFactory; | 54 using WebKit::WebInputEventFactory; |
52 using WebKit::WebMouseWheelEvent; | 55 using WebKit::WebMouseWheelEvent; |
53 using WebKit::WebTouchEvent; | 56 using WebKit::WebTouchEvent; |
54 | 57 |
55 const char RenderWidgetHostViewViews::kViewClassName[] = | 58 const char RenderWidgetHostViewViews::kViewClassName[] = |
56 "browser/renderer_host/RenderWidgetHostViewViews"; | 59 "browser/renderer_host/RenderWidgetHostViewViews"; |
57 | 60 |
58 namespace { | 61 namespace { |
59 | 62 |
| 63 bool UsingBackingStoreSkia() { |
| 64 static bool decided = false; |
| 65 static bool use_skia = false; |
| 66 if (!decided) { |
| 67 CommandLine* cmdline = CommandLine::ForCurrentProcess(); |
| 68 use_skia = (cmdline && cmdline->HasSwitch(kBackingStoreSkiaSwitch)); |
| 69 decided = true; |
| 70 } |
| 71 |
| 72 return use_skia; |
| 73 } |
| 74 |
60 int WebInputEventFlagsFromViewsEvent(const views::Event& event) { | 75 int WebInputEventFlagsFromViewsEvent(const views::Event& event) { |
61 int modifiers = 0; | 76 int modifiers = 0; |
62 | 77 |
63 if (event.IsShiftDown()) | 78 if (event.IsShiftDown()) |
64 modifiers |= WebKit::WebInputEvent::ShiftKey; | 79 modifiers |= WebKit::WebInputEvent::ShiftKey; |
65 if (event.IsControlDown()) | 80 if (event.IsControlDown()) |
66 modifiers |= WebKit::WebInputEvent::ControlKey; | 81 modifiers |= WebKit::WebInputEvent::ControlKey; |
67 if (event.IsAltDown()) | 82 if (event.IsAltDown()) |
68 modifiers |= WebKit::WebInputEvent::AltKey; | 83 modifiers |= WebKit::WebInputEvent::AltKey; |
69 if (event.IsCapsLockDown()) | 84 if (event.IsCapsLockDown()) |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 | 495 |
481 bool RenderWidgetHostViewViews::IsPopup() { | 496 bool RenderWidgetHostViewViews::IsPopup() { |
482 return popup_type_ != WebKit::WebPopupTypeNone; | 497 return popup_type_ != WebKit::WebPopupTypeNone; |
483 } | 498 } |
484 | 499 |
485 BackingStore* RenderWidgetHostViewViews::AllocBackingStore( | 500 BackingStore* RenderWidgetHostViewViews::AllocBackingStore( |
486 const gfx::Size& size) { | 501 const gfx::Size& size) { |
487 gfx::NativeView nview = GetInnerNativeView(); | 502 gfx::NativeView nview = GetInnerNativeView(); |
488 if (!nview) | 503 if (!nview) |
489 return NULL; | 504 return NULL; |
490 return new BackingStoreX(host_, size, | 505 |
491 ui::GetVisualFromGtkWidget(nview), | 506 if (UsingBackingStoreSkia()) { |
492 gtk_widget_get_visual(nview)->depth); | 507 return new BackingStoreSkia(host_, size); |
| 508 } else { |
| 509 return new BackingStoreX(host_, size, |
| 510 ui::GetVisualFromGtkWidget(nview), |
| 511 gtk_widget_get_visual(nview)->depth); |
| 512 } |
493 } | 513 } |
494 | 514 |
495 gfx::NativeView RenderWidgetHostViewViews::GetInnerNativeView() const { | 515 gfx::NativeView RenderWidgetHostViewViews::GetInnerNativeView() const { |
496 // TODO(sad): Ideally this function should be equivalent to GetNativeView, and | 516 // TODO(sad): Ideally this function should be equivalent to GetNativeView, and |
497 // WidgetGtk-specific function call should not be necessary. | 517 // WidgetGtk-specific function call should not be necessary. |
498 const views::WidgetGtk* widget = | 518 const views::WidgetGtk* widget = |
499 static_cast<const views::WidgetGtk*>(GetWidget()); | 519 static_cast<const views::WidgetGtk*>(GetWidget()); |
500 return widget ? widget->window_contents() : NULL; | 520 return widget ? widget->window_contents() : NULL; |
501 } | 521 } |
502 | 522 |
(...skipping 30 matching lines...) Expand all Loading... |
533 GdkWindow* window = GetInnerNativeView()->window; | 553 GdkWindow* window = GetInnerNativeView()->window; |
534 DCHECK(!about_to_validate_and_paint_); | 554 DCHECK(!about_to_validate_and_paint_); |
535 | 555 |
536 // TODO(anicolao): get the damage somehow | 556 // TODO(anicolao): get the damage somehow |
537 // invalid_rect_ = damage_rect; | 557 // invalid_rect_ = damage_rect; |
538 invalid_rect_ = bounds(); | 558 invalid_rect_ = bounds(); |
539 gfx::Point origin; | 559 gfx::Point origin; |
540 ConvertPointToWidget(this, &origin); | 560 ConvertPointToWidget(this, &origin); |
541 | 561 |
542 about_to_validate_and_paint_ = true; | 562 about_to_validate_and_paint_ = true; |
543 BackingStoreX* backing_store = static_cast<BackingStoreX*>( | 563 BackingStore* backing_store = host_->GetBackingStore(true); |
544 host_->GetBackingStore(true)); | |
545 // Calling GetBackingStore maybe have changed |invalid_rect_|... | 564 // Calling GetBackingStore maybe have changed |invalid_rect_|... |
546 about_to_validate_and_paint_ = false; | 565 about_to_validate_and_paint_ = false; |
547 | 566 |
548 gfx::Rect paint_rect = gfx::Rect(0, 0, kMaxWindowWidth, kMaxWindowHeight); | 567 gfx::Rect paint_rect = gfx::Rect(0, 0, kMaxWindowWidth, kMaxWindowHeight); |
549 paint_rect = paint_rect.Intersect(invalid_rect_); | 568 paint_rect = paint_rect.Intersect(invalid_rect_); |
550 | 569 |
551 if (backing_store) { | 570 if (backing_store) { |
552 // Only render the widget if it is attached to a window; there's a short | 571 // Only render the widget if it is attached to a window; there's a short |
553 // period where this object isn't attached to a window but hasn't been | 572 // period where this object isn't attached to a window but hasn't been |
554 // Destroy()ed yet and it receives paint messages... | 573 // Destroy()ed yet and it receives paint messages... |
555 if (window) { | 574 if (window) { |
556 if (!visually_deemphasized_) { | 575 if (!visually_deemphasized_) { |
557 // In the common case, use XCopyArea. We don't draw more than once, so | 576 // In the common case, use XCopyArea. We don't draw more than once, so |
558 // we don't need to double buffer. | 577 // we don't need to double buffer. |
559 backing_store->XShowRect(origin, | 578 |
560 paint_rect, ui::GetX11WindowFromGdkWindow(window)); | 579 if (UsingBackingStoreSkia()) { |
561 } else { | 580 static_cast<BackingStoreSkia*>(backing_store)->SkiaShowRect( |
| 581 gfx::Point(paint_rect.x(), paint_rect.y()), canvas); |
| 582 } else { |
| 583 static_cast<BackingStoreX*>(backing_store)->XShowRect(origin, |
| 584 paint_rect, ui::GetX11WindowFromGdkWindow(window)); |
| 585 } |
| 586 } else if (!UsingBackingStoreSkia()) { |
562 // If the grey blend is showing, we make two drawing calls. Use double | 587 // If the grey blend is showing, we make two drawing calls. Use double |
563 // buffering to prevent flicker. Use CairoShowRect because XShowRect | 588 // buffering to prevent flicker. Use CairoShowRect because XShowRect |
564 // shortcuts GDK's double buffering. | 589 // shortcuts GDK's double buffering. |
565 GdkRectangle rect = { paint_rect.x(), paint_rect.y(), | 590 GdkRectangle rect = { paint_rect.x(), paint_rect.y(), |
566 paint_rect.width(), paint_rect.height() }; | 591 paint_rect.width(), paint_rect.height() }; |
567 gdk_window_begin_paint_rect(window, &rect); | 592 gdk_window_begin_paint_rect(window, &rect); |
568 | 593 |
569 backing_store->CairoShowRect(paint_rect, GDK_DRAWABLE(window)); | 594 static_cast<BackingStoreX*>(backing_store)->CairoShowRect( |
| 595 paint_rect, GDK_DRAWABLE(window)); |
570 | 596 |
571 cairo_t* cr = gdk_cairo_create(window); | 597 cairo_t* cr = gdk_cairo_create(window); |
572 gdk_cairo_rectangle(cr, &rect); | 598 gdk_cairo_rectangle(cr, &rect); |
573 cairo_set_source_rgba(cr, 0, 0, 0, 0.7); | 599 cairo_set_source_rgba(cr, 0, 0, 0, 0.7); |
574 cairo_fill(cr); | 600 cairo_fill(cr); |
575 cairo_destroy(cr); | 601 cairo_destroy(cr); |
576 | 602 |
577 gdk_window_end_paint(window); | 603 gdk_window_end_paint(window); |
| 604 } else { |
| 605 // TODO(sad) |
| 606 NOTIMPLEMENTED(); |
578 } | 607 } |
579 } | 608 } |
580 if (!whiteout_start_time_.is_null()) { | 609 if (!whiteout_start_time_.is_null()) { |
581 base::TimeDelta whiteout_duration = base::TimeTicks::Now() - | 610 base::TimeDelta whiteout_duration = base::TimeTicks::Now() - |
582 whiteout_start_time_; | 611 whiteout_start_time_; |
583 UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration); | 612 UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration); |
584 | 613 |
585 // Reset the start time to 0 so that we start recording again the next | 614 // Reset the start time to 0 so that we start recording again the next |
586 // time the backing store is NULL... | 615 // time the backing store is NULL... |
587 whiteout_start_time_ = base::TimeTicks(); | 616 whiteout_start_time_ = base::TimeTicks(); |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
939 } | 968 } |
940 | 969 |
941 // static | 970 // static |
942 RenderWidgetHostView* | 971 RenderWidgetHostView* |
943 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( | 972 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( |
944 gfx::NativeView widget) { | 973 gfx::NativeView widget) { |
945 gpointer user_data = g_object_get_data(G_OBJECT(widget), | 974 gpointer user_data = g_object_get_data(G_OBJECT(widget), |
946 kRenderWidgetHostViewKey); | 975 kRenderWidgetHostViewKey); |
947 return reinterpret_cast<RenderWidgetHostView*>(user_data); | 976 return reinterpret_cast<RenderWidgetHostView*>(user_data); |
948 } | 977 } |
OLD | NEW |