Author: spitzak
Date: 2007-06-19 13:50:14 -0400 (Tue, 19 Jun 2007)
New Revision: 5916
Log:
Made fltk::in_main_thread() much more reliable and made it work without
having to grab the fltk::lock().

Made fltk::awake() work without having to grab the fltk::lock().


Modified:
   trunk/fltk/run.h
   trunk/src/MenuBar.cxx
   trunk/src/ScrollGroup.cxx
   trunk/src/lock.cxx
   trunk/src/osx/run.cxx
   trunk/src/run.cxx
   trunk/src/win32/lock.cxx
   trunk/src/win32/run.cxx
   trunk/src/x11/run.cxx

Modified: trunk/fltk/run.h
===================================================================
--- trunk/fltk/run.h    2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/fltk/run.h    2007-06-19 17:50:14 UTC (rev 5916)
@@ -79,13 +79,11 @@
 FL_API void add_fd(int fd, FileHandler, void* = 0);
 FL_API void remove_fd(int, int when = -1);
 
-extern FL_API bool in_main_thread_;
-
 FL_API void lock();
 FL_API void unlock();
 FL_API void awake(void* message = 0);
 FL_API void* thread_message();
-inline bool in_main_thread() {return in_main_thread_;}
+FL_API bool in_main_thread();
 
 }
 

Modified: trunk/src/MenuBar.cxx
===================================================================
--- trunk/src/MenuBar.cxx       2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/MenuBar.cxx       2007-06-19 17:50:14 UTC (rev 5916)
@@ -44,7 +44,6 @@
 #include <config.h>
 #include <fltk/Item.h> // for TOGGLE, RADIO
 #define checkmark(item) (item->type()>=Item::TOGGLE && 
item->type()<=Item::RADIO)
-#include <stdio.h>
 
 using namespace fltk;
 
@@ -104,7 +103,7 @@
       for (i = 0; i < children; i++) {
        Widget* w = child(i);
        if (w->active() && w->test_label_shortcut()) {
-         if (w->is_group()) {value(i); printf("Picking %s\n", w->label()); 
goto J1;} // menu title
+         if (w->is_group()) {value(i); goto J1;} // menu title
          focus_index(Group::find(w)); // Set focus_index, so Menu::get_item() 
works
          if (checkmark(w)) { w->invert_flag(STATE); redraw(); }
          execute(w); // button in the menu bar

Modified: trunk/src/ScrollGroup.cxx
===================================================================
--- trunk/src/ScrollGroup.cxx   2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/ScrollGroup.cxx   2007-06-19 17:50:14 UTC (rev 5916)
@@ -184,7 +184,7 @@
   int layout_damage = this->layout_damage();
 
   // handle movement in xy without wasting time:
-  if (!(layout_damage&(LAYOUT_WH|LAYOUT_DAMAGE))) {
+  if (!(layout_damage&(LAYOUT_WH|LAYOUT_DAMAGE|LAYOUT_CHILD))) {
     Group::layout();
     return;
   }

Modified: trunk/src/lock.cxx
===================================================================
--- trunk/src/lock.cxx  2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/lock.cxx  2007-06-19 17:50:14 UTC (rev 5916)
@@ -154,7 +154,7 @@
 # ifndef __USE_GNU
 #  define __USE_GNU // makes the RECURSIVE stuff appear on Linux
 # endif
-#include <fltk/Threads.h>
+# include <fltk/Threads.h>
 
 # if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && !defined(__CYGWIN__)
 static pthread_mutexattr_t recursive_attrib={PTHREAD_MUTEX_RECURSIVE_NP};
@@ -162,7 +162,7 @@
 # elif defined(PTHREAD_MUTEX_RECURSIVE)
 static pthread_mutexattr_t* recursive_attrib() {
   static pthread_mutexattr_t a;
-  static bool beenhere;
+  static bool beenhere = false;
   if (!beenhere) {
     pthread_mutexattr_init(&a);
     pthread_mutexattr_settype(&a,PTHREAD_MUTEX_RECURSIVE);
@@ -197,20 +197,27 @@
 
 static fltk::RecursiveMutex fltkmutex;
 
-static void lock_function() {fltkmutex.lock();}
-static void unlock_function() {fltkmutex.unlock();}
+static void lock_function() { fltkmutex.lock(); }
+static void unlock_function() { fltkmutex.unlock(); }
 
+static pthread_t main_thread_id;
+
+#if !USE_QUARTZ
 static void* thread_message_;
 static void thread_awake_cb(int fd, void*) {
   while (read(fd, &thread_message_, sizeof(void*)) > 0);
 }
 static int thread_filedes[2];
+#endif
 
 static void init_function() {
   // Init threads communication pipe to let threads awake FLTK from wait
+  main_thread_id = pthread_self();
   pipe(thread_filedes);
+#if !USE_QUARTZ
   fcntl(thread_filedes[0], F_SETFL, O_NONBLOCK);
   fltk::add_fd(thread_filedes[0], fltk::READ, thread_awake_cb);
+#endif
   fl_lock_function = init_or_lock_function = lock_function;
   fl_unlock_function = unlock_function;
   lock_function();
@@ -220,18 +227,24 @@
 
 void fltk::unlock() {fl_unlock_function();}
 
+bool fltk::in_main_thread() {
+  return init_or_lock_function == init_function || pthread_self() == 
main_thread_id;
+}
+
+#if !USE_QUARTZ
 void fltk::awake(void* msg) {
   write(thread_filedes[1], &msg, sizeof(void*));
 }
 
 // the following is already defined in CYGWIN
 // for the common win32/run.cxx part
-#if !defined(__CYGWIN__) 
+# if !defined(__CYGWIN__) 
 void* fltk::thread_message() {
   void* r = thread_message_;
   thread_message_ = 0;
   return r;
 }
+# endif
 #endif
 
 #else

Modified: trunk/src/osx/run.cxx
===================================================================
--- trunk/src/osx/run.cxx       2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/osx/run.cxx       2007-06-19 17:50:14 UTC (rev 5916)
@@ -215,22 +215,33 @@
        DEBUGMSG("reading from G_pipe\n");
        char buf[1]; read(G_pipe[0],buf,1);
       }
-      // wake up the main thread with a message:
-      EventRef drEvent;
-      CreateEvent( 0, kEventClassFLTK, kEventFLTKDataReady,
-                  0, kEventAttributeUserEvent, &drEvent);
-      PostEventToQueue(eventqueue, drEvent, kEventPriorityStandard);
+      fltk::awake();
     }
   }
 }
 
+static void* thread_message_;
+void fltk::awake(void* msg) {
+  thread_message_ = msg;
+  // wake up the main thread with a message:
+  EventRef drEvent;
+  CreateEvent( 0, kEventClassFLTK, kEventFLTKDataReady,
+               0, kEventAttributeUserEvent, &drEvent);
+  PostEventToQueue(eventqueue, drEvent, kEventPriorityStandard);
+}
+
+void* fltk::thread_message() {
+  void* r = thread_message_;
+  thread_message_ = 0;
+  return r;
+}
+
 // Main thread calls this when it gets the above data-ready message:
 // This does nothing right now because above code did the callbacks:
 static void HandleDataReady()
 {
 #if 0
   fl_lock_function();
-  in_main_thread_ = true;
   timeval t = { 0, 0 };                // quick check
   fd_set r = fdsets[0];
   fd_set w = fdsets[1];
@@ -251,7 +262,6 @@
       }
     }
   }
