[Spice-devel] [PATCH 14/17] Create a class encapsulating the X11 display cursor capture
Christophe de Dinechin
christophe at dinechin.org
Fri Feb 16 16:15:44 UTC 2018
From: Christophe de Dinechin <dinechin at redhat.com>
This class will need to be moved to a separate file in a later patch.
This is done in two steps to make the evolution of the code easier to track,
as well as to facilitate later 'git bisect'
Signed-off-by: Christophe de Dinechin <dinechin at redhat.com>
---
src/spice-streaming-agent.cpp | 106 ++++++++++++++++++++++++++----------------
1 file changed, 66 insertions(+), 40 deletions(-)
diff --git a/src/spice-streaming-agent.cpp b/src/spice-streaming-agent.cpp
index faf850c..f4df6be 100644
--- a/src/spice-streaming-agent.cpp
+++ b/src/spice-streaming-agent.cpp
@@ -191,6 +191,70 @@ private:
std::unique_ptr<uint32_t[]> pixels;
};
+
+class X11CursorThread
+{
+public:
+ X11CursorThread(Stream &stream);
+ ~X11CursorThread();
+
+ static void record_cursor_changes(X11CursorThread *self) { self->cursor_changes(); }
+ void cursor_changes();
+
+private:
+ Stream &stream;
+ Display *display;
+ std::thread thread;
+};
+
+
+X11CursorThread::X11CursorThread(Stream &stream)
+ : stream(stream),
+ display(XOpenDisplay(NULL)),
+ thread(record_cursor_changes, this)
+{
+ if (display == NULL) {
+ throw std::runtime_error("failed to open display\n");
+ }
+ thread.detach();
+}
+
+X11CursorThread::~X11CursorThread()
+{
+ XCloseDisplay(display);
+}
+
+void X11CursorThread::cursor_changes()
+{
+ unsigned long last_serial = 0;
+
+ int event_base, error_base;
+ if (!XFixesQueryExtension(display, &event_base, &error_base)) {
+ syslog(LOG_WARNING, "XFixesQueryExtension failed, not sending cursor changes\n");
+ return; // also terminates the thread
+ }
+ Window rootwindow = DefaultRootWindow(display);
+ XFixesSelectCursorInput(display, rootwindow, XFixesDisplayCursorNotifyMask);
+
+ while (true) {
+ XEvent event;
+ XNextEvent(display, &event);
+ if (event.type != event_base + 1)
+ continue;
+
+ XFixesCursorImage *cursor = XFixesGetCursorImage(display);
+ if (!cursor)
+ continue;
+
+ if (cursor->cursor_serial == last_serial)
+ continue;
+
+ last_serial = cursor->cursor_serial;
+ if (!stream.send<X11CursorMessage>(cursor))
+ syslog(LOG_WARNING, "FAILED to send cursor\n");
+ }
+}
+
}} // namespace spice::streaming_agent
@@ -338,29 +402,6 @@ static void usage(const char *progname)
exit(1);
}
-static void cursor_changes(Stream *stream, Display *display, int event_base)
-{
- unsigned long last_serial = 0;
-
- while (1) {
- XEvent event;
- XNextEvent(display, &event);
- if (event.type != event_base + 1)
- continue;
-
- XFixesCursorImage *cursor = XFixesGetCursorImage(display);
- if (!cursor)
- continue;
-
- if (cursor->cursor_serial == last_serial)
- continue;
-
- last_serial = cursor->cursor_serial;
- if (!stream->send<X11CursorMessage>(cursor))
- syslog(LOG_WARNING, "FAILED to send cursor\n");
- }
-}
-
static void
do_capture(Stream &stream, const char *streamport, FILE *f_log)
{
@@ -503,25 +544,10 @@ int main(int argc, char* argv[])
}
}
- Display *display = XOpenDisplay(NULL);
- if (display == NULL) {
- syslog(LOG_ERR, "failed to open display\n");
- return EXIT_FAILURE;
- }
- int event_base, error_base;
- if (!XFixesQueryExtension(display, &event_base, &error_base)) {
- syslog(LOG_ERR, "XFixesQueryExtension failed\n");
- return EXIT_FAILURE;
- }
- Window rootwindow = DefaultRootWindow(display);
- XFixesSelectCursorInput(display, rootwindow, XFixesDisplayCursorNotifyMask);
-
- Stream streamfd(streamport);
- std::thread cursor_th(cursor_changes, &streamfd, display, event_base);
- cursor_th.detach();
-
int ret = EXIT_SUCCESS;
try {
+ Stream streamfd(streamport);
+ X11CursorThread cursor_thread(streamfd);
do_capture(streamfd, streamport, f_log);
}
catch (std::runtime_error &err) {
--
2.13.5 (Apple Git-94)
More information about the Spice-devel
mailing list