xmessage is no longer a required dependency due to the addition of
tinyfiledialogs. xmessage is an option, but there are both better
alternatives on Linux and backup options if xmessage and friends cannot
be found so it is not required.
libcurl is now a dependency, so the curl package needs to be installed
on Linux (very likely to already be there) along with the development
files (some distros have separate 'devel' packages).
Fixes: #265
The commands _ScreenX and _ScreenY got significantly slower due to the
need to wait for the GLUT thread to wake up and execute the glutGet()
command for them. We've already seen a few programs (including the IDE)
where this behavior completely grinds the program to a halt, so we
definitely can't keep it.
The simple solution here is to not call glutGet() on every _ScreenX/Y
command. Instead every time the idle/timer function runs we get the
current values for the relevant glutGet() variables and store them.
libqb_glut_get() then checks if the value being read is one of the ones
we read in the idle/timer functionand if so just returns the last read
value. By doing it this way the commands no longer has to wait on the
GLUT thread for the result.
Fairly straightfowrad, programs were randomly seg faulting on exit. This
was happening due to GLUT registering a cleanup function via atexit(),
which then gets called when exit() is called.
The issue happens when exit() is called on a thread other than the GLUT
thread, which leads to the exit() call then attempting to cleanup GLUT
while the other thread is still using it, which randomly leads to seg
faults.
Fixing this is slightly annoying. We cannot stop the GLUT thread, as
the basic GLUT API (which is used on Mac OS) simply does not offer a way
to exit the glutMainLoop() call. Thus the simplest solution is to simply
make sure we call exit() on the GLUT thread, which we can fairly easily
due via the message queue.
That being the case, a new libqb_exit() API was added, which simply
regsiters the GLUT exit message and then waits for the program to end.
The atexit() handler then runs on the GLUT thread and everything works
out fine.
In the future we probably should redo the exit logic a bit so that all
the threads are actually stopped/joined to ensure the exit process is
consistent, however this is good enough for now. Also, there's plenty of
error states which call exit() which I did not address.
With the recent changes to libqb.cpp to pull out some of the GLUT logic,
the only actual Objective-C in libqb.cpp was pulled out. That being the
case, it's no longer necessary to have libqb.mm for compiling libqb.cpp,
so we're removing it to simplify the compliation logic a bit.
This fixes all the code so that all the calls to glut functions
happen on the same thread that is running GLUT.
We achieve this by creating a queue of GLUT commands to execute.
Commands can be added to the queue anywhere in the code, and then the
queue is processed on the GLUT thread via it's idle func or timer func.
The command is run and if necessary the result is provided in the
message queue object. Each object contains a completion which can be
waited on to block until the GLUT thread has processed the command.
Fixes: #66
Xvfb is being used to give us an X server implementation on the Linux
build agents. A running X server is necessary for graphics to function
(which we have so far avoided testing).
These tests cover all the commands that generally interact with GLUT.
The ensure that these functions can be used at the very beginning of a
program with no issues. Additionally they verify the behavior of these
functions in the presence of `$SCREENHIDE`, and also `_ScreenHide`.
This was overlooked in #258, previously this printing was being skipped
over via a check of idemode, but after changing where it was located so
it only prints once it now runs when using the IDE, which screwed up the
drawing of the IDE screen.
The simple fix is to check for idemode before doing the printing, which
is effectively what it was doing before anyway.
Fixes: #266