From: Christophe de Dinechin <dinechin@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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) _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel