2024-09-29 02:04:03 +00:00
# include <archx.h>
2024-09-24 12:54:57 +00:00
# include "main.h"
# include "VideoOutput.h"
# include "VideoOutputChild.h"
# include "vid_none.h"
# include "vid_ddraw.h"
# include "vid_overlay.h"
# include "vid_d3d.h"
# include <cassert>
# include "directdraw.h"
# include "video.h"
# include "api.h"
# include "WinampAttributes.h"
# include "resource.h"
# include "../nu/AutoWide.h"
# include "stats.h"
# include "IVideoD3DOSD.h"
extern " C " int is_fullscreen_video ;
# define WM_VIDEO_UPDATE_STATUS_TEXT WM_USER+0x874
# define WM_VIDEO_OPEN WM_USER+0x875
# define WM_VIDEO_CLOSE WM_USER+0x876
# define WM_VIDEO_RESIZE WM_USER+0x877
# define WM_VIDEO_OSDCHANGE WM_USER+0x888
# define WM_VIDEO_CREATE WM_USER+0x900
int g_bitmap_id = IDB_VIDEOLOGO ;
int VideoOutput : : class_refcnt = 0 ;
wchar_t vidoutbuf_save [ 1024 ] = { 0 } ;
static bool input_plugin_thread_safe = false ;
//#define USE_GDIPLUS_VIDEO_RENDERER
IVideoOSD * posd = new IVideoD3DOSD ;
HRESULT ( WINAPI * _DirectDrawCreate ) ( GUID FAR * lpGUID , LPDIRECTDRAW FAR * lplpDD , IUnknown FAR * pUnkOuter ) = 0 ;
void OpenDirectDraw ( )
{
static int a = 0 ;
if ( ! _DirectDrawCreate & & ! a )
{
a + + ;
HINSTANCE h = LoadLibraryW ( L " ddraw.dll " ) ;
if ( h )
{
* ( void * * ) & _DirectDrawCreate = ( void * ) GetProcAddress ( h , " DirectDrawCreate " ) ;
}
}
}
HMENU BuildPopupMenu ( )
{
HMENU menu = GetSubMenu ( GetSubMenu ( top_menu , 3 ) , 13 ) ;
{
static int menuset = 0 ;
if ( ! menuset )
{
InsertMenu ( menu , ( UINT ) - 1 , MF_BYPOSITION | MF_SEPARATOR , 0 , 0 ) ;
InsertMenuA ( menu , ( UINT ) - 1 , MF_BYPOSITION | MF_POPUP , ( UINT_PTR ) GetSubMenu ( top_menu , 0 ) , " Winamp " ) ;
menuset = 1 ;
}
}
updateTrackSubmenu ( ) ;
return menu ;
}
void VideoOutput : : mainthread_Create ( )
{
if ( ! video_created )
{
m_video_output = new Direct3DVideoOutput ( video_hwnd , this ) ;
video_created = true ;
}
}
VideoOutput : : VideoOutput ( HWND parent_hwnd , int initxpos , int initypos )
: m_logo ( 0 ) ,
m_logo_w ( 0 ) ,
m_logo_h ( 0 ) ,
userVideo ( false )
{
video_palette = 0 ;
video_created = false ;
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::VideoOutput " ) ) ;
WNDCLASSW wc = { 0 , } ;
wc . style = CS_DBLCLKS ;
wc . hCursor = LoadCursor ( NULL , IDC_ARROW ) ;
wc . lpfnWndProc = WndProc ;
wc . hInstance = GetModuleHandle ( NULL ) ;
wc . lpszClassName = L " WinampVideoChild " ;
wc . hbrBackground = ( HBRUSH ) GetStockObject ( WHITE_BRUSH ) ;
if ( ! class_refcnt ) RegisterClassW ( & wc ) ;
class_refcnt + + ;
m_tracksel = NULL ;
fs_reparented_rgn = 0 ;
fs_reparented = 0 ;
m_ignore_change = false ;
fs_has_resized = false ;
m_opened = 0 ;
last_fullscreen_exit_time = 0 ;
curSubtitle = NULL ;
m_statusmsg = 0 ;
m_bufferstate = - 1 ;
m_msgcallback = 0 ;
m_msgcallback_tok = 0 ;
video_hwnd = 0 ;
aspect = 1.0 ;
m_need_change = false ;
is_fs = 0 ;
memset ( & oldfsrect , 0 , sizeof ( oldfsrect ) ) ;
memset ( & lastfsrect , 0 , sizeof ( lastfsrect ) ) ;
m_video_output = NULL ;
resetSubtitle ( ) ;
m_lastbufinvalid = NULL ;
CreateWindowExW ( 0 , wc . lpszClassName , L " WinampVideoChildWindow " ,
parent_hwnd ? WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS :
( WS_OVERLAPPEDWINDOW & ( ~ WS_MAXIMIZEBOX ) ) ,
0 , 0 , 1 , 1 ,
parent_hwnd , NULL , wc . hInstance , ( void * ) this ) ;
posd - > SetParent ( video_hwnd ) ;
}
VideoOutput : : ~ VideoOutput ( )
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::~VideoOutput " ) ) ;
free ( m_statusmsg ) ;
posd - > Hide ( ) ;
if ( m_video_output ) m_video_output - > close ( ) ;
m_video_output = 0 ;
DestroyWindow ( video_hwnd ) ;
if ( m_logo )
DeleteObject ( m_logo ) ;
m_logo = 0 ;
if ( posd )
{
delete posd ;
posd = NULL ;
}
}
void VideoOutput : : LoadLogo ( )
{
static wchar_t logo_tmp [ MAX_PATH ] ;
if ( ! logo_tmp [ 0 ] ) StringCchPrintfW ( logo_tmp , MAX_PATH , L " %s \\ videologo.bmp " , CONFIGDIR ) ;
if ( PathFileExistsW ( logo_tmp ) ) m_logo = ( HBITMAP ) LoadImageW ( 0 , logo_tmp , IMAGE_BITMAP , 0 , 0 , LR_LOADFROMFILE ) ;
if ( ! m_logo ) m_logo = ( HBITMAP ) LoadImage ( hMainInstance , MAKEINTRESOURCE ( g_bitmap_id ) , IMAGE_BITMAP , 0 , 0 , LR_CREATEDIBSECTION ) ;
BITMAP bm ;
GetObject ( m_logo , sizeof ( BITMAP ) , & bm ) ;
m_logo_w = bm . bmWidth ;
m_logo_h = bm . bmHeight ;
if ( m_logo_h < 0 )
m_logo_h = - m_logo_h ;
}
void VideoOutput : : UpdateText ( const wchar_t * videoInfo )
{
{
//AutoLock lock(textGuard);
StringCchCopyW ( vidoutbuf_save , 1023 , ( wchar_t * ) videoInfo ) ; // 1023 so that we can guarantee that this will be null terminated even in the middle of a strcpy
}
PostMessageW ( hVideoWindow , WM_VIDEO_UPDATE_STATUS_TEXT , ( WPARAM ) vidoutbuf_save , 0 ) ;
PostMessageW ( hMainWindow , WM_WA_IPC , IPC_CB_MISC_VIDEOINFO , IPC_CB_MISC ) ;
}
INT_PTR VideoOutput : : extended ( INT_PTR param1 , INT_PTR param2 , INT_PTR param3 )
{
switch ( param1 ) // nonlocking commands
{
case VIDUSER_GET_VIDEOHWND :
return ( INT_PTR ) video_hwnd ;
case VIDUSER_SET_INFOSTRING :
if ( param2 )
UpdateText ( AutoWide ( ( const char * ) param2 ) ) ;
return 0 ;
case VIDUSER_SET_INFOSTRINGW :
if ( param2 )
UpdateText ( ( const wchar_t * ) param2 ) ;
return 0 ;
}
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::extended " ) ) ;
switch ( param1 )
{
case VIDUSER_SET_PALETTE :
{
RGBQUAD * palette = ( RGBQUAD * ) param2 ;
if ( m_video_output )
m_video_output - > setPalette ( palette ) ;
else
video_palette = palette ;
return 0 ;
}
case VIDUSER_SET_VFLIP :
{
if ( m_video_output )
m_video_output - > setVFlip ( param2 ) ;
return 0 ;
}
case VIDUSER_SET_TRACKSELINTERFACE :
m_tracksel = ( ITrackSelector * ) param2 ;
return 0 ;
case VIDUSER_OPENVIDEORENDERER :
{ /*
userVideo = true ;
m_video_output = ( VideoRenderer * ) param2 ;
VideoOpenStruct * openStruct = ( VideoOpenStruct * ) param3 ;
int x = openUser ( openStruct - > w , openStruct - > h , openStruct - > vflip , openStruct - > aspectratio , openStruct - > fmt ) ;
if ( x )
{
m_video_output = 0 ;
userVideo = false ;
return 0 ;
}
else */
return 1 ;
}
case VIDUSER_CLOSEVIDEORENDERER :
close ( ) ;
userVideo = false ;
return 1 ;
case VIDUSER_GETPOPUPMENU :
return ( INT_PTR ) BuildPopupMenu ( ) ;
case VIDUSER_SET_THREAD_SAFE :
input_plugin_thread_safe = ! ! param2 ;
break ;
}
return 0 ;
}
int VideoOutput : : get_latency ( )
{
return config_video_vsync2 ? 15 : 0 ;
}
void VideoOutput : : adjustAspect ( RECT & rd )
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::adjustAspect " ) ) ;
if ( posd - > Showing ( ) /*&& config_video_osd*/ )
{
rd . top + = posd - > GetBarHeight ( ) ;
rd . bottom - = posd - > GetBarHeight ( ) ;
}
if ( config_video_aspectadj )
{
int outh = rd . bottom - rd . top ;
int outw = rd . right - rd . left ;
double outputaspect = aspect ;
if ( config_video_useratio & & config_video_ratio1 & & config_video_ratio2 )
{
RECT r ;
getViewport ( & r , hVideoWindow , 1 , NULL ) ;
int screenx = r . right - r . left ;
int screeny = r . bottom - r . top ;
if ( screenx & & screeny )
{
outputaspect * = config_video_ratio1 * screeny / ( ( double ) screenx * ( double ) config_video_ratio2 ) ;
}
}
int newh = ( int ) ( ( outputaspect * height * outw ) / ( double ) width ) ;
int neww = ( int ) ( ( width * outh ) / ( height * outputaspect ) ) ;
if ( outh > newh ) // black bars on top and bottom
{
int d = outh - newh ;
rd . top + = d / 2 ;
rd . bottom - = d - d / 2 ;
}
else if ( outw > neww ) // black bars on left and right
{
int d = outw - neww ;
rd . left + = d / 2 ;
rd . right - = d - d / 2 ;
}
}
}
LRESULT CALLBACK VideoOutput : : WndProc ( HWND hwnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
if ( uMsg = = g_scrollMsg ) // can't check against variables in case statements
{
wParam < < = 16 ;
uMsg = WM_MOUSEWHEEL ;
}
if ( FALSE ! = IsDirectMouseWheelMessage ( uMsg ) )
{
SendMessageW ( hwnd , WM_MOUSEWHEEL , wParam , lParam ) ;
return TRUE ;
}
switch ( uMsg )
{
case WM_MOUSEWHEEL :
return SendMessageW ( hMainWindow , uMsg , wParam , lParam ) ;
case WM_CREATE :
{
VideoOutput * vid = ( VideoOutput * ) ( ( CREATESTRUCT * ) lParam ) - > lpCreateParams ;
vid - > video_hwnd = hwnd ;
SetWindowLongPtrW ( hwnd , GWLP_USERDATA , ( LONG_PTR ) vid ) ;
}
return 0 ;
default : /// pass it on to the other window procedure
VideoOutput * _This = ( VideoOutput * ) GetWindowLongPtrW ( hwnd , GWLP_USERDATA ) ;
if ( _This )
return _This - > WindowProc ( hwnd , uMsg , wParam , lParam ) ;
else
return DefWindowProc ( hwnd , uMsg , wParam , lParam ) ;
}
}
void VideoOutput : : notifyBufferState ( int bufferstate ) /* 0-255*/
{
m_bufferstate = bufferstate ;
if ( bufferstate = = - 1 | | bufferstate = = 255 | | ( GetTickCount ( ) - m_lastbufinvalid > 500 ) ) // don't want to do this too often
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::notifyBufferState " ) ) ;
if ( ! m_video_output | | ! m_video_output - > onPaint ( video_hwnd ) )
InvalidateRect ( video_hwnd , 0 , TRUE ) ;
m_lastbufinvalid = GetTickCount ( ) ;
}
}
void VideoOutput : : DrawLogo ( HDC out , RECT * canvas_size )
{
int bufferState = m_bufferstate ;
if ( m_logo & & config_video_logo )
{
HDC dc = CreateCompatibleDC ( NULL ) ;
SelectObject ( dc , m_logo ) ;
int xp = ( canvas_size - > right - canvas_size - > left - m_logo_w ) / 2 ;
int yp = ( canvas_size - > bottom - canvas_size - > top - m_logo_h ) / 2 ;
BitBlt ( out , xp , yp , m_logo_w , m_logo_h , dc , 0 , 0 , SRCCOPY ) ;
if ( bufferState ! = - 1 )
{
if ( bufferState < 16 ) bufferState = 16 ;
HGDIOBJ oldobj1 = SelectObject ( out , CreateSolidBrush ( RGB ( 0 , 0 , 0 ) ) ) ;
HGDIOBJ oldobj2 = SelectObject ( out , CreatePen ( PS_SOLID , 0 , RGB ( 0 , 0 , 0 ) ) ) ;
Rectangle ( out , canvas_size - > left , canvas_size - > top , canvas_size - > right , yp ) ;
if ( m_statusmsg )
Rectangle ( out , canvas_size - > left , yp + m_logo_h , canvas_size - > right , canvas_size - > bottom ) ;
else
{
Rectangle ( out , canvas_size - > left , yp + m_logo_h + 2 + 9 , canvas_size - > right , canvas_size - > bottom ) ;
Rectangle ( out , xp + ( ( bufferState * ( m_logo_w + 2 ) ) > > 8 ) , yp + m_logo_h + 2 , canvas_size - > right , yp + 9 + m_logo_h + 2 ) ;
}
Rectangle ( out , canvas_size - > left , yp , xp - 1 , yp + m_logo_h + 9 + 2 ) ;
Rectangle ( out , xp + m_logo_w + 1 , yp , canvas_size - > right , yp + m_logo_h + 2 ) ;
DeleteObject ( SelectObject ( out , oldobj2 ) ) ;
DeleteObject ( SelectObject ( out , oldobj1 ) ) ;
}
if ( m_statusmsg )
{
RECT subr = { 0 , yp + m_logo_h + 2 , canvas_size - > right , canvas_size - > bottom } ;
SetTextColor ( out , RGB ( 255 , 255 , 255 ) ) ;
SetBkMode ( out , TRANSPARENT ) ;
DrawTextA ( out , m_statusmsg , - 1 , & subr , DT_TOP | DT_CENTER | DT_NOCLIP | DT_NOPREFIX ) ;
}
else
{
yp + = m_logo_h + 2 ;
if ( bufferState )
{
HGDIOBJ oldobj1 = SelectObject ( out , CreateSolidBrush ( RGB ( 128 , 128 , 128 ) ) ) ;
HGDIOBJ oldobj2 = SelectObject ( out , CreatePen ( PS_SOLID , 0 , RGB ( 255 , 255 , 255 ) ) ) ;
Rectangle ( out , xp - 1 , yp , xp + ( ( bufferState * ( m_logo_w + 2 ) ) > > 8 ) , yp + 9 ) ;
DeleteObject ( SelectObject ( out , oldobj2 ) ) ;
DeleteObject ( SelectObject ( out , oldobj1 ) ) ;
}
}
DeleteDC ( dc ) ;
}
}
void VideoOutput : : PaintLogo ( int bufferState )
{
// TODO: ask renderer to draw this shiz
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::PaintLogo " ) ) ;
PAINTSTRUCT p ;
BeginPaint ( video_hwnd , & p ) ;
RECT r ;
GetClientRect ( video_hwnd , & r ) ;
HDC out = p . hdc ;
HRGN hrgn = CreateRectRgnIndirect ( & r ) ;
HBRUSH b = ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ;
FillRgn ( out , hrgn , b ) ;
DeleteObject ( b ) ;
DeleteObject ( hrgn ) ;
DrawLogo ( out , & r ) ;
EndPaint ( video_hwnd , & p ) ;
}
// the big window procedure
LRESULT VideoOutput : : WindowProc ( HWND hwnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
// the follow messages are handled w/o a lock
switch ( uMsg )
{
case WM_USER + 0x1 :
m_need_change = true ;
break ;
case WM_USER + 0x2 :
m_ignore_change = ! ! lParam ;
break ;
case WM_ERASEBKGND :
return 1 ;
case WM_COMMAND :
switch ( LOWORD ( wParam ) )
{
case ID_VIDEOWND_VIDEOOPTIONS :
prefs_last_page = 24 ;
prefs_dialog ( 1 ) ;
break ;
case ID_VID_AUDIO0 :
case ID_VID_AUDIO1 :
case ID_VID_AUDIO2 :
case ID_VID_AUDIO3 :
case ID_VID_AUDIO4 :
case ID_VID_AUDIO5 :
case ID_VID_AUDIO6 :
case ID_VID_AUDIO7 :
case ID_VID_AUDIO8 :
case ID_VID_AUDIO9 :
case ID_VID_AUDIO10 :
case ID_VID_AUDIO11 :
case ID_VID_AUDIO12 :
case ID_VID_AUDIO13 :
case ID_VID_AUDIO14 :
case ID_VID_AUDIO15 :
{
VideoOutput * out = ( VideoOutput * ) video_getIVideoOutput ( ) ;
if ( ! out )
break ;
out - > getTrackSelector ( ) - > setAudioTrack ( LOWORD ( wParam ) - ID_VID_AUDIO0 ) ;
break ;
}
case ID_VID_VIDEO0 :
case ID_VID_VIDEO1 :
case ID_VID_VIDEO2 :
case ID_VID_VIDEO3 :
case ID_VID_VIDEO4 :
case ID_VID_VIDEO5 :
case ID_VID_VIDEO6 :
case ID_VID_VIDEO7 :
case ID_VID_VIDEO8 :
case ID_VID_VIDEO9 :
case ID_VID_VIDEO10 :
case ID_VID_VIDEO11 :
case ID_VID_VIDEO12 :
case ID_VID_VIDEO13 :
case ID_VID_VIDEO14 :
case ID_VID_VIDEO15 :
{
VideoOutput * out = ( VideoOutput * ) video_getIVideoOutput ( ) ;
if ( ! out ) break ;
out - > getTrackSelector ( ) - > setVideoTrack ( LOWORD ( wParam ) - ID_VID_VIDEO0 ) ;
break ;
}
}
break ;
case WM_RBUTTONUP :
if ( ! is_fs )
{
POINT p ;
GetCursorPos ( & p ) ;
DoTrackPopup ( BuildPopupMenu ( ) , TPM_RIGHTBUTTON | TPM_LEFTBUTTON , p . x , p . y , hwnd ) ;
}
break ;
case WM_LBUTTONDOWN : // putting this here prevents a deadlock, but allows a race condition over video drawing =(
{
int x = GET_X_LPARAM ( lParam ) ;
int y = GET_Y_LPARAM ( lParam ) ;
if ( is_fs & & config_video_osd )
{
if ( ( ( IVideoD3DOSD * ) posd ) - > isOSDReadyToDraw ( ) )
{
if ( posd - > MouseDown ( x , y , wParam ) )
videoToggleFullscreen ( ) ;
}
}
else
{
SetCapture ( video_hwnd ) ;
clickx = x ;
clicky = y ;
SetFocus ( video_hwnd ) ;
}
}
break ;
case WM_MOUSEMOVE :
{
int x = GET_X_LPARAM ( lParam ) ;
int y = GET_Y_LPARAM ( lParam ) ;
if ( is_fs & & config_video_osd )
{
if ( ( ( IVideoD3DOSD * ) posd ) - > isOSDReadyToDraw ( ) )
{
posd - > MouseMove ( x , y , wParam ) ;
}
}
else if ( GetCapture ( ) = = video_hwnd & & config_easymove )
{
POINT p = { x , y } ;
ClientToScreen ( hVideoWindow , & p ) ;
p . x - = clickx ;
p . y - = clicky ;
SendMessageW ( hVideoWindow , WM_USER + 0x100 , 1 , ( LPARAM ) & p ) ;
}
}
break ;
case WM_LBUTTONUP :
{
int x = GET_X_LPARAM ( lParam ) ;
int y = GET_Y_LPARAM ( lParam ) ;
if ( GetCapture ( ) = = video_hwnd )
ReleaseCapture ( ) ;
if ( is_fs & & config_video_osd )
{
if ( ( ( IVideoD3DOSD * ) posd ) - > isOSDReadyToDraw ( ) )
if ( posd - > MouseUp ( x , y , wParam ) )
videoToggleFullscreen ( ) ;
}
SetFocus ( hVideoWindow ) ;
}
break ;
}
switch ( uMsg )
{
case WM_VIDEO_OSDCHANGE :
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::WM_VIDEO_OSDCHANGE " ) ) ;
if ( m_video_output )
{
m_video_output - > Refresh ( ) ;
m_video_output - > timerCallback ( ) ;
}
}
break ;
case WM_SHOWWINDOW :
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::WM_SHOWWINDOW " ) ) ;
if ( wParam = = TRUE // being shown
& & ! m_logo ) // logo hasn't been loaded yet
LoadLogo ( ) ;
}
break ;
case WM_INITMENUPOPUP :
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::WM_INITMENUPOPUP " ) ) ;
return SendMessageW ( hMainWindow , uMsg , wParam , lParam ) ; // for popup menus
}
case WM_WINDOWPOSCHANGED :
case WM_SIZE :
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::WM_SIZE " ) ) ;
if ( m_video_output )
{
m_video_output - > OnWindowSize ( ) ;
if ( is_fs )
if ( ( ( IVideoD3DOSD * ) posd ) - > isOSDInited ( ) )
( ( IVideoD3DOSD * ) posd ) - > UpdateOSD ( hwnd , this ) ;
}
}
break ;
case WM_TIMER :
case WM_WINDOWPOSCHANGING :
case WM_MOVE :
case WM_MOVING :
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::WM_TIMER, etc " ) ) ;
if ( m_video_output & & ! m_ignore_change )
m_video_output - > timerCallback ( ) ;
if ( uMsg = = WM_TIMER )
return 0 ;
}
break ;
case WM_LBUTTONDBLCLK :
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::WM_LBUTTONDBLCLK " ) ) ;
videoToggleFullscreen ( ) ;
}
break ;
case WM_PAINT :
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::WM_PAINT " ) ) ;
if ( m_video_output & & m_video_output - > onPaint ( hwnd ) )
return 0 ;
PaintLogo ( m_bufferstate ) ;
}
return 0 ;
break ;
case WM_PRINTCLIENT :
{
//AutoLock autoLock(guard LOCKNAME("VideoOutput::WM_PAINT"));
//if (m_video_output && m_video_output->onPaint(hwnd))
// return 0;
RECT r ;
GetClientRect ( video_hwnd , & r ) ;
DrawLogo ( ( HDC ) wParam , & r ) ;
}
return 0 ;
break ;
case WM_KEYDOWN :
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::WM_KEYDOWN " ) ) ;
if ( wParam = = VK_ESCAPE & & is_fs )
{
videoToggleFullscreen ( ) ;
//remove_fullscreen();
return 1 ;
}
if ( ! is_fs )
{
if ( wParam = = ' 3 ' | | LOWORD ( wParam ) = = 192 /* ` */ )
{
SendMessageW ( hwnd , WM_COMMAND , ID_VIDEOWND_ZOOM50 , 0 ) ; return 0 ;
}
if ( wParam = = ' 1 ' )
{
SendMessageW ( hwnd , WM_COMMAND , ID_VIDEOWND_ZOOM100 , 0 ) ; return 0 ;
}
if ( wParam = = ' 2 ' )
{
SendMessageW ( hwnd , WM_COMMAND , ID_VIDEOWND_ZOOM200 , 0 ) ; return 0 ;
}
}
if ( wParam = = ' ' )
{
SendMessageW ( hMainWindow , WM_COMMAND , WINAMP_BUTTON3 , 0 ) ; return 0 ;
}
if ( wParam = = ' F ' & & ( GetAsyncKeyState ( VK_SHIFT ) & 0x8000 ) & & ! ( GetAsyncKeyState ( VK_CONTROL ) & 0x8000 ) )
{
SendMessageW ( hwnd , WM_COMMAND , ID_VIDEOWND_VERTICALLYFLIP , 0 ) ; return 0 ;
}
}
break ;
case WM_COMMAND :
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::WM_COMMAND " ) ) ;
switch ( LOWORD ( wParam ) )
{
case ID_VIDEOWND_VERTICALLYFLIP :
{
int new_fliprgb = ! config_video_fliprgb ; //IsDlgButtonChecked(hwndDlg,IDC_PREFS_VIDEO_FLIPRGB)?1:0;
config_video_fliprgb = 0 ;
videoSetFlip ( new_fliprgb ) ;
config_video_fliprgb = new_fliprgb ;
break ;
}
case ID_VIDEOWND_ZOOMFULLSCREEN :
videoGoFullscreen ( ) ;
break ;
case ID_VIDEOWND_ZOOM200 :
case ID_VIDEOWND_ZOOM100 :
case ID_VIDEOWND_ZOOM50 :
if ( m_video_output )
UpdateVideoSize ( width , height , aspect , LOWORD ( wParam ) ) ;
else
UpdateVideoSize ( 320 , 240 , 1.0 , LOWORD ( wParam ) ) ;
break ;
default :
SendMessageW ( hMainWindow , WM_COMMAND , wParam , lParam ) ;
break ;
}
}
break ;
case WM_SETCURSOR :
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::WM_SETCURSOR " ) ) ;
if ( is_fs )
{
SetCursor ( posd - > Showing ( ) ? LoadCursor ( NULL , IDC_ARROW ) : NULL ) ;
return TRUE ;
}
else
SetCursor ( LoadCursor ( NULL , IDC_ARROW ) ) ;
}
break ;
case WM_SYSCOMMAND :
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::WM_SYSCOMMAND " ) ) ;
// eat screen saver message when fullscreen
if ( ( ( wParam & 0xfff0 ) = = SC_SCREENSAVE | | ( wParam & 0xfff0 ) = = SC_MONITORPOWER ) & & config_video_noss & &
video_isVideoPlaying ( ) )
{
return - 1 ;
}
}
break ;
}
if ( m_msgcallback )
{
return m_msgcallback ( m_msgcallback_tok , hwnd , uMsg , wParam , lParam ) ;
}
return ( DefWindowProc ( hwnd , uMsg , wParam , lParam ) ) ;
}
void VideoOutput : : fullscreen ( )
{
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::fullscreen " ) ) ;
if ( ! m_video_output | | ! m_opened )
return ;
if ( is_fs )
return ;
// TODO: let the video renderer handle fullscreen itself, if it can.
/*if (last_fullscreen_exit_time + 250 > GetTickCount()) // gay hack
return ; // dont let you go back and forth too quickly
*/
GetWindowRect ( hVideoWindow , & oldfsrect ) ; // save the old coordinates
getViewport ( & lastfsrect , video_hwnd , 1 , NULL ) ;
if ( GetParent ( hVideoWindow ) )
{
fs_reparented_rgn = CreateRectRgn ( 0 , 0 , 0 , 0 ) ;
GetWindowRgn ( hVideoWindow , fs_reparented_rgn ) ;
fs_reparented = SetParent ( hVideoWindow , NULL ) ;
SetWindowRgn ( hVideoWindow , NULL , FALSE ) ;
ScreenToClient ( fs_reparented , ( LPPOINT ) & oldfsrect ) ;
ScreenToClient ( fs_reparented , ( ( LPPOINT ) & oldfsrect ) + 1 ) ;
}
is_fullscreen_video = true ;
is_fs = true ;
//m_video_output->Fullscreen(true);
SetWindowPos ( hVideoWindow , HWND_TOPMOST , lastfsrect . left , lastfsrect . top , lastfsrect . right - lastfsrect . left , lastfsrect . bottom - lastfsrect . top , SWP_DRAWFRAME | SWP_NOACTIVATE ) ;
SetFocus ( hVideoWindow ) ;
resetSubtitle ( ) ;
}
extern " C " HWND hExternalVisWindow ;
int VideoOutput : : openUser ( int w , int h , int vflip , double aspectratio , unsigned int fmt )
{
// TODO
return 1 ;
}
int VideoOutput : : open ( int w , int h , int vflip , double aspectratio , unsigned int fmt )
{
if ( ! video_created )
SendMessageW ( hVideoWindow , WM_VIDEO_CREATE , 0 , 0 ) ;
if ( ! h | | ! w | | ! fmt ) // check this after creating the video window. some plugins use this call to open the video output early
return 0 ;
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::open " ) ) ;
if ( ! m_need_change )
stats . IncrementStat ( Stats : : VIDEOS_PLAYED ) ;
if ( hExternalVisWindow )
PostMessageW ( hExternalVisWindow , WM_USER + 1666 , 1 , 15 ) ;
m_opened = false ;
userVideo = false ;
width = w ;
height = h ;
type = fmt ;
aspect = aspectratio ;
if ( m_video_output )
{
if ( type = = VIDEO_MAKETYPE ( ' N ' , ' O ' , ' N ' , ' E ' ) )
{
m_opened = true ;
PostMessageW ( hMainWindow , WM_WA_IPC , IPC_CB_MISC_INFO , IPC_CB_MISC ) ;
OpenVideoSize ( width , height , aspect ) ;
fs_has_resized = is_fs ;
return 0 ;
}
else if ( m_video_output - > OpenVideo ( w , h , type , vflip , aspect ) )
{
if ( video_palette )
m_video_output - > setPalette ( video_palette ) ;
video_palette = 0 ;
DoTheVistaVideoDance ( ) ;
InvalidateRect ( video_hwnd , NULL , TRUE ) ;
m_opened = true ;
PostMessageW ( hMainWindow , WM_WA_IPC , IPC_CB_MISC_INFO , IPC_CB_MISC ) ;
if ( ! m_need_change ) //don't update size when renegotiating video output
{
OpenVideoSize ( width , height , aspect ) ;
fs_has_resized = is_fs ;
}
return 0 ;
}
}
return 1 ;
}
void VideoOutput : : draw ( void * frame )
{
if ( ! frame )
return ;
AutoLock autoLock ( guard LOCKNAME ( " VideoOutput::draw " ) ) ;
if ( m_video_output )
{
m_video_output - > displayFrame ( ( const char * ) frame , 0 , 0 ) ;
}
}
extern wchar_t draw_vw_info_lastb [ 512 ] ;
void VideoOutput : : close ( )
{
UpdateText ( L " " ) ;
AutoLock autoLock ( guard ) ;
if ( ! m_opened )
return ;
m_opened = false ;
if ( m_video_output )
{
m_video_output - > drawSubtitle ( 0 ) ;
m_video_output - > close ( ) ;
}
m_bufferstate = - 1 ;
draw_vw_info_lastb [ 0 ] = 0 ;
input_plugin_thread_safe = false ; // reset this
InvalidateRect ( video_hwnd , NULL , true ) ;
PostMessageW ( hVideoWindow , WM_VIDEO_CLOSE , 0 , 0 ) ;
}
int VideoOutput : : is_fullscreen ( )
{
return is_fs ;
}
void VideoOutput : : showStatusMsg ( const char * text )
{
AutoLock autoLock ( guard ) ;
m_statusmsg = _strdup ( text ) ;
PaintLogo ( m_bufferstate ) ;
//InvalidateRect(video_hwnd, NULL, TRUE);
}
void VideoOutput : : drawSubtitle ( SubsItem * item )
{
AutoLock autoLock ( guard ) ;
if ( item = = curSubtitle )
return ;
curSubtitle = item ;
if ( m_video_output )
m_video_output - > drawSubtitle ( item ) ;
}
void VideoOutput : : resetSubtitle ( )
{
AutoLock autoLock ( guard ) ;
curSubtitle = NULL ;
if ( m_video_output )
m_video_output - > resetSubtitle ( ) ;
// InvalidateRect(this->getHwnd(), 0, TRUE);
}
void VideoOutput : : remove_fullscreen ( )
{
AutoLock autoLock ( guard ) ;
if ( ! is_fs )
{
is_fullscreen_video = false ;
return ;
}
posd - > Hide ( ) ;
posd - > ctrlrects_ready = 0 ; //tofix
if ( m_video_output )
{
// m_video_output->Fullscreen(false);
}
resetSubtitle ( ) ;
is_fs = 0 ;
if ( fs_reparented )
{
SetParent ( hVideoWindow , fs_reparented ) ;
SetWindowRgn ( hVideoWindow , fs_reparented_rgn , FALSE ) ;
fs_reparented = 0 ;
SetWindowPos ( hVideoWindow , HWND_TOPMOST , oldfsrect . left , oldfsrect . top , oldfsrect . right - oldfsrect . left , oldfsrect . bottom - oldfsrect . top , SWP_NOACTIVATE | SWP_NOZORDER ) ;
}
else
SetWindowPos ( hVideoWindow , config_aot ? HWND_TOPMOST : HWND_NOTOPMOST , oldfsrect . left , oldfsrect . top , oldfsrect . right - oldfsrect . left , oldfsrect . bottom - oldfsrect . top , SWP_NOACTIVATE ) ;
last_fullscreen_exit_time = GetTickCount ( ) ;
posd - > Hide ( ) ;
if ( ! m_opened & & m_video_output )
{
m_video_output - > close ( ) ;
}
is_fullscreen_video = false ;
if ( fs_has_resized )
{
fs_has_resized = false ;
if ( config_video_updsize )
UpdateVideoSize ( width , height , aspect ) ;
}
}
void VideoOutput : : UpdateVideoSize ( int newWidth , int newHeight , double newAspect , int zoom )
{
if ( ! m_opened )
return ;
// fill in default values if we have 0s
if ( ! newWidth )
newWidth = 320 ;
if ( ! newHeight )
newHeight = 240 ;
switch ( zoom )
{
case ID_VIDEOWND_ZOOM200 :
newWidth * = 2 ;
newHeight * = 2 ;
break ;
case ID_VIDEOWND_ZOOM50 :
newWidth / = 2 ;
newHeight / = 2 ;
break ;
}
// establish a minimum window size
if ( newWidth < 256 )
newWidth = 256 ;
if ( newHeight < 64 )
newHeight = 64 ;
if ( newAspect > 0.001 ) // floating point can be weird about checking == 0
{
if ( newAspect < 1.0 )
newWidth = ( int ) ( ( double ) newWidth / newAspect ) ;
else
newHeight = ( int ) ( ( double ) newHeight * newAspect ) ;
}
//SendNotifyMessage(hVideoWindow, WM_VIDEO_RESIZE, newWidth, newHeight);
PostMessageW ( hVideoWindow , WM_VIDEO_RESIZE , newWidth , newHeight ) ;
}
void VideoOutput : : OpenVideoSize ( int newWidth , int newHeight , double newAspect )
{
// fill in default values if we have 0s
if ( ! newWidth )
newWidth = 320 ;
if ( ! newHeight )
newHeight = 240 ;
// establish a minimum window size
if ( newWidth < 256 )
newWidth = 256 ;
if ( newHeight < 64 )
newHeight = 64 ;
if ( newAspect > 0.001 ) // floating point can be weird about checking == 0
{
if ( newAspect < 1.0 )
newWidth = ( int ) ( ( double ) newWidth / newAspect ) ;
else
newHeight = ( int ) ( ( double ) newHeight * newAspect ) ;
}
PostMessageW ( hVideoWindow , WM_VIDEO_OPEN , newWidth , newHeight ) ;
}
void VideoOutput : : SetVideoPosition ( int x , int y , int width , int height )
{
AutoLock autoLock ( guard ) ;
SetWindowPos ( getHwnd ( ) , 0 , x , y , width , height , SWP_NOZORDER | SWP_NOACTIVATE ) ;
}