Skip to content

Commit

Permalink
Add handler for thread messages (STR #1536)
Browse files Browse the repository at this point in the history
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@5683 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
  • Loading branch information
michaelrsweet committed Feb 8, 2007
1 parent 057e542 commit 6e9a163
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 45 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -2,6 +2,8 @@ CHANGES IN FLTK 1.1.8

- Documentation fixes (STR #1454, STR #1455, STR #1456,
STR #1457, STR #1458, STR #1460, STR #1481, STR #1578)
- Added Fl::set_awake_cb() to set a handler for thread
messages (STR #1536)
- Added "mute sound" option to Sudoku game.
- Updated the bundled zlib to v1.2.3.
- Updated the bundled libpng to v1.2.16.
Expand Down
2 changes: 2 additions & 0 deletions FL/Fl.H
Expand Up @@ -78,6 +78,7 @@ public: // should be private!
static void damage(int d) {damage_ = d;}

static void (*idle)();
static void (*awake_cb)(void *);

static const char* scheme_;
static Fl_Image* scheme_bg_;
Expand Down Expand Up @@ -266,6 +267,7 @@ public:
static void lock();
static void unlock();
static void awake(void* message = 0);
static void set_awake_cb(void (*cb)(void *)) { awake_cb = cb; }
static void* thread_message();

// Widget deletion:
Expand Down
17 changes: 8 additions & 9 deletions documentation/Fl.html
Expand Up @@ -126,6 +126,7 @@ <H3>Methods</H3>
<LI><A HREF="#Fl.selection_owner">selection_owner</A></LI>
<LI><A HREF="#Fl.set_abort">set_abort</A></LI>
<LI><A HREF="#Fl.set_atclose">set_atclose</A></LI>
<LI><A HREF="#Fl.set_awake_cb">set_awake_cb</A></LI>
<LI><A HREF="#Fl.set_boxtype">set_boxtype</A></LI>
<LI><A HREF="#Fl.set_color">set_color</A></LI>
<LI><A HREF="#Fl.set_font">set_font</A></LI>
Expand Down Expand Up @@ -390,17 +391,11 @@ <H4><A NAME="Fl.atclose">void (*atclose)(Fl_Window*,void*);</A></H4>

<H4><A NAME="Fl.awake">void awake(void *p);</A></H4>

<P>The <TT>awake()</TT> method sends a message pointer to the
main thread, causing any pending <TT>wait()</TT> call to
terminate so that the main thread can retrieve the message and
any pending redraws can be processed.
<P>The <TT>awake()</TT> method sends a message pointer to the main thread, causing any pending <A HREF="#Fl.wait"><TT>Fl::wait()</TT></A> call to terminate so that the main thread can retrieve the message and any pending redraws can be processed.

<P>Multiple calls to <TT>awake()</TT> will overwrite the same
message pointer.
<A HREF="#Fl.thread_message"><TT>thread_message()</TT></A> only returns
the last message stored by the last <TT>awake()</TT> call.
<P>Multiple calls to <TT>Fl::awake()</TT> will queue multiple pointers for the main thread to process, up to a system-defined (typically several thousand) depth. The default message handler saves the last message which can be accessed using the <A HREF="#Fl.thread_message"><TT>Fl::thread_message()</TT></A> function. Use the <A HREF="#Fl.set_awake_cb"><TT>Fl::set_awake_cb()</TT></A> function to register your own thread message handler that is called for every message received by the main thread.

<P>See also: <a href="advanced.html#multithreading">multithreading</a>
<P>See also: <a href="advanced.html#multithreading">multithreading</a>.

<H4><A NAME="Fl.background2">void background2(uchar, uchar, uchar);</A></H4>

Expand Down Expand Up @@ -1174,6 +1169,10 @@ <H4><A NAME="Fl.set_abort">void set_abort(void (*f)(const char*,...));</A></H4>

<H4><A NAME="Fl.set_atclose">void set_atclose(void (*f)(Fl_Window*,void*));</A></H4>

<H4><A NAME="Fl.set_awake_cb">void set_awake_cb(void (*cb)(void*));</A></H4>

<P>Sets a function to handle thread messages sent via the <A HREF="#Fl.awake"><TT>Fl::awake()</TT></A> function.</P>

<H4><A NAME="Fl.set_boxtype">void set_boxtype(Fl_Boxtype, Fl_Box_Draw_F*,uchar,uchar,uchar,uchar);<BR>
void set_boxtype(Fl_Boxtype, Fl_Boxtype from);</A></H4>

Expand Down
38 changes: 12 additions & 26 deletions documentation/advanced.html
Expand Up @@ -9,24 +9,13 @@ <H1 ALIGN="RIGHT"><A NAME="advanced">10 - Advanced FLTK</A></H1>
<P>This chapter explains advanced programming and design topics
that will help you to get the most out of FLTK.</P>

<H2><A NAME="multithreading">10.1 Multithreading</H2>
<H2><A NAME="multithreading">Multithreading</H2>

<P>FLTK supports multithreaded application using a locking mechanism
based on "pthreads". We do not provide a threading interface
as part of the library. However a simple example how threads can
be implemented for all supported platforms can be found in
<tt>test/threads.h</tt> and <tt>test/threads.cxx</tt>.
<P>FLTK supports multithreaded application using a locking mechanism based on "pthreads". We do not provide a threading interface as part of the library. However a simple example how threads can be implemented for all supported platforms can be found in <tt>test/threads.h</tt> and <tt>test/threads.cxx</tt>.

<P>To use the locking mechanism, the command line version of FLTK
must be compiled with <tt>--enable-threads</tt> set during the
<tt>configure</tt> process. IDE-based versions of FLTK are
automatically compiled with locking enabled if possible.
<P>To use the locking mechanism, FLTK must be compiled with <tt>--enable-threads</tt> set during the <tt>configure</tt> process. IDE-based versions of FLTK are automatically compiled with locking enabled if possible.

<P>In <TT>main()</TT>, before calling <TT>Fl::run()</TT>, call
<TT>Fl::lock()</TT>. This will startup the runtime multithreading
support for your program. All callbacks and derived functions
like <tt>handle()</tt> and <tt>draw()</tt> will now be properly
locked.
<P>In <TT>main()</TT>, call <TT>Fl::lock()</TT> before <TT>Fl::run()</TT> to start the runtime multithreading support for your program. All callbacks and derived functions like <tt>handle()</tt> and <tt>draw()</tt> will now be properly locked.

<pre>
main() {
Expand Down Expand Up @@ -56,34 +45,31 @@ <H2><A NAME="multithreading">10.1 Multithreading</H2>
<P>FLTK supports multiple platforms, some of them which do not
allow any other but the main thread to handle system events and
open or close windows. The safe thing to do is to adhere to the
following rulesi for threads on all operating systems.
following rules for threads on all operating systems:

<ul>

<li>don't <tt>show()</tt> or <tt>hide()</tt>anything that contains
<li>Don't <tt>show()</tt> or <tt>hide()</tt>anything that contains
widgets derived from <tt>Fl_Window</tt>, including dialogs, file
choosers, subwindows or <tt>Fl_GL_Window</tt>s</li>

<li>don't call <tt>Fl::wait()</tt>, <tt>Fl::flush()</tt> or any
<li>Don't call <tt>Fl::wait()</tt>, <tt>Fl::flush()</tt> or any
related methods that will handle system messages</li>

<li>don't start or cancel timers</li>
<li>Don't start or cancel timers</li>

<li>don't change window decorations or titles</li>
<li>Don't change window decorations or titles</li>

<li><tt>make_current()</tt> may or may not work well for regular
windows, but should always work for <tt>Fl_GL_Window</tt>s to
allow for high speed rendering on graphics cards with multiple
pipelines</li>
<li>The <tt>make_current()</tt> method may or may not work well for regular windows, but should always work for <tt>Fl_GL_Window</tt>s to allow for high speed rendering on graphics cards with multiple pipelines</li>

</ul>

<P>See also:
<a href="Fl.html#Fl.awake">void awake(void *message)</A>,
<a href="Fl.html#Fl.lock">void lock()</A>,
<a href="Fl.html#Fl.unlock">void unlock()</A>,
<a href="Fl.html#Fl.awake">void awake(void *message)</A>,
<a href="Fl.html#Fl.set_awake_cb">void set_awake_cb(void (*cb)(void *)</A>,
<a href="Fl.html#Fl.thread_message">void *thread_message()</A>.


</BODY>
</HTML>
4 changes: 2 additions & 2 deletions documentation/common.html
Expand Up @@ -533,15 +533,15 @@ <H4><A NAME="add_symbol">Making your own symbols</A></H4>
table using <tt>fl_add_symbol</tt>:</P>

<UL><PRE>
int fl_add_symbol(const char *name, void (*drawit)(Fl_Color), int scalable)
<A NAME="fl_add_symbol">int fl_add_symbol(const char *name, void (*drawit)(Fl_Color), int scalable)</A>
</PRE></UL>

<P><i>name</i> is the name of the symbol without the "@"; <i>scalable</I>
must be set to 1 if the symbol is generated using scalable vector drawing
functions.</P>

<UL><PRE>
int fl_draw_symbol(const char *name,int x,int y,int w,int h,Fl_Color col)
<A NAME="fl_draw_symbol">int fl_draw_symbol(const char *name,int x,int y,int w,int h,Fl_Color col)</A>
</PRE></UL>

<P>This function draw a named symbol fitting the given rectangle.
Expand Down
2 changes: 1 addition & 1 deletion documentation/drawing.html
Expand Up @@ -229,7 +229,7 @@ <h3><A name="lines">Line Dashes and Thickness</a></h3>
and Me due to the reduced drawing functionality these operating
systems provide.

<h4>void fl_line_style(int style, int width=0, char* dashes=0)</h4>
<h4><A NAME="fl_line_style">void fl_line_style(int style, int width=0, char* dashes=0)</A></h4>

<P>Set how to draw lines (the "pen"). If you change this it is your
responsibility to set it back to the default with
Expand Down
2 changes: 1 addition & 1 deletion documentation/examples.html
Expand Up @@ -4,7 +4,7 @@
</HEAD>
<BODY>

<H1 ALIGN="RIGHT"><A NAME="tests">I - Tests and Demo Source Code</A></H1>
<H1 ALIGN="RIGHT"><A NAME="examples">I - Tests and Demo Source Code</A></H1>

<P ALIGN="RIGHT">March 19, 2005</P>

Expand Down
6 changes: 4 additions & 2 deletions documentation/fltk.book
@@ -1,5 +1,5 @@
#HTMLDOC 1.8.20
-t pdf13 -f fltk.pdf --book --toclevels 2 --no-numbered --toctitle "Table of Contents" --title --titleimage FL.gif --linkstyle underline --size Universal --left 1.00in --right 0.50in --top 0.50in --bottom 0.50in --header .t. --footer h.1 --tocheader .t. --tocfooter ..i --duplex --portrait --color --no-pscommands --no-xrxcomments --compression=9 --jpeg=50 --no-embedfonts --fontsize 11.0 --fontspacing 1.2 --headingfont Helvetica --bodyfont Times --headfootsize 11.0 --headfootfont Helvetica --charset 8859-1 --links --no-truetype --pagemode outline --pagelayout single --firstpage c1 --pageeffect none --pageduration 10 --effectduration 1.0 --no-encryption --permissions all --owner-password "" --user-password "" --browserwidth 680
#HTMLDOC 1.8.27.1
-t pdf13 -f "fltk.pdf" --book --toclevels 2 --no-numbered --toctitle "Table of Contents" --title --titleimage "FL.gif" --linkstyle underline --size Universal --left 1.00in --right 0.50in --top 0.50in --bottom 0.50in --header .t. --header1 ... --footer h.1 --nup 1 --tocheader .t. --tocfooter ..i --duplex --portrait --color --no-pscommands --no-xrxcomments --compression=9 --jpeg=50 --fontsize 11.0 --fontspacing 1.2 --headingfont Helvetica --bodyfont Times --headfootsize 11.0 --headfootfont Helvetica --charset iso-8859-1 --links --no-embedfonts --pagemode outline --pagelayout single --firstpage c1 --pageeffect none --pageduration 10 --effectduration 1.0 --no-encryption --permissions all --owner-password "" --user-password "" --browserwidth 680 --strict --no-overflow
preface.html
intro.html
basics.html
Expand All @@ -11,6 +11,7 @@ subclassing.html
opengl.html
fluid.html
widgets.html
advanced.html
Fl.html
Fl_Adjuster.html
Fl_Bitmap.html
Expand Down Expand Up @@ -75,6 +76,7 @@ Fl_Scroll.html
Fl_Scrollbar.html
Fl_Secret_Input.html
Fl_Select_Browser.html
Fl_Shared_Image.html
Fl_Single_Window.html
Fl_Slider.html
Fl_Spinner.html
Expand Down
4 changes: 2 additions & 2 deletions documentation/intro.html
Expand Up @@ -335,8 +335,8 @@ <H2>Internet Resources</H2>
<DD><A href="mailto:fltk-bugs@fltk.org">fltk-bugs@fltk.org</A> [for
reporting bugs]

<DT>News</DT>
<DD><A HREF="news://news.easysw.com">news.easysw.com</A></DD>
<DT>NNTP Newsgroups</DT>
<DD>news.easysw.com</DD>

</DL>

Expand Down
2 changes: 1 addition & 1 deletion documentation/osissues.html
Expand Up @@ -136,7 +136,7 @@ <H4><A name="fl_xpixel">unsigned long fl_xpixel(Fl_Color i)<BR>
index or RGB color. This is the X pixel that <A
href="drawing.html#fl_color"><TT>fl_color()</TT></A> would use.

<H4><A name="fl_parse_color">int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b)</A></H4>
<H4><A name="fl_parse_color">int fl_parse_color(const char* p, uchar&amp; r, uchar&amp; g, uchar&amp; b)</A></H4>

<P>Convert a name into the red, green, and blue values of a color
by parsing the X11 color names. On other systems, <tt>fl_parse_color</tt>
Expand Down
14 changes: 14 additions & 0 deletions src/Fl_lock.cxx
Expand Up @@ -38,6 +38,14 @@
another. This file is an attempt to make minimal additions
and make them self-contained in this source file.
From Mike:
Starting with 1.1.8, we now have a callback so that you can
process awake() messages as they come in.
The API:
Fl::lock() - recursive lock. You must call this before the
first call to Fl::wait()/run() to initialize the thread
system. The lock is locked all the time except when
Expand All @@ -48,12 +56,17 @@
Fl::awake(void*) - Causes Fl::wait() to return (with the lock
locked) even if there are no events ready.
Fl::set_awake_cb(void (*cb)(void *)) - Registers a function
to call for Fl::awake() messages that is called for each
message received.
Fl::thread_message() - returns an argument sent to an
Fl::awake() call, or returns NULL if none. WARNING: the
current implementation only has a one-entry queue and only
returns the most recent value!
*/

void (*Fl::awake_cb)(void *);

////////////////////////////////////////////////////////////////
// Windows threading...
Expand Down Expand Up @@ -189,6 +202,7 @@ void* Fl::thread_message() {

static void thread_awake_cb(int fd, void*) {
read(fd, &thread_message_, sizeof(void*));
if (Fl::awake_cb) (*Fl::awake_cb)(thread_message_);
}

// These pointers are in Fl_x.cxx:
Expand Down
5 changes: 4 additions & 1 deletion src/Fl_win32.cxx
Expand Up @@ -291,8 +291,11 @@ int fl_wait(double time_to_wait) {
}
#endif

if (fl_msg.message == fl_wake_msg) // Used for awaking wait() from another thread
if (fl_msg.message == fl_wake_msg) {
// Used for awaking wait() from another thread
thread_message_ = (void*)fl_msg.wParam;
if (awake_cb) (*awake_cb)(thread_message_);
}

TranslateMessage(&fl_msg);
DispatchMessage(&fl_msg);
Expand Down

0 comments on commit 6e9a163

Please sign in to comment.