The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
SDL_CreateWindowFrom and blocking SDL_CreateRenderer
Alvin Beach
Guest

Hello,

I am working on updating an older application that uses SDL 1.2 where, the main SDL_Surface is embedded into another window. This works great with SDL
1.2.

However, I am having issues doing the same with SDL2, but with SDL_Window (not SDL_Surface). I call SDL_CreateWindowFrom() when I have the window
handle. It seems to work just fine as I do get a non-NULL pointer. However, calling SDL_CreateRenderer() just hangs. I've stepped through
SDL_CreateRenderer() and it appears to block here:

SDL_x11window.c:X11_HideWindow:

...

/* Blocking wait for "UnmapNotify" event */
X11_XIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow); //<--- hangs here
...

I have a suspicion that the X11 events are being consumed by the application toolkit (FLTK) and not are not reaching SDL2.

Does anyone have any experience with embedding a SDL2 SDL_Window inside of another window? Or any insights on how it is done differently than SDL 1.2?
Any information or advice would be greatly appreciated. Thanks.

Cheers,

Alvin
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
SDL_CreateWindowFrom and blocking SDL_CreateRenderer
Alvin Beach
Guest

After some troubleshooting, it appears that the SDL_CreateWindowFrom()
works just fine. However, SDL_CreateRender() hangs.

From what I can see, when creating the renderer, the window is checked
if it has the SDL_WINDOW_OPENGL flag set. If it does not (it doesn't I
know that for sure), SDL_RecreateWindow() is called. Eventually, the
window is unmapped via SDL_HideWindow(). On my machine, this calls
X11_HideWindow(). That is where it is hanging.

X11_HideWindow() withdraws the window, but then waits indefinitely for
an UnmapNotify event. I stuck a SDL_Log() in isUnmapNotify() and it
appears that this event is never received. I do see a DestroyNotify
event (17) but the Window ID doesn't match what it is waiting for.

Interestingly, if I comment out this line (i.e. X11_XIfEvent(...)),
everything appears to work just fine (the SDL_Window embedded in my
app). I've also commented out the equivalent line in X11_ShowWindow().

My definition of "just fine" is very very limited. I cleared the
renderer with an arbitrary colour and drew a filled rectangle at the
centre of the window. Not very thorough, but it appeared when
SDL_RenderPresent() was called.

I'm fairly sure that not consuming the UnmapNotify and MapNotify
events is likely not a good thing. Is there something else that could
be done? Perhaps using the commented out X11_XIfEventTimeout() in
SDL_x11window.c?

On Fri, Jul 25, 2014 at 3:11 PM, Alvin Beach wrote:
Quote:
Hello,

I am working on updating an older application that uses SDL 1.2 where, the main SDL_Surface is embedded into another window. This works great with SDL
1.2.

However, I am having issues doing the same with SDL2, but with SDL_Window (not SDL_Surface). I call SDL_CreateWindowFrom() when I have the window
handle. It seems to work just fine as I do get a non-NULL pointer. However, calling SDL_CreateRenderer() just hangs. I've stepped through
SDL_CreateRenderer() and it appears to block here:

SDL_x11window.c:X11_HideWindow:

...

/* Blocking wait for "UnmapNotify" event */
X11_XIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow); //<--- hangs here
...

I have a suspicion that the X11 events are being consumed by the application toolkit (FLTK) and not are not reaching SDL2.

Does anyone have any experience with embedding a SDL2 SDL_Window inside of another window? Or any insights on how it is done differently than SDL 1.2?
Any information or advice would be greatly appreciated. Thanks.

Cheers,

Alvin
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Other t
perilsensitive


Joined: 25 Jul 2014
Posts: 3
I ran into this myself, but I didn't want to modify SDL to fix it. I worked around it by copying the definition of SDL_Window into my code (at least everything up to and including the flags member) so that I could modify the window flags directly. My code looks something like this:

Code:

struct SDL_Window
{
        const void *magic;
        Uint32 id;
        char *title;
        SDL_Surface *icon;
        int x, y;
        int w, h;
        int min_w, min_h;
        int max_w, max_h;
        Uint32 flags;
};
typedef struct SDL_Window SDL_Window;


Then, in my video initialization code:

Code:

window = SDL_CreateWindowFrom((void *)xwindow);
window->flags |= SDL_WINDOW_OPENGL;
SDL_GL_LoadLibrary(NULL);


The last line turns out to be necessary to get OpenGL initialized properly.

It's definitely an evil hack, but I couldn't find any other way to make this work. I don't want to use OpenGL directly as I'm trying to keep most of my code as platform-independent as possible, so I'd rather let SDL handle the rendering. The port using the hack above is guaranteed to use OpenGL though so I don't feel too bad about it. :-/

