Commit 88ca4341 authored by Jean-Baptiste Kempf's avatar Jean-Baptiste Kempf
Browse files

Win32: cleanup the events.c codebase

No functionnal change
parent deb9a70e
......@@ -89,12 +89,24 @@ struct event_thread_t
bool has_moved;
};
/***************************
* Local Prototypes *
***************************/
/* Window Creation */
static int Win32VoutCreateWindow( event_thread_t * );
static void Win32VoutCloseWindow ( event_thread_t * );
static long FAR PASCAL WinVoutEventProc( HWND, UINT, WPARAM, LPARAM );
static int Win32VoutConvertKey( int i_key );
static int Win32VoutConvertKey( int i_key );
/* Display/Hide Cursor */
static void UpdateCursor( event_thread_t *p_event, bool b_show );
static HCURSOR EmptyCursor( HINSTANCE instance );
/* Mouse events sending functions */
static void MouseReleased( event_thread_t *p_event, unsigned button );
static void MousePressed( event_thread_t *p_event, HWND hwnd, unsigned button );
/* Local helpers */
static inline bool isMouseEvent( WPARAM type )
{
return type >= WM_MOUSEFIRST &&
......@@ -106,69 +118,6 @@ static inline bool isKeyEvent( WPARAM type )
return type >= WM_KEYFIRST &&
type <= WM_KEYLAST;
}
static void UpdateCursor( event_thread_t *p_event, bool b_show )
{
if( p_event->is_cursor_hidden == !b_show )
return;
p_event->is_cursor_hidden = !b_show;
#if 1
HCURSOR cursor = b_show ? p_event->cursor_arrow : p_event->cursor_empty;
if( p_event->hvideownd )
SetClassLongPtr( p_event->hvideownd, GCLP_HCURSOR, (LONG_PTR)cursor );
if( p_event->hwnd )
SetClassLongPtr( p_event->hwnd, GCLP_HCURSOR, (LONG_PTR)cursor );
#endif
/* FIXME I failed to find a cleaner way to force a redraw of the cursor */
POINT p;
GetCursorPos(&p);
HWND hwnd = WindowFromPoint(p);
if( hwnd == p_event->hvideownd || hwnd == p_event->hwnd )
{
if( b_show )
SetCursor( cursor );
else
SetCursorPos( p.x, p.y );
}
}
static HCURSOR EmptyCursor( HINSTANCE instance )
{
const int cw = GetSystemMetrics(SM_CXCURSOR);
const int ch = GetSystemMetrics(SM_CYCURSOR);
HCURSOR cursor = NULL;
uint8_t *and = malloc(cw * ch);
uint8_t *xor = malloc(cw * ch);
if( and && xor )
{
memset(and, 0xff, cw * ch );
memset(xor, 0x00, cw * ch );
cursor = CreateCursor( instance, 0, 0, cw, ch, and, xor);
}
free( and );
free( xor );
return cursor;
}
static void MousePressed( event_thread_t *p_event, HWND hwnd, unsigned button )
{
if( !p_event->button_pressed )
SetCapture( hwnd );
p_event->button_pressed |= 1 << button;
vout_display_SendEventMousePressed( p_event->vd, button );
}
static void MouseReleased( event_thread_t *p_event, unsigned button )
{
p_event->button_pressed &= ~(1 << button);
if( !p_event->button_pressed )
ReleaseCapture();
vout_display_SendEventMouseReleased( p_event->vd, button );
}
/*****************************************************************************
* EventThread: Create video window & handle its messages
*****************************************************************************
......@@ -428,6 +377,241 @@ static void *EventThread( void *p_this )
return NULL;
}
void EventThreadMouseHide( event_thread_t *p_event )
{
PostMessage( p_event->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
}
void EventThreadUpdateTitle( event_thread_t *p_event, const char *psz_fallback )
{
char *psz_title = var_InheritString( p_event->vd, "video-title" );
if( !psz_title )
psz_title = strdup( psz_fallback );
if( !psz_title )
return;
vlc_mutex_lock( &p_event->lock );
free( p_event->psz_title );
p_event->psz_title = psz_title;
vlc_mutex_unlock( &p_event->lock );
PostMessage( p_event->hwnd, WM_VLC_CHANGE_TEXT, 0, 0 );
}
int EventThreadGetWindowStyle( event_thread_t *p_event )
{
/* No need to lock, it is serialized by EventThreadStart */
return p_event->i_window_style;
}
void EventThreadUpdateWindowPosition( event_thread_t *p_event,
bool *pb_moved, bool *pb_resized,
int x, int y, unsigned w, unsigned h )
{
vlc_mutex_lock( &p_event->lock );
*pb_moved = x != p_event->wnd_cfg.x ||
y != p_event->wnd_cfg.y;
*pb_resized = w != p_event->wnd_cfg.width ||
h != p_event->wnd_cfg.height;
p_event->wnd_cfg.x = x;
p_event->wnd_cfg.y = y;
p_event->wnd_cfg.width = w;
p_event->wnd_cfg.height = h;
vlc_mutex_unlock( &p_event->lock );
}
void EventThreadUpdateSourceAndPlace( event_thread_t *p_event,
const video_format_t *p_source,
const vout_display_place_t *p_place )
{
vlc_mutex_lock( &p_event->lock );
p_event->source = *p_source;
p_event->place = *p_place;
vlc_mutex_unlock( &p_event->lock );
}
void EventThreadUseOverlay( event_thread_t *p_event, bool b_used )
{
vlc_mutex_lock( &p_event->lock );
p_event->use_overlay = b_used;
vlc_mutex_unlock( &p_event->lock );
}
bool EventThreadGetAndResetHasMoved( event_thread_t *p_event )
{
vlc_mutex_lock( &p_event->lock );
const bool has_moved = p_event->has_moved;
p_event->has_moved = false;
vlc_mutex_unlock( &p_event->lock );
return has_moved;
}
event_thread_t *EventThreadCreate( vout_display_t *vd)
{
/* Create the Vout EventThread, this thread is created by us to isolate
* the Win32 PeekMessage function calls. We want to do this because
* Windows can stay blocked inside this call for a long time, and when
* this happens it thus blocks vlc's video_output thread.
* Vout EventThread will take care of the creation of the video
* window (because PeekMessage has to be called from the same thread which
* created the window). */
msg_Dbg( vd, "creating Vout EventThread" );
event_thread_t *p_event = malloc( sizeof(*p_event) );
if( !p_event )
return NULL;
p_event->vd = vd;
vlc_mutex_init( &p_event->lock );
vlc_cond_init( &p_event->wait );
p_event->is_cursor_hidden = false;
p_event->button_pressed = 0;
p_event->psz_title = NULL;
p_event->source = vd->source;
vout_display_PlacePicture(&p_event->place, &vd->source, vd->cfg, false);
_sntprintf( p_event->class_main, sizeof(p_event->class_main)/sizeof(*p_event->class_main),
_T("VLC video main %p"), p_event );
_sntprintf( p_event->class_video, sizeof(p_event->class_video)/sizeof(*p_event->class_video),
_T("VLC video output %p"), p_event );
return p_event;
}
void EventThreadDestroy( event_thread_t *p_event )
{
free( p_event->psz_title );
vlc_cond_destroy( &p_event->wait );
vlc_mutex_destroy( &p_event->lock );
free( p_event );
}
int EventThreadStart( event_thread_t *p_event, event_hwnd_t *p_hwnd, const event_cfg_t *p_cfg )
{
p_event->use_desktop = p_cfg->use_desktop;
p_event->use_overlay = p_cfg->use_overlay;
p_event->wnd_cfg = p_cfg->win;
p_event->has_moved = false;
p_event->b_ready = false;
p_event->b_done = false;
p_event->b_error = false;
if( vlc_clone( &p_event->thread, EventThread, p_event,
VLC_THREAD_PRIORITY_LOW ) )
{
msg_Err( p_event->vd, "cannot create Vout EventThread" );
return VLC_EGENERIC;
}
vlc_mutex_lock( &p_event->lock );
while( !p_event->b_ready )
vlc_cond_wait( &p_event->wait, &p_event->lock );
const bool b_error = p_event->b_error;
vlc_mutex_unlock( &p_event->lock );
if( b_error )
{
vlc_join( p_event->thread, NULL );
p_event->b_ready = false;
return VLC_EGENERIC;
}
msg_Dbg( p_event->vd, "Vout EventThread running" );
/* */
p_hwnd->parent_window = p_event->parent_window;
p_hwnd->hparent = p_event->hparent;
p_hwnd->hwnd = p_event->hwnd;
p_hwnd->hvideownd = p_event->hvideownd;
p_hwnd->hfswnd = p_event->hfswnd;
return VLC_SUCCESS;
}
void EventThreadStop( event_thread_t *p_event )
{
if( !p_event->b_ready )
return;
vlc_mutex_lock( &p_event->lock );
p_event->b_done = true;
vlc_mutex_unlock( &p_event->lock );
/* we need to be sure Vout EventThread won't stay stuck in
* GetMessage, so we send a fake message */
if( p_event->hwnd )
PostMessage( p_event->hwnd, WM_NULL, 0, 0);
vlc_join( p_event->thread, NULL );
p_event->b_ready = false;
}
/***********************************
* Local functions implementations *
***********************************/
static void UpdateCursor( event_thread_t *p_event, bool b_show )
{
if( p_event->is_cursor_hidden == !b_show )
return;
p_event->is_cursor_hidden = !b_show;
#if 1
HCURSOR cursor = b_show ? p_event->cursor_arrow : p_event->cursor_empty;
if( p_event->hvideownd )
SetClassLongPtr( p_event->hvideownd, GCLP_HCURSOR, (LONG_PTR)cursor );
if( p_event->hwnd )
SetClassLongPtr( p_event->hwnd, GCLP_HCURSOR, (LONG_PTR)cursor );
#endif
/* FIXME I failed to find a cleaner way to force a redraw of the cursor */
POINT p;
GetCursorPos(&p);
HWND hwnd = WindowFromPoint(p);
if( hwnd == p_event->hvideownd || hwnd == p_event->hwnd )
{
if( b_show )
SetCursor( cursor );
else
SetCursorPos( p.x, p.y );
}
}
static HCURSOR EmptyCursor( HINSTANCE instance )
{
const int cw = GetSystemMetrics(SM_CXCURSOR);
const int ch = GetSystemMetrics(SM_CYCURSOR);
HCURSOR cursor = NULL;
uint8_t *and = malloc(cw * ch);
uint8_t *xor = malloc(cw * ch);
if( and && xor )
{
memset(and, 0xff, cw * ch );
memset(xor, 0x00, cw * ch );
cursor = CreateCursor( instance, 0, 0, cw, ch, and, xor);
}
free( and );
free( xor );
return cursor;
}
static void MousePressed( event_thread_t *p_event, HWND hwnd, unsigned button )
{
if( !p_event->button_pressed )
SetCapture( hwnd );
p_event->button_pressed |= 1 << button;
vout_display_SendEventMousePressed( p_event->vd, button );
}
static void MouseReleased( event_thread_t *p_event, unsigned button )
{
p_event->button_pressed &= ~(1 << button);
if( !p_event->button_pressed )
ReleaseCapture();
vout_display_SendEventMouseReleased( p_event->vd, button );
}
#ifdef MODULE_NAME_IS_direct3d
static int CALLBACK
enumWindowsProc(HWND hwnd, LPARAM lParam)
......@@ -466,7 +650,6 @@ static HWND GetDesktopHandle(vout_display_t *vd)
return hwnd;
}
#endif
/* following functions are local */
/*****************************************************************************
* Win32VoutCreateWindow: create a window for the video.
......@@ -920,9 +1103,7 @@ static struct
static int Win32VoutConvertKey( int i_key )
{
int i;
for( i = 0; dxkeys_to_vlckeys[i].i_dxkey != 0; i++ )
for( int i = 0; dxkeys_to_vlckeys[i].i_dxkey != 0; i++ )
{
if( dxkeys_to_vlckeys[i].i_dxkey == i_key )
{
......@@ -933,171 +1114,3 @@ static int Win32VoutConvertKey( int i_key )
return 0;
}
void EventThreadMouseHide( event_thread_t *p_event )
{
PostMessage( p_event->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
}
void EventThreadUpdateTitle( event_thread_t *p_event, const char *psz_fallback )
{
char *psz_title = var_InheritString( p_event->vd, "video-title" );
if( !psz_title )
psz_title = strdup( psz_fallback );
if( !psz_title )
return;
vlc_mutex_lock( &p_event->lock );
free( p_event->psz_title );
p_event->psz_title = psz_title;
vlc_mutex_unlock( &p_event->lock );
PostMessage( p_event->hwnd, WM_VLC_CHANGE_TEXT, 0, 0 );
}
int EventThreadGetWindowStyle( event_thread_t *p_event )
{
/* No need to lock, it is serialized by EventThreadStart */
return p_event->i_window_style;
}
void EventThreadUpdateWindowPosition( event_thread_t *p_event,
bool *pb_moved, bool *pb_resized,
int x, int y, unsigned w, unsigned h )
{
vlc_mutex_lock( &p_event->lock );
*pb_moved = x != p_event->wnd_cfg.x ||
y != p_event->wnd_cfg.y;
*pb_resized = w != p_event->wnd_cfg.width ||
h != p_event->wnd_cfg.height;
p_event->wnd_cfg.x = x;
p_event->wnd_cfg.y = y;
p_event->wnd_cfg.width = w;
p_event->wnd_cfg.height = h;
vlc_mutex_unlock( &p_event->lock );
}
void EventThreadUpdateSourceAndPlace( event_thread_t *p_event,
const video_format_t *p_source,
const vout_display_place_t *p_place )
{
vlc_mutex_lock( &p_event->lock );
p_event->source = *p_source;
p_event->place = *p_place;
vlc_mutex_unlock( &p_event->lock );
}
void EventThreadUseOverlay( event_thread_t *p_event, bool b_used )
{
vlc_mutex_lock( &p_event->lock );
p_event->use_overlay = b_used;
vlc_mutex_unlock( &p_event->lock );
}
bool EventThreadGetAndResetHasMoved( event_thread_t *p_event )
{
vlc_mutex_lock( &p_event->lock );
const bool has_moved = p_event->has_moved;
p_event->has_moved = false;
vlc_mutex_unlock( &p_event->lock );
return has_moved;
}
event_thread_t *EventThreadCreate( vout_display_t *vd)
{
/* Create the Vout EventThread, this thread is created by us to isolate
* the Win32 PeekMessage function calls. We want to do this because
* Windows can stay blocked inside this call for a long time, and when
* this happens it thus blocks vlc's video_output thread.
* Vout EventThread will take care of the creation of the video
* window (because PeekMessage has to be called from the same thread which
* created the window). */
msg_Dbg( vd, "creating Vout EventThread" );
event_thread_t *p_event = malloc( sizeof(*p_event) );
if( !p_event )
return NULL;
p_event->vd = vd;
vlc_mutex_init( &p_event->lock );
vlc_cond_init( &p_event->wait );
p_event->is_cursor_hidden = false;
p_event->button_pressed = 0;
p_event->psz_title = NULL;
p_event->source = vd->source;
vout_display_PlacePicture(&p_event->place, &vd->source, vd->cfg, false);
_sntprintf( p_event->class_main, sizeof(p_event->class_main)/sizeof(*p_event->class_main),
_T("VLC MSW %p"), p_event );
_sntprintf( p_event->class_video, sizeof(p_event->class_video)/sizeof(*p_event->class_video),
_T("VLC MSW video %p"), p_event );
return p_event;
}
void EventThreadDestroy( event_thread_t *p_event )
{
free( p_event->psz_title );
vlc_cond_destroy( &p_event->wait );
vlc_mutex_destroy( &p_event->lock );
free( p_event );
}
int EventThreadStart( event_thread_t *p_event, event_hwnd_t *p_hwnd, const event_cfg_t *p_cfg )
{
p_event->use_desktop = p_cfg->use_desktop;
p_event->use_overlay = p_cfg->use_overlay;
p_event->wnd_cfg = p_cfg->win;
p_event->has_moved = false;
p_event->b_ready = false;
p_event->b_done = false;
p_event->b_error = false;
if( vlc_clone( &p_event->thread, EventThread, p_event,
VLC_THREAD_PRIORITY_LOW ) )
{
msg_Err( p_event->vd, "cannot create Vout EventThread" );
return VLC_EGENERIC;
}
vlc_mutex_lock( &p_event->lock );
while( !p_event->b_ready )
vlc_cond_wait( &p_event->wait, &p_event->lock );
const bool b_error = p_event->b_error;
vlc_mutex_unlock( &p_event->lock );
if( b_error )
{
vlc_join( p_event->thread, NULL );
p_event->b_ready = false;
return VLC_EGENERIC;
}
msg_Dbg( p_event->vd, "Vout EventThread running" );
/* */
p_hwnd->parent_window = p_event->parent_window;
p_hwnd->hparent = p_event->hparent;
p_hwnd->hwnd = p_event->hwnd;
p_hwnd->hvideownd = p_event->hvideownd;
p_hwnd->hfswnd = p_event->hfswnd;
return VLC_SUCCESS;
}
void EventThreadStop( event_thread_t *p_event )
{
if( !p_event->b_ready )
return;
vlc_mutex_lock( &p_event->lock );
p_event->b_done = true;
vlc_mutex_unlock( &p_event->lock );
/* we need to be sure Vout EventThread won't stay stuck in
* GetMessage, so we send a fake message */
if( p_event->hwnd )
PostMessage( p_event->hwnd, WM_NULL, 0, 0);
vlc_join( p_event->thread, NULL );
p_event->b_ready = false;
}
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