So based on what I wrote last. Here's the improved CFLTKKeepAlive class should anyone else find it useful for popup splash windows in the same thread under Linux/X.
// // 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(unsigned waitms=0); }; //------------------- // 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(0); } else Stop(0); } // indicate if keep alive setup completed return result; } //------------------------------------------------------------------------- // Purpose: Stop the keep alive process // // Input: waitms - [i] time wait for x event to be reported // // Output: na // // Notes: // void CFLTKKeepAlive::Stop(unsigned waitms) { // 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; } // wait for events from xserver due to removed window unsigned i; for (i=0;i<waitms && !Fl::wait(0.001);i++); // wait for no more events or timeout // (at minimum there needs to be one Fl::check after the loop above // for fltk to send the draws to the server) for (;i<waitms && Fl::wait(0.001);i++); } //------------------------------------------------------------------------- // 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 fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk