summaryrefslogtreecommitdiffstats
path: root/libvo
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-11-01 20:24:37 +0000
committerreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-11-01 20:24:37 +0000
commit1a7a3f8b389b4febd41dd2d3f7c16fb033d98fe7 (patch)
tree0619ef71f423acd2f182db83235c2e29dcee1bae /libvo
parent0e49449d13c63f3673e6cc5021459bcf30ebe285 (diff)
downloadmpv-1a7a3f8b389b4febd41dd2d3f7c16fb033d98fe7.tar.bz2
mpv-1a7a3f8b389b4febd41dd2d3f7c16fb033d98fe7.tar.xz
fullscreen fixes and GUI support for vo_gl
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@13844 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libvo')
-rw-r--r--libvo/gl_common.c98
-rw-r--r--libvo/gl_common.h21
-rw-r--r--libvo/vo_gl.c131
-rw-r--r--libvo/x11_common.c15
-rw-r--r--libvo/x11_common.h1
5 files changed, 209 insertions, 57 deletions
diff --git a/libvo/gl_common.c b/libvo/gl_common.c
index 900c8a3ec6..7c82c74076 100644
--- a/libvo/gl_common.c
+++ b/libvo/gl_common.c
@@ -17,3 +17,101 @@ void glAdjustAlignment(int stride) {
glPixelStorei (GL_UNPACK_ALIGNMENT, gl_alignment);
}
+#ifndef GL_WIN32
+/**
+ * Returns the XVisualInfo associated with Window win.
+ * \param win Window whose XVisualInfo is returne.
+ * \return XVisualInfo of the window. Caller must use XFree to free it.
+ */
+static XVisualInfo *getWindowVisualInfo(Window win) {
+ XWindowAttributes xw_attr;
+ XVisualInfo vinfo_template;
+ int tmp;
+ XGetWindowAttributes(mDisplay, win, &xw_attr);
+ vinfo_template.visualid = XVisualIDFromVisual(xw_attr.visual);
+ return XGetVisualInfo(mDisplay, VisualIDMask, &vinfo_template, &tmp);
+}
+
+/**
+ * \brief Changes the window in which video is displayed.
+ * If possible only transfers the context to the new window, otherwise
+ * creates a new one, which must be initialized by the caller.
+ * \param vinfo Currently used visual.
+ * \param context Currently used context.
+ * \param win window that should be used for drawing.
+ * \return one of SET_WINDOW_FAILED, SET_WINDOW_OK or SET_WINDOW_REINIT.
+ * In case of SET_WINDOW_REINIT the context could not be transfered
+ * and the caller must initialize it correctly.
+ */
+int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win)
+{
+ XVisualInfo *new_vinfo;
+ GLXContext new_context = NULL;
+ int keep_context = 0;
+
+ // should only be needed when keeping context, but not doing glFinish
+ // can cause flickering even when we do not keep it.
+ glFinish();
+ new_vinfo = getWindowVisualInfo(win);
+ if (*context && *vinfo && new_vinfo &&
+ (*vinfo)->visualid == new_vinfo->visualid) {
+ // we can keep the GLXContext
+ new_context = *context;
+ XFree(new_vinfo);
+ new_vinfo = *vinfo;
+ keep_context = 1;
+ } else {
+ // create a context
+ new_context = glXCreateContext(mDisplay, new_vinfo, NULL, True);
+ if (!new_context) {
+ mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create GLX context!\n");
+ XFree(new_vinfo);
+ return SET_WINDOW_FAILED;
+ }
+ }
+
+ // set context
+ if (!glXMakeCurrent(mDisplay, vo_window, new_context)) {
+ mp_msg (MSGT_VO, MSGL_FATAL, "[gl] Could not set GLX context!\n");
+ if (!keep_context) {
+ glXDestroyContext (mDisplay, new_context);
+ XFree(new_vinfo);
+ }
+ return SET_WINDOW_FAILED;
+ }
+
+ // set new values
+ vo_window = win;
+ {
+ Window root;
+ int tmp;
+ XGetGeometry(mDisplay, vo_window, &root, &tmp, &tmp,
+ &vo_dwidth, &vo_dheight, &tmp, &tmp);
+ }
+ if (!keep_context) {
+ if (*context)
+ glXDestroyContext(mDisplay, *context);
+ *context = new_context;
+ if (*vinfo)
+ XFree(*vinfo);
+ *vinfo = new_vinfo;
+
+ // and inform that reinit is neccessary
+ return SET_WINDOW_REINIT;
+ }
+ return SET_WINDOW_OK;
+}
+
+/**
+ * \brief free the VisualInfo and GLXContext of an OpenGL context.
+ */
+void releaseGlContext(XVisualInfo **vinfo, GLXContext *context) {
+ if (*vinfo)
+ XFree(*vinfo);
+ *vinfo = NULL;
+ if (*context)
+ glXDestroyContext(mDisplay, *context);
+ *context = 0;
+}
+#endif
+
diff --git a/libvo/gl_common.h b/libvo/gl_common.h
index 2d31c3058f..7760e319ab 100644
--- a/libvo/gl_common.h
+++ b/libvo/gl_common.h
@@ -1,8 +1,29 @@
#ifndef __GL_COMMON_H__
#define __GL_COMMON_H__
+#include "mp_msg.h"
+#include "config.h"
+
#include <GL/gl.h>
+#include "video_out.h"
+
+#ifndef GL_WIN32
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+#include "x11_common.h"
+#endif
void glAdjustAlignment(int stride);
+//! could not set new window, will continue drawing into the old one.
+#define SET_WINDOW_FAILED -1
+//! new window is set, could even transfer the OpenGL context.
+#define SET_WINDOW_OK 0
+//! new window is set, but the OpenGL context needs to be reinitialized.
+#define SET_WINDOW_REINIT 1
+
+#ifndef GL_WIN32
+int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win);
+#endif
+
#endif
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index 9337aea074..dac83135fa 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -24,6 +24,9 @@
#include "gl_common.h"
#include "x11_common.h"
#include "aspect.h"
+#ifdef HAVE_NEW_GUI
+#include "Gui/interface.h"
+#endif
static vo_info_t info =
{
@@ -35,7 +38,8 @@ static vo_info_t info =
LIBVO_EXTERN(gl)
-static GLXContext wsGLXContext;
+static XVisualInfo *gl_vinfo = NULL;
+static GLXContext gl_context = 0;
static int wsGLXAttrib[] = { GLX_RGBA,
GLX_RED_SIZE,1,
GLX_GREEN_SIZE,1,
@@ -172,26 +176,54 @@ static int find_gl_format (uint32_t format)
return 1;
}
+/**
+ * \brief Initialize a (new or reused) OpenGL context.
+ */
+static int initGl(uint32_t d_width, uint32_t d_height) {
+ unsigned char *ImageData = NULL;
+ texture_width = 32;
+ while (texture_width < image_width ||
+ texture_width < image_height)
+ texture_width *= 2;
+ texture_height = texture_width;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_TEXTURE_2D);
+
+ mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",
+ texture_width, texture_height);
+
+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ glAdjustAlignment(texture_width * image_bytes);
+ ImageData = malloc(texture_width * texture_height * image_bytes);
+ memset(ImageData, 0, texture_width * texture_height * image_bytes);
+ glTexImage2D(GL_TEXTURE_2D, 0, gl_texfmt, texture_width, texture_height, 0,
+ gl_format, gl_type, ImageData);
+ free (ImageData);
+
+ // set alignment as default is 4 which will break some files
+ glAdjustAlignment(image_width * image_bytes);
+
+ resize(d_width, d_height);
+
+ glClearColor( 0.0f,0.0f,0.0f,0.0f );
+ glClear( GL_COLOR_BUFFER_BIT );
+}
+
/* connect to server, create and map window,
* allocate colors and (shared) memory
*/
static uint32_t
config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format)
{
- unsigned char *ImageData=NULL;
-// int screen;
- unsigned int fg, bg;
- XSizeHints hint;
- XVisualInfo *vinfo;
- XEvent xev;
-
-// XGCValues xgcv;
-
image_height = height;
image_width = width;
find_gl_format (format);
- vo_dwidth = d_width;
- vo_dheight = d_height;
sub_bg_alpha = 255; // We need alpha = 255 for invisible part of the OSD
int_pause = 0;
@@ -207,6 +239,26 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
// aspect(&d_width,&d_height,A_ZOOM);
// }
#endif
+#ifdef HAVE_NEW_GUI
+ if (use_gui) {
+ // GUI creates and manages window for us
+ vo_dwidth = d_width;
+ vo_dheight= d_height;
+ guiGetEvent(guiSetShVideo, 0);
+ setGlWindow(&gl_vinfo, &gl_context, vo_window);
+ initGl(vo_dwidth, vo_dheight);
+ return 0;
+ }
+#endif
+ if ( vo_window == None ) {
+ unsigned int fg, bg;
+ XSizeHints hint;
+ XVisualInfo *vinfo;
+ XEvent xev;
+
+ vo_dwidth = d_width;
+ vo_dheight = d_height;
+
hint.x = 0;
hint.y = 0;
hint.width = d_width;
@@ -229,8 +281,6 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
- if ( vo_window == None )
- {
vo_window = vo_x11_create_smooth_window(mDisplay, mRootWin, vinfo->visual, hint.x, hint.y, hint.width, hint.height,
vinfo->depth, XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocNone));
@@ -243,7 +293,6 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
XSetStandardProperties(mDisplay, vo_window, title, title, None, NULL, 0, &hint);
/* Map window. */
XMapWindow(mDisplay, vo_window);
- if ( flags&1 ) vo_x11_fullscreen();
#ifdef HAVE_XINERAMA
vo_x11_xinerama_move(mDisplay,vo_window);
#endif
@@ -256,56 +305,21 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
while (xev.type != MapNotify || xev.xmap.event != vo_window);
XSelectInput(mDisplay, vo_window, NoEventMask);
- }
-
- if ( vo_config_count ) glXDestroyContext( mDisplay,wsGLXContext );
- wsGLXContext=glXCreateContext( mDisplay,vinfo,NULL,True );
- glXMakeCurrent( mDisplay,vo_window,wsGLXContext );
XSync(mDisplay, False);
vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PointerMotionMask
| ButtonPressMask | ButtonReleaseMask | ExposureMask
);
-
- texture_width=32;
- while(texture_width<image_width || texture_width<image_height) texture_width*=2;
- texture_height=texture_width;
-
- ImageData=malloc(texture_width*texture_height*image_bytes);
- memset(ImageData,0,texture_width*texture_height*image_bytes);
-
- glDisable(GL_BLEND);
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
- glDisable(GL_CULL_FACE);
-
- glEnable(GL_TEXTURE_2D);
-
- // set alignment as default is 4 which will break some files
- glAdjustAlignment(image_width * image_bytes);
-
- mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",texture_width,texture_height);
-
-#if 1
-// glBindTexture(GL_TEXTURE_2D, texture_id);
- glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, gl_texfmt, texture_width, texture_height, 0,
- gl_format, gl_type, ImageData);
-#endif
-
- free (ImageData);
-
- resize(d_width,d_height);
-
- glClearColor( 0.0f,0.0f,0.0f,0.0f );
- glClear( GL_COLOR_BUFFER_BIT );
-
-// printf("OpenGL setup OK!\n");
-
+ }
if (vo_ontop) vo_x11_setlayer(mDisplay, vo_window, vo_ontop);
+ vo_x11_nofs_sizepos(0, 0, d_width, d_height);
+ if (vo_fs ^ (flags & VOFLAG_FULLSCREEN))
+ vo_x11_fullscreen();
+ setGlWindow(&gl_vinfo, &gl_context, vo_window);
+ initGl(vo_dwidth, vo_dheight);
+
return 0;
}
@@ -519,6 +533,7 @@ static void
uninit(void)
{
if ( !vo_config_count ) return;
+ releaseGlContext(&gl_vinfo, &gl_context);
vo_x11_uninit();
}
@@ -612,6 +627,8 @@ static uint32_t control(uint32_t request, void *data, ...)
case VOCTRL_RESUME: return (int_pause=0);
case VOCTRL_QUERY_FORMAT:
return query_format(*((uint32_t*)data));
+ case VOCTRL_GUISUPPORT:
+ return VO_TRUE;
case VOCTRL_ONTOP:
vo_x11_ontop();
return VO_TRUE;
diff --git a/libvo/x11_common.c b/libvo/x11_common.c
index df51192b8c..fd97843f39 100644
--- a/libvo/x11_common.c
+++ b/libvo/x11_common.c
@@ -1133,6 +1133,21 @@ int vo_x11_check_events(Display * mydisplay)
return ret;
}
+/**
+ * \brief sets the size and position of the non-fullscreen window.
+ */
+void vo_x11_nofs_sizepos(int x, int y, int width, int height)
+{
+ if (vo_fs) {
+ vo_old_x = x;
+ vo_old_y = y;
+ vo_old_width = width;
+ vo_old_height = height;
+ }
+ else
+ XMoveResizeWindow(mDisplay, vo_window, x, y, width, height);
+}
+
void vo_x11_sizehint(int x, int y, int width, int height, int max)
{
vo_hint.flags = PPosition | PSize | PWinGravity;
diff --git a/libvo/x11_common.h b/libvo/x11_common.h
index dd6265bb75..d5c27c8135 100644
--- a/libvo/x11_common.h
+++ b/libvo/x11_common.h
@@ -52,6 +52,7 @@ extern void vo_hidecursor ( Display* , Window );
extern void vo_showcursor( Display *disp, Window win );
extern void vo_x11_decoration( Display * vo_Display,Window w,int d );
extern void vo_x11_classhint( Display * display,Window window,char *name );
+extern void vo_x11_nofs_sizepos(int x, int y, int width, int height);
extern void vo_x11_sizehint( int x, int y, int width, int height, int max );
extern int vo_x11_check_events(Display *mydisplay);
extern void vo_x11_selectinput_witherr(Display *display, Window w, long event_mask);