/*****************************************************************************
* Preamble
*****************************************************************************/
-#include <errno.h> /* ENOMEM */
-#include <stdlib.h> /* free() */
-#include <string.h> /* strerror() */
-
#include <vlc/vlc.h>
#include <vlc_interface.h>
#include <vlc_playlist.h>
#include <vlc_vout.h>
#include <vlc_keys.h>
+#include <errno.h> /* ENOMEM */
+
#ifdef HAVE_MACHINE_PARAM_H
/* BSD */
# include <machine/param.h>
# include <netinet/in.h> /* BSD: struct in_addr */
#endif
+#ifdef HAVE_XSP
+#include <X11/extensions/Xsp.h>
+#endif
+
#ifdef HAVE_SYS_SHM_H
# include <sys/shm.h> /* shmget(), shmctl() */
#endif
#include <X11/Xmd.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
+#include <X11/XF86keysym.h>
#ifdef HAVE_SYS_SHM_H
# include <X11/extensions/XShm.h>
#endif
static int X11ErrorHandler( Display *, XErrorEvent * );
+#ifdef HAVE_XSP
+static void EnablePixelDoubling( vout_thread_t *p_vout );
+static void DisablePixelDoubling( vout_thread_t *p_vout );
+#endif
+
+#ifdef HAVE_OSSO
+static const int i_backlight_on_interval = 300;
+#endif
+
+
+
/*****************************************************************************
* Activate: allocate X11 video thread output method
*****************************************************************************
}
}
p_vout->output.i_chroma = X112VLC_FOURCC(p_vout->output.i_chroma);
+#elif defined(MODULE_NAME_IS_glx)
+ {
+ int i_opcode, i_evt, i_err = 0;
+ int i_maj, i_min = 0;
+
+ /* Check for GLX extension */
+ if( !XQueryExtension( p_vout->p_sys->p_display, "GLX",
+ &i_opcode, &i_evt, &i_err ) )
+ {
+ msg_Err( p_this, "GLX extension not supported" );
+ XCloseDisplay( p_vout->p_sys->p_display );
+ free( p_vout->p_sys );
+ return VLC_EGENERIC;
+ }
+ if( !glXQueryExtension( p_vout->p_sys->p_display, &i_err, &i_evt ) )
+ {
+ msg_Err( p_this, "glXQueryExtension failed" );
+ XCloseDisplay( p_vout->p_sys->p_display );
+ free( p_vout->p_sys );
+ return VLC_EGENERIC;
+ }
+
+ /* Check GLX version */
+ if (!glXQueryVersion( p_vout->p_sys->p_display, &i_maj, &i_min ) )
+ {
+ msg_Err( p_this, "glXQueryVersion failed" );
+ XCloseDisplay( p_vout->p_sys->p_display );
+ free( p_vout->p_sys );
+ return VLC_EGENERIC;
+ }
+ if( i_maj <= 0 || ((i_maj == 1) && (i_min < 3)) )
+ {
+ p_vout->p_sys->b_glx13 = VLC_FALSE;
+ msg_Dbg( p_this, "using GLX 1.2 API" );
+ }
+ else
+ {
+ p_vout->p_sys->b_glx13 = VLC_TRUE;
+ msg_Dbg( p_this, "using GLX 1.3 API" );
+ }
+ }
#endif
/* Create blank cursor (for mouse cursor autohiding) */
p_vout->p_sys->last_date = 0;
#endif
+#ifdef HAVE_XSP
+ p_vout->p_sys->i_hw_scale = 1;
+#endif
+
+#ifdef HAVE_OSSO
+ p_vout->p_sys->i_backlight_on_counter = i_backlight_on_interval;
+ p_vout->p_sys->p_octx = osso_initialize( "vlc", VERSION, 0, NULL );
+ if ( p_vout->p_sys->p_octx == NULL ) {
+ msg_Err( p_vout, "Could not get osso context" );
+ } else {
+ msg_Dbg( p_vout, "Initialized osso context" );
+ }
+#endif
+
/* Variable to indicate if the window should be on top of others */
/* Trigger a callback right now */
var_Get( p_vout, "video-on-top", &val );
}
#endif
+#ifdef HAVE_XSP
+ DisablePixelDoubling(p_vout);
+#endif
+
DestroyCursor( p_vout );
EnableXScreenSaver( p_vout );
DestroyWindow( p_vout, &p_vout->p_sys->original_window );
free_context_lock( &p_vout->p_sys->xvmc_lock );
#endif
+#ifdef HAVE_OSSO
+ if ( p_vout->p_sys->p_octx != NULL ) {
+ msg_Dbg( p_vout, "Deinitializing osso context" );
+ osso_deinitialize( p_vout->p_sys->p_octx );
+ }
+#endif
+
free( p_vout->p_sys );
}
}
#endif
+#ifdef HAVE_XSP
+/*****************************************************************************
+ * EnablePixelDoubling: Enables pixel doubling
+ *****************************************************************************
+ * Checks if the double size image fits in current window, and enables pixel
+ * doubling accordingly. The i_hw_scale is the integer scaling factor.
+ *****************************************************************************/
+static void EnablePixelDoubling( vout_thread_t *p_vout )
+{
+ int i_hor_scale = ( p_vout->p_sys->p_win->i_width ) / p_vout->render.i_width;
+ int i_vert_scale = ( p_vout->p_sys->p_win->i_height ) / p_vout->render.i_height;
+ if ( ( i_hor_scale > 1 ) && ( i_vert_scale > 1 ) ) {
+ p_vout->p_sys->i_hw_scale = 2;
+ msg_Dbg( p_vout, "Enabling pixel doubling, scaling factor %d", p_vout->p_sys->i_hw_scale );
+ XSPSetPixelDoubling( p_vout->p_sys->p_display, 0, 1 );
+ }
+}
+
+/*****************************************************************************
+ * DisablePixelDoubling: Disables pixel doubling
+ *****************************************************************************
+ * The scaling factor i_hw_scale is reset to the no-scaling value 1.
+ *****************************************************************************/
+static void DisablePixelDoubling( vout_thread_t *p_vout )
+{
+ if ( p_vout->p_sys->i_hw_scale > 1 ) {
+ msg_Dbg( p_vout, "Disabling pixel doubling" );
+ XSPSetPixelDoubling( p_vout->p_sys->p_display, 0, 0 );
+ p_vout->p_sys->i_hw_scale = 1;
+ }
+}
+#endif
+
+
+
/*****************************************************************************
* InitVideo: initialize X11 video thread output method
*****************************************************************************
return VLC_SUCCESS;
}
+#ifdef HAVE_XSP
+ vout_PlacePicture( p_vout, p_vout->p_sys->p_win->i_width / p_vout->p_sys->i_hw_scale,
+ p_vout->p_sys->p_win->i_height / p_vout->p_sys->i_hw_scale,
+ &i_index, &i_index,
+ &p_vout->fmt_out.i_visible_width,
+ &p_vout->fmt_out.i_visible_height );
+#else
vout_PlacePicture( p_vout, p_vout->p_sys->p_win->i_width,
p_vout->p_sys->p_win->i_height,
&i_index, &i_index,
&p_vout->fmt_out.i_visible_width,
&p_vout->fmt_out.i_visible_height );
+#endif
p_vout->fmt_out.i_chroma = p_vout->output.i_chroma;
first_field);
XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display );
- if( p_vout->p_sys->xvmc_deinterlace_method == 2 )
+ if( p_vout->p_sys->xvmc_deinterlace_method == 2 )
{ /* BOB DEINTERLACE */
if( p_picture->p_sys->nb_display == 0 )/* && ((t2-t1) < 15000)) */
{
*/
if ( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
{
- vlc_value_t val;
+ vlc_value_t val_fs, val_ontop;
/* Update the object variable and trigger callback */
- val.b_bool = !p_vout->b_fullscreen;
+ val_fs.b_bool = !p_vout->b_fullscreen;
- /*
- * FIXME FIXME FIXME FIXME: EXPLICIT HACK.
- * On the one hand, we cannot hold the lock while triggering a
- * callback, as it causes a deadlock with video-on-top handling.
- * On the other hand, we have to lock while triggering the
- * callback to:
- * 1/ make sure video-on-top remains in sync with fullscreen
- * (i.e. unlocking creates a race condition if fullscreen is
- * switched on and off VERY FAST).
- * 2/ avoid possible corruption bugs if another thread gets the
- * mutex and modifies our data in-between.
- *
- * This is obviously contradictory. Correct solutions may include:
- * - putting the fullscreen NAND video-on-top logic out of libvlc,
- * back into the video output plugins (ugly code duplication...),
- * - serializing fullscreen and video-on-top handling properly
- * instead of doing it via the fullscreen callback. That's got to
- * be the correct one.
- */
-#ifdef MODULE_NAME_IS_xvmc
- xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
-#endif
- vlc_mutex_unlock( &p_vout->p_sys->lock );
+ var_Set( p_vout, "fullscreen", val_fs );
- var_Set( p_vout, "fullscreen", val );
-
- vlc_mutex_lock( &p_vout->p_sys->lock );
-#ifdef MODULE_NAME_IS_xvmc
- xvmc_context_reader_lock( &p_vout->p_sys->xvmc_lock );
-#endif
+ /* Disable "always on top" in fullscreen mode */
+ var_Get( p_vout, "video-on-top", &val_ontop );
+ if( val_ontop.b_bool )
+ WindowOnTop( p_vout, val_fs.b_bool );
ToggleFullScreen( p_vout );
p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
#ifdef MODULE_NAME_IS_xvmc
xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );
#endif
-
+
+#ifdef HAVE_OSSO
+ if ( p_vout->p_sys->p_octx != NULL ) {
+ if ( p_vout->p_sys->i_backlight_on_counter == i_backlight_on_interval ) {
+ if ( osso_display_blanking_pause( p_vout->p_sys->p_octx ) != OSSO_OK ) {
+ msg_Err( p_vout, "Could not disable backlight blanking" );
+ } else {
+ msg_Dbg( p_vout, "Backlight blanking disabled" );
+ }
+ p_vout->p_sys->i_backlight_on_counter = 0;
+ } else {
+ p_vout->p_sys->i_backlight_on_counter ++;
+ }
+ }
+#endif
+
vlc_mutex_unlock( &p_vout->p_sys->lock );
return 0;
}
CWBackingStore | CWBackPixel | CWEventMask,
&xwindow_attributes );
+ var_Get( p_vout, "video-title", &val );
+ if( !val.psz_string || !*val.psz_string )
+ {
+ XStoreName( p_vout->p_sys->p_display, p_win->base_window,
+#ifdef MODULE_NAME_IS_x11
+ VOUT_TITLE " (X11 output)"
+#elif defined(MODULE_NAME_IS_glx)
+ VOUT_TITLE " (GLX output)"
+#else
+ VOUT_TITLE " (XVideo output)"
+#endif
+ );
+ }
+ else
+ {
+ XStoreName( p_vout->p_sys->p_display,
+ p_win->base_window, val.psz_string );
+ }
+ if( val.psz_string ) free( val.psz_string );
+
if( !p_vout->b_fullscreen )
{
/* Set window manager hints and properties: size hints, command,
(unsigned char *)&mwmhints,
PROP_MWM_HINTS_ELEMENTS );
}
- else
- {
- var_Get( p_vout, "video-title", &val );
- if( !val.psz_string || !*val.psz_string )
- {
- XStoreName( p_vout->p_sys->p_display, p_win->base_window,
-#ifdef MODULE_NAME_IS_x11
- VOUT_TITLE " (X11 output)"
-#elif defined(MODULE_NAME_IS_glx)
- VOUT_TITLE " (GLX output)"
-#else
- VOUT_TITLE " (XVideo output)"
-#endif
- );
- }
- else
- {
- XStoreName( p_vout->p_sys->p_display,
- p_win->base_window, val.psz_string );
- }
- if( val.psz_string ) free( val.psz_string );
- }
}
}
else
p_pic->p_sys->p_image =
CreateImage( p_vout, p_vout->p_sys->p_display,
#if defined(MODULE_NAME_IS_xvideo) || defined(MODULE_NAME_IS_xvmc)
- p_vout->p_sys->i_xvport,
+ p_vout->p_sys->i_xvport,
VLC2X11_FOURCC(p_vout->output.i_chroma),
p_pic->format.i_bits_per_pixel,
#else
p_vout->p_sys->p_win->i_y,
p_vout->p_sys->p_win->i_width,
p_vout->p_sys->p_win->i_height );
+
+#ifdef HAVE_XSP
+ EnablePixelDoubling( p_vout );
+#endif
+
}
else
{
msg_Dbg( p_vout, "leaving fullscreen mode" );
+#ifdef HAVE_XSP
+ DisablePixelDoubling( p_vout );
+#endif
+
XReparentWindow( p_vout->p_sys->p_display,
p_vout->p_sys->original_window.video_window,
p_vout->p_sys->original_window.base_window, 0, 0 );
*****************************************************************************/
static int X11ErrorHandler( Display * display, XErrorEvent * event )
{
- /* Ingnore errors on XSetInputFocus()
- * (they happen when a window is not yet mapped) */
- if( event->request_code == X_SetInputFocus )
+ switch( event->request_code )
{
- fprintf(stderr, "XSetInputFocus failed\n");
+ case X_SetInputFocus:
+ /* Ignore errors on XSetInputFocus()
+ * (they happen when a window is not yet mapped) */
return 0;
- }
- if( event->request_code == 150 /* MIT-SHM */ &&
- event->minor_code == X_ShmAttach )
- {
- fprintf(stderr, "XShmAttach failed\n");
- b_shm = VLC_FALSE;
- return 0;
+ case 150: /* MIT-SHM */
+ case 146: /* MIT-SHM too, what gives? */
+ if( event->minor_code == X_ShmAttach )
+ {
+ b_shm = VLC_FALSE;
+ return 0;
+ }
+ break;
}
XSetErrorHandler(NULL);
{ XK_Insert, KEY_INSERT },
{ XK_Delete, KEY_DELETE },
+ { XF86XK_AudioNext, KEY_MEDIA_NEXT_TRACK},
+ { XF86XK_AudioPrev, KEY_MEDIA_PREV_TRACK},
+ { XF86XK_AudioMute, KEY_VOLUME_MUTE },
+ { XF86XK_AudioLowerVolume, KEY_VOLUME_DOWN },
+ { XF86XK_AudioRaiseVolume, KEY_VOLUME_UP },
+ { XF86XK_AudioPlay, KEY_MEDIA_PLAY_PAUSE },
+ { XF86XK_AudioPause, KEY_MEDIA_PLAY_PAUSE },
{ 0, 0 }
};