Okay, well, tonight I decided to check for timer functions and found them and
came up with the following. The only quesiton I have is if the Stop() routine
loop of 4 checks is okay or if slow X server/client communcations would matter?
Wouldn't it all just be sent down? maybe use Fl::flush instead?
//
// class to keep FLTK splash windows alive
//
class CFLTKKeepAlive
{
// IMPORTANT NOTE: Even though this using custom timer values
// SIGRTMIN through SIGRTMAX and not SIGALRM, it causes sleep,
// usleep, etc.. to return as soon as the signal occurs. see
// the manual for sleep and usleep, which only discus SIGALRM,
// for details.
protected:
static timer_t TimerID; // timer id created
// signal handler
static void SignalHandler(int signo, siginfo_t *info, void *context);
public:
static int SigNum; // signal number being used
// start the keep alive timer.
static int Start(int signum=SIGRTMIN, unsigned intervalms=250);
// stop the keep alive timer
static void Stop();
};
//-------------------
// static variables
//-------------------
timer_t CFLTKKeepAlive::TimerID=0;
int CFLTKKeepAlive::SigNum=0;
//-------------------------------------------------------------------------
// Purpose: Start the keep alive process
//
// Input: signum - [i] custom signum to use (SIGRTMIN to SIGRTMAX)
//
// Output: -1 on failure (with errno set) otherwise 0.
//
// Notes: sleep/usleep within same thread will return as soon as a
// signal is issued from this keep alive process. see sleep
// and usleep documentation for details.
//
int CFLTKKeepAlive::Start(int signum, unsigned intervalms)
{
// presume failure
int result=-1;
// setup the sigaction first to ensure our callback is used
struct sigaction sigact;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags=SA_SIGINFO;
sigact.sa_sigaction=CFLTKKeepAlive::SignalHandler;
if (sigaction(signum, &sigact, NULL)!=-1) {
// call back setup for signum so init tracking variable
SigNum=signum;
// now we need to create a timer that will cause a signal
struct sigevent sigev;
sigev.sigev_notify=SIGEV_SIGNAL;
sigev.sigev_signo=SigNum;
sigev.sigev_value.sival_ptr=&TimerID;
if (timer_create(CLOCK_REALTIME, &sigev, &TimerID)==0) {
// setup the internval
struct itimerspec itval;
struct itimerspec oitval;
itval.it_value.tv_sec=intervalms/1000;
itval.it_value.tv_nsec=(intervalms%1000)*1000000;
itval.it_interval.tv_sec=itval.it_value.tv_sec;
itval.it_interval.tv_nsec=itval.it_value.tv_nsec;
// set and start the timer interval
if (timer_settime(TimerID, 0, &itval, &oitval)==0) {
result=0;
}
else Stop();
}
else Stop();
}
// indicate if keep alive setup completed
return result;
}
//-------------------------------------------------------------------------
// Purpose: Stop the keep alive process
//
// Input: na
//
// Output: na
//
// Notes:
//
void CFLTKKeepAlive::Stop()
{
// determine if timer appears started
if (TimerID!=0) {
timer_delete(TimerID);
TimerID=0;
}
// reassign signal to be ignored
if (SigNum!=0) {
signal(SigNum, SIG_IGN);
SigNum=0;
}
// ensure window is removed and background drawn
for (UINT i=0;i<4;i++) {
Fl::check();
}
}
//-------------------------------------------------------------------------
// Purpose: Signal handler to keep FLTK popup splash windows responsive
//
// Input: signum - [i] signal number occuring
// info - [i]
// context - [i]
//
// Output: na
//
// Notes:
//
void CFLTKKeepAlive::SignalHandler(int signum, siginfo_t *info, void *context)
{
if (signum==SigNum) {
Fl::check();
}
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk