summaryrefslogtreecommitdiffstats
path: root/libvo/x11_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvo/x11_common.c')
-rw-r--r--libvo/x11_common.c311
1 files changed, 311 insertions, 0 deletions
diff --git a/libvo/x11_common.c b/libvo/x11_common.c
index bae6c647a0..e0f0a74282 100644
--- a/libvo/x11_common.c
+++ b/libvo/x11_common.c
@@ -46,6 +46,8 @@
#ifdef HAVE_XV
#include <X11/extensions/Xv.h>
#include <X11/extensions/Xvlib.h>
+
+#include "subopt-helper.h"
#endif
#include "input/input.h"
@@ -2242,4 +2244,313 @@ int vo_xv_get_eq(uint32_t xv_port, char *name, int *value)
return (VO_FALSE);
}
+/** \brief contains flags changing the execution of the colorkeying code */
+xv_ck_info_t xv_ck_info = { CK_METHOD_MANUALFILL, CK_SRC_CUR };
+unsigned long xv_colorkey; ///< The color used for manual colorkeying.
+unsigned int xv_port; ///< The selected Xv port.
+
+/**
+ * \brief Interns the requested atom if it is available.
+ *
+ * \param atom_name String containing the name of the requested atom.
+ *
+ * \return Returns the atom if available, else None is returned.
+ *
+ */
+static Atom xv_intern_atom_if_exists( char const * atom_name )
+{
+ XvAttribute * attributes;
+ int attrib_count,i;
+ Atom xv_atom = None;
+
+ attributes = XvQueryPortAttributes( mDisplay, xv_port, &attrib_count );
+ if( attributes!=NULL )
+ {
+ for ( i = 0; i < attrib_count; ++i )
+ {
+ if ( strcmp(attributes[i].name, atom_name ) == 0 )
+ {
+ xv_atom = XInternAtom( mDisplay, atom_name, False );
+ break; // found what we want, break out
+ }
+ }
+ XFree( attributes );
+ }
+
+ return xv_atom;
+}
+/**
+ * \brief Print information about the colorkey method and source.
+ *
+ * \param ck_handling Integer value containing the information about
+ * colorkey handling (see x11_common.h).
+ *
+ * Outputs the content of |ck_handling| as a readable message.
+ *
+ */
+void vo_xv_print_ck_info()
+{
+ mp_msg( MSGT_VO, MSGL_V, "[xv common] " );
+
+ switch ( xv_ck_info.method )
+ {
+ case CK_METHOD_NONE:
+ mp_msg( MSGT_VO, MSGL_V, "Drawing no colorkey.\n" ); return;
+ case CK_METHOD_AUTOPAINT:
+ mp_msg( MSGT_VO, MSGL_V, "Colorkey is drawn by Xv." ); break;
+ case CK_METHOD_MANUALFILL:
+ mp_msg( MSGT_VO, MSGL_V, "Drawing colorkey manually." ); break;
+ case CK_METHOD_BACKGROUND:
+ mp_msg( MSGT_VO, MSGL_V, "Colorkey is drawn as window background." ); break;
+ }
+
+ mp_msg( MSGT_VO, MSGL_V, "\n[xv common] " );
+
+ switch ( xv_ck_info.source )
+ {
+ case CK_SRC_CUR:
+ mp_msg( MSGT_VO, MSGL_V, "Using colorkey from Xv (0x%06x).\n",
+ xv_colorkey );
+ break;
+ case CK_SRC_USE:
+ if ( xv_ck_info.method == CK_METHOD_AUTOPAINT )
+ {
+ mp_msg( MSGT_VO, MSGL_V,
+ "Ignoring colorkey from MPlayer (0x%06x).\n",
+ xv_colorkey );
+ }
+ else
+ {
+ mp_msg( MSGT_VO, MSGL_V,
+ "Using colorkey from MPlayer (0x%06x)."
+ " Use -colorkey to change.\n",
+ xv_colorkey );
+ }
+ break;
+ case CK_SRC_SET:
+ mp_msg( MSGT_VO, MSGL_V,
+ "Setting and using colorkey from MPlayer (0x%06x)."
+ " Use -colorkey to change.\n",
+ xv_colorkey );
+ break;
+ }
+}
+/**
+ * \brief Init colorkey depending on the settings in xv_ck_info.
+ *
+ * \return Returns 0 on failure and 1 on success.
+ *
+ * Sets the colorkey variable according to the CK_SRC_* and CK_METHOD_*
+ * flags in xv_ck_info.
+ *
+ * Possiblilities:
+ * * Methods
+ * - manual colorkey drawing ( CK_METHOD_MANUALFILL )
+ * - set colorkey as window background ( CK_METHOD_BACKGROUND )
+ * - let Xv paint the colorkey ( CK_METHOD_AUTOPAINT )
+ * * Sources
+ * - use currently set colorkey ( CK_SRC_CUR )
+ * - use colorkey in vo_colorkey ( CK_SRC_USE )
+ * - use and set colorkey in vo_colorkey ( CK_SRC_SET )
+ *
+ * NOTE: If vo_colorkey has bits set after the first 3 low order bytes
+ * we don't draw anything as this means it was forced to off.
+ */
+int vo_xv_init_colorkey()
+{
+ Atom xv_atom;
+ int rez;
+
+ /* check if colorkeying is needed */
+ xv_atom = xv_intern_atom_if_exists( "XV_COLORKEY" );
+
+ /* if we have to deal with colorkeying ... */
+ if( xv_atom != None && !(vo_colorkey & 0xFF000000) )
+ {
+ /* check if we should use the colorkey specified in vo_colorkey */
+ if ( xv_ck_info.source != CK_SRC_CUR )
+ {
+ xv_colorkey = vo_colorkey;
+
+ /* check if we have to set the colorkey too */
+ if ( xv_ck_info.source == CK_SRC_SET )
+ {
+ xv_atom = XInternAtom(mDisplay, "XV_COLORKEY",False);
+
+ rez = XvSetPortAttribute( mDisplay, xv_port, xv_atom, vo_colorkey );
+ if ( rez != Success )
+ {
+ mp_msg( MSGT_VO, MSGL_FATAL,
+ "[xv common] Couldn't set colorkey!\n" );
+ return 0; // error setting colorkey
+ }
+ }
+ }
+ else
+ {
+ int colorkey_ret;
+
+ rez=XvGetPortAttribute(mDisplay,xv_port, xv_atom, &colorkey_ret);
+ if ( rez == Success )
+ {
+ xv_colorkey = colorkey_ret;
+ }
+ else
+ {
+ mp_msg( MSGT_VO, MSGL_FATAL,
+ "[xv common] Couldn't get colorkey!"
+ "Maybe the selected Xv port has no overlay.\n" );
+ return 0; // error getting colorkey
+ }
+ }
+
+ /* should we draw the colorkey ourselves or activate autopainting? */
+ if ( xv_ck_info.method == CK_METHOD_AUTOPAINT )
+ {
+ rez = !Success; // reset rez to something different than Success
+ xv_atom = xv_intern_atom_if_exists( "XV_AUTOPAINT_COLORKEY" );
+
+ if ( xv_atom != None ) // autopaint is supported
+ {
+ rez = XvSetPortAttribute( mDisplay, xv_port, xv_atom, 1 );
+ }
+
+ if ( rez != Success )
+ {
+ // fallback to manual colorkey drawing
+ xv_ck_info.method = CK_METHOD_MANUALFILL;
+ }
+ }
+ }
+ else // do no colorkey drawing at all
+ {
+ xv_ck_info.method = CK_METHOD_NONE;
+ } /* end: should we draw colorkey */
+
+ /* output information about the curren colorkey settings */
+ vo_xv_print_ck_info();
+
+ return 1; // success
+}
+
+/**
+ * \brief Draw the colorkey on the video window.
+ *
+ * Draws the colorkey depending on the set method ( colorkey_handling ).
+ *
+ * It also draws the black bars ( when the video doesn't fit to the
+ * display in full screen ) seperately, so they don't overlap with the
+ * video area.
+ *
+ */
+inline void vo_xv_draw_colorkey( uint32_t x, uint32_t y,
+ uint32_t w, uint32_t h )
+{
+ if( xv_ck_info.method == CK_METHOD_MANUALFILL )
+ {
+ XSetForeground( mDisplay, vo_gc, xv_colorkey );
+ XFillRectangle( mDisplay, vo_window, vo_gc,
+ x, y,
+ w, h );
+ }
+
+ /* draw black bars if needed */
+ if ( vo_fs )
+ {
+ XSetForeground( mDisplay, vo_gc, 0 );
+ if ( y > 0 )
+ XFillRectangle( mDisplay, vo_window, vo_gc,
+ 0, 0,
+ vo_screenwidth, y);
+ if (x > 0)
+ XFillRectangle( mDisplay, vo_window, vo_gc,
+ 0, y,
+ x, h );
+ if (x + w < vo_screenwidth)
+ XFillRectangle( mDisplay, vo_window, vo_gc,
+ x + w, y,
+ vo_screenwidth - (x + w), h );
+ if (y + h < vo_screenheight)
+ XFillRectangle( mDisplay, vo_window, vo_gc,
+ 0, y + h,
+ vo_screenwidth, vo_screenheight - (y + h) );
+ }
+
+ XFlush( mDisplay );
+}
+
+/** \brief tests if a valid arg for the ck suboption was given */
+int xv_test_ck( void * arg )
+{
+ strarg_t * strarg = (strarg_t *)arg;
+
+ if ( strncmp( "use", strarg->str, 3 ) == 0 ||
+ strncmp( "set", strarg->str, 3 ) == 0 ||
+ strncmp( "cur", strarg->str, 3 ) == 0 )
+ {
+ return 1;
+ }
+
+ return 0;
+}
+/** \brief tests if a valid arg for the ck-method suboption was given */
+int xv_test_ckm( void * arg )
+{
+ strarg_t * strarg = (strarg_t *)arg;
+
+ if ( strncmp( "bg", strarg->str, 2 ) == 0 ||
+ strncmp( "man", strarg->str, 3 ) == 0 ||
+ strncmp( "auto", strarg->str, 4 ) == 0 )
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * \brief Modify the colorkey_handling var according to str
+ *
+ * Checks if a valid pointer ( not NULL ) to the string
+ * was given. And in that case modifies the colorkey_handling
+ * var to reflect the requested behaviour.
+ * If nothing happens the content of colorkey_handling stays
+ * the same.
+ *
+ * \param str Pointer to the string or NULL
+ *
+ */
+void xv_setup_colorkeyhandling( char const * ck_method_str,
+ char const * ck_str )
+{
+ /* check if a valid pointer to the string was passed */
+ if ( ck_str )
+ {
+ if ( strncmp( ck_str, "use", 3 ) == 0 )
+ {
+ xv_ck_info.source = CK_SRC_USE;
+ }
+ else if ( strncmp( ck_str, "set", 3 ) == 0 )
+ {
+ xv_ck_info.source = CK_SRC_SET;
+ }
+ }
+ /* check if a valid pointer to the string was passed */
+ if ( ck_method_str )
+ {
+ if ( strncmp( ck_method_str, "bg", 2 ) == 0 )
+ {
+ xv_ck_info.method = CK_METHOD_BACKGROUND;
+ }
+ else if ( strncmp( ck_method_str, "man", 3 ) == 0 )
+ {
+ xv_ck_info.method = CK_METHOD_MANUALFILL;
+ }
+ else if ( strncmp( ck_method_str, "auto", 4 ) == 0 )
+ {
+ xv_ck_info.method = CK_METHOD_AUTOPAINT;
+ }
+ }
+}
+
#endif