Frameless/splash window

How can I make a frameless window (like xmms) or a splash image with SDL?–
Roger D. Vargas
ICQ: 117641572
Linux User: 180787

This was something I needed for TuxReader:
http://www.geekcomix.com/dm/tuxread/

The short answer is yes you can. The long answer is sort of… but the method
of doing it will probably be changing (since you have to modify the screen
surface’s flags (which are supposed to be read-only).

The way you can do it right now is:

  1. Create your screen surface passing SDL_NOFRAME as part of the init flags.

  2. Do your splashscreen.

  3. Toggle the SDL_NOFRAME flag on your screen surface -For example, if your
    surface is called “screen”, you’d have a line like this:
    screen->flags |= ~SDL_NOFRAME;

  4. Recreate the surface with another call to SDL_SetVideoMode(…)

However, we’re not s’posed to do this. About a week ago, SL said this was a
bug and that he’d look into it:
http://www.libsdl.org/pipermail/sdl/2001-August/038053.html

I think what is supposed to happen is when you recall SDL_SetVideoMode(…)
without SDL_NOFRAME, it should switch that flag off if it already on. (Which
is not what happens now, and why you have to do the kludge listed above ;-)On Thursday 30 August 2001 9:11am, Roger Dura?ona Vargas wrote:

How can I make a frameless window (like xmms) or a splash image with SDL?


Sam “Criswell” Hart <@Sam_Hart> AIM, Yahoo!:
Homepage: < http://www.geekcomix.com/snh/ >
PGP Info: < http://www.geekcomix.com/snh/contact/ >
Tux4Kids: < http://www.geekcomix.com/tux4kids/ >

First I thought this was a typo…
|= ~SDL_NOFRAME sets all bits except SDL_NOFRAME, which is already set!
What’s happening on the next SDL_SetVideoMode is (when I interpret the source
correctly): SDL thinks the current display has SDL_OPENGL enabled, but you
don’t request it in your new flags. SDL will then close the current window
and open a new one, probably because it can’t change the opengl-what-ever on
the fly.
Usually SDL tries to resize the window, but it seems to fail to change the
window’s frame on the fly. If there’s no other way to fix it, SDL should
close old/open new window when the SDL_NOFRAME flag changed (as I already
suggested).

bye.On Thursday 30 August 2001 21:36, you wrote:

On Thursday 30 August 2001 9:11am, Roger Dura?ona Vargas wrote:

How can I make a frameless window (like xmms) or a splash image with SDL?
[snip]

  1. Toggle the SDL_NOFRAME flag on your screen surface -For example, if your
    surface is called “screen”, you’d have a line like this:
    screen->flags |= ~SDL_NOFRAME;

    Benjamin Niemann (P!\K)
    pink at odahoda.de
    http://www.odahoda.de

How can I make a frameless window (like xmms) or a splash image with
SDL?

[snip]
3) Toggle the SDL_NOFRAME flag on your screen surface -For example, if
your surface is called “screen”, you’d have a line like this:
screen->flags |= ~SDL_NOFRAME;

First I thought this was a typo…

|= ~SDL_NOFRAME sets all bits except SDL_NOFRAME, which is already set!

You’re right, but it’s the only thing that I ever could figure out that would
work (I was a shocked as you are :wink:

What’s happening on the next SDL_SetVideoMode is (when I interpret the
source correctly): SDL thinks the current display has SDL_OPENGL enabled,
but you don’t request it in your new flags. SDL will then close the current
window and open a new one, probably because it can’t change the
opengl-what-ever on the fly.
Usually SDL tries to resize the window, but it seems to fail to change the
window’s frame on the fly. If there’s no other way to fix it, SDL should
close old/open new window when the SDL_NOFRAME flag changed (as I already
suggested).

You mean shutting down and restarting the SDL_VIDEO subsystem, right?

When all you want is a simple splashscreen, this isn’t very practical.

Ideally what should happen (and what I would expect to happen) is when you
re-call SDL_SetVideoMode(…) without SDL_NOFRAME it would wipe out the
previous SDL_NOFRAME flag. As it stands now, this doesn’t work, so you need
to do some sort of kludge (like listed above) if you really want it to work.

If I a) had time and b) had the ability, I’d look into the SDL source code
and see what’s up. Unfortunately, I have neither ;-)On Friday 31 August 2001 3:44am, Benjamin Niemann wrote:

On Thursday 30 August 2001 21:36, you wrote:

On Thursday 30 August 2001 9:11am, Roger Dura?ona Vargas wrote:


Sam “Criswell” Hart <@Sam_Hart> AIM, Yahoo!:
Homepage: < http://www.geekcomix.com/snh/ >
PGP Info: < http://www.geekcomix.com/snh/contact/ >
Tux4Kids: < http://www.geekcomix.com/tux4kids/ >

How can I make a frameless window (like xmms) or a splash image with
SDL?

[snip]
3) Toggle the SDL_NOFRAME flag on your screen surface -For example, if
your surface is called “screen”, you’d have a line like this:
screen->flags |= ~SDL_NOFRAME;

First I thought this was a typo…