-  in_main_thread_ = false;
   fl_unlock_function();
 #endif
 }
@@ -364,9 +374,7 @@
       case kEventCommandProcess:
         GetEventParameter( event, kEventParamDirectObject, typeHICommand, 
NULL, sizeof(HICommand), NULL, &cmd );
        fl_lock_function();
-       in_main_thread_ = true;
         ret = HandleMenu( &cmd );
-       in_main_thread_ = false;
        fl_unlock_function();
         break;
     }
@@ -442,7 +450,6 @@
                   (void*)GetCurrentEventQueue());
   }
 
-  in_main_thread_ = false;
   fl_unlock_function();
 
   EventRef event;
@@ -474,7 +481,6 @@
     time = 0.0; // just peek for pending events
   }
   fl_lock_function();
-  in_main_thread_ = true;
 
   // we send LEAVE only if the mouse did not enter some other window:
   // I'm not sure if this is needed or if it works...
@@ -555,7 +561,6 @@
   OSStatus ret = noErr;
   Window *window = (Window*)userData;
   fl_lock_function();
-  in_main_thread_ = true;
 
   switch ( kind )
   {
@@ -615,7 +620,6 @@
     ret = eventNotHandledErr;
     break;
   }
-  in_main_thread_ = false;
   fl_unlock_function();
   return ret;
 }
@@ -637,7 +641,6 @@
                      NULL, sizeof(long), NULL, &delta );
   OSStatus ret = noErr;
   fl_lock_function();
-  in_main_thread_ = true;
   if ( axis == kEventMouseWheelAxisX ) {
     e_dx = -delta;
     e_dy = 0;
@@ -649,7 +652,6 @@
   } else {
     ret = eventNotHandledErr;
   }
-  in_main_thread_ = false;
   fl_unlock_function();
   return ret;
 }
