/* * This program demostrates a threading problem with FLTK on MinGW and * MSYS. The main thread should be able to process events from * windows shown in another thread, but in order to make this work on * MinGW, one must enable a hack. The hack causes the latest thread * that creates a window to take over event processing, since if it is * left to the main thread, the new windows remains invisible. * * The problem behavior has been observed on Windows XP, with MinGW * 3.1.0, MSYS 1.0.10, and FLTK 1.1.6. * * John D. Ramsdell -- January 2005 */ #define ENABLE_HACK #include #include #include #if defined HAVE_PTHREAD_H # include # include # define thread_exit() return 0 typedef pthread_t thread_t; typedef void *result_t; int thread_create(thread_t *t, void *(*f)(void *), void *p) { int i; pthread_attr_t a[1]; if (pthread_attr_init(a)) return EINVAL; if (pthread_attr_setdetachstate(a, PTHREAD_CREATE_DETACHED)) return EINVAL; i = pthread_create(t, a, f, p); if (pthread_attr_destroy(a)) return EINVAL; return i; } #elif defined WIN32 # include # include # include # define thread_exit() return typedef unsigned long thread_t; #define result_t void __cdecl int thread_create(thread_t *t, void (__cdecl *f)(void *), void *p) { *t = _beginthread(f, 0, p); if (*t != (thread_t)-1) return 0; else return errno; } #else #error "No thread package available" #endif Fl_Window *mkwin(); result_t run(void *data) { Fl::lock(); Fl_Window *window = mkwin(); window->show(); #if defined ENABLE_HACK Fl::run(); #endif Fl::awake(); Fl::unlock(); thread_exit(); } void run_callback(Fl_Widget *w, void *d) { thread_t t; thread_create(&t, run, 0); } int main(int argc, char **argv) { Fl::lock(); Fl_Window *window = mkwin(); window->show(argc, argv); return Fl::run(); } Fl_Window *mkwin() { Fl_Window *window = new Fl_Window(300,180); Fl_Button *button = new Fl_Button(20,40,260,100,"Spawn Thread"); button->box(FL_UP_BOX); button->labelsize(36); button->labelfont(FL_BOLD+FL_ITALIC); button->labeltype(FL_SHADOW_LABEL); button->callback(run_callback, window); window->end(); return window; }