Whoops!  We have a compatibility issue.

Since GLUT exits immediately, there are no more callbacks generated when the user clicks on the "x".  If we drop out of the freeglut main loop and then exit, then the idle callback may easily get called again.  (I know this because I was checking this out with a three-window application and it keeps crashing.)  Without the application defining a window destroy callback, there is no way for the application to find out that the window has been closed.  So when it tries to render the window in its idle callback, we get a "window ID %d not found!" warning from freeglut, followed by a program crash when I call "glutSwapBuffers".

So now it's time for a design decision.  Shall we:

(1) make the default behaviour absolutely compatible with GLUT and exit immediately, or

(2) make the default behaviour clean up after itself and possible break some GLUT applications?

John F. Fay

-----Original Message-----
From: Fay John F Contr AAC/WMG
Sent: Monday, October 28, 2002 10:24 AM
To: 'freeglut-developer@lists.sourceforge.net'
Subject: RE: [Freeglut-developer] RE: Window Destruction Callback

Here is my latest cut at the window-closing issue.  The files aren't on CVS yet ... and my latest files exist only on my disk.  I want to hear what other people say before I inflict them on the community.

(1) There are now three defined constants in "freeglut.h":

#define GLUT_ACTION_EXIT                         0

There is also a variable in the "fgState" structure called "ActionOnWindowClose", whose default value is GLUT_ACTION_EXIT.

(2) There is a new interface function "glutSetOption" by which the programmer can change the value of "ActionOnWindowClose" and a new option in "glutGet" which allows him to retrieve the current value.

(3) There is a new enumerated variable in "fgState" called "ExecState".  Its allowed values are "GLUT_EXEC_STATE_INIT", "GLUT_EXEC_STATE_RUNNING", and "GLUT_EXEC_STATE_STOP".  The value is ...

        - initialized to "INIT" at compile time and in "fgDeinitialize"
        - set to "RUNNING" in "glutMainLoop" just before the code enters the main loop
        - set to "STOP" if (1) all windows are closed, (2) there are no new messages (Win32 version--replacing the "bLoop" variable), or (3) the user has closed a window by clicking on its "x" (see (5) below).

(4) The "glutMainLoop" code stays in its main loop as long as the "ExecState" variable keeps the "RUNNING" value.

(5) If the user clicks on the "x" to close a window which is not the last window open, then
        - if the action at window close is "continue execution", execution continues with the other windows
        - otherwise "ExecState" is set to "STOP" and the main loop will stop at the end of its current iteration.
If the user clicks on the "x" to close the last window, then there will be no more windows (unless the destroy window callback creates a new one) and the "ExecState" flag will be set to "STOP" in the main loop because there are no more windows open.

(6) At the end of the "glutMainLoop" code after the actual main loop itself, there is a call to "fgCleanUpGlutsMess" which closes any open windows and (when we get it written completely) do anything else that needs doing.  There is also a call to "fgDeinitialize" which may have some code that we want to move to "fgCleanUpGlutsMess".

(7) At the end of "glutMainLoop", if the action on window close is "exit", the program exits.  Otherwise it returns control to the calling function.

Please note that GLUT's behaviour, that the application exits immediately, is no longer supported (although the default behaviour is close enough to GLUT that nobody should notice anything except a possible improvement.)

Once again, I am open for comments.  This is most definitely a work in progress.

John F. Fay

-----Original Message-----
From: Stephen J Baker [mailto:sjbaker@link.com]
Sent: Monday, October 28, 2002 8:20 AM
To: Fay John F Contr AAC/WMG
Subject: RE: [Freeglut-developer] RE: Window Destruction Callback

On Thu, 24 Oct 2002, Fay John F Contr AAC/WMG wrote:

>       The primary difference between what you are saying and what I am
> saying is in the question of using the "x" to close windows before the last
> window.  GLUT kills the application, period.  And if freeglut is going to
> imitate GLUT, then freeglut needs to kill the application, period.  My
> customer doesn't like that--and I don't either--and so I propose the option
> to continue execution.

Oh - I thought GLUT only killed the application when you 'X'ed the last

OK - then you are right and we need something better than I proposed.

The glutSetOption thingy now needs (IMHO) two enumerations:

  * What to do when the LAST window is closed.
  * What to do when any other window is closed.

>       There are actually three issues at hand.
> (1) Should we have a "destroy function" callback?  I think we both agree
> that the answer is yes.  It is nice to have for cases when the application
> calls "glutDestroyWindow" and it is absolutely necessary if we are going to
> allow the user to click on the "x" (on some window which is not the last
> one) and have execution continue.


> (2) What should happen when the user clicks on the "x" on a window which is
> not the last?  I see three options:  continue execution, close all windows
> and return from the main loop, or exit immediately.

Yes.  'continue execution' meaning - call the destroy function callback,
then destroy the window - then carry on running UNLESS it was the last
window - in which case we need another option:

> I submit that if the user clicks on the "x" in a window which is not
> the last window we should at least allow the option of continuing the
> program execution.

Yes - I'm horrified that this isn't what GLUT does...but then I don't
do much multi-window stuff.

> (3) What should happen when the program closes the last window by any
> method?  I agree with you that there are only two options which make sense:
> return from the main loop or exit immediately.  The "glutMainLoop" function
> will not continue to execute if there are no windows open, so the "continue
> execution" option turns into "return from the main loop."

I guess so.  I was thinking of two separate flags - but once you've
set a flag that GLUT doesn't have, you are already admitting that your
program isn't GLUT-compatible - so it's not unreasonable to say that
glutMainLoop will always return if you select some non-GLUT option
for general window destruction because no existing program can fall
foul of that.

>       Actually, I see on reading your e-mail again that I have been
> confusing what are actually two separate options:  call "exit" from the main
> loop, and return from the main loop.  I hadn't really considered calling
> "exit" from the main loop because I was thinking that it would be redundant,
> given that the "exit immediately" option would do some GLUT cleanup.  But
> perhaps we should discard the notion of exiting from within the callback and
> instead make "exit immediately" mean "set a flag, drop out of the main loop,
> close all the windows in a civilized manner, and then exit."
>       The only issue of backwards compatibility is, as you say, with the
> option to return from the main loop.  And since we are setting the "exit
> immediately" option to be the default, existing applications won't need to
> be changed.

>       There is also another question, which we haven't really taken up
> yet:  do we want this window-closing behaviour to be selectable on a
> window-by-window basis, or do we want one behaviour fits all windows?

I'd suggest one-fits-all.  If you want your application to exit when
some windows are destroyed (type A) and not others (type B), then
you can handle that by telling freeglut:

  1) Don't exit on window destruction - ever.
  2) Register a close-window callback for type A windows which closes
     all the other windows and thereby triggers the program-exit.
  3) Register a close-window callback for type B windows which just
     closes that window.

>  In my
> fifty-window application, there are four basic windows that I can't live
> without, while the other forty-something come and go.  While it would be
> nice to have the behaviour selectable, it's not that important; I can just
> put the "exit" statement in the destroy callback.


In general, the less per-window behavior there is, the easier this
thing will be to understand.

Steve Baker                      (817)619-2657 (Vox/Vox-Mail)
L3Com/Link Simulation & Training (817)619-2466 (Fax)
Work: sjbaker@link.com           http://www.link.com
Home: sjbaker1@airmail.net       http://www.sjbaker.org