@@ -691,7 +693,6 @@
 static pascal OSStatus carbonMouseHandler( EventHandlerCallRef nextHandler, 
EventRef event, void *userData )
 {
   fl_lock_function();
-  in_main_thread_ = true;
 
   os_event = event;
   Window *window = (Window*)userData;
@@ -713,18 +714,15 @@
     fix_xfocus(window);
     if ( FindWindow( pos, 0 ) != inContent ) {
       // let the OS handle clicks in the title bar
-      in_main_thread_ = false;
       fl_unlock_function();
       return CallNextEventHandler( nextHandler, event );
     }
     if ( !IsWindowActive( fltk::xid(window) ) ) {
       // let the OS handle the activation,
       // but continue to get a click-through effect
-      in_main_thread_ = false;
       fl_unlock_function();
       CallNextEventHandler( nextHandler, event );
       fl_lock_function();
-      in_main_thread_ = true;
     }
     os_capture = fltk::xid(window); // make all mouse events go to this window
     px = pos.h; py = pos.v;
@@ -756,7 +754,6 @@
     break;
   }
 
-  in_main_thread_ = false;
   fl_unlock_function();
   return noErr;
 }
@@ -845,7 +842,6 @@
   unsigned short sym;
 
   fl_lock_function();
-  in_main_thread_ = true;
   if (!xfocus) fix_xfocus((Window*)userData);
 
   switch ( GetEventKind( event ) )
@@ -912,7 +908,6 @@
     break; }
   }
   bool r = (sendEvent && handle(sendEvent, xfocus));
-  in_main_thread_ = false;
   fl_unlock_function();
   if (r) return noErr;
   return CallNextEventHandler( nextHandler, event );

Modified: trunk/src/run.cxx
===================================================================
--- trunk/src/run.cxx   2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/run.cxx   2007-06-19 17:50:14 UTC (rev 5916)
@@ -127,8 +127,6 @@
 }
 } /* extern "C" */
 
-bool fltk::in_main_thread_ = true;
-
 /*! Tries to make this widget be the keyboard focus widget, by first
   sending it an fltk::FOCUS event, and if it returns non-zero, setting
   fltk::focus() to this widget. You should use this method to assign

Modified: trunk/src/win32/lock.cxx
===================================================================
--- trunk/src/win32/lock.cxx    2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/win32/lock.cxx    2007-06-19 17:50:14 UTC (rev 5916)
@@ -17,21 +17,25 @@
   EnterCriticalSection(&cs);
 }
 
-static DWORD main_thread;
+static DWORD main_thread_id;
 
 static void init_function() {
   InitializeCriticalSection(&cs);
   lock_function();
   fl_lock_function = init_or_lock_function = lock_function;
   fl_unlock_function = unlock_function;
-  main_thread = GetCurrentThreadId();
+  main_thread_id = GetCurrentThreadId();
 }
 
 void fltk::lock() {init_or_lock_function();}
 
 void fltk::unlock() {fl_unlock_function();}
 
+bool fltk::in_main_thread() {
+  return init_or_lock_function == init_function || GetCurrentThreadId() == 
main_thread_id;
+}
+
 #define WM_MAKEWAITRETURN (WM_USER+0x401)
 void fltk::awake(void* msg) {
-  PostThreadMessage( main_thread, WM_MAKEWAITRETURN, (WPARAM)msg, 0);
+  PostThreadMessage( main_thread_id, WM_MAKEWAITRETURN, (WPARAM)msg, 0);
 }

Modified: trunk/src/win32/run.cxx
===================================================================
--- trunk/src/win32/run.cxx     2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/win32/run.cxx     2007-06-19 17:50:14 UTC (rev 5916)
@@ -424,14 +424,12 @@
 #endif // USE_ASYNC_SELECT
 
   if (!fl_ready()) {
-    in_main_thread_ = false;
     fl_unlock_function();
     int t_msec =
       time_to_wait < 2147483.647 ? int(time_to_wait*1000+.5) : 0x7fffffff;
     // int ret_val =
       MsgWaitForMultipleObjects(0, NULL, false, t_msec, QS_ALLINPUT);
     fl_lock_function();
-    in_main_thread_ = true;
   }
 
   // Execute all pending messages:

Modified: trunk/src/x11/run.cxx
===================================================================
--- trunk/src/x11/run.cxx       2007-06-19 17:49:29 UTC (rev 5915)
+++ trunk/src/x11/run.cxx       2007-06-19 17:50:14 UTC (rev 5916)
@@ -426,7 +426,6 @@
   fdt[2] = fdsets[2];
 #endif
 
-  in_main_thread_ = false;
   fl_unlock_function();
 #if USE_POLL
   int n = ::poll(pollfds, nfds,
@@ -443,7 +442,6 @@
   }
 #endif
   fl_lock_function();
-  in_main_thread_ = true;
 
   if (n > 0) {
     for (int i=0; i<nfds; i++) {

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to