Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(815)

Unified Diff: remoting/host/capturer_linux.cc

Issue 10382184: [Chromoting] Initial plumbing for cursor shape. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add comment for CaptureCursor Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: remoting/host/capturer_linux.cc
diff --git a/remoting/host/capturer_linux.cc b/remoting/host/capturer_linux.cc
index e513bb7c8932492f9dcf14c8fb061f885bebc253..3245c338839283eb2e16d696d3603a46023e3780 100644
--- a/remoting/host/capturer_linux.cc
+++ b/remoting/host/capturer_linux.cc
@@ -7,6 +7,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xdamage.h>
+#include <X11/extensions/Xfixes.h>
#include <set>
@@ -77,6 +78,8 @@ class CapturerLinux : public Capturer {
// Capturer interface.
virtual void Start() OVERRIDE;
virtual void Stop() OVERRIDE;
+ virtual void SetCursorShapeChangedCallback(
+ const CursorShapeChangedCallback& callback) OVERRIDE;
virtual void ScreenConfigurationChanged() OVERRIDE;
virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
virtual void ClearInvalidRegion() OVERRIDE;
@@ -106,6 +109,10 @@ class CapturerLinux : public Capturer {
// previous capture.
CaptureData* CaptureFrame();
+ // Capture the cursor shape pixels and call the CursorShapeChangedCallback,
Wez 2012/05/16 00:20:04 nit: "shape pixels" -> "image" ?
garykac 2012/05/22 00:42:03 Done.
+ // if it has been set (using SetCursorShapeChangedCallback).
+ void CaptureCursor();
+
// Synchronize the current buffer with |last_buffer_|, by copying pixels from
// the area of |last_invalid_rects|.
// Note this only works on the assumption that kNumBuffers == 2, as
@@ -129,6 +136,11 @@ class CapturerLinux : public Capturer {
GC gc_;
Window root_window_;
+ // XFixes.
+ bool has_xfixes_;
+ int xfixes_event_base_;
+ int xfixes_error_base_;
+
// XDamage information.
bool use_damage_;
Damage damage_handle_;
@@ -143,6 +155,9 @@ class CapturerLinux : public Capturer {
// recently captured screen.
CapturerHelper helper_;
+ // Callback to call whenever the cursor shape is changed.
Wez 2012/05/16 00:20:04 nit: "Callback notified ..."
garykac 2012/05/22 00:42:03 Done.
+ CursorShapeChangedCallback cursor_shape_changed_callback_;
+
// Capture state.
static const int kNumBuffers = 2;
VideoFrameBuffer buffers_[kNumBuffers];
@@ -168,6 +183,9 @@ CapturerLinux::CapturerLinux()
: display_(NULL),
gc_(NULL),
root_window_(BadValue),
+ has_xfixes_(false),
+ xfixes_event_base_(-1),
+ xfixes_error_base_(-1),
use_damage_(false),
damage_handle_(0),
damage_event_base_(-1),
@@ -208,6 +226,15 @@ bool CapturerLinux::Init() {
return false;
}
+ // Check for XFixes extension. This is required for our XDamage support and
Wez 2012/05/16 00:20:04 nit: Suggest "This is required for cursor shape no
garykac 2012/05/22 00:42:03 Done.
+ // to get the cursor shape notifications.
+ if (XFixesQueryExtension(display_, &xfixes_event_base_,
+ &xfixes_error_base_)) {
+ has_xfixes_ = true;
+ } else {
+ LOG(INFO) << "X server does not support XFixes.";
+ }
+
if (ShouldUseXDamage()) {
InitXDamage();
}
@@ -215,18 +242,21 @@ bool CapturerLinux::Init() {
// Register for changes to the dimensions of the root window.
XSelectInput(display_, root_window_, StructureNotifyMask);
+ if (has_xfixes_) {
+ // Register for changes to the cursor shape.
+ XFixesSelectCursorInput(display_, root_window_,
+ XFixesDisplayCursorNotifyMask);
+ }
+
return true;
}
void CapturerLinux::InitXDamage() {
- // Check for XFixes and XDamage extensions. If both are found then use
- // XDamage to get explicit notifications of on-screen changes.
- int xfixes_event_base;
- int xfixes_error_base;
- if (!XFixesQueryExtension(display_, &xfixes_event_base, &xfixes_error_base)) {
- LOG(INFO) << "X server does not support XFixes.";
+ if (!has_xfixes_)
return;
- }
+
+ // Check for XDamage extension. If this and XFixes are both found then use
Wez 2012/05/16 00:20:04 nit: You've already tested for XFixes, so don't me
garykac 2012/05/22 00:42:03 Done.
+ // XDamage to get explicit notifications of on-screen changes.
if (!XDamageQueryExtension(display_, &damage_event_base_,
&damage_error_base_)) {
LOG(INFO) << "X server does not support XDamage.";
@@ -264,6 +294,11 @@ void CapturerLinux::Start() {
void CapturerLinux::Stop() {
}
+void CapturerLinux::SetCursorShapeChangedCallback(
+ const CursorShapeChangedCallback& callback) {
+ cursor_shape_changed_callback_ = callback;
+}
+
void CapturerLinux::ScreenConfigurationChanged() {
last_buffer_ = NULL;
for (int i = 0; i < kNumBuffers; ++i) {
@@ -296,8 +331,7 @@ void CapturerLinux::InvalidateFullScreen() {
void CapturerLinux::CaptureInvalidRegion(
const CaptureCompletedCallback& callback) {
- // TODO(lambroslambrou): In the non-DAMAGE case, there should be no need
- // for any X event processing in this class.
+ // Process XEvents for XDamage and cursor shape.
Wez 2012/05/16 00:20:04 nit: "... cursor shape tracking"
garykac 2012/05/22 00:42:03 Done.
ProcessPendingXEvents();
// Resize the current buffer if there was a recent change of
@@ -326,16 +360,34 @@ void CapturerLinux::ProcessPendingXEvents() {
for (int i = 0; i < events_to_process; i++) {
XNextEvent(display_, &e);
if (use_damage_ && (e.type == damage_event_base_ + XDamageNotify)) {
- XDamageNotifyEvent *event = reinterpret_cast<XDamageNotifyEvent*>(&e);
+ XDamageNotifyEvent* event = reinterpret_cast<XDamageNotifyEvent*>(&e);
DCHECK(event->level == XDamageReportNonEmpty);
} else if (e.type == ConfigureNotify) {
ScreenConfigurationChanged();
+ } else if (has_xfixes_ &&
+ e.type == xfixes_event_base_ + XFixesCursorNotify) {
+ XFixesCursorNotifyEvent* cne;
+ cne = reinterpret_cast<XFixesCursorNotifyEvent*>(&e);
+ if (cne->subtype == XFixesDisplayCursorNotify) {
+ CaptureCursor();
+ }
} else {
LOG(WARNING) << "Got unknown event type: " << e.type;
}
}
}
+void CapturerLinux::CaptureCursor() {
+ DCHECK(has_xfixes_);
+ if (cursor_shape_changed_callback_.is_null())
+ return;
+
+ // TODO(garykac) Get cursor shape using XFixesGetCursorImage.
+
+ scoped_refptr<CursorShapeData> cursor_data;
+ cursor_shape_changed_callback_.Run(cursor_data);
+}
+
CaptureData* CapturerLinux::CaptureFrame() {
VideoFrameBuffer& buffer = buffers_[current_buffer_];
DataPlanes planes;

Powered by Google App Engine
This is Rietveld 408576698