Fullscreen again

Thanks for your answers.

I have tested ToggleFullScreen under Windows and indeed it does not
work. For me that’s a real pity because one of the reason I switched to
SDL instead of my own code was to implement fullscreen under linux.
(Mine was awful). If I gain fs under linux but lose it under win, I
don’t progress much :slight_smile:
I am really talking about switching back and forth to fullscreen mode,
not initially creating a fullscreen window, which works well.
I wonder why this isn’t implemented. Is there a technical reason for
that, or just lack of time ? I would gladly contribute on this very
precise point if needed.

I am really talking about switching back and forth to fullscreen mode,
not initially creating a fullscreen window, which works well.
I wonder why this isn’t implemented. Is there a technical reason for
that, or just lack of time ? I would gladly contribute on this very
precise point if needed.

excuse me for butting in, but is it not possible for one to use the GLUT
fullscreen functions, or have i just said a rude word.

bill
programming hobbyist (GPL)

Christopher GAUTIER wrote:

I have tested ToggleFullScreen under Windows and indeed it does not
work. For me that’s a real pity because one of the reason I switched to
SDL instead of my own code was to implement fullscreen under linux.

you can always call SDL_SetVideoMode() a second (and third) time to
change between fullscreen and windowed display modes.

excuse me for butting in, but is it not possible for one to use the GLUT
fullscreen functions, or have i just said a rude word.

Probably not at the same time as SDL, since both have internal state
regarding GL contexts that would conflict.

–ryan.

I have tested ToggleFullScreen under Windows and indeed it does not
work. For me that’s a real pity because one of the reason I switched to
SDL instead of my own code was to implement fullscreen under linux.
(Mine was awful). If I gain fs under linux but lose it under win, I
don’t progress much :slight_smile:

I have some mostly-working code for toggling fullscreen/windowed in a
platform independent way with SDL. If anyone wants to
try/test/debug/comment upon, it’s at the bottom of this email.

SDL_WM_ToggleFullScreen() makes no promises to work, because the basic
assumption behind it is that your surface->pixels pointer won’t change.
Under X11, this assumption is valid, since the window itself isn’t
recreated; it’s just moved to the upper left corner, and the screen’s
resolution is changed to match the size of the window (that’s an
oversimplification, but that’s the gist of it).

Under Win32, you need to destroy the window, and recreate it with the
correct attributes, which means that the framebuffer might be/probably
will be somewhere else.

I am really talking about switching back and forth to fullscreen mode,
not initially creating a fullscreen window, which works well.
I wonder why this isn’t implemented. Is there a technical reason for
that, or just lack of time ? I would gladly contribute on this very
precise point if needed.

See above. If you can make SDL_WM_ToggleFullScreen() fit those assumptions
under Win32, go for it. Otherwise, look at this:

–ryan.

------------snip.-------------------

/*

  • (This code may be considered public domain, and under no licensing
  • restrictions. --rcg.)
    */

#define sdldebug printf

