Chromium Code Reviews| Index: webrtc/modules/desktop_capture/screen_drawer_linux.cc |
| diff --git a/webrtc/modules/desktop_capture/screen_drawer_linux.cc b/webrtc/modules/desktop_capture/screen_drawer_linux.cc |
| index 2aff80b6c7ce1259f48f32ef94b12121f0256ac5..3599e642953aa08bc257d915a095952163c60ce9 100644 |
| --- a/webrtc/modules/desktop_capture/screen_drawer_linux.cc |
| +++ b/webrtc/modules/desktop_capture/screen_drawer_linux.cc |
| @@ -13,6 +13,7 @@ |
| #include "webrtc/base/checks.h" |
| #include "webrtc/modules/desktop_capture/screen_drawer.h" |
| #include "webrtc/modules/desktop_capture/x11/shared_x_display.h" |
| +#include "webrtc/system_wrappers/include/sleep.h" |
| namespace webrtc { |
| @@ -26,12 +27,12 @@ class ScreenDrawerLinux : public ScreenDrawer { |
| // ScreenDrawer interface. |
| DesktopRect DrawableRegion() override; |
| - void DrawRectangle(DesktopRect rect, uint32_t rgba) override; |
| + void DrawRectangle(DesktopRect rect, Color color) override; |
| void Clear() override; |
| + void WaitForPendingDraws() override; |
| private: |
| rtc::scoped_refptr<SharedXDisplay> display_; |
| - Screen* screen_; |
| int screen_num_; |
| DesktopRect rect_; |
| Window window_; |
| @@ -42,15 +43,18 @@ class ScreenDrawerLinux : public ScreenDrawer { |
| ScreenDrawerLinux::ScreenDrawerLinux() { |
| display_ = SharedXDisplay::CreateDefault(); |
| RTC_CHECK(display_.get()); |
| - screen_ = DefaultScreenOfDisplay(display_->display()); |
| - RTC_CHECK(screen_); |
| screen_num_ = DefaultScreen(display_->display()); |
| - rect_ = DesktopRect::MakeWH(screen_->width, screen_->height); |
| - window_ = XCreateSimpleWindow(display_->display(), |
| - RootWindow(display_->display(), screen_num_), 0, |
| - 0, rect_.width(), rect_.height(), 0, |
| - BlackPixel(display_->display(), screen_num_), |
| - BlackPixel(display_->display(), screen_num_)); |
| + XWindowAttributes root_attributes; |
| + if (!XGetWindowAttributes(display_->display(), |
| + RootWindow(display_->display(), screen_num_), |
| + &root_attributes)) { |
| + RTC_DCHECK(false) << "Failed to get root window size."; |
| + } |
| + window_ = XCreateSimpleWindow( |
| + display_->display(), RootWindow(display_->display(), screen_num_), 0, 0, |
| + root_attributes.width, root_attributes.height, 0, |
| + BlackPixel(display_->display(), screen_num_), |
| + BlackPixel(display_->display(), screen_num_)); |
| XSelectInput(display_->display(), window_, StructureNotifyMask); |
| XMapWindow(display_->display(), window_); |
| while (true) { |
| @@ -61,8 +65,23 @@ ScreenDrawerLinux::ScreenDrawerLinux() { |
| } |
| } |
| XFlush(display_->display()); |
| + Window child; |
| + int x, y; |
| + if (!XTranslateCoordinates(display_->display(), window_, |
| + RootWindow(display_->display(), screen_num_), 0, 0, |
| + &x, &y, &child)) { |
| + RTC_DCHECK(false) << "Failed to get window position."; |
| + } |
| + // Some window manager does not allow a window to cover two or more monitors. |
| + // So if the window is on the first monitor of a two-monitor system, the |
| + // second half won't be able to show up without changing configurations of WM, |
| + // and its DrawableRegion() is not accurate. |
| + rect_ = DesktopRect::MakeLTRB(x, y, root_attributes.width, |
| + root_attributes.height); |
| context_ = DefaultGC(display_->display(), screen_num_); |
| colormap_ = DefaultColormap(display_->display(), screen_num_); |
| + // Wait for window animations. |
| + SleepMs(200); |
| } |
| ScreenDrawerLinux::~ScreenDrawerLinux() { |
| @@ -74,33 +93,41 @@ DesktopRect ScreenDrawerLinux::DrawableRegion() { |
| return rect_; |
| } |
| -void ScreenDrawerLinux::DrawRectangle(DesktopRect rect, uint32_t rgba) { |
| - int r = (rgba & 0xff00) >> 8; |
| - int g = (rgba & 0xff0000) >> 16; |
| - int b = (rgba & 0xff000000) >> 24; |
| +void ScreenDrawerLinux::DrawRectangle(DesktopRect rect, Color color) { |
| + rect.Translate(-rect_.left(), -rect_.top()); |
| + XColor xcolor; |
| // X11 does not support Alpha. |
| - XColor color; |
| // X11 uses 16 bits for each primary color. |
| - color.red = r * 256; |
| - color.green = g * 256; |
| - color.blue = b * 256; |
| - color.flags = DoRed | DoGreen | DoBlue; |
| - XAllocColor(display_->display(), colormap_, &color); |
| - XSetForeground(display_->display(), context_, color.pixel); |
| + xcolor.red = color.red() * 256 + color.red(); |
|
Sergey Ulanov
2016/09/01 19:26:38
Isn't it the same as color.red() * 257?
Same for g
Jamie
2016/09/01 20:38:53
It is the same, but I think the explicit addition
Hzj_jie
2016/09/01 23:25:09
My initial thought is, "color.red() * 257" looks l
|
| + xcolor.green = color.green() * 256 + color.green(); |
| + xcolor.blue = color.blue() * 256 + color.blue(); |
| + xcolor.flags = DoRed | DoGreen | DoBlue; |
| + XAllocColor(display_->display(), colormap_, &xcolor); |
| + XSetForeground(display_->display(), context_, xcolor.pixel); |
| XFillRectangle(display_->display(), window_, context_, rect.left(), |
| rect.top(), rect.width(), rect.height()); |
| XFlush(display_->display()); |
| } |
| void ScreenDrawerLinux::Clear() { |
| - DrawRectangle(DrawableRegion(), 0); |
| + DrawRectangle(rect_, Color(0, 0, 0)); |
| +} |
| + |
| +// TODO(zijiehe): Find the right signal from X11 to indicate the finish of all |
| +// pending paintings. |
| +void ScreenDrawerLinux::WaitForPendingDraws() { |
| + SleepMs(50); |
| } |
| } // namespace |
| // static |
| std::unique_ptr<ScreenDrawer> ScreenDrawer::Create() { |
| - return std::unique_ptr<ScreenDrawer>(new ScreenDrawerLinux()); |
| + if (SharedXDisplay::CreateDefault().get()) { |
| + return std::unique_ptr<ScreenDrawer>(new ScreenDrawerLinux()); |
| + } else { |
|
Sergey Ulanov
2016/09/01 19:26:38
no else after return please.
Hzj_jie
2016/09/01 23:25:09
Done.
|
| + return nullptr; |
| + } |
| } |
| } // namespace webrtc |