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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * vout_intf.c : video output interface
  3.  *****************************************************************************
  4.  * Copyright (C) 2000-2004 VideoLAN
  5.  * $Id: vout_intf.c 8669 2004-09-08 21:11:31Z 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 <stdlib.h>                                                /* free() */
  27. #include <vlc/vlc.h>
  28. #include <vlc/intf.h>
  29. #include "vlc_video.h"
  30. #include "video_output.h"
  31. /*****************************************************************************
  32.  * Local prototypes
  33.  *****************************************************************************/
  34. /* Object variables callbacks */
  35. static int ZoomCallback( vlc_object_t *, char const *,
  36.                          vlc_value_t, vlc_value_t, void * );
  37. static int OnTopCallback( vlc_object_t *, char const *,
  38.                           vlc_value_t, vlc_value_t, void * );
  39. static int FullscreenCallback( vlc_object_t *, char const *,
  40.                                vlc_value_t, vlc_value_t, void * );
  41. /*****************************************************************************
  42.  * vout_RequestWindow: Create/Get a video window if possible.
  43.  *****************************************************************************
  44.  * This function looks for the main interface and tries to request
  45.  * a new video window. If it fails then the vout will still need to create the
  46.  * window by itself.
  47.  *****************************************************************************/
  48. void *vout_RequestWindow( vout_thread_t *p_vout,
  49.                           int *pi_x_hint, int *pi_y_hint,
  50.                           unsigned int *pi_width_hint,
  51.                           unsigned int *pi_height_hint )
  52. {
  53.     intf_thread_t *p_intf = NULL;
  54.     vlc_list_t *p_list;
  55.     void *p_window;
  56.     vlc_value_t val;
  57.     int i;
  58.     /* Small kludge */
  59.     if( !var_Type( p_vout, "aspect-ratio" ) ) vout_IntfInit( p_vout );
  60.     /* Get requested coordinates */
  61.     var_Get( p_vout, "video-x", &val );
  62.     *pi_x_hint = val.i_int ;
  63.     var_Get( p_vout, "video-y", &val );
  64.     *pi_y_hint = val.i_int;
  65.     *pi_width_hint = p_vout->i_window_width;
  66.     *pi_height_hint = p_vout->i_window_height;
  67.     /* Check whether someone provided us with a window ID */
  68.     var_Get( p_vout->p_vlc, "drawable", &val );
  69.     if( val.i_int ) return (void *)val.i_int;
  70.     /* Find if the main interface supports embedding */
  71.     p_list = vlc_list_find( p_vout, VLC_OBJECT_INTF, FIND_ANYWHERE );
  72.     if( !p_list ) return NULL;
  73.     for( i = 0; i < p_list->i_count; i++ )
  74.     {
  75.         p_intf = (intf_thread_t *)p_list->p_values[i].p_object;
  76.         if( p_intf->b_block && p_intf->pf_request_window ) break;
  77.         p_intf = NULL;
  78.     }
  79.     if( !p_intf )
  80.     {
  81.         vlc_list_release( p_list );
  82.         return NULL;
  83.     }
  84.     vlc_object_yield( p_intf );
  85.     vlc_list_release( p_list );
  86.     p_window = p_intf->pf_request_window( p_intf, p_vout, pi_x_hint, pi_y_hint,
  87.                                           pi_width_hint, pi_height_hint );
  88.     if( !p_window ) vlc_object_release( p_intf );
  89.     else p_vout->p_parent_intf = p_intf;
  90.     return p_window;
  91. }
  92. void vout_ReleaseWindow( vout_thread_t *p_vout, void *p_window )
  93. {
  94.     intf_thread_t *p_intf = p_vout->p_parent_intf;
  95.     if( !p_intf ) return;
  96.     vlc_mutex_lock( &p_intf->object_lock );
  97.     if( p_intf->b_dead )
  98.     {
  99.         vlc_mutex_unlock( &p_intf->object_lock );
  100.         return;
  101.     }
  102.     if( !p_intf->pf_release_window )
  103.     {
  104.         msg_Err( p_vout, "no pf_release_window");
  105.         vlc_mutex_unlock( &p_intf->object_lock );
  106.         vlc_object_release( p_intf );
  107.         return;
  108.     }
  109.     p_intf->pf_release_window( p_intf, p_window );
  110.     p_vout->p_parent_intf = NULL;
  111.     vlc_mutex_unlock( &p_intf->object_lock );
  112.     vlc_object_release( p_intf );
  113. }
  114. int vout_ControlWindow( vout_thread_t *p_vout, void *p_window,
  115.                         int i_query, va_list args )
  116. {
  117.     intf_thread_t *p_intf = p_vout->p_parent_intf;
  118.     int i_ret;
  119.     if( !p_intf ) return VLC_EGENERIC;
  120.     vlc_mutex_lock( &p_intf->object_lock );
  121.     if( p_intf->b_dead )
  122.     {
  123.         vlc_mutex_unlock( &p_intf->object_lock );
  124.         return VLC_EGENERIC;
  125.     }
  126.     if( !p_intf->pf_control_window )
  127.     {
  128.         msg_Err( p_vout, "no pf_control_window");
  129.         vlc_mutex_unlock( &p_intf->object_lock );
  130.         return VLC_EGENERIC;
  131.     }
  132.     i_ret = p_intf->pf_control_window( p_intf, p_window, i_query, args );
  133.     vlc_mutex_unlock( &p_intf->object_lock );
  134.     return i_ret;
  135. }
  136. /*****************************************************************************
  137.  * vout_IntfInit: called during the vout creation to initialise misc things.
  138.  *****************************************************************************/
  139. void vout_IntfInit( vout_thread_t *p_vout )
  140. {
  141.     vlc_value_t val, text, old_val;
  142.     /* Create a few object variables we'll need later on */
  143.     var_Create( p_vout, "aspect-ratio", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
  144.     var_Create( p_vout, "width", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
  145.     var_Create( p_vout, "height", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
  146.     var_Create( p_vout, "align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
  147.     var_Create( p_vout, "video-x", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
  148.     var_Create( p_vout, "video-y", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
  149.     var_Create( p_vout, "zoom", VLC_VAR_FLOAT | VLC_VAR_ISCOMMAND |
  150.                 VLC_VAR_HASCHOICE | VLC_VAR_DOINHERIT );
  151.     text.psz_string = _("Zoom");
  152.     var_Change( p_vout, "zoom", VLC_VAR_SETTEXT, &text, NULL );
  153.     var_Get( p_vout, "zoom", &old_val );
  154.     if( old_val.f_float == 0.25 ||
  155.         old_val.f_float == 0.5 ||
  156.         old_val.f_float == 1 ||
  157.         old_val.f_float == 2 )
  158.     {
  159.         var_Change( p_vout, "zoom", VLC_VAR_DELCHOICE, &old_val, NULL );
  160.     }
  161.     val.f_float = 0.25; text.psz_string = _("1:4 Quarter");
  162.     var_Change( p_vout, "zoom", VLC_VAR_ADDCHOICE, &val, &text );
  163.     val.f_float = 0.5; text.psz_string = _("1:2 Half");
  164.     var_Change( p_vout, "zoom", VLC_VAR_ADDCHOICE, &val, &text );
  165.     val.f_float = 1; text.psz_string = _("1:1 Original");
  166.     var_Change( p_vout, "zoom", VLC_VAR_ADDCHOICE, &val, &text );
  167.     val.f_float = 2; text.psz_string = _("2:1 Double");
  168.     var_Change( p_vout, "zoom", VLC_VAR_ADDCHOICE, &val, &text );
  169.     var_Set( p_vout, "zoom", old_val );
  170.     var_AddCallback( p_vout, "zoom", ZoomCallback, NULL );
  171.     /* Add a variable to indicate if the window should be on top of others */
  172.     var_Create( p_vout, "video-on-top", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
  173.     text.psz_string = _("Always on top");
  174.     var_Change( p_vout, "video-on-top", VLC_VAR_SETTEXT, &text, NULL );
  175.     var_AddCallback( p_vout, "video-on-top", OnTopCallback, NULL );
  176.     /* Add a fullscreen variable */
  177.     var_Create( p_vout, "fullscreen", VLC_VAR_BOOL );
  178.     text.psz_string = _("Fullscreen");
  179.     var_Change( p_vout, "fullscreen", VLC_VAR_SETTEXT, &text, NULL );
  180.     var_Change( p_vout, "fullscreen", VLC_VAR_INHERITVALUE, &val, NULL );
  181.     if( val.b_bool )
  182.     {
  183.         /* user requested fullscreen */
  184.         p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
  185.     }
  186.     var_AddCallback( p_vout, "fullscreen", FullscreenCallback, NULL );
  187.     /* Mouse coordinates */
  188.     var_Create( p_vout, "mouse-x", VLC_VAR_INTEGER );
  189.     var_Create( p_vout, "mouse-y", VLC_VAR_INTEGER );
  190.     var_Create( p_vout, "mouse-button-down", VLC_VAR_INTEGER );
  191.     var_Create( p_vout, "mouse-moved", VLC_VAR_BOOL );
  192.     var_Create( p_vout, "mouse-clicked", VLC_VAR_INTEGER );
  193.     var_Create( p_vout, "intf-change", VLC_VAR_BOOL );
  194.     val.b_bool = VLC_TRUE;
  195.     var_Set( p_vout, "intf-change", val );
  196. }
  197. /*****************************************************************************
  198.  * vout_ControlDefault: default methods for video output control.
  199.  *****************************************************************************/
  200. int vout_vaControlDefault( vout_thread_t *p_vout, int i_query, va_list args )
  201. {
  202.     switch( i_query )
  203.     {
  204.     case VOUT_REPARENT:
  205.     case VOUT_CLOSE:
  206.         if( p_vout->p_parent_intf )
  207.         {
  208.             vlc_object_release( p_vout->p_parent_intf );
  209.             p_vout->p_parent_intf = NULL;
  210.         }
  211.         return VLC_SUCCESS;
  212.         break;
  213.     default:
  214.         msg_Dbg( p_vout, "control query not supported" );
  215.         return VLC_EGENERIC;
  216.     }
  217. }
  218. /*****************************************************************************
  219.  * Object variables callbacks
  220.  *****************************************************************************/
  221. static int ZoomCallback( vlc_object_t *p_this, char const *psz_cmd,
  222.                          vlc_value_t oldval, vlc_value_t newval, void *p_data )
  223. {
  224.     vout_thread_t *p_vout = (vout_thread_t *)p_this;
  225.     vout_Control( p_vout, VOUT_SET_ZOOM, newval.f_float );
  226.     return VLC_SUCCESS;
  227. }
  228. static int OnTopCallback( vlc_object_t *p_this, char const *psz_cmd,
  229.                          vlc_value_t oldval, vlc_value_t newval, void *p_data )
  230. {
  231.     vout_thread_t *p_vout = (vout_thread_t *)p_this;
  232.     playlist_t *p_playlist;
  233.     vout_Control( p_vout, VOUT_SET_STAY_ON_TOP, newval.b_bool );
  234.     p_playlist = (playlist_t *)vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
  235.                                                  FIND_PARENT );
  236.     if( p_playlist )
  237.     {
  238.         /* Modify playlist as well because the vout might have to be restarted */
  239.         var_Create( p_playlist, "video-on-top", VLC_VAR_BOOL );
  240.         var_Set( p_playlist, "video-on-top", newval );
  241.         vlc_object_release( p_playlist );
  242.     }
  243.     return VLC_SUCCESS;
  244. }
  245. static int FullscreenCallback( vlc_object_t *p_this, char const *psz_cmd,
  246.                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
  247. {
  248.     vout_thread_t *p_vout = (vout_thread_t *)p_this;
  249.     playlist_t *p_playlist;
  250.     vlc_value_t val;
  251.     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
  252.     p_playlist = (playlist_t *)vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
  253.                                                  FIND_PARENT );
  254.     if( p_playlist )
  255.     {
  256.         /* Modify playlist as well because the vout might have to be restarted */
  257.         var_Create( p_playlist, "fullscreen", VLC_VAR_BOOL );
  258.         var_Set( p_playlist, "fullscreen", newval );
  259.         vlc_object_release( p_playlist );
  260.     }
  261.     /* Disable "always on top" in fullscreen mode */
  262.     var_Get( p_vout, "video-on-top", &val );
  263.     if( newval.b_bool && val.b_bool )
  264.     {
  265.         val.b_bool = VLC_FALSE;
  266.         vout_Control( p_vout, VOUT_SET_STAY_ON_TOP, val.b_bool );
  267.     }
  268.     else if( !newval.b_bool && val.b_bool )
  269.     {
  270.         vout_Control( p_vout, VOUT_SET_STAY_ON_TOP, val.b_bool );
  271.     }
  272.     val.b_bool = VLC_TRUE;
  273.     var_Set( p_vout, "intf-change", val );
  274.     return VLC_SUCCESS;
  275. }