With this setup, no window system events make it through to SDL (this makes sense because the toolkit wants to handle those itself). Timer events do, as do joystick/gamecontroller events. If you want the latter, you'll need to set SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS to 1. Otherwise SDL will discard the events because it thinks the window doesn't have keyboard focus, and there's no API call to tell it that it actually does.

My code has handlers for the toolkit's window, keyboard and mouse events. These handlers translate the events to the appropriate SDL_Event structures and push them into the SDL event queue with SDL_PushEvent(), and sometimes call SDL other API calls as necessary (such as SDL_SetWindowSize() when the embedded window changes size). This way the rest of my code only needs to worry about handling SDL events, and will work as-is if I build my code with the GUI disabled.

Keyboard events can also be a pain. Significant parts of the SDL keyboard state are not accessible (without nasty hacks anyway), and getting an accurate map between your toolkit's key events and the corresponding SDL_Scancodes and SDL_Keycodes is not trivial. I decided to have my SDL key event handler only care about the keysym, key state and modifier state of the event and to track key press/release state internally instead of using SDL_GetKeyboardState(). This way the code that converts toolkit key events to SDL key events only needs to worry about a few fields instead of perfectly mapping the toolkit event to
an equivalent SDL event.
perilsensitive


Joined: 25 Jul 2014
Posts: 3
Hit the wrong key by accident when typing that last post. Sad The subject shouldn't have been changed to 'Other t'. I intended to add this to the end of the post:

Other than the above issues, I've had no problems; rendering works perfectly and everything seems stable.
SDL_CreateWindowFrom and blocking SDL_CreateRenderer
Alvin Beach
Guest

That's a very interesting workaround! I've tested and it works. Thanks! I did get the same freezing behaviour when SDL_Quit() was called. Turned out, I had to ensure that the window was hidden (unmapped) before calling SDL_Quit(). What toolkit are you using?


I would still like to find out what the issue really is though. Seems to me that SDL2 is executing low-level Xlib calls that maybe it should not be doing when the SDL_Window has been created using SDL_CreateWindowFrom(). I'm hoping that someone with more low-level SDL2 and X11 knowledge might be able to shine some light on this issue.



On Mon, Jul 28, 2014 at 1:57 PM, perilsensitive wrote:
Quote:
Hit the wrong key by accident when typing that last post. The subject shouldn't have been changed to 'Other t'. I intended to add this to the end of the post:

Other than the above issues, I've had no problems; rendering works perfectly and everything seems stable.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

tehcloud


Joined: 08 Jul 2013
Posts: 18
There was talk a long time ago about SDL_CreateGLWindowFrom(), but I haven't heard anything since then.

perilsensitive's hack seems to work for what I need. I have written functions that convert GDK keypresses and mouse clicks to SDL events to complete the puzzle.
SDL_CreateWindowFrom and blocking SDL_CreateRenderer
Alvin Beach
Guest

On 29/07/14 16:00, tehcloud wrote:
Quote:
There was talk a long time ago about SDL_CreateGLWindowFrom(), but I haven't heard anything since then.

perilsensitive's hack seems to work for what I need. I have written functions that convert GDK
keypresses and mouse clicks to SDL events to complete the puzzle.

I checked bugzilla again and this time I found an existing bug entry for SDL_CreateWindowFrom() -
https://bugzilla.libsdl.org/show_bug.cgi?id=2500

This isn't the SDL_Create_GL_WindowFrom() though. This is strange as I searched before and I am sure
I didn't see this bug.

I have added my 2 cents to the bug report along with a patch that seems to work. I like
perilsensitive's idea too, but the underlying issue of Xlib event processing causes concern for me.

Cheers,

Alvin


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: SDL_CreateWindowFrom and blocking SDL_CreateRenderer
perilsensitive


Joined: 25 Jul 2014
Posts: 3
Alvin Beach wrote:
That's a very interesting workaround! I've tested and it works. Thanks! I did get the same freezing behaviour when SDL_Quit() was called. Turned out, I had to ensure that the window was hidden (unmapped) before calling SDL_Quit(). What toolkit are you using?


gtk+-3.0. I noticed that behavior when calling SDL_Quit() as well, but I don't remember what I did about it, which means I might have just commented it out and forgotten to fix it. :-) If so, I'll try unmapping the window first as you did.

Alvin Beach wrote:
I would still like to find out what the issue really is though. Seems to me that SDL2 is executing low-level Xlib calls that maybe it should not be doing when the SDL_Window has been created using SDL_CreateWindowFrom(). I'm hoping that someone with more low-level SDL2 and X11 knowledge might be able to shine some light on this issue.


Agreed. It would be nice to have this fixed in a future release so that I can get rid of my hack. Other projects use OpenGL directly when using CreateWindowFrom() rather than use the Render API, but since I want the video code to be (mostly) portable and my rendering needs are simple (blit one big texture to the screen with HW-accelerated scaling), I didn't want to do that.