Commit c01dd5d3 authored by Sam Hocevar's avatar Sam Hocevar

* ./modules/video_output/directx/events.c: start the colorkey search at 10,

    not 5, to avoid using a color used by another application.
  * ./modules/video_output/directx/events.c: support for drawing in a parent
    window instead of creating our own; still a bit flakey.

  * ./mozilla/vlcshell.cpp: we can now compile the Mozilla plugin so that it
    does not call libvlc (for testing purposes).
parent ebbc5f8b
......@@ -2,7 +2,7 @@
* vout.c: Windows DirectX video output display method
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: directx.c,v 1.4 2002/10/22 21:10:28 sam Exp $
* $Id: directx.c,v 1.5 2002/10/25 18:17:59 sam Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -98,11 +98,16 @@ static int DirectXGetSurfaceDesc ( picture_t *p_pic );
"isn't recommended as usually using video memory allows to benefit from " \
"more hardware acceleration (like rescaling or YUV->RGB conversions). " \
"This option doesn't have any effect when using overlays." )
#define WINDOW_TEXT N_("specify an existing window")
#define WINDOW_LONGTEXT N_( \
"Specify a window to use instead of opening a new one. This option is " \
"DANGEROUS, use with care." )
vlc_module_begin();
add_category_hint( N_("Video"), NULL );
add_bool( "directx-hw-yuv", 1, NULL, HW_YUV_TEXT, HW_YUV_LONGTEXT );
add_bool( "directx-use-sysmem", 0, NULL, SYSMEM_TEXT, SYSMEM_LONGTEXT );
add_integer( "directx-window", 0, NULL, WINDOW_TEXT, WINDOW_LONGTEXT );
set_description( _("DirectX video module") );
set_capability( "video output", 100 );
add_shortcut( "directx" );
......@@ -131,7 +136,7 @@ static int OpenVideo( vlc_object_t *p_this )
if( p_vout->p_sys == NULL )
{
msg_Err( p_vout, "out of memory" );
return 1;
return VLC_ENOMEM;
}
/* Initialisations */
......@@ -147,6 +152,7 @@ static int OpenVideo( vlc_object_t *p_this )
p_vout->p_sys->p_clipper = NULL;
p_vout->p_sys->hbrush = NULL;
p_vout->p_sys->hwnd = NULL;
p_vout->p_sys->hparent = NULL;
p_vout->p_sys->i_changes = 0;
p_vout->p_sys->b_caps_overlay_clipping = 0;
SetRectEmpty( &p_vout->p_sys->rect_display );
......@@ -206,12 +212,11 @@ static int OpenVideo( vlc_object_t *p_this )
goto error;
}
return 0;
return VLC_SUCCESS;
error:
CloseVideo( VLC_OBJECT(p_vout) );
return 1;
return VLC_EGENERIC;
}
/*****************************************************************************
......@@ -282,7 +287,9 @@ static int Init( vout_thread_t *p_vout )
}
/* Change the window title bar text */
if( p_vout->p_sys->b_using_overlay )
if( p_vout->p_sys->hparent )
; /* Do nothing */
else if( p_vout->p_sys->b_using_overlay )
SetWindowText( p_vout->p_sys->hwnd,
VOUT_TITLE " (hardware YUV overlay DirectX output)" );
else if( p_vout->p_sys->b_hw_yuv )
......@@ -291,7 +298,7 @@ static int Init( vout_thread_t *p_vout )
else SetWindowText( p_vout->p_sys->hwnd,
VOUT_TITLE " (software RGB DirectX output)" );
return 0;
return VLC_SUCCESS;
}
/*****************************************************************************
......@@ -325,12 +332,14 @@ static void CloseVideo( vlc_object_t *p_this )
vlc_object_detach( p_vout->p_sys->p_event );
/* Kill DirectXEventThread */
p_vout->p_sys->p_event->b_die = 1;
p_vout->p_sys->p_event->b_die = VLC_TRUE;
/* we need to be sure DirectXEventThread won't stay stuck in
* GetMessage, so we send a fake message */
if( p_vout->p_sys->hwnd )
{
PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0);
}
vlc_thread_join( p_vout->p_sys->p_event );
vlc_object_destroy( p_vout->p_sys->p_event );
......@@ -353,6 +362,13 @@ static int Manage( vout_thread_t *p_vout )
{
WINDOWPLACEMENT window_placement;
/* If we do not control our window, we check for geometry changes
* ourselves because the parent might not send us its events. */
if( p_vout->p_sys->hparent )
{
DirectXUpdateRects( p_vout, VLC_FALSE );
}
/* We used to call the Win32 PeekMessage function here to read the window
* messages. But since window can stay blocked into this function for a
* long time (for example when you move your window on the screen), I
......@@ -362,9 +378,9 @@ static int Manage( vout_thread_t *p_vout )
* Scale Change
*/
if( p_vout->i_changes & VOUT_SCALE_CHANGE
|| p_vout->p_sys->i_changes & VOUT_SCALE_CHANGE)
|| p_vout->p_sys->i_changes & VOUT_SCALE_CHANGE )
{
msg_Dbg( p_vout, "Scale Change" );
msg_Dbg( p_vout, "scale change" );
if( !p_vout->p_sys->b_using_overlay )
InvalidateRect( p_vout->p_sys->hwnd, NULL, TRUE );
else
......@@ -379,7 +395,7 @@ static int Manage( vout_thread_t *p_vout )
if( p_vout->i_changes & VOUT_SIZE_CHANGE
|| p_vout->p_sys->i_changes & VOUT_SIZE_CHANGE )
{
msg_Dbg( p_vout, "Size Change" );
msg_Dbg( p_vout, "size change" );
if( !p_vout->p_sys->b_using_overlay )
InvalidateRect( p_vout->p_sys->hwnd, NULL, TRUE );
else
......@@ -429,15 +445,20 @@ static int Manage( vout_thread_t *p_vout )
( (mdate() - p_vout->p_sys->i_lastmoved) > 5000000 ) )
{
/* Hide the mouse automatically */
p_vout->p_sys->b_cursor_hidden = 1;
PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
if( p_vout->p_sys->hwnd != p_vout->p_sys->hparent )
{
p_vout->p_sys->b_cursor_hidden = VLC_TRUE;
PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
}
}
/* Check if the event thread is still running */
if( p_vout->p_sys->p_event->b_die )
return 1; /* exit */
{
return VLC_EGENERIC; /* exit */
}
return 0;
return VLC_SUCCESS;
}
/*****************************************************************************
......@@ -466,11 +487,11 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
ddbltfx.dwDDFX = DDBLTFX_NOTEARING;
/* Blit video surface to display */
dxresult = IDirectDrawSurface2_Blt(p_vout->p_sys->p_display,
&p_vout->p_sys->rect_dest_clipped,
p_pic->p_sys->p_surface,
&p_vout->p_sys->rect_src_clipped,
DDBLT_ASYNC, &ddbltfx );
dxresult = IDirectDrawSurface2_Blt( p_vout->p_sys->p_display,
&p_vout->p_sys->rect_dest_clipped,
p_pic->p_sys->p_surface,
&p_vout->p_sys->rect_src_clipped,
DDBLT_ASYNC, &ddbltfx );
if ( dxresult == DDERR_SURFACELOST )
{
/* Our surface can be lost so be sure
......@@ -478,7 +499,7 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
IDirectDrawSurface2_Restore( p_vout->p_sys->p_display );
/* Now that the surface has been restored try to display again */
dxresult = IDirectDrawSurface2_Blt(p_vout->p_sys->p_display,
dxresult = IDirectDrawSurface2_Blt( p_vout->p_sys->p_display,
&p_vout->p_sys->rect_dest_clipped,
p_pic->p_sys->p_surface,
&p_vout->p_sys->rect_src_clipped,
......@@ -487,17 +508,18 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
if( dxresult != DD_OK )
{
msg_Warn( p_vout, "could not Blit the surface" );
msg_Warn( p_vout, "could not blit surface (error %i)", dxresult );
return;
}
}
else /* using overlay */
{
/* Flip the overlay buffers if we are using back buffers */
if( p_pic->p_sys->p_front_surface == p_pic->p_sys->p_surface )
{
return;
}
dxresult = IDirectDrawSurface2_Flip( p_pic->p_sys->p_front_surface,
NULL, DDFLIP_WAIT );
......@@ -515,16 +537,18 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
}
if( dxresult != DD_OK )
msg_Warn( p_vout, "could not flip overlay surface" );
{
msg_Warn( p_vout, "could not flip overlay (error %i)", dxresult );
}
if( !DirectXGetSurfaceDesc( p_pic ) )
if( DirectXGetSurfaceDesc( p_pic ) )
{
/* AAARRGG */
msg_Err( p_vout, "cannot get surface desc" );
return;
}
if( !UpdatePictureStruct( p_vout, p_pic, p_vout->output.i_chroma ) )
if( UpdatePictureStruct( p_vout, p_pic, p_vout->output.i_chroma ) )
{
/* AAARRGG */
msg_Err( p_vout, "invalid pic chroma" );
......@@ -534,7 +558,6 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
/* set currently displayed pic */
p_vout->p_sys->p_current_surface = p_pic->p_sys->p_front_surface;
}
}
......@@ -602,7 +625,7 @@ static int DirectXInitDDraw( vout_thread_t *p_vout )
DirectXGetDDrawCaps( p_vout );
msg_Dbg( p_vout, "End DirectXInitDDraw" );
return 0;
return VLC_SUCCESS;
error:
if( p_vout->p_sys->p_ddobject )
......@@ -611,7 +634,7 @@ static int DirectXInitDDraw( vout_thread_t *p_vout )
FreeLibrary( p_vout->p_sys->hddraw_dll );
p_vout->p_sys->hddraw_dll = NULL;
p_vout->p_sys->p_ddobject = NULL;
return 1;
return VLC_EGENERIC;
}
/*****************************************************************************
......@@ -641,8 +664,8 @@ static int DirectXCreateDisplay( vout_thread_t *p_vout )
&p_display, NULL );
if( dxresult != DD_OK )
{
msg_Err( p_vout, "cannot get direct draw primary surface" );
return 1;
msg_Err( p_vout, "cannot get primary surface (error %i)", dxresult );
return VLC_EGENERIC;
}
dxresult = IDirectDrawSurface_QueryInterface( p_display,
......@@ -652,8 +675,9 @@ static int DirectXCreateDisplay( vout_thread_t *p_vout )
IDirectDrawSurface_Release( p_display );
if ( dxresult != DD_OK )
{
msg_Err( p_vout, "cannot get IDirectDrawSurface2 interface" );
return 1;
msg_Err( p_vout, "cannot query IDirectDrawSurface2 interface "
"(error %i)", dxresult );
return VLC_EGENERIC;
}
/* The clipper will be used only in non-overlay mode */
......@@ -667,13 +691,16 @@ static int DirectXCreateDisplay( vout_thread_t *p_vout )
dxresult = IDirectDrawSurface2_GetPixelFormat( p_vout->p_sys->p_display,
&pixel_format );
if( dxresult != DD_OK )
msg_Warn( p_vout, "DirectXUpdateOverlay GetPixelFormat failed" );
{
msg_Warn( p_vout, "DirectXUpdateOverlay GetPixelFormat failed "
"(error %i)", dxresult );
}
p_vout->p_sys->i_colorkey = (DWORD)((( p_vout->p_sys->i_rgb_colorkey
* pixel_format.dwRBitMask) / 255)
& pixel_format.dwRBitMask);
& pixel_format.dwRBitMask );
#endif
return 0;
return VLC_SUCCESS;
}
......@@ -696,17 +723,17 @@ static int DirectXCreateClipper( vout_thread_t *p_vout )
&p_vout->p_sys->p_clipper, NULL );
if( dxresult != DD_OK )
{
msg_Warn( p_vout, "DirectXCreateClipper cannot create clipper" );
msg_Warn( p_vout, "cannot create clipper (error %i)", dxresult );
goto error;
}
/* associate the clipper to the window */
/* Associate the clipper to the window */
dxresult = IDirectDrawClipper_SetHWnd(p_vout->p_sys->p_clipper, 0,
p_vout->p_sys->hwnd);
if( dxresult != DD_OK )
{
msg_Warn( p_vout,
"DirectXCreateClipper cannot attach clipper to window" );
msg_Warn( p_vout, "cannot attach clipper to window (error %i)",
dxresult );
goto error;
}
......@@ -715,19 +742,20 @@ static int DirectXCreateClipper( vout_thread_t *p_vout )
p_vout->p_sys->p_clipper);
if( dxresult != DD_OK )
{
msg_Warn( p_vout,
"DirectXCreateClipper cannot attach clipper to surface" );
msg_Warn( p_vout, "cannot attach clipper to surface (error %i)",
dxresult );
goto error;
}
return 0;
return VLC_SUCCESS;
error:
if( p_vout->p_sys->p_clipper )
{
IDirectDrawClipper_Release( p_vout->p_sys->p_clipper );
}
p_vout->p_sys->p_clipper = NULL;
return 1;
return VLC_EGENERIC;
}
/*****************************************************************************
......@@ -784,7 +812,7 @@ static int DirectXCreateSurface( vout_thread_t *p_vout,
if( dxresult != DD_OK )
{
*pp_surface_final = NULL;
return 0;
return VLC_EGENERIC;
}
}
......@@ -825,7 +853,7 @@ static int DirectXCreateSurface( vout_thread_t *p_vout,
if( dxresult != DD_OK )
{
*pp_surface_final = NULL;
return 0;
return VLC_EGENERIC;
}
}
......@@ -836,12 +864,13 @@ static int DirectXCreateSurface( vout_thread_t *p_vout,
IDirectDrawSurface_Release( p_surface ); /* Release the old interface */
if ( dxresult != DD_OK )
{
msg_Err( p_vout, "cannot get IDirectDrawSurface2 interface" );
msg_Err( p_vout, "cannot query IDirectDrawSurface2 interface "
"(error %i)", dxresult );
*pp_surface_final = NULL;
return 0;
return VLC_EGENERIC;
}
return 1;
return VLC_SUCCESS;
}
/*****************************************************************************
......@@ -958,7 +987,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
int i_num_pics )
{
int i;
vlc_bool_t b_result_ok;
int i_ret = VLC_SUCCESS;
LPDIRECTDRAWSURFACE2 p_surface;
msg_Dbg( p_vout, "NewPictureVec" );
......@@ -977,19 +1006,21 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
* (you don't have to wait for the vsync) and provides for a very nice
* video quality (no tearing). */
b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
2 /* number of backbuffers */ );
i_ret = DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
2 /* number of backbuffers */ );
if( !b_result_ok )
if( i_ret != VLC_SUCCESS )
{
/* Try to reduce the number of backbuffers */
b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
0 /* number of backbuffers */);
i_ret = DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
0 /* number of backbuffers */ );
}
if( b_result_ok )
if( i_ret == VLC_SUCCESS )
{
DDSCAPS dds_caps;
picture_t front_pic;
......@@ -1001,7 +1032,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
if( p_pic[0].p_sys == NULL )
{
DirectXCloseSurface( p_vout, p_surface );
return -1;
return VLC_ENOMEM;
}
/* set front buffer */
......@@ -1023,10 +1054,10 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
p_vout->p_sys->p_current_surface = front_pic.p_sys->p_surface =
p_pic[0].p_sys->p_front_surface;
/* reset the front buffer memory */
if( DirectXGetSurfaceDesc( &front_pic ) &&
UpdatePictureStruct( p_vout, &front_pic,
p_vout->output.i_chroma ) )
/* Reset the front buffer memory */
if( !DirectXGetSurfaceDesc( &front_pic ) &&
!UpdatePictureStruct( p_vout, &front_pic,
p_vout->output.i_chroma ) )
{
int i,j;
for( i = 0; i < front_pic.i_planes; i++ )
......@@ -1050,14 +1081,15 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
* want to display it */
if( !p_vout->p_sys->b_using_overlay )
{
if( p_vout->p_sys->b_hw_yuv )
b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
0 /* no back buffers */ );
{
i_ret = DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
0 /* no back buffers */ );
}
if( !p_vout->p_sys->b_hw_yuv || !b_result_ok )
if( i_ret || !p_vout->p_sys->b_hw_yuv )
{
/* Our last choice is to use a plain RGB surface */
DDPIXELFORMAT ddpfPixelFormat;
......@@ -1087,7 +1119,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
break;
default:
msg_Err( p_vout, "unknown screen depth" );
return 0;
return VLC_EGENERIC;
}
p_vout->output.i_rmask = ddpfPixelFormat.dwRBitMask;
p_vout->output.i_gmask = ddpfPixelFormat.dwGBitMask;
......@@ -1096,20 +1128,20 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
p_vout->p_sys->b_hw_yuv = 0;
b_result_ok = DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
0 /* no back buffers */ );
i_ret = DirectXCreateSurface( p_vout, &p_surface,
p_vout->output.i_chroma,
p_vout->p_sys->b_using_overlay,
0 /* no back buffers */ );
}
if( b_result_ok )
if( i_ret == VLC_SUCCESS )
{
/* Allocate internal structure */
p_pic[0].p_sys = malloc( sizeof( picture_sys_t ) );
if( p_pic[0].p_sys == NULL )
{
DirectXCloseSurface( p_vout, p_surface );
return -1;
return VLC_ENOMEM;
}
p_pic[0].p_sys->p_surface = p_pic[0].p_sys->p_front_surface
= p_surface;
......@@ -1129,28 +1161,27 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
p_pic[i].i_type = DIRECT_PICTURE;
PP_OUTPUTPICTURE[i] = &p_pic[i];
if( !DirectXGetSurfaceDesc( &p_pic[i] ) )
if( DirectXGetSurfaceDesc( &p_pic[i] ) )
{
/* AAARRGG */
FreePictureVec( p_vout, p_pic, I_OUTPUTPICTURES );
I_OUTPUTPICTURES = 0;
return -1;
return VLC_EGENERIC;
}
if( !UpdatePictureStruct(p_vout, &p_pic[i], p_vout->output.i_chroma) )
if( UpdatePictureStruct(p_vout, &p_pic[i], p_vout->output.i_chroma) )
{
/* Unknown chroma, tell the guy to get lost */
msg_Err( p_vout, "never heard of chroma 0x%.8x (%4.4s)",
p_vout->output.i_chroma, (char*)&p_vout->output.i_chroma );
FreePictureVec( p_vout, p_pic, I_OUTPUTPICTURES );
I_OUTPUTPICTURES = 0;
return -1;
return VLC_EGENERIC;
}
}
msg_Dbg( p_vout, "End NewPictureVec");
return 0;
return VLC_SUCCESS;
}
/*****************************************************************************
......@@ -1182,7 +1213,6 @@ static void FreePictureVec( vout_thread_t *p_vout, picture_t *p_pic,
static int UpdatePictureStruct( vout_thread_t *p_vout, picture_t *p_pic,
int i_chroma )
{
switch( p_vout->output.i_chroma )
{
case VLC_FOURCC('R','G','B','2'):
......@@ -1207,7 +1237,7 @@ static int UpdatePictureStruct( vout_thread_t *p_vout, picture_t *p_pic,
p_pic->p->i_pixel_pitch = 4;
break;
default:
return -1;
return VLC_EGENERIC;
}
p_pic->p->i_visible_pitch = p_vout->output.i_width *
p_pic->p->i_pixel_pitch;
......@@ -1284,11 +1314,10 @@ static int UpdatePictureStruct( vout_thread_t *p_vout, picture_t *p_pic,
default:
/* Not supported */
return 0;
return VLC_EGENERIC;
}
return 1;
return VLC_SUCCESS;
}
/*****************************************************************************
......@@ -1374,11 +1403,11 @@ static int DirectXGetSurfaceDesc( picture_t *p_pic )
if( dxresult != DD_OK )
{
//X msg_Err( p_vout, "DirectXGetSurfaceDesc cannot lock surface" );
return 0;
return VLC_EGENERIC;
}
/* Unlock the Surface */
dxresult = IDirectDrawSurface2_Unlock( p_pic->p_sys->p_surface, NULL );
return 1;
return VLC_SUCCESS;
}
......@@ -2,7 +2,7 @@
* events.c: Windows DirectX video output events handler
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: events.c,v 1.5 2002/10/17 17:30:10 ipkiss Exp $
* $Id: events.c,v 1.6 2002/10/25 18:17:59 sam Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -49,7 +49,6 @@
*****************************************************************************/
static int DirectXCreateWindow( vout_thread_t *p_vout );
static void DirectXCloseWindow ( vout_thread_t *p_vout );
static void DirectXUpdateRects( vout_thread_t *p_vout );
static long FAR PASCAL DirectXEventProc ( HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam );
......@@ -72,11 +71,11 @@ void DirectXEventThread( event_thread_t *p_event )
/* Create a window for the video */
/* Creating a window under Windows also initializes the thread's event
* message qeue */
* message queue */
if( DirectXCreateWindow( p_event->p_vout ) )
{
msg_Err( p_event, "out of memory" );
p_event->b_dead = 1;
p_event->b_dead = VLC_TRUE;
}
/* signal the creation of the window */
......@@ -164,7 +163,7 @@ void DirectXEventThread( event_thread_t *p_event )
{
case VK_ESCAPE:
/* exit application */
p_event->p_vlc->b_die = 1;
p_event->p_vlc->b_die = VLC_TRUE;
break;
case VK_F1: network_ChannelJoin( p_event, 1 ); break;
......@@ -189,7 +188,7 @@ void DirectXEventThread( event_thread_t *p_event )
case 'q':
case 'Q':
/* exit application */
p_event->p_vlc->b_die = 1;
p_event->p_vlc->b_die = VLC_TRUE;
break;
case 'f': /* switch to fullscreen */
......@@ -241,7 +240,7 @@ void DirectXEventThread( event_thread_t *p_event )
p_event->p_vout->p_sys->hwnd = NULL; /* Window already destroyed */
}
msg_Dbg( p_event, "DirectXEventThread Terminating" );
msg_Dbg( p_event, "DirectXEventThread terminating" );
/* clear the changes formerly signaled */
p_event->p_vout->p_sys->i_changes = 0;
......@@ -262,17 +261,14 @@ void DirectXEventThread( event_thread_t *p_event )
static int DirectXCreateWindow( vout_thread_t *p_vout )
{
HINSTANCE hInstance;
WNDCLASSEX wc; /* window class components */
RECT rect_window;
COLORREF colorkey;
COLORREF colorkey;
HDC hdc;
HMENU hMenu;
HICON vlc_icon = NULL;
char vlc_path[MAX_PATH+1];
RECT rect_window;
msg_Dbg( p_vout, "DirectXCreateWindow" );
/* get this module's instance */
/* Get this module's instance */
hInstance = GetModuleHandle(NULL);
/* Create a BRUSH that will be used by Windows to paint the window
......@@ -288,14 +284,16 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
* comes from the potential dithering (depends on the display depth)
* because we need to know the real RGB value of the chosen colorkey */
hdc = GetDC( NULL );
for( colorkey = 5; colorkey < 0xFF /*all shades of red*/; colorkey++ )
for( colorkey = 0x0a; colorkey < 0xff /* all shades of red */; colorkey++ )
{
if( colorkey == GetNearestColor( hdc, colorkey ) )
break;
{
break;
}
}
msg_Dbg( p_vout, "background color: %i", colorkey );
/* create the actual brush */
/* Create the actual brush */
p_vout->p_sys->hbrush = CreateSolidBrush(colorkey);
p_vout->p_sys->i_rgb_colorkey = (int)colorkey;
......@@ -310,66 +308,98 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
ReleaseDC( NULL, hdc );
/* Get the Icon from the main app */
vlc_icon = NULL;
if( GetModuleFileName( NULL, vlc_path, MAX_PATH ) )
/* If an external window was specified, we'll draw in it. */
p_vout->p_sys->hparent = p_vout->p_sys->hwnd =
(void*)(ptrdiff_t)config_GetInt( p_vout, "directx-window" );
if( p_vout->p_sys->hparent )
{
vlc_icon = ExtractIcon( hInstance, vlc_path, 0 );
msg_Dbg( p_vout, "using external window %p\n", p_vout->p_sys->hwnd );
/* Set stuff in the window that we can not put directly in
* a class (see below). */
SetClassLong( p_vout->p_sys->hwnd,
GCL_STYLE, CS_DBLCLKS );
SetClassLong( p_vout->p_sys->hwnd,
GCL_HBRBACKGROUND, (LONG)p_vout->p_sys->hbrush );
SetClassLong( p_vout->p_sys->hwnd,
GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_ARROW) );
p_vout->p_sys->pf_wndproc =
(WNDPROC)SetWindowLong( p_vout->p_sys->hwnd,
GWL_WNDPROC, (LONG)DirectXEventProc );
/* Blam! Erase everything that might have been there. */
RedrawWindow( p_vout->p_sys->hwnd, NULL, NULL,
RDW_INVALIDATE | RDW_ERASE );
}
/* fill in the window class structure */
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_DBLCLKS; /* style: dbl click */
wc.lpfnWndProc = (WNDPROC)DirectXEventProc; /* event handler */
wc.cbClsExtra = 0; /* no extra class data */
wc.cbWndExtra = 0; /* no extra window data */
wc.hInstance = hInstance; /* instance */
wc.hIcon = vlc_icon; /* load the vlc icon */
wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* load a default cursor */
wc.hbrBackground = p_vout->p_sys->hbrush; /* background color */
wc.lpszMenuName = NULL; /* no menu */
wc.lpszClassName = "VLC DirectX"; /* use a special class */
wc.hIconSm = vlc_icon; /* load the vlc icon */
/* register the window class */
if (!RegisterClassEx(&wc))
else
{
WNDCLASS wndclass;
WNDCLASSEX wc; /* window class components */
HICON vlc_icon = NULL;
char vlc_path[MAX_PATH+1];
/* free window background brush */
if( p_vout->p_sys->hbrush )
/* Get the Icon from the main app */
vlc_icon = NULL;
if( GetModuleFileName( NULL, vlc_path, MAX_PATH ) )
{
DeleteObject( p_vout->p_sys->hbrush );
p_vout->p_sys->hbrush = NULL;
vlc_icon = ExtractIcon( hInstance, vlc_path, 0 );
}
if( vlc_icon )
DestroyIcon( vlc_icon );
/* Check why it failed. If it's because one already exists then fine */
if( !GetClassInfo( hInstance, "VLC DirectX", &wndclass ) )
/* Fill in the window class structure */
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_DBLCLKS; /* style: dbl click */
wc.lpfnWndProc = (WNDPROC)DirectXEventProc; /* event handler */
wc.cbClsExtra = 0; /* no extra class data */
wc.cbWndExtra = 0; /* no extra window data */
wc.hInstance = hInstance; /* instance */
wc.hIcon = vlc_icon; /* load the vlc big icon */
wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* default cursor */
wc.hbrBackground = p_vout->p_sys->hbrush; /* background color */
wc.lpszMenuName = NULL; /* no menu */
wc.lpszClassName = "VLC DirectX"; /* use a special class */
wc.hIconSm = vlc_icon; /* load the vlc small icon */
/* Register the window class */
if( !RegisterClassEx(&wc) )
{
msg_Err( p_vout, "DirectXCreateWindow RegisterClass FAILED" );
return (1);
WNDCLASS wndclass;
/* Free window background brush */
if( p_vout->p_sys->hbrush )
{
DeleteObject( p_vout->p_sys->hbrush );
p_vout->p_sys->hbrush = NULL;
}
if( vlc_icon )
{
DestroyIcon( vlc_icon );
}
/* Check why it failed. If it's because one already exists
* then fine, otherwise return with an error. */
if( !GetClassInfo( hInstance, "VLC DirectX", &wndclass ) )
{
msg_Err( p_vout, "DirectXCreateWindow RegisterClass FAILED" );
return VLC_EGENERIC;
}
}
}
/* when you create a window you give the dimensions you wish it to have.
* Unfortunatly these dimensions will include the borders and title bar.
* We use the following function to find out the size of the window
* corresponding to the useable surface we want */
rect_window.top = 10;
rect_window.left = 10;
rect_window.right = rect_window.left + p_vout->p_sys->i_window_width;
rect_window.bottom = rect_window.top + p_vout->p_sys->i_window_height;
AdjustWindowRect( &rect_window, WS_OVERLAPPEDWINDOW|WS_SIZEBOX, 0 );
/* create the window */
p_vout->p_sys->hwnd = CreateWindow("VLC DirectX",/* name of window class */
/* When you create a window you give the dimensions you wish it to
* have. Unfortunatly these dimensions will include the borders and
* titlebar. We use the following function to find out the size of
* the window corresponding to the useable surface we want */
rect_window.top = 10;
rect_window.left = 10;
rect_window.right = rect_window.left + p_vout->p_sys->i_window_width;
rect_window.bottom = rect_window.top + p_vout->p_sys->i_window_height;
AdjustWindowRect( &rect_window, WS_OVERLAPPEDWINDOW|WS_SIZEBOX, 0 );
/* Create the window */
p_vout->p_sys->hwnd =
CreateWindow( "VLC DirectX", /* name of window class */
VOUT_TITLE " (DirectX Output)", /* window title bar text */
WS_OVERLAPPEDWINDOW
| WS_SIZEBOX, /* window style */
WS_OVERLAPPEDWINDOW | WS_SIZEBOX, /* window style */
CW_USEDEFAULT, /* default X coordinate */
0, /* default Y coordinate */
rect_window.right - rect_window.left, /* window width */
......@@ -379,25 +409,28 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
hInstance, /* handle of this program instance */
NULL); /* no additional arguments */
if (p_vout->p_sys->hwnd == NULL) {
msg_Warn( p_vout, "DirectXCreateWindow create window FAILED" );
return (1);
if( !p_vout->p_sys->hwnd )
{
msg_Warn( p_vout, "DirectXCreateWindow create window FAILED" );
return VLC_EGENERIC;
}
}
/* store a p_vout pointer into the window local storage (for later use
/* Store a p_vout pointer into the window local storage (for later use
* in DirectXEventProc).
* We need to use SetWindowLongPtr when it is available in mingw */
SetWindowLong( p_vout->p_sys->hwnd, GWL_USERDATA, (LONG)p_vout );
/* append a "Always On Top" entry in the system menu */
/* Append a "Always On Top" entry in the system menu */
hMenu = GetSystemMenu( p_vout->p_sys->hwnd, FALSE );
AppendMenu( hMenu, MF_SEPARATOR, 0, "" );
AppendMenu( hMenu, MF_STRING | MF_UNCHECKED, IDM_TOGGLE_ON_TOP, "Always on &Top");
AppendMenu( hMenu, MF_STRING | MF_UNCHECKED,
IDM_TOGGLE_ON_TOP, "Always on &Top" );
/* now display the window */
ShowWindow(p_vout->p_sys->hwnd, SW_SHOW);
/* Now display the window */
ShowWindow( p_vout->p_sys->hwnd, SW_SHOW );
return ( 0 );
return VLC_SUCCESS;
}
/*****************************************************************************
......@@ -409,50 +442,77 @@ static void DirectXCloseWindow( vout_thread_t *p_vout )
{
msg_Dbg( p_vout, "DirectXCloseWindow" );
if( p_vout->p_sys->hwnd != NULL )
if( p_vout->p_sys->hwnd && !p_vout->p_sys->hparent )
{
DestroyWindow( p_vout->p_sys->hwnd );
p_vout->p_sys->hwnd = NULL;
}
p_vout->p_sys->hwnd = NULL;
/* We don't unregister the Window Class because it could lead to race
* conditions and it will be done anyway by the system when the app will
* exit */
}
/*****************************************************************************
* DirectXUpdateRects:
* DirectXUpdateRects: update clipping rectangles
*****************************************************************************
* This function is called when the window position and size is changed, and
* This function is called when the window position or size are changed, and
* its job is to update the source and destination RECTs used to display the
* picture.
*****************************************************************************/
static void DirectXUpdateRects( vout_thread_t *p_vout )
void DirectXUpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force )
{
int i_width, i_height, i_x, i_y;
#define rect_src p_vout->p_sys->rect_src
#define rect_src_clipped p_vout->p_sys->rect_src_clipped
#define rect_dest p_vout->p_sys->rect_dest
#define rect_dest_clipped p_vout->p_sys->rect_dest_clipped
#define rect_display p_vout->p_sys->rect_display
vout_PlacePicture( p_vout, p_vout->p_sys->i_window_width,
p_vout->p_sys->i_window_height,
int i_width, i_height, i_x, i_y;
RECT rect;
POINT point;
/* Retrieve the window size */
GetClientRect( p_vout->p_sys->hwnd, &rect );
/* Retrieve the window position */
point.x = point.y = 0;
ClientToScreen( p_vout->p_sys->hwnd, &point );
/* If nothing changed, we can return */
if( !b_force
&& p_vout->p_sys->i_window_width == rect.right
&& p_vout->p_sys->i_window_height == rect.bottom
&& p_vout->p_sys->i_window_x == point.x
&& p_vout->p_sys->i_window_y == point.y )
{
return;
}
/* Update the window position and size */
p_vout->p_sys->i_window_x = point.x;
p_vout->p_sys->i_window_y = point.y;
p_vout->p_sys->i_window_width = rect.right;
p_vout->p_sys->i_window_height = rect.bottom;
vout_PlacePicture( p_vout, rect.right, rect.bottom,
&i_x, &i_y, &i_width, &i_height );
/* Destination image position and dimensions */
rect_dest.left = i_x + p_vout->p_sys->i_window_x;
rect_dest.top = i_y + p_vout->p_sys->i_window_y;
rect_dest.left = point.x + i_x;
rect_dest.right = rect_dest.left + i_width;
rect_dest.top = point.y + i_y;
rect_dest.bottom = rect_dest.top + i_height;
/* UpdateOverlay directdraw function doesn't automatically clip to the
* display size so we need to do it otherwise it will fails */
* display size so we need to do it otherwise it will fail */
/* Clip the destination window */
IntersectRect( &rect_dest_clipped, &rect_dest, &rect_display );
IntersectRect( &rect_dest_clipped,
&rect_dest,
&p_vout->p_sys->rect_display );
#if 0
msg_Dbg( p_vout, "DirectXUpdateRects image_dst_clipped coords:"
......@@ -478,7 +538,7 @@ static void DirectXUpdateRects( vout_thread_t *p_vout )
/* Clip the source image */
rect_src_clipped.left = (rect_dest_clipped.left - rect_dest.left) *
p_vout->render.i_width / (rect_dest.right - rect_dest.left);
rect_src_clipped.right = p_vout->render.i_width -
rect_src_clipped.right = p_vout->render.i_width -
(rect_dest.right - rect_dest_clipped.right) * p_vout->render.i_width /
(rect_dest.right - rect_dest.left);
rect_src_clipped.top = (rect_dest_clipped.top - rect_dest.top) *
......@@ -494,11 +554,23 @@ static void DirectXUpdateRects( vout_thread_t *p_vout )
rect_src_clipped.right, rect_src_clipped.bottom );
#endif
/* Signal the size change */
if( !p_vout->p_sys->p_event->b_die )
{
if( p_vout->p_sys->b_using_overlay )
{
DirectXUpdateOverlay( p_vout );
}
else
{
p_vout->p_sys->i_changes |= VOUT_SIZE_CHANGE;
}
}
#undef rect_src
#undef rect_src_clipped
#undef rect_dest
#undef rect_dest_clipped
#undef rect_display
}
/*****************************************************************************
......@@ -518,47 +590,25 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
vout_thread_t *p_vout =
(vout_thread_t *)GetWindowLong( hwnd, GWL_USERDATA );
/* Just in case the window wasn't properly initialized yet */
if( !p_vout )
{
return DefWindowProc( hwnd, message, wParam, lParam );
}
switch( message )
{
case WM_WINDOWPOSCHANGED:
{
RECT rect_window;
POINT point_window;
/* update the window position */
point_window.x = 0;
point_window.y = 0;
ClientToScreen( hwnd, &point_window );
p_vout->p_sys->i_window_x = point_window.x;
p_vout->p_sys->i_window_y = point_window.y;
/* update the window size */
GetClientRect( hwnd, &rect_window );
p_vout->p_sys->i_window_width = rect_window.right;
p_vout->p_sys->i_window_height = rect_window.bottom;
DirectXUpdateRects( p_vout );
if( p_vout->p_sys->b_using_overlay &&
!p_vout->p_sys->p_event->b_die )
DirectXUpdateOverlay( p_vout );
/* signal the size change */
if( !p_vout->p_sys->b_using_overlay &&
!p_vout->p_sys->p_event->b_die )
p_vout->p_sys->i_changes |= VOUT_SIZE_CHANGE;
DirectXUpdateRects( p_vout, VLC_TRUE );
return 0;
}
break;
/* the user wants to close the window */
case WM_CLOSE:
msg_Dbg( p_vout, "WinProc WM_CLOSE" );
/* exit application */
p_vout->p_vlc->b_die = 1;
p_vout->p_vlc->b_die = VLC_TRUE;
return 0;
break;
/* the window has been closed so shut down everything now */
case WM_DESTROY:
......@@ -566,7 +616,6 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
/* just destroy the window */
PostQuitMessage( 0 );
return 0;
break;
case WM_SYSCOMMAND:
switch (wParam)
......@@ -632,3 +681,4 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
return DefWindowProc(hwnd, message, wParam, lParam);
}
......@@ -2,7 +2,7 @@
* vout.h: Windows DirectX video output header file
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vout.h,v 1.2 2002/10/01 20:43:35 ipkiss Exp $
* $Id: vout.h,v 1.3 2002/10/25 18:17:59 sam Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -46,7 +46,10 @@ struct vout_sys_t
LPDIRECTDRAWCLIPPER p_clipper; /* clipper used for blitting */
HINSTANCE hddraw_dll; /* handle of the opened ddraw dll */
HBRUSH hbrush; /* window backgound brush (color) */
HWND hwnd; /* Handle of the main window */
HWND hparent; /* Handle of the parent window */
WNDPROC pf_wndproc; /* Window handling callback */
vlc_bool_t b_using_overlay; /* Are we using an overlay surface */
vlc_bool_t b_use_sysmem; /* Should we use system memory for surfaces */
......@@ -99,12 +102,13 @@ struct picture_sys_t
/*****************************************************************************
* Prototypes from vout.c
*****************************************************************************/
void DirectXUpdateOverlay( vout_thread_t *p_vout );
/*****************************************************************************
* Prototypes from events.c
*****************************************************************************/
void DirectXEventThread ( event_thread_t *p_event );
void DirectXUpdateOverlay( vout_thread_t *p_vout );
void DirectXUpdateRects ( vout_thread_t *p_vout, vlc_bool_t b_force );
/*****************************************************************************
* Constants
......
*.dll
vlcintf.h
vlcintf.xpt
.deps
......
......@@ -2,7 +2,7 @@
* vlcplugin.h: a VideoLAN plugin for Mozilla
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: vlcplugin.h,v 1.6 2002/10/22 21:10:28 sam Exp $
* $Id: vlcplugin.h,v 1.7 2002/10/25 18:17:59 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -37,17 +37,20 @@ public:
void SetFileName( const char* );
/* Window settings */
NPWindow* fWindow;
uint16 fMode;
NPWindow* p_npwin;
uint16 i_npmode;
uint32 i_width, i_height;
#ifdef WIN32
#ifdef XP_WIN
/* Windows data members */
HWND p_hwnd;
WNDPROC pf_wndproc;
#endif
#else
#ifdef XP_UNIX
/* UNIX data members */
Window window;
Display *display;
uint32 x, y;
uint32 width, height;
Window window;
Display *p_display;
#endif
/* vlc data members */
......
......@@ -2,7 +2,7 @@
* vlcshell.c: a VideoLAN Client plugin for Mozilla
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: vlcshell.cpp,v 1.5 2002/10/22 21:10:28 sam Exp $
* $Id: vlcshell.cpp,v 1.6 2002/10/25 18:17:59 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -33,9 +33,11 @@
/* Mozilla stuff */
#include <npapi.h>
#ifdef WIN32
#ifdef XP_WIN
/* Windows stuff */
#endif
#else
#ifdef XP_UNIX
/* X11 stuff */
# include <X11/Xlib.h>
# include <X11/Intrinsic.h>
......@@ -45,17 +47,32 @@
#include "vlcpeer.h"
#include "vlcplugin.h"
/* XXX: disable VLC */
#define USE_LIBVLC 1
#if USE_LIBVLC
# define WINDOW_TEXT "(no picture)"
#else
# define WINDOW_TEXT "(no libvlc)"
#endif
/*****************************************************************************
* Unix-only declarations
******************************************************************************/
#ifndef WIN32
#ifdef XP_UNIX
# define VOUT_PLUGINS "xvideo,x11,dummy"
# define AOUT_PLUGINS "dsp,dummy"
static void Redraw( Widget w, XtPointer closure, XEvent *event );
#endif
/*****************************************************************************
* Windows-only declarations
*****************************************************************************/
#ifdef WIN32
#ifdef XP_WIN
# define VOUT_PLUGINS "directx,dummy"
# define AOUT_PLUGINS "none" /* "directx,waveout,dummy" */
HINSTANCE g_hDllInstance = NULL;
BOOL WINAPI
......@@ -63,17 +80,20 @@ DllMain( HINSTANCE hinstDLL, // handle of DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
g_hDllInstance = hinstDLL;
break;
case DLL_THREAD_ATTACH:
case DLL_PROCESS_DETACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hDllInstance = hinstDLL;
break;
case DLL_THREAD_ATTACH:
case DLL_PROCESS_DETACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
LRESULT CALLBACK Manage( HWND, UINT, WPARAM, LPARAM );
#endif
/******************************************************************************
......@@ -96,7 +116,11 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value )
return NPERR_NO_ERROR;
case NPPVpluginDescriptionString:
#if USE_LIBVLC
snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, VLC_Version() );
#else
snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, "(disabled)" );
#endif
psz_desc[1000-1] = 0;
*((char **)value) = psz_desc;
return NPERR_NO_ERROR;
......@@ -160,15 +184,17 @@ void NPP_Shutdown( void )
NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
char* argn[], char* argv[], NPSavedData* saved )
{
int i;
#if USE_LIBVLC
vlc_value_t value;
int i_ret;
int i;
char *ppsz_foo[] =
{
"vlc"
/*, "--plugin-path", "/home/sam/videolan/vlc_MAIN/plugins"*/
};
#endif
if( instance == NULL )
{
......@@ -184,14 +210,22 @@ NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
instance->pdata = p_plugin;
p_plugin->fMode = mode;
p_plugin->fWindow = NULL;
#ifdef WIN32
#ifdef XP_WIN
p_plugin->p_hwnd = NULL;
p_plugin->pf_wndproc = NULL;
#endif
#else
#ifdef XP_UNIX
p_plugin->window = 0;
p_plugin->p_display = NULL;
#endif
p_plugin->p_npwin = NULL;
p_plugin->i_npmode = mode;
p_plugin->i_width = 0;
p_plugin->i_height = 0;
#if USE_LIBVLC
p_plugin->i_vlc = VLC_Create();
if( p_plugin->i_vlc < 0 )
{
......@@ -213,21 +247,18 @@ NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
value.psz_string = "dummy";
VLC_Set( p_plugin->i_vlc, "conf::intf", value );
#ifdef WIN32
value.psz_string = "directx,dummy";
#else
value.psz_string = "xvideo,x11,dummy";
#endif
value.psz_string = VOUT_PLUGINS;
VLC_Set( p_plugin->i_vlc, "conf::vout", value );
#ifdef WIN32
value.psz_string = "none";//"directx,waveout,dummy";
#else
value.psz_string = "dsp,dummy";
#endif
value.psz_string = AOUT_PLUGINS;
VLC_Set( p_plugin->i_vlc, "conf::aout", value );
p_plugin->b_stream = 0;
p_plugin->b_autoplay = 0;
#else
p_plugin->i_vlc = 1;
#endif /* USE_LIBVLC */
p_plugin->b_stream = VLC_FALSE;
p_plugin->b_autoplay = VLC_FALSE;
p_plugin->psz_target = NULL;
for( i = 0; i < argc ; i++ )
......@@ -243,6 +274,7 @@ NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
p_plugin->b_autoplay = 1;
}
}
#if USE_LIBVLC
else if( !strcmp( argn[i], "loop" ) )
{
if( !strcmp( argv[i], "yes" ) )
......@@ -251,6 +283,7 @@ NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
VLC_Set( p_plugin->i_vlc, "conf::loop", value );
}
}
#endif
}
if( p_plugin->psz_target )
......@@ -274,8 +307,10 @@ NPError NPP_Destroy( NPP instance, NPSavedData** save )
{
if( p_plugin->i_vlc )
{
#if USE_LIBVLC
VLC_Stop( p_plugin->i_vlc );
VLC_Destroy( p_plugin->i_vlc );
#endif
p_plugin->i_vlc = 0;
}
......@@ -295,8 +330,6 @@ NPError NPP_Destroy( NPP instance, NPSavedData** save )
NPError NPP_SetWindow( NPP instance, NPWindow* window )
{
vlc_value_t value;
if( instance == NULL )
{
return NPERR_INVALID_INSTANCE_ERROR;
......@@ -305,13 +338,18 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
/* Write the window ID for vlc */
//value.p_address = (void*)window->window;
//VLC_Set( p_plugin->i_vlc, "drawable", value );
#if USE_LIBVLC
vlc_value_t value;
/* FIXME: this cast sucks */
value.i_int = (int) (long long) (void *) window->window;
value.i_int = (int) (ptrdiff_t) (void *) window->window;
VLC_Set( p_plugin->i_vlc, "conf::x11-drawable", value );
VLC_Set( p_plugin->i_vlc, "conf::xvideo-drawable", value );
value.i_int = (int) (ptrdiff_t) (void *) window->window;
VLC_Set( p_plugin->i_vlc, "conf::directx-window", value );
#endif
/*
* PLUGIN DEVELOPERS:
* Before setting window to point to the
......@@ -320,26 +358,67 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
* size changes, etc.
*/
#ifdef WIN32
#ifdef XP_WIN
if( !window || !window->window )
{
/* Window was destroyed. Invalidate everything. */
if( p_plugin->p_npwin )
{
SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC,
(LONG)p_plugin->pf_wndproc );
p_plugin->pf_wndproc = NULL;
p_plugin->p_hwnd = NULL;
}
#else
Widget netscape_widget;
p_plugin->p_npwin = window;
return NPERR_NO_ERROR;
}
if( p_plugin->p_npwin )
{
if( p_plugin->p_hwnd == (HWND)window->window )
{
/* Same window, but something may have changed. First we
* update the plugin structure, then we redraw the window */
InvalidateRect( p_plugin->p_hwnd, NULL, TRUE );
p_plugin->i_width = window->width;
p_plugin->i_height = window->height;
p_plugin->p_npwin = window;
UpdateWindow( p_plugin->p_hwnd );
return NPERR_NO_ERROR;
}
/* Window has changed. Destroy the one we have, and go
* on as if it was a real initialization. */
SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC,
(LONG)p_plugin->pf_wndproc );
p_plugin->pf_wndproc = NULL;
p_plugin->p_hwnd = NULL;
}
p_plugin->pf_wndproc = (WNDPROC)SetWindowLong( (HWND)window->window,
GWL_WNDPROC, (LONG)Manage );
p_plugin->p_hwnd = (HWND)window->window;
SetProp( p_plugin->p_hwnd, "w00t", (HANDLE)p_plugin );
InvalidateRect( p_plugin->p_hwnd, NULL, TRUE );
UpdateWindow( p_plugin->p_hwnd );
#endif
#ifdef XP_UNIX
p_plugin->window = (Window) window->window;
p_plugin->x = window->x;
p_plugin->y = window->y;
p_plugin->width = window->width;
p_plugin->height = window->height;
p_plugin->display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
netscape_widget = XtWindowToWidget(p_plugin->display, p_plugin->window);
XtAddEventHandler(netscape_widget, ExposureMask, FALSE, (XtEventHandler)Redraw, p_plugin);
Redraw(netscape_widget, (XtPointer)p_plugin, NULL);
p_plugin->p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
Widget w = XtWindowToWidget( p_plugin->p_display, p_plugin->window );
XtAddEventHandler( w, ExposureMask, FALSE,
(XtEventHandler)Redraw, p_plugin );
Redraw( w, (XtPointer)p_plugin, NULL );
#endif
p_plugin->fWindow = window;
p_plugin->p_npwin = window;
p_plugin->i_width = window->width;
p_plugin->i_height = window->height;
#if 1
if( !p_plugin->b_stream )
{
int i_mode = PLAYLIST_APPEND;
......@@ -351,12 +430,13 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
if( p_plugin->psz_target )
{
#if USE_LIBVLC
VLC_AddTarget( p_plugin->i_vlc, p_plugin->psz_target,
i_mode, PLAYLIST_END );
p_plugin->b_stream = 1;
#endif
p_plugin->b_stream = VLC_TRUE;
}
}
#endif
return NPERR_NO_ERROR;
}
......@@ -379,10 +459,10 @@ NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream *stream,
*stype = NP_ASFILE;
#if 0
if( p_plugin->b_stream == 0 )
if( !p_plugin->b_stream )
{
p_plugin->psz_target = strdup( stream->url );
p_plugin->b_stream = 1;
p_plugin->b_stream = VLC_TRUE;
}
#endif
......@@ -447,22 +527,15 @@ void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
return;
}
fprintf(stderr, "NPP_StreamAsFile %s\n", fname);
#if USE_LIBVLC
VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
fprintf(stderr, "NPP_StreamAsFile\n");
VLC_AddTarget( p_plugin->i_vlc, fname,
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
}
#if 0
void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
{
fprintf(stderr,"filename : %s\n", fname);
((VlcPlugin*) instance->pdata)->SetFileName(fname);
fprintf(stderr,"SetFileNeme ok. \n");
}
#endif
}
void NPP_URLNotify( NPP instance, const char* url,
......@@ -543,31 +616,66 @@ void NPP_Print( NPP instance, NPPrint* printInfo )
}
}
/******************************************************************************
* Windows-only methods
*****************************************************************************/
#ifdef XP_WIN
LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar )
{
VlcPlugin* p_plugin = (VlcPlugin*) GetProp( p_hwnd, "w00t" );
switch( i_msg )
{
#if !USE_LIBVLC
case WM_PAINT:
{
PAINTSTRUCT paintstruct;
HDC hdc;
RECT rect;
hdc = BeginPaint( p_hwnd, &paintstruct );
GetClientRect( p_hwnd, &rect );
FillRect( hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH) );
TextOut( hdc, p_plugin->i_width / 2 - 40, p_plugin->i_height / 2,
WINDOW_TEXT, strlen(WINDOW_TEXT) );
EndPaint( p_hwnd, &paintstruct );
break;
}
#endif
default:
p_plugin->pf_wndproc( p_hwnd, i_msg, wpar, lpar );
break;
}
return 0;
}
#endif
/******************************************************************************
* UNIX-only methods
*****************************************************************************/
#ifndef WIN32
#ifdef XP_UNIX
static void Redraw( Widget w, XtPointer closure, XEvent *event )
{
VlcPlugin* p_plugin = (VlcPlugin*)closure;
GC gc;
XGCValues gcv;
const char * psz_text = "(no picture)";
gcv.foreground = BlackPixel( p_plugin->display, 0 );
gc = XCreateGC( p_plugin->display, p_plugin->window, GCForeground, &gcv );
gcv.foreground = BlackPixel( p_plugin->p_display, 0 );
gc = XCreateGC( p_plugin->p_display, p_plugin->window, GCForeground, &gcv );
XFillRectangle( p_plugin->display, p_plugin->window, gc,
0, 0, p_plugin->width, p_plugin->height );
XFillRectangle( p_plugin->p_display, p_plugin->window, gc,
0, 0, p_plugin->i_width, p_plugin->i_height );
gcv.foreground = WhitePixel( p_plugin->display, 0 );
XChangeGC( p_plugin->display, gc, GCForeground, &gcv );
gcv.foreground = WhitePixel( p_plugin->p_display, 0 );
XChangeGC( p_plugin->p_display, gc, GCForeground, &gcv );
XDrawString( p_plugin->display, p_plugin->window, gc,
p_plugin->width / 2 - 40, p_plugin->height / 2,
psz_text, strlen(psz_text) );
XDrawString( p_plugin->p_display, p_plugin->window, gc,
p_plugin->i_width / 2 - 40, p_plugin->i_height / 2,
WINDOW_TEXT, strlen(WINDOW_TEXT) );
XFreeGC( p_plugin->display, gc );
XFreeGC( p_plugin->p_display, gc );
}
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment