summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
Diffstat (limited to 'remoting')
-rw-r--r--remoting/host/local_input_monitor_thread_linux.cc110
1 files changed, 58 insertions, 52 deletions
diff --git a/remoting/host/local_input_monitor_thread_linux.cc b/remoting/host/local_input_monitor_thread_linux.cc
index 0c6e007..8bfdd36 100644
--- a/remoting/host/local_input_monitor_thread_linux.cc
+++ b/remoting/host/local_input_monitor_thread_linux.cc
@@ -87,71 +87,77 @@ void LocalInputMonitorThread::Run() {
if (wakeup_pipe_[0] == -1)
return;
- scoped_x_record_context scoper;
-
// TODO(jamiewalch): We should pass the display in. At that point, since
// XRecord needs a private connection to the X Server for its data channel
// and both channels are used from a separate thread, we'll need to duplicate
// them with something like the following:
// XOpenDisplay(DisplayString(display));
display_ = XOpenDisplay(NULL);
- scoper.data_channel = XOpenDisplay(NULL);
- if (!display_ || !scoper.data_channel) {
- LOG(ERROR) << "Couldn't open X display";
- return;
- }
- int xr_opcode, xr_event, xr_error;
- if (!XQueryExtension(display_, "RECORD", &xr_opcode, &xr_event, &xr_error)) {
- LOG(ERROR) << "X Record extension not available.";
- return;
- }
+ // Inner scope needed here, because the |scoper| destructor may call into
+ // LocalKeyPressed() which needs |display_| to be still open.
+ {
+ scoped_x_record_context scoper;
+ scoper.data_channel = XOpenDisplay(NULL);
+ if (!display_ || !scoper.data_channel) {
+ LOG(ERROR) << "Couldn't open X display";
+ return;
+ }
- scoper.range[0] = XRecordAllocRange();
- scoper.range[1] = XRecordAllocRange();
- if (!scoper.range[0] || !scoper.range[1]) {
- LOG(ERROR) << "XRecordAllocRange failed.";
- return;
- }
- scoper.range[0]->device_events.first = MotionNotify;
- scoper.range[0]->device_events.last = MotionNotify;
- scoper.range[1]->device_events.first = KeyPress;
- scoper.range[1]->device_events.last = KeyRelease;
- XRecordClientSpec client_spec = XRecordAllClients;
-
- scoper.context = XRecordCreateContext(
- scoper.data_channel, 0, &client_spec, 1, scoper.range,
- arraysize(scoper.range));
- if (!scoper.context) {
- LOG(ERROR) << "XRecordCreateContext failed.";
- return;
- }
+ int xr_opcode, xr_event, xr_error;
+ if (!XQueryExtension(display_, "RECORD", &xr_opcode, &xr_event,
+ &xr_error)) {
+ LOG(ERROR) << "X Record extension not available.";
+ return;
+ }
- if (!XRecordEnableContextAsync(scoper.data_channel, scoper.context,
- ProcessReply,
- reinterpret_cast<XPointer>(this))) {
- LOG(ERROR) << "XRecordEnableContextAsync failed.";
- return;
- }
+ scoper.range[0] = XRecordAllocRange();
+ scoper.range[1] = XRecordAllocRange();
+ if (!scoper.range[0] || !scoper.range[1]) {
+ LOG(ERROR) << "XRecordAllocRange failed.";
+ return;
+ }
+ scoper.range[0]->device_events.first = MotionNotify;
+ scoper.range[0]->device_events.last = MotionNotify;
+ scoper.range[1]->device_events.first = KeyPress;
+ scoper.range[1]->device_events.last = KeyRelease;
+ XRecordClientSpec client_spec = XRecordAllClients;
+
+ scoper.context = XRecordCreateContext(
+ scoper.data_channel, 0, &client_spec, 1, scoper.range,
+ arraysize(scoper.range));
+ if (!scoper.context) {
+ LOG(ERROR) << "XRecordCreateContext failed.";
+ return;
+ }
+
+ if (!XRecordEnableContextAsync(scoper.data_channel, scoper.context,
+ ProcessReply,
+ reinterpret_cast<XPointer>(this))) {
+ LOG(ERROR) << "XRecordEnableContextAsync failed.";
+ return;
+ }
- bool stopped = false;
- while (!stopped) {
- while (XPending(scoper.data_channel)) {
- XEvent ev;
- XNextEvent(scoper.data_channel, &ev);
+ bool stopped = false;
+ while (!stopped) {
+ while (XPending(scoper.data_channel)) {
+ XEvent ev;
+ XNextEvent(scoper.data_channel, &ev);
+ }
+ fd_set read_fs;
+ FD_ZERO(&read_fs);
+ FD_SET(ConnectionNumber(scoper.data_channel), &read_fs);
+ FD_SET(wakeup_pipe_[0], &read_fs);
+ select(FD_SETSIZE, &read_fs, NULL, NULL, NULL);
+ stopped = FD_ISSET(wakeup_pipe_[0], &read_fs);
}
- fd_set read_fs;
- FD_ZERO(&read_fs);
- FD_SET(ConnectionNumber(scoper.data_channel), &read_fs);
- FD_SET(wakeup_pipe_[0], &read_fs);
- select(FD_SETSIZE, &read_fs, NULL, NULL, NULL);
- stopped = FD_ISSET(wakeup_pipe_[0], &read_fs);
+
+ // Context must be disabled via the control channel because we can't send
+ // any X protocol traffic over the data channel while it's recording.
+ XRecordDisableContext(display_, scoper.context);
+ XFlush(display_);
}
- // Context must be disabled via the control channel because we can't send any
- // X protocol traffic over the data channel while it's recording.
- XRecordDisableContext(display_, scoper.context);
- XFlush(display_);
XCloseDisplay(display_);
display_ = NULL;
}