Both MPlayer and GStreamer can output video to some X11 Window given its ID, this is done using mplayer -wid
or gst_x_overlay_set_xwindow_id()
. But if you are developing an SDL application and tried it, you may have faced the same problem as I did: You can just output to whole SDL window, not just part of it.
Why does this happen?
The X Window System uses the term "Window" for any rectangular area, not just toplevel windows as we know. Toolkits often use X Windows as base for everything visible: buttons, labels, text areas and the window background itself. Every window is attached to another window, the parent window, except by the root window (that one that holds desktop wallpaper).
However, SDL is composed of just one X window and you don't have any way to create more using SDL itself. So if you want to output your video to just part of window, you need to create another X Window with desired geometry and position, using SDL's as parent.
How to work around this?
As I said, there is no SDL functions to create X Window. You need to create it yourself using Xlib functions. Xlib is the C implementation for the X protocol, a client-server. It's not that hard to develop, but you need to understand some things beforehand (You can see more information on Christophe Tronche - The Xlib Manual or Guy Keren - Basic Graphics Programming With The Xlib Library):
Display
- Structure representing the connection to X server. You can get this from SDL using
SDL_SysWMinfo.info.x11.display
or you can create your own usingXOpenDisplay()
. Window
- Integer that identifies some window inside a display. You can create windows using
XCreateSimpleWindow()
using a parent window, which you can get from SDL usingSDL_SysWMinfo.info.x11.window
. XMapWindow()
XCreateSimpleWindow()
doesn't display the window, you need to do it yourself. The X way to do it is callXMapWindow()
. Note that X window is asynchronous and you need to wait until server process and replies. First, you need to select what events you want to listen usingXSelectInput()
. Then you need to have client to send commands to server, this is done byXFlush()
or any call that does this, in this case we useXNextEvent()
, which already waits for events from X server.
Show me the code!
Updates
- 2007-03-07 12:05 --Moved SVN to Google Code at http://barbieri-playground.googlecode.com/svn