/**

  • Attempt to flip the video surface to fullscreen or windowed mode.
  • Attempts to maintain the surface’s state, but makes no guarantee
  • that pointers (i.e., the surface’s pixels field) will be the same
  • after this call.*
  • Caveats: Your surface pointers will be changing; if you have any other
  •       copies laying about, they are invalidated.
    
  •      Do NOT call this from an SDL event filter on Windows. You can
    
  •       call it based on the return values from SDL_PollEvent, etc, just
    
  •       not during the function you passed to SDL_SetEventFilter().
    
  •      Thread safe? Likely not.
    
  •      This has been tested briefly under Linux/X11 and Win/DirectX. YMMV.
    
  •      Palette setting is possibly/probably broken. Please fix.
    
  • @param surface pointer to surface ptr to toggle. May be different
  •              pointer on return. MAY BE NULL ON RETURN IF FAILURE!
    
  • @param flags pointer to flags to set on surface. The value pointed
  •              to will be XOR'd with SDL_FULLSCREEN before use. Actual
    
  •              flags set will be filled into pointer. Contents are
    
  •              undefined on failure. Can be NULL, in which case the
    
  •              surface's current flags are used.
    
  • @return non-zero on success, zero on failure.
    */
    static int attempt_fullscreen_toggle(SDL_Surface **surface, Uint32 *flags)
    {
    long framesize = 0;
    void *pixels = NULL;
    SDL_Rect clip;
    Uint32 tmpflags = 0;
    int w = 0;
    int h = 0;
    int bpp = 0;
    int grabmouse = (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
    int showmouse = SDL_ShowCursor(-1);

#ifdef BROKEN
SDL_Color *palette = NULL;
int ncolors = 0;
#endif

sdldebug("attempting to toggle fullscreen flag...");

if ( (!surface) || (!(*surface)) )  /* don't try if there's no surface. */
{
    sdldebug("Null surface (?!). Not toggling fullscreen flag.");
    return(0);
} /* if */

if (SDL_WM_ToggleFullScreen(*surface))
{
    sdldebug("SDL_WM_ToggleFullScreen() seems to work on this system.");
    if (flags)
        *flags ^= SDL_FULLSCREEN;
    return(1);
} /* if */

if ( !(SDL_GetVideoInfo()->wm_available) )
{
    sdldebug("No window manager. Not toggling fullscreen flag.");
    return(0);
} /* if */

sdldebug("toggling fullscreen flag The Hard Way...");
tmpflags = (*surface)->flags;
w = (*surface)->w;
h = (*surface)->h;
bpp = (*surface)->format->BitsPerPixel;

if (flags == NULL)  /* use the surface's flags. */
    flags = &tmpflags;

SDL_GetClipRect(*surface, &clip);

    /* save the contents of the screen. */
if ( (!(tmpflags & SDL_OPENGL)) && (!(tmpflags & SDL_OPENGLBLIT)) )
{
    framesize = (w * h) * ((*surface)->format->BytesPerPixel);
    pixels = malloc(framesize);
    if (pixels == NULL)
        return(0);
    memcpy(pixels, (*surface)->pixels, framesize);
} /* if */

#ifdef BROKEN
if ((*surface)->format->palette != NULL)
{
ncolors = (surface)->format->palette->ncolors;
palette = malloc(ncolors * sizeof (SDL_Color));
if (palette == NULL)
{
free(pixels);
return(0);
} /
if */
memcpy(palette, (surface)->format->palette->colors,
ncolors * sizeof (SDL_Color));
} /
if */
#endif

if (grabmouse)
    SDL_WM_GrabInput(SDL_GRAB_OFF);

SDL_ShowCursor(1);

*surface = SDL_SetVideoMode(w, h, bpp, (*flags) ^ SDL_FULLSCREEN);

if (*surface != NULL)
    *flags ^= SDL_FULLSCREEN;

else  /* yikes! Try to put it back as it was... */
{
    *surface = SDL_SetVideoMode(w, h, bpp, tmpflags);
    if (*surface == NULL)  /* completely screwed. */
    {
        if (pixels != NULL)
            free(pixels);
        if (palette != NULL)
            free(palette);
        return(0);
    } /* if */
} /* if */

/* Unfortunately, you lose your OpenGL image until the next frame... */

if (pixels != NULL)
{
    memcpy((*surface)->pixels, pixels, framesize);
    free(pixels);
} /* if */

#ifdef BROKEN
if (palette != NULL)
{
/* !!! FIXME : No idea if that flags param is right. */
SDL_SetPalette(surface, SDL_LOGPAL, palette, 0, ncolors);
free(palette);
} /
if */
#endif

SDL_SetClipRect(*surface, &clip);

if (grabmouse)
    SDL_WM_GrabInput(SDL_GRAB_ON);

SDL_ShowCursor(showmouse);

return(1);

} /* attempt_fullscreen_toggle */

I think that you can do it with #ifdefs, like this:

void ToggleFullScreen(void)
#ifdef unix
{
return(SDL_WM_Toggle_Fullscreen(screen));
}
#endif
#ifdef win32 /* is that correct? */
{

}
#endif

This might be incorrect and/or not what you want.On Sat, Oct 27, 2001 at 10:19:19PM +0200, Christopher GAUTIER wrote:

I have tested ToggleFullScreen under Windows and indeed it does not
work. For me that’s a real pity because one of the reason I switched to
SDL instead of my own code was to implement fullscreen under linux.
(Mine was awful). If I gain fs under linux but lose it under win, I
don’t progress much :slight_smile:

I have tested ToggleFullScreen under Windows and indeed it does not
work. For me that’s a real pity because one of the reason I switched
to

SDL_WM_ToggleFullScreen() makes no promises to work, because the basic
assumption behind it is that your surface->pixels pointer won’t
change.
Under X11, this assumption is valid, since the window itself isn’t

Is this the only problem? I mean ->pixels isn’t guaranteed to stay the
same even between surface locks. Simply require that surface isn’t
locked when you call _ToggleFullScreen(). Is there some another reason
this cannot be implemented for win32 pretty easily? Do we have all the
required information available to SDL to create exactly similar window
[for developer] in fullscreen and windowed modes? Or is the problem that
we don’t store all the flags and cannot re-create surface for
fullscreen?

It should be pretty much the same for YUV surface, shouldn’t it?

/*

  • (This code may be considered public domain, and under no licensing
  • restrictions. --rcg.)
    */
  • Caveats: Your surface pointers will be changing; if you have any
    other
  •       copies laying about, they are invalidated.
    

If this works otherwise I don’t see a problem. Someone will, probably.

  • Mikko

[…]

/*

  • (This code may be considered public domain, and under no licensing
  • restrictions. --rcg.)
    */
  • Caveats: Your surface pointers will be changing; if you have any

other

  •       copies laying about, they are invalidated.
    

If this works otherwise I don’t see a problem. Someone will, probably.

Well, the problem is that the so popular screen = SDL_SetVideoMode(…)
construct won’t work - the screen pointer would be invalid after a call
to SDL_WM_ToggleFullScreen(). There are countless SDL applications out
there that would start crashing.

Anyway, why not reuse the very memory occupied by the old SDL_Surface
struct, rather than creating a new one in new memory?

Make the SDL_Surface creation and freeing calls private, and remove the
SDL_Surface allocation/freeing calls. Wrap the private calls in new
functions that do the allocation/freeing. Use the private versions when
"replacing" the screen surface.

One possible problem remains: What if applications extract information
from the SDL_Surface struct, and SDL_WM_ToggleFullScreen() invalidates
this information? I’m not sure there’s any such information that you’re
really allowed to keep accross locked accesses of the surface. If there
isnt’t, “replacing” the surface struct should be about all that’s
required.

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Tuesday 30 October 2001 10:49, Mikko Rantalainen wrote: