* events.c: Windows DirectX video output events handler
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: events.c,v 1.9 2003/01/26 02:22:59 ipkiss Exp $
+ * $Id: events.c,v 1.24 2003/10/17 16:40:09 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
#include <vlc/vlc.h>
#include <vlc/intf.h>
+#include <vlc/input.h>
#include <vlc/vout.h>
-#include "netutils.h"
-
#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>
static long FAR PASCAL DirectXEventProc ( HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam );
+static void DirectXPopupMenu( event_thread_t *p_event, vlc_bool_t b_open )
+{
+ playlist_t *p_playlist =
+ vlc_object_find( p_event, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+ if( p_playlist != NULL )
+ {
+ vlc_value_t val;
+ val.b_bool = b_open;
+ var_Set( p_playlist, "intf-popupmenu", val );
+ vlc_object_release( p_playlist );
+ }
+}
+
/*****************************************************************************
* DirectXEventThread: Create video window & handle its messages
*****************************************************************************
void DirectXEventThread( event_thread_t *p_event )
{
MSG msg;
- POINT old_mouse_pos;
+ POINT old_mouse_pos = {0,0};
vlc_value_t val;
int i_width, i_height, i_x, i_y;
/* Main loop */
/* GetMessage will sleep if there's no message in the queue */
- while( !p_event->b_die
- && GetMessage( &msg, p_event->p_vout->p_sys->hwnd, 0, 0 ) )
+ while( !p_event->b_die && ( p_event->p_vout->p_sys->hparent ||
+ GetMessage( &msg, p_event->p_vout->p_sys->hwnd, 0, 0 ) ) )
{
/* Check if we are asked to exit */
if( p_event->b_die )
break;
+ if( p_event->p_vout->p_sys->hparent ) msleep( INTF_IDLE_SLEEP );
+
switch( msg.message )
{
ShowCursor( FALSE );
break;
- case WM_RBUTTONUP:
- {
- intf_thread_t *p_intf;
- p_intf = vlc_object_find( p_event, VLC_OBJECT_INTF,
- FIND_ANYWHERE );
- if( p_intf )
- {
- p_intf->b_menu_change = 1;
- vlc_object_release( p_intf );
- }
- }
+ case WM_LBUTTONDOWN:
+ var_Get( p_event->p_vout, "mouse-button-down", &val );
+ val.i_int |= 1;
+ var_Set( p_event->p_vout, "mouse-button-down", val );
+ DirectXPopupMenu( p_event, VLC_FALSE );
break;
case WM_LBUTTONUP:
+ var_Get( p_event->p_vout, "mouse-button-down", &val );
+ val.i_int &= ~1;
+ var_Set( p_event->p_vout, "mouse-button-down", val );
+
val.b_bool = VLC_TRUE;
var_Set( p_event->p_vout, "mouse-clicked", val );
break;
- case WM_LBUTTONDOWN:
- break;
-
case WM_LBUTTONDBLCLK:
p_event->p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;
break;
+ case WM_MBUTTONDOWN:
+ var_Get( p_event->p_vout, "mouse-button-down", &val );
+ val.i_int |= 2;
+ var_Set( p_event->p_vout, "mouse-button-down", val );
+ DirectXPopupMenu( p_event, VLC_FALSE );
+ break;
+
+ case WM_MBUTTONUP:
+ var_Get( p_event->p_vout, "mouse-button-down", &val );
+ val.i_int &= ~2;
+ var_Set( p_event->p_vout, "mouse-button-down", val );
+ break;
+
+ case WM_RBUTTONDOWN:
+ var_Get( p_event->p_vout, "mouse-button-down", &val );
+ val.i_int |= 4;
+ var_Set( p_event->p_vout, "mouse-button-down", val );
+ DirectXPopupMenu( p_event, VLC_FALSE );
+ break;
+
+ case WM_RBUTTONUP:
+ var_Get( p_event->p_vout, "mouse-button-down", &val );
+ val.i_int &= ~4;
+ var_Set( p_event->p_vout, "mouse-button-down", val );
+ DirectXPopupMenu( p_event, VLC_TRUE );
+ break;
+
case WM_KEYDOWN:
/* the key events are first processed here. The next
* message processed by this main message loop will be the
switch( msg.wParam )
{
case VK_ESCAPE:
- /* exit application */
- p_event->p_vlc->b_die = VLC_TRUE;
+ if( p_event->p_vout->b_fullscreen )
+ {
+ p_event->p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
+ }
+ else
+ {
+ /* close video window */
+ PostMessage( msg.hwnd, WM_CLOSE, 0, 0 );
+ }
break;
- case VK_F1: network_ChannelJoin( p_event, 1 ); break;
- case VK_F2: network_ChannelJoin( p_event, 2 ); break;
- case VK_F3: network_ChannelJoin( p_event, 3 ); break;
- case VK_F4: network_ChannelJoin( p_event, 4 ); break;
- case VK_F5: network_ChannelJoin( p_event, 5 ); break;
- case VK_F6: network_ChannelJoin( p_event, 6 ); break;
- case VK_F7: network_ChannelJoin( p_event, 7 ); break;
- case VK_F8: network_ChannelJoin( p_event, 8 ); break;
- case VK_F9: network_ChannelJoin( p_event, 9 ); break;
- case VK_F10: network_ChannelJoin( p_event, 10 ); break;
- case VK_F11: network_ChannelJoin( p_event, 11 ); break;
- case VK_F12: network_ChannelJoin( p_event, 12 ); break;
+ case VK_MENU:
+ {
+ playlist_t *p_playlist =
+ vlc_object_find( p_event, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ if( p_playlist != NULL )
+ {
+ vlc_value_t val;
+ var_Set( p_playlist, "intf-popupmenu", val );
+ vlc_object_release( p_playlist );
+ }
+ }
+ break;
+
+ case VK_LEFT:
+ if( GetKeyState(VK_CONTROL) & 0x8000 )
+ {
+ input_Seek( p_event->p_vout, -60,
+ INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
+ }
+ else
+ {
+ val.psz_string = "LEFT";
+ var_Set( p_event->p_vout, "key-pressed", val );
+ }
+ break;
+ case VK_RIGHT:
+ if( GetKeyState(VK_CONTROL) & 0x8000 )
+ {
+ input_Seek( p_event->p_vout, 60,
+ INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
+ }
+ else
+ {
+ val.psz_string = "RIGHT";
+ var_Set( p_event->p_vout, "key-pressed", val );
+ }
+ break;
+ case VK_UP:
+ val.psz_string = "UP";
+ var_Set( p_event->p_vout, "key-pressed", val );
+ break;
+ case VK_DOWN:
+ val.psz_string = "DOWN";
+ var_Set( p_event->p_vout, "key-pressed", val );
+ break;
+ case VK_RETURN:
+ val.psz_string = "ENTER";
+ var_Set( p_event->p_vout, "key-pressed", val );
+ break;
+ case VK_HOME:
+ input_Seek( p_event->p_vout, 0,
+ INPUT_SEEK_BYTES | INPUT_SEEK_SET );
+ break;
+ case VK_END:
+ input_Seek( p_event->p_vout, 0,
+ INPUT_SEEK_BYTES | INPUT_SEEK_END );
+ break;
+ case VK_PRIOR:
+ input_Seek( p_event->p_vout, 10,
+ INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
+ break;
+ case VK_NEXT:
+ input_Seek( p_event->p_vout, -10,
+ INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
+ break;
+ case VK_SPACE:
+ input_SetStatus( p_event->p_vout, INPUT_STATUS_PAUSE );
+ break;
}
TranslateMessage(&msg);
break;
p_event->p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;
break;
- case 'c': /* toggle grayscale */
- case 'C':
- p_event->p_vout->b_grayscale = ! p_event->p_vout->b_grayscale;
- p_event->p_vout->p_sys->i_changes |= VOUT_GRAYSCALE_CHANGE;
- break;
-
- case 'i': /* toggle info */
- case 'I':
- p_event->p_vout->b_info = ! p_event->p_vout->b_info;
- p_event->p_vout->p_sys->i_changes |= VOUT_INFO_CHANGE;
- break;
-
- case 's': /* toggle scaling */
- case 'S':
- p_event->p_vout->b_scale = ! p_event->p_vout->b_scale;
- p_event->p_vout->p_sys->i_changes |= VOUT_SCALE_CHANGE;
- break;
-
- case ' ': /* toggle interface */
- p_event->p_vout->b_interface = ! p_event->p_vout->b_interface;
- p_event->p_vout->p_sys->i_changes |= VOUT_INTF_CHANGE;
- break;
-
default:
break;
}
HMENU hMenu;
RECT rect_window;
+ vlc_value_t val;
+
msg_Dbg( p_vout, "DirectXCreateWindow" );
/* Get this module's instance */
ReleaseDC( NULL, hdc );
/* If an external window was specified, we'll draw in it. */
+ var_Get( p_vout->p_vlc, "drawable", &val );
p_vout->p_sys->hparent = p_vout->p_sys->hwnd =
- (void*)(ptrdiff_t)config_GetInt( p_vout, "directx-window" );
+ val.i_int ? (void*)(ptrdiff_t) val.i_int : NULL;
if( p_vout->p_sys->hparent )
{
{
DestroyWindow( p_vout->p_sys->hwnd );
}
+ else if( p_vout->p_sys->hparent )
+ {
+ /* We don't want our windowproc to be called anymore */
+ SetWindowLong( p_vout->p_sys->hwnd,
+ GWL_WNDPROC, (LONG)p_vout->p_sys->pf_wndproc );
+
+ /* Blam! Erase everything that might have been there. */
+ InvalidateRect( p_vout->p_sys->hwnd, NULL, TRUE );
+ }
p_vout->p_sys->hwnd = NULL;
/* 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 = VLC_TRUE;
+ {
+ playlist_t * p_playlist =
+ (playlist_t *)vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ if( p_playlist == NULL )
+ {
+ return 0;
+ }
+
+ playlist_Stop( p_playlist );
+ vlc_object_release( p_playlist );
return 0;
+ }
/* the window has been closed so shut down everything now */
case WM_DESTROY:
return DefWindowProc(hwnd, message, wParam, lParam);
}
-