On Fri, 2018-02-16 at 17:15 +0100, Christophe de Dinechin wrote: > 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; > +}; I would still very much like this class to be a functor that is passed to a thread. It IMHO makes for a better encapsulation. You can then launch it any way you like, for example on the main thread in a test. FWIW, I came up with the name CursorUpdater :) (since if it's not a thread we can't call it so) > + > + > +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) { _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel