video.cpp
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:9k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * video.cpp : wxWindows plugin for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2000-2004, 2003 VideoLAN
  5.  * $Id: video.cpp 8980 2004-10-13 12:32:06Z gbazin $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@videolan.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <vlc/vlc.h>
  27. #include <vlc/vout.h>
  28. #include <vlc/intf.h>
  29. #include "wxwindows.h"
  30. static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *,
  31.                         int *pi_x_hint, int *pi_y_hint,
  32.                         unsigned int *pi_width_hint,
  33.                         unsigned int *pi_height_hint );
  34. static void ReleaseWindow( intf_thread_t *p_intf, void *p_window );
  35. static int ControlWindow( intf_thread_t *p_intf, void *p_window,
  36.                           int i_query, va_list args );
  37. /* IDs for the controls and the menu commands */
  38. enum
  39. {
  40.     UpdateSize_Event = wxID_HIGHEST + 1,
  41.     UpdateHide_Event,
  42.     SetStayOnTop_Event,
  43. };
  44. class VideoWindow: public wxWindow
  45. {
  46. public:
  47.     /* Constructor */
  48.     VideoWindow( intf_thread_t *_p_intf, wxWindow *p_parent );
  49.     virtual ~VideoWindow();
  50.     void *GetWindow( vout_thread_t *p_vout, int *, int *,
  51.                      unsigned int *, unsigned int * );
  52.     void ReleaseWindow( void * );
  53.     int  ControlWindow( void *, int, va_list );
  54. private:
  55.     intf_thread_t *p_intf;
  56.     vout_thread_t *p_vout;
  57.     wxWindow *p_parent;
  58.     vlc_mutex_t lock;
  59.     vlc_bool_t b_shown;
  60.     wxWindow *p_child_window;
  61.     void UpdateSize( wxSizeEvent & );
  62.     void UpdateHide( wxSizeEvent & );
  63.     void OnControlEvent( wxCommandEvent & );
  64.     DECLARE_EVENT_TABLE();
  65. };
  66. DEFINE_LOCAL_EVENT_TYPE( wxEVT_VLC_VIDEO );
  67. BEGIN_EVENT_TABLE(VideoWindow, wxWindow)
  68.     EVT_CUSTOM( wxEVT_SIZE, UpdateSize_Event, VideoWindow::UpdateSize )
  69.     EVT_CUSTOM( wxEVT_SIZE, UpdateHide_Event, VideoWindow::UpdateHide )
  70.     EVT_COMMAND( SetStayOnTop_Event, wxEVT_VLC_VIDEO,
  71.                  VideoWindow::OnControlEvent )
  72. END_EVENT_TABLE()
  73. /*****************************************************************************
  74.  * Public methods.
  75.  *****************************************************************************/
  76. wxWindow *VideoWindow( intf_thread_t *p_intf, wxWindow *p_parent )
  77. {
  78.     return new VideoWindow::VideoWindow( p_intf, p_parent );
  79. }
  80. /*****************************************************************************
  81.  * Constructor.
  82.  *****************************************************************************/
  83. VideoWindow::VideoWindow( intf_thread_t *_p_intf, wxWindow *_p_parent ):
  84.     wxWindow( _p_parent, -1 )
  85. {
  86.     /* Initializations */
  87.     p_intf = _p_intf;
  88.     p_parent = _p_parent;
  89.     vlc_mutex_init( p_intf, &lock );
  90.     p_vout = NULL;
  91.     p_intf->pf_request_window = ::GetWindow;
  92.     p_intf->pf_release_window = ::ReleaseWindow;
  93.     p_intf->pf_control_window = ::ControlWindow;
  94.     p_intf->p_sys->p_video_window = this;
  95.     p_child_window = new wxWindow( this, -1, wxDefaultPosition, wxSize(0,0) );
  96.     p_child_window->Show();
  97.     Show();
  98.     b_shown = VLC_TRUE;
  99.     p_intf->p_sys->p_video_sizer = new wxBoxSizer( wxHORIZONTAL );
  100.     p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND );
  101.     ReleaseWindow( NULL );
  102. }
  103. VideoWindow::~VideoWindow()
  104. {
  105.     vlc_mutex_lock( &lock );
  106.     if( p_vout )
  107.     {
  108.         if( !p_intf->psz_switch_intf )
  109.         {
  110.             if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
  111.                 vout_Control( p_vout, VOUT_REPARENT );
  112.         }
  113.         else
  114.         {
  115.             if( vout_Control( p_vout, VOUT_REPARENT ) != VLC_SUCCESS )
  116.                 vout_Control( p_vout, VOUT_CLOSE );
  117.         }
  118.     }
  119.     p_intf->pf_request_window = NULL;
  120.     p_intf->pf_release_window = NULL;
  121.     p_intf->pf_control_window = NULL;
  122.     vlc_mutex_unlock( &lock );
  123.     vlc_mutex_destroy( &lock );
  124. }
  125. /*****************************************************************************
  126.  * Private methods.
  127.  *****************************************************************************/
  128. static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *p_vout,
  129.                         int *pi_x_hint, int *pi_y_hint,
  130.                         unsigned int *pi_width_hint,
  131.                         unsigned int *pi_height_hint )
  132. {
  133.     return p_intf->p_sys->p_video_window->GetWindow( p_vout,
  134.                                                      pi_x_hint, pi_y_hint,
  135.                                                      pi_width_hint,
  136.                                                      pi_height_hint );
  137. }
  138. /* Part of the hack to get the X11 window handle from the GtkWidget */
  139. #ifdef __WXGTK__
  140. extern "C" {
  141. #ifdef __WXGTK20__
  142.     int gdk_x11_drawable_get_xid( void * );
  143. #endif
  144.     void *gtk_widget_get_parent_window( void * );
  145. }
  146. #endif
  147. void *VideoWindow::GetWindow( vout_thread_t *_p_vout,
  148.                               int *pi_x_hint, int *pi_y_hint,
  149.                               unsigned int *pi_width_hint,
  150.                               unsigned int *pi_height_hint )
  151. {
  152. #if defined(__WXGTK__) || defined(WIN32)
  153.     vlc_mutex_lock( &lock );
  154.     if( p_vout )
  155.     {
  156.         vlc_mutex_unlock( &lock );
  157.         msg_Dbg( p_intf, "Video window already in use" );
  158.         return NULL;
  159.     }
  160.     p_vout = _p_vout;
  161.     wxSizeEvent event( wxSize(*pi_width_hint, *pi_height_hint),
  162.                        UpdateSize_Event );
  163.     AddPendingEvent( event );
  164.     vlc_mutex_unlock( &lock );
  165. #ifdef __WXGTK__
  166.     GtkWidget *p_widget = p_child_window->GetHandle();
  167. #ifdef __WXGTK20__
  168.     return (void *)gdk_x11_drawable_get_xid(
  169.                gtk_widget_get_parent_window( p_widget ) );
  170. #elif defined(__WXGTK__)
  171.     return (void *)*(int *)( (char *)gtk_widget_get_parent_window( p_widget )
  172.                + 2 * sizeof(void *) );
  173. #endif
  174. #elif defined(WIN32)
  175.     return (void*)GetHandle();
  176. #endif
  177. #else // defined(__WXGTK__) || defined(WIN32)
  178.     return NULL;
  179. #endif
  180. }
  181. static void ReleaseWindow( intf_thread_t *p_intf, void *p_window )
  182. {
  183.     return p_intf->p_sys->p_video_window->ReleaseWindow( p_window );
  184. }
  185. void VideoWindow::ReleaseWindow( void *p_window )
  186. {
  187.     vlc_mutex_lock( &lock );
  188.     p_vout = NULL;
  189. #if defined(__WXGTK__) || defined(WIN32)
  190.     wxSizeEvent event( wxSize(0, 0), UpdateHide_Event );
  191.     AddPendingEvent( event );
  192. #endif
  193.     vlc_mutex_unlock( &lock );
  194. }
  195. void VideoWindow::UpdateSize( wxSizeEvent &event )
  196. {
  197.     if( !b_shown )
  198.     {
  199.         p_intf->p_sys->p_video_sizer->Show( this, TRUE );
  200.         p_intf->p_sys->p_video_sizer->Layout();
  201.         SetFocus();
  202.         b_shown = VLC_TRUE;
  203.     }
  204.     p_intf->p_sys->p_video_sizer->SetMinSize( event.GetSize() );
  205.     wxCommandEvent intf_event( wxEVT_INTF, 0 );
  206.     p_parent->AddPendingEvent( intf_event );
  207. }
  208. void VideoWindow::UpdateHide( wxSizeEvent &event )
  209. {
  210.     if( b_shown )
  211.     {
  212.         p_intf->p_sys->p_video_sizer->Show( this, FALSE );
  213.         p_intf->p_sys->p_video_sizer->Layout();
  214.         b_shown = VLC_FALSE;
  215.         SetSize(0,0);
  216.         Show();
  217.     }
  218.     p_intf->p_sys->p_video_sizer->SetMinSize( event.GetSize() );
  219.     wxCommandEvent intf_event( wxEVT_INTF, 0 );
  220.     p_parent->AddPendingEvent( intf_event );
  221. }
  222. void VideoWindow::OnControlEvent( wxCommandEvent &event )
  223. {
  224.     switch( event.GetId() )
  225.     {
  226.     case SetStayOnTop_Event:
  227.         wxCommandEvent intf_event( wxEVT_INTF, 1 );
  228.         intf_event.SetInt( event.GetInt() );
  229.         p_parent->AddPendingEvent( intf_event );
  230.         break;
  231.     }
  232. }
  233. static int ControlWindow( intf_thread_t *p_intf, void *p_window,
  234.                           int i_query, va_list args )
  235. {
  236.     return p_intf->p_sys->p_video_window->ControlWindow( p_window, i_query,
  237.                                                          args );
  238. }
  239. int VideoWindow::ControlWindow( void *p_window, int i_query, va_list args )
  240. {
  241.     int i_ret = VLC_EGENERIC;
  242.     vlc_mutex_lock( &lock );
  243.     switch( i_query )
  244.     {
  245.         case VOUT_SET_ZOOM:
  246.         {
  247.             double f_arg = va_arg( args, double );
  248.             /* Update dimensions */
  249.             wxSizeEvent event( wxSize((int)(p_vout->i_window_width * f_arg),
  250.                                       (int)(p_vout->i_window_height * f_arg)),
  251.                                UpdateSize_Event );
  252.             AddPendingEvent( event );
  253.             i_ret = VLC_SUCCESS;
  254.         }
  255.         break;
  256.         case VOUT_SET_STAY_ON_TOP:
  257.         {
  258.             int i_arg = va_arg( args, int );
  259.             wxCommandEvent event( wxEVT_VLC_VIDEO, SetStayOnTop_Event );
  260.             event.SetInt( i_arg );
  261.             AddPendingEvent( event );
  262.             i_ret = VLC_SUCCESS;
  263.         }
  264.         break;
  265.         default:
  266.             msg_Dbg( p_intf, "control query not supported" );
  267.             break;
  268.     }
  269.     vlc_mutex_unlock( &lock );
  270.     return i_ret;
  271. }