|= ~SDL_NOFRAME sets all bits except SDL_NOFRAME, which is already
| set!

You’re right, but it’s the only thing that I ever could figure out that
would work (I was a shocked as you are :wink:

What’s happening on the next SDL_SetVideoMode is (when I interpret the
source correctly): SDL thinks the current display has SDL_OPENGL enabled,
but you don’t request it in your new flags. SDL will then close the
current window and open a new one, probably because it can’t change the
opengl-what-ever on the fly.
Usually SDL tries to resize the window, but it seems to fail to change
the window’s frame on the fly. If there’s no other way to fix it, SDL
should close old/open new window when the SDL_NOFRAME flag changed (as I
already suggested).

You mean shutting down and restarting the SDL_VIDEO subsystem, right?
No, I mean the way SDL handles the X window internally. What you discovered
is a SDL bug.

When all you want is a simple splashscreen, this isn’t very practical.

Ideally what should happen (and what I would expect to happen) is when you
re-call SDL_SetVideoMode(…) without SDL_NOFRAME it would wipe out the
previous SDL_NOFRAME flag. As it stands now, this doesn’t work, so you need
to do some sort of kludge (like listed above) if you really want it to
work.
That’s how it’s supposed to work - but it doesn’t, until it gets fixed. In
the meantime, you have to live with a workaround. Your solution can
effectively be reduced to ‘screen->flags |= SDL_OPENGL’ (assuming that you
don’t use opengl after the splash), but it’s a really dirty hack.

If I a) had time and b) had the ability, I’d look into the SDL source code
and see what’s up. Unfortunately, I have neither :wink:
Well, I already posted a fix (or at least something I believe should fix it -
I didn’t tested it so far…):
http://www.libsdl.org/pipermail/sdl/2001-August/038036.html

c yaOn Friday 31 August 2001 17:21, you wrote:

On Friday 31 August 2001 3:44am, Benjamin Niemann wrote:

On Thursday 30 August 2001 21:36, you wrote:

On Thursday 30 August 2001 9:11am, Roger Dura?ona Vargas wrote:


Benjamin Niemann (P!\K)
pink at odahoda.de
http://www.odahoda.de

Well, I made a quick proof of concept and here is a simple source that creates
a splash window, display an image and switch to fullscreen mode (by setting
video mode again). Seems to work, except that the splash screen appears in the
lower left corner of screen, and I suppose will appear in many different
places except the place that you want (middle of screen).
I haven’t tested it in Windows yet. BTW, I was looking at WM_ToggleFullScreen
and I was wondering about the current state of this function (portability
issues, etc) to achieve the same effect without resetting video mode.

#include <SDL.h>
#include <stdlib.h>

int main()
{
SDL_Surface *screen;
SDL_Surface *image;
SDL_Rect dest;

/* Initialize the SDL library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr,
            "Couldn't initialize SDL: %s\n", SDL_GetError());
    exit(1);
}

/* Clean up on exit */
atexit(SDL_Quit);

/* Initialize the display in a 640x480 frameless window */
screen = SDL_SetVideoMode(640, 480, 16, SDL_NOFRAME);
if ( screen == NULL ) {
    fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                    SDL_GetError());
    exit(1);
}

//Load and display splash
/* Load the BMP file into a surface /
image = SDL_LoadBMP(“splash.bmp”);
if ( image == NULL ) {
fprintf(stderr, “Couldn’t load sample.bmp: %s\n”,
SDL_GetError());
return 1;
}
/
Blit onto the screen surface */
dest.x = 0;
dest.y = 0;
dest.w = image->w;
dest.h = image->h;
SDL_BlitSurface(image, NULL, screen, &dest);

SDL_UpdateRects(screen, 1, &dest);

/* Free the allocated BMP surface */
SDL_FreeSurface(image);
SDL_Delay(4000);

//Go fullscreen mode
screen = SDL_SetVideoMode(640, 480, 16, SDL_FULLSCREEN);
if ( screen == NULL ) {
fprintf(stderr, “Couldn’t set 640x480x8 video mode: %s\n”,
SDL_GetError());
exit(1);
}
SDL_Delay(4000);
return 0;
}–
POSIBLE SPOILER!!!

  • El mayordomo es el asesino *

Roger D. Vargas
ICQ: 117641572
Linux User: 180787

This is fine, if you want the final window to be fullscreen.

If you want the final window (after splash screen) to be windowed with a
frame, that’s where the problem comes up.On Tuesday 04 September 2001 8:47am, Roger Dura?ona Vargas wrote:

Well, I made a quick proof of concept and here is a simple source that
creates a splash window, display an image and switch to fullscreen mode (by
setting video mode again). Seems to work, except that the splash screen
appears in the lower left corner of screen, and I suppose will appear in
many different places except the place that you want (middle of screen).


Sam “Criswell” Hart <@Sam_Hart> AIM, Yahoo!:
Homepage: < http://www.geekcomix.com/snh/ >
PGP Info: < http://www.geekcomix.com/snh/contact/ >
Tux4Kids: < http://www.geekcomix.com/tux4kids/ >