x11 buttons are responsive now
This commit is contained in:
parent
b71e4e1a35
commit
da59dc9063
|
|
@ -24,12 +24,6 @@
|
|||
#include <sys/select.h>
|
||||
#include <signal.h>
|
||||
|
||||
// Sleeps for a short time.
|
||||
#define MILLISLEEP() \
|
||||
timespec ts; \
|
||||
ts.tv_sec = 0; ts.tv_nsec = 100000; \
|
||||
nanosleep(&ts, NULL);
|
||||
|
||||
// Clamps a value to two boundaries.
|
||||
#define clamp(x, lb, hb) (x < lb ? lb : (x > hb ? hb : x))
|
||||
|
||||
|
|
@ -45,6 +39,10 @@ P3DX11SplashWindow(P3DInstance *inst) :
|
|||
// Init for parent process
|
||||
_subprocess_pid = -1;
|
||||
|
||||
// Init for read thread
|
||||
_started_read_thread = false;
|
||||
INIT_THREAD(_read_thread);
|
||||
|
||||
// Init for subprocess
|
||||
_display = None;
|
||||
_window = None;
|
||||
|
|
@ -185,6 +183,11 @@ button_click_detected() {
|
|||
// This method is called in the child process, and must relay
|
||||
// the information to the parent process.
|
||||
cerr << "click detected\n";
|
||||
|
||||
TiXmlDocument doc;
|
||||
TiXmlElement *xcommand = new TiXmlElement("click");
|
||||
doc.LinkEndChild(xcommand);
|
||||
write_xml(_pipe_write, &doc, nout);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -198,18 +201,23 @@ void P3DX11SplashWindow::
|
|||
start_subprocess() {
|
||||
assert(_subprocess_pid == -1);
|
||||
|
||||
// Create a directional pipe to send messages to the sub-process.
|
||||
// (We don't need a receive pipe.)
|
||||
// Create a bi-directional pipe to communicate with the sub-process.
|
||||
int to_fd[2];
|
||||
if (pipe(to_fd) < 0) {
|
||||
perror("failed to create pipe");
|
||||
}
|
||||
int from_fd[2];
|
||||
if (pipe(from_fd) < 0) {
|
||||
perror("failed to create pipe");
|
||||
}
|
||||
|
||||
// Fork and exec.
|
||||
pid_t child = fork();
|
||||
if (child < 0) {
|
||||
close(to_fd[0]);
|
||||
close(to_fd[1]);
|
||||
close(from_fd[0]);
|
||||
close(from_fd[1]);
|
||||
perror("fork");
|
||||
return;
|
||||
}
|
||||
|
|
@ -220,6 +228,8 @@ start_subprocess() {
|
|||
// Open the read end of the pipe, and close the write end.
|
||||
_pipe_read.open_read(to_fd[0]);
|
||||
close(to_fd[1]);
|
||||
_pipe_write.open_write(from_fd[1]);
|
||||
close(from_fd[0]);
|
||||
|
||||
subprocess_run();
|
||||
_exit(0);
|
||||
|
|
@ -229,6 +239,10 @@ start_subprocess() {
|
|||
_subprocess_pid = child;
|
||||
_pipe_write.open_write(to_fd[1]);
|
||||
close(to_fd[0]);
|
||||
_pipe_read.open_read(from_fd[0]);
|
||||
close(from_fd[1]);
|
||||
|
||||
spawn_read_thread();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -300,6 +314,8 @@ stop_subprocess() {
|
|||
} else if (WIFSTOPPED(status)) {
|
||||
nout << " stopped by " << WSTOPSIG(status) << "\n";
|
||||
}
|
||||
|
||||
join_read_thread();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -343,9 +359,76 @@ check_stopped() {
|
|||
}
|
||||
|
||||
_subprocess_pid = -1;
|
||||
join_read_thread();
|
||||
|
||||
_inst->request_stop();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::spawn_read_thread
|
||||
// Access: Private
|
||||
// Description: Starts the read thread. We need this thread to
|
||||
// listen for feedback from the subprocess. (At the
|
||||
// moment, the only kind of feedback we might receive is
|
||||
// whether the button has been clicked.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
spawn_read_thread() {
|
||||
SPAWN_THREAD(_read_thread, rt_thread_run, this);
|
||||
_started_read_thread = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::join_read_thread
|
||||
// Access: Private
|
||||
// Description: Waits for the read thread to stop.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
join_read_thread() {
|
||||
if (!_started_read_thread) {
|
||||
return;
|
||||
}
|
||||
|
||||
JOIN_THREAD(_read_thread);
|
||||
_started_read_thread = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::rt_thread_run
|
||||
// Access: Private
|
||||
// Description: The main function for the read thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
rt_thread_run() {
|
||||
while (true) {
|
||||
TiXmlDocument *doc = read_xml(_pipe_read, nout);
|
||||
if (doc == NULL) {
|
||||
// Some error on reading.
|
||||
return;
|
||||
}
|
||||
|
||||
// Successfully read an XML document.
|
||||
rt_handle_request(doc);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::rt_handle_request
|
||||
// Access: Private
|
||||
// Description: Processes a single request or notification received
|
||||
// from an instance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
rt_handle_request(TiXmlDocument *doc) {
|
||||
// Eh, don't even bother decoding the XML. We know it can only be a
|
||||
// click notification.
|
||||
delete doc;
|
||||
|
||||
ACQUIRE_LOCK(_api_lock);
|
||||
P3DSplashWindow::button_click_detected();
|
||||
RELEASE_LOCK(_api_lock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::subprocess_run
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -51,11 +51,26 @@ private:
|
|||
void stop_subprocess();
|
||||
void check_stopped();
|
||||
|
||||
void spawn_read_thread();
|
||||
void join_read_thread();
|
||||
|
||||
private:
|
||||
// These methods run only within the read thread.
|
||||
THREAD_CALLBACK_DECLARATION(P3DX11SplashWindow, rt_thread_run);
|
||||
void rt_thread_run();
|
||||
void rt_terminate();
|
||||
void rt_handle_request(TiXmlDocument *doc);
|
||||
|
||||
private:
|
||||
// Data members that are stored in the parent process.
|
||||
pid_t _subprocess_pid;
|
||||
HandleStream _pipe_read;
|
||||
HandleStream _pipe_write;
|
||||
|
||||
// The remaining members are manipulated by or for the read thread.
|
||||
bool _started_read_thread;
|
||||
THREAD _read_thread;
|
||||
|
||||
private:
|
||||
// These methods run only within the subprocess.
|
||||
class X11ImageData;
|
||||
|
|
@ -93,7 +108,6 @@ private:
|
|||
X11ImageData _button_click_image;
|
||||
|
||||
bool _subprocess_continue;
|
||||
HandleStream _pipe_read;
|
||||
|
||||
bool _own_display;
|
||||
string _install_label;
|
||||
|
|
|
|||
Loading…
Reference in New Issue