You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
codeine/src/part/videoWindow.cpp

193 lines
4.3 KiB

// (C) 2005 Max Howell (max.howell@methylblue.com)
// See COPYING file for licensing information
#define CODEINE_DEBUG_PREFIX "videoWindow"
#include <cstdlib>
#include "debug.h"
#include <ntqapplication.h> //sendEvent()
#include <ntqcursor.h>
#include <ntqevent.h>
#include "videoWindow.h"
#include <X11/Xlib.h> //TODO this breaks compile for lots of people due to excessive macro content
#include <xine.h> //x11_visual_t
namespace Codeine {
VideoWindow *VideoWindow::s_instance = 0;
namespace X
{
Display *d;
int s, w;
}
VideoWindow::VideoWindow( TQWidget *parent, const char *name )
: TQWidget( parent, name )
, m_osd( 0 )
, m_stream( 0 )
, m_eventQueue( 0 )
, m_videoPort( 0 )
, m_audioPort( 0 )
, m_xine( 0 )
, m_displayRatio( 1 )
{
s_instance = this;
// with this Konqueror would crash on exit
// without this we may be unstable!
//XInitThreads();
show();
setWFlags( TQt::WNoAutoErase );
setMouseTracking( true );
setAcceptDrops( true );
setUpdatesEnabled( false ); //to stop TQt drawing over us
setPaletteBackgroundColor( TQt::black );
X::d = XOpenDisplay( std::getenv("DISPLAY") );
X::s = DefaultScreen( X::d );
X::w = winId();
XLockDisplay( X::d );
XSelectInput( X::d, X::w, ExposureMask );
{
using X::d; using X::s;
//these are Xlib macros
double w = DisplayWidth( d, s ) * 1000 / DisplayWidthMM( d, s );
double h = DisplayHeight( d, s ) * 1000 / DisplayHeightMM( d, s );
m_displayRatio = w / h;
}
XUnlockDisplay( X::d );
connect( &m_timer, SIGNAL(timeout()), SLOT(hideCursor()) );
}
VideoWindow::~VideoWindow()
{
DEBUG_BLOCK
if( m_osd ) xine_osd_free( m_osd );
if( m_stream ) xine_close( m_stream );
if( m_eventQueue ) xine_event_dispose_queue( m_eventQueue );
if( m_stream ) xine_dispose( m_stream );
if( m_videoPort ) xine_close_video_driver( m_xine, m_videoPort );
if( m_audioPort ) xine_close_audio_driver( m_xine, m_audioPort );
if( m_xine ) xine_exit( m_xine );
XCloseDisplay( X::d );
}
void*
VideoWindow::x11Visual() const
{
x11_visual_t* visual = new x11_visual_t;
visual->display = X::d;
visual->screen = X::s;
visual->d = X::w;
visual->dest_size_cb = &VideoWindow::destSizeCallBack;
visual->frame_output_cb = &VideoWindow::frameOutputCallBack;
visual->user_data = (void*)this;
return visual;
}
void
VideoWindow::destSizeCallBack(
void* p, int /*video_width*/, int /*video_height*/,
double /*video_aspect*/, int* dest_width,
int* dest_height, double* dest_aspect )
{
if( !p )
return;
#define vw static_cast<VideoWindow*>(p)
*dest_width = vw->width();
*dest_height = vw->height();
*dest_aspect = vw->m_displayRatio;
}
void
VideoWindow::frameOutputCallBack(
void* p, int video_width, int video_height, double video_aspect,
int* dest_x, int* dest_y, int* dest_width, int* dest_height,
double* dest_aspect, int* win_x, int* win_y )
{
if( !p )
return;
*dest_x = 0;
*dest_y = 0 ;
*dest_width = vw->width();
*dest_height = vw->height();
*win_x = vw->x();
*win_y = vw->y();
*dest_aspect = vw->m_displayRatio;
// correct size with video aspect
// TODO what's this about?
if( video_aspect >= vw->m_displayRatio )
video_width = int( double(video_width * video_aspect / vw->m_displayRatio + 0.5) );
else
video_height = int( double(video_height * vw->m_displayRatio / video_aspect) + 0.5 );
#undef vw
}
bool
VideoWindow::event( TQEvent *e )
{
switch( e->type() )
{
case TQEvent::MouseMove:
case TQEvent::MouseButtonPress:
unsetCursor();
m_timer.start( CURSOR_HIDE_TIMEOUT, true );
break;
case TQEvent::Close:
case TQEvent::Hide:
xine_stop( m_stream );
break;
case TQEvent::Leave:
m_timer.stop();
break;
default:
;
}
return TQWidget::event( e );
}
bool
VideoWindow::x11Event( XEvent *e )
{
if( e->type == Expose && e->xexpose.count == 0 ) {
xine_gui_send_vo_data( m_stream, XINE_GUI_SEND_EXPOSE_EVENT, e );
return true;
}
return false;
}
void
VideoWindow::hideCursor()
{
setCursor( TQt::BlankCursor );
}
} //namespace Codeine