skin_main.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:18k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * skin_main.cpp
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 the VideoLAN team
  5.  * $Id: f5608699fbda8e87981a4e1f028965abaa751fda $
  6.  *
  7.  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
  8.  *          Olivier Teulière <ipkiss@via.ecp.fr>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. #ifdef HAVE_CONFIG_H
  25. # include "config.h"
  26. #endif
  27. #include <vlc_common.h>
  28. #include <vlc_plugin.h>
  29. #include <vlc_input.h>
  30. #include <vlc_demux.h>
  31. #include <vlc_playlist.h>
  32. #include <vlc_threads.h>
  33. #include <vlc_window.h>
  34. #include "dialogs.hpp"
  35. #include "os_factory.hpp"
  36. #include "os_loop.hpp"
  37. #include "var_manager.hpp"
  38. #include "vlcproc.hpp"
  39. #include "theme_loader.hpp"
  40. #include "theme.hpp"
  41. #include "theme_repository.hpp"
  42. #include "vout_window.hpp"
  43. #include "vout_manager.hpp"
  44. #include "../parser/interpreter.hpp"
  45. #include "../commands/async_queue.hpp"
  46. #include "../commands/cmd_quit.hpp"
  47. #include "../commands/cmd_dialogs.hpp"
  48. #include "../commands/cmd_minimize.hpp"
  49. #include "../commands/cmd_playlist.hpp"
  50. //---------------------------------------------------------------------------
  51. // Exported interface functions.
  52. //---------------------------------------------------------------------------
  53. #ifdef WIN32_SKINS
  54. extern "C" __declspec( dllexport )
  55.     int __VLC_SYMBOL( vlc_entry ) ( module_t *p_module );
  56. #endif
  57. //---------------------------------------------------------------------------
  58. // Local prototypes
  59. //---------------------------------------------------------------------------
  60. static int  Open  ( vlc_object_t * );
  61. static void Close ( vlc_object_t * );
  62. static void Run   ( intf_thread_t * );
  63. static int DemuxOpen( vlc_object_t * );
  64. static int Demux( demux_t * );
  65. static int DemuxControl( demux_t *, int, va_list );
  66. //---------------------------------------------------------------------------
  67. // Prototypes for configuration callbacks
  68. //---------------------------------------------------------------------------
  69. static int onSystrayChange( vlc_object_t *pObj, const char *pVariable,
  70.                             vlc_value_t oldVal, vlc_value_t newVal,
  71.                             void *pParam );
  72. static int onTaskBarChange( vlc_object_t *pObj, const char *pVariable,
  73.                             vlc_value_t oldVal, vlc_value_t newVal,
  74.                             void *pParam );
  75. static struct
  76. {
  77.     intf_thread_t *intf;
  78.     vlc_mutex_t mutex;
  79. } skin_load = { NULL, VLC_STATIC_MUTEX };
  80. //---------------------------------------------------------------------------
  81. // Open: initialize interface
  82. //---------------------------------------------------------------------------
  83. static int Open( vlc_object_t *p_this )
  84. {
  85.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  86.     // Allocate instance and initialize some members
  87.     p_intf->p_sys = (intf_sys_t *) malloc( sizeof( intf_sys_t ) );
  88.     if( p_intf->p_sys == NULL )
  89.         return( VLC_ENOMEM );
  90.     p_intf->pf_run = Run;
  91.     // Suscribe to messages bank
  92. #if 0
  93.     p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
  94. #endif
  95.     p_intf->p_sys->p_input = NULL;
  96.     p_intf->p_sys->p_playlist = pl_Hold( p_intf );
  97.     // Initialize "singleton" objects
  98.     p_intf->p_sys->p_logger = NULL;
  99.     p_intf->p_sys->p_queue = NULL;
  100.     p_intf->p_sys->p_dialogs = NULL;
  101.     p_intf->p_sys->p_interpreter = NULL;
  102.     p_intf->p_sys->p_osFactory = NULL;
  103.     p_intf->p_sys->p_osLoop = NULL;
  104.     p_intf->p_sys->p_varManager = NULL;
  105.     p_intf->p_sys->p_voutManager = NULL;
  106.     p_intf->p_sys->p_vlcProc = NULL;
  107.     p_intf->p_sys->p_repository = NULL;
  108. #ifdef WIN32
  109.     p_intf->p_sys->b_exitRequested = false;
  110.     p_intf->p_sys->b_exitOK = false;
  111. #endif
  112.     // No theme yet
  113.     p_intf->p_sys->p_theme = NULL;
  114.     // Create a variable to be notified of skins to be loaded
  115.     var_Create( p_intf, "skin-to-load", VLC_VAR_STRING );
  116.     // Initialize singletons
  117.     if( OSFactory::instance( p_intf ) == NULL )
  118.     {
  119.         msg_Err( p_intf, "cannot initialize OSFactory" );
  120.         vlc_object_release( p_intf->p_sys->p_playlist );
  121. #if 0
  122.         msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
  123. #endif
  124.         return VLC_EGENERIC;
  125.     }
  126.     if( AsyncQueue::instance( p_intf ) == NULL )
  127.     {
  128.         msg_Err( p_intf, "cannot initialize AsyncQueue" );
  129.         vlc_object_release( p_intf->p_sys->p_playlist );
  130. #if 0
  131.         msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
  132. #endif
  133.         return VLC_EGENERIC;
  134.     }
  135.     if( Interpreter::instance( p_intf ) == NULL )
  136.     {
  137.         msg_Err( p_intf, "cannot instanciate Interpreter" );
  138.         vlc_object_release( p_intf->p_sys->p_playlist );
  139. #if 0
  140.         msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
  141. #endif
  142.         return VLC_EGENERIC;
  143.     }
  144.     if( VarManager::instance( p_intf ) == NULL )
  145.     {
  146.         msg_Err( p_intf, "cannot instanciate VarManager" );
  147.         vlc_object_release( p_intf->p_sys->p_playlist );
  148. #if 0
  149.         msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
  150. #endif
  151.         return VLC_EGENERIC;
  152.     }
  153.     if( VlcProc::instance( p_intf ) == NULL )
  154.     {
  155.         msg_Err( p_intf, "cannot initialize VLCProc" );
  156.         vlc_object_release( p_intf->p_sys->p_playlist );
  157. #if 0
  158.         msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
  159. #endif
  160.         return VLC_EGENERIC;
  161.     }
  162.     if( VoutManager::instance( p_intf ) == NULL )
  163.     {
  164.         msg_Err( p_intf, "cannot instanciate VoutManager" );
  165.         vlc_object_release( p_intf->p_sys->p_playlist );
  166.         return VLC_EGENERIC;
  167.     }
  168.     vlc_mutex_lock( &skin_load.mutex );
  169.     skin_load.intf = p_intf;
  170.     vlc_mutex_unlock( &skin_load.mutex );
  171.     Dialogs::instance( p_intf );
  172.     ThemeRepository::instance( p_intf );
  173.     // Load a theme
  174.     char *skin_last = config_GetPsz( p_intf, "skins2-last" );
  175.     ThemeLoader *pLoader = new ThemeLoader( p_intf );
  176.     if( !skin_last || !*skin_last || !pLoader->load( skin_last ) )
  177.     {
  178.         // Get the resource path and try to load the default skin
  179.         OSFactory *pOSFactory = OSFactory::instance( p_intf );
  180.         const list<string> &resPath = pOSFactory->getResourcePath();
  181.         const string &sep = pOSFactory->getDirSeparator();
  182.         list<string>::const_iterator it;
  183.         for( it = resPath.begin(); it != resPath.end(); it++ )
  184.         {
  185.             string path = (*it) + sep + "default.vlt";
  186.             if( pLoader->load( path ) )
  187.             {
  188.                 // Theme loaded successfully
  189.                 break;
  190.             }
  191.         }
  192.         if( it == resPath.end() )
  193.         {
  194.             // Last chance: the user can select a new theme file
  195.             if( Dialogs::instance( p_intf ) )
  196.             {
  197.                 CmdDlgChangeSkin *pCmd = new CmdDlgChangeSkin( p_intf );
  198.                 AsyncQueue *pQueue = AsyncQueue::instance( p_intf );
  199.                 pQueue->push( CmdGenericPtr( pCmd ) );
  200.             }
  201.             else
  202.             {
  203.                 // No dialogs provider, just quit...
  204.                 CmdQuit *pCmd = new CmdQuit( p_intf );
  205.                 AsyncQueue *pQueue = AsyncQueue::instance( p_intf );
  206.                 pQueue->push( CmdGenericPtr( pCmd ) );
  207.                 msg_Err( p_intf,
  208.                          "cannot show the "open skin" dialog: exiting...");
  209.             }
  210.         }
  211.     }
  212.     delete pLoader;
  213.     free( skin_last );
  214. #ifdef WIN32
  215.     p_intf->b_should_run_on_first_thread = true;
  216.     // enqueue a command to automatically start the first playlist item
  217.     AsyncQueue *pQueue = AsyncQueue::instance( p_intf );
  218.     CmdPlaylistFirst *pCmd = new CmdPlaylistFirst( p_intf );
  219.     pQueue->push( CmdGenericPtr( pCmd ) );
  220. #endif
  221.     return( VLC_SUCCESS );
  222. }
  223. //---------------------------------------------------------------------------
  224. // Close: destroy interface
  225. //---------------------------------------------------------------------------
  226. static void Close( vlc_object_t *p_this )
  227. {
  228.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  229.     msg_Dbg( p_intf, "closing skins2 module" );
  230.     vlc_mutex_lock( &skin_load.mutex );
  231.     skin_load.intf = NULL;
  232.     vlc_mutex_unlock( &skin_load.mutex);
  233.     if( p_intf->p_sys->p_theme )
  234.     {
  235.         delete p_intf->p_sys->p_theme;
  236.         p_intf->p_sys->p_theme = NULL;
  237.         msg_Dbg( p_intf, "current theme deleted" );
  238.     }
  239.     // Destroy "singleton" objects
  240.     OSFactory::instance( p_intf )->destroyOSLoop();
  241.     ThemeRepository::destroy( p_intf );
  242.     VoutManager::destroy( p_intf );
  243.     //Dialogs::destroy( p_intf );
  244.     Interpreter::destroy( p_intf );
  245.     AsyncQueue::destroy( p_intf );
  246.     VarManager::destroy( p_intf );
  247.     VlcProc::destroy( p_intf );
  248.     OSFactory::destroy( p_intf );
  249.     if( p_intf->p_sys->p_playlist )
  250.     {
  251.         vlc_object_release( p_intf->p_sys->p_playlist );
  252.     }
  253.     // Unsubscribe from messages bank
  254. #if 0
  255.     msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
  256. #endif
  257.     // Destroy structure
  258.     free( p_intf->p_sys );
  259. }
  260. //---------------------------------------------------------------------------
  261. // Run: main loop
  262. //---------------------------------------------------------------------------
  263. static void Run( intf_thread_t *p_intf )
  264. {
  265.     int canc = vlc_savecancel();
  266.     // Get the instance of OSLoop
  267.     OSLoop *loop = OSFactory::instance( p_intf )->getOSLoop();
  268.     // Enter the main event loop
  269.     loop->run();
  270.     // Delete the theme and save the configuration of the windows
  271.     if( p_intf->p_sys->p_theme )
  272.     {
  273.         p_intf->p_sys->p_theme->saveConfig();
  274.     }
  275.     // cannot be called in "Close", because it refcounts skins2
  276.     Dialogs::destroy( p_intf );
  277.     // save config file
  278.     config_SaveConfigFile( p_intf, NULL );
  279.     vlc_restorecancel(canc);
  280. }
  281. // Callbacks for vout requests
  282. static int WindowOpen( vlc_object_t *p_this )
  283. {
  284.     vout_window_t *pWnd = (vout_window_t *)p_this;
  285.     intf_thread_t *pIntf = (intf_thread_t *)
  286.         vlc_object_find_name( p_this, "skins2", FIND_ANYWHERE );
  287.     if( pIntf == NULL )
  288.         return VLC_EGENERIC;
  289.     if( !config_GetInt( pIntf, "skinned-video") )
  290.     {
  291.         vlc_object_release( pIntf );
  292.         return VLC_EGENERIC;
  293.     }
  294.     vlc_object_release( pIntf );
  295.     pWnd->handle.hwnd = VoutManager::getWindow( pIntf, pWnd );
  296.     if( pWnd->handle.hwnd )
  297.     {
  298.         pWnd->p_private = pIntf;
  299.         pWnd->control = &VoutManager::controlWindow;
  300.         return VLC_SUCCESS;
  301.     }
  302.     else
  303.     {
  304.         return VLC_EGENERIC;
  305.     }
  306. }
  307. static void WindowClose( vlc_object_t *p_this )
  308. {
  309.     vout_window_t *pWnd = (vout_window_t *)p_this;
  310.     intf_thread_t *pIntf = (intf_thread_t *)p_this->p_private;
  311.     VoutManager::releaseWindow( pIntf, pWnd );
  312. }
  313. //---------------------------------------------------------------------------
  314. // DemuxOpen: initialize demux
  315. //---------------------------------------------------------------------------
  316. static int DemuxOpen( vlc_object_t *p_this )
  317. {
  318.     demux_t *p_demux = (demux_t*)p_this;
  319.     intf_thread_t *p_intf;
  320.     char *ext;
  321.     // Needed callbacks
  322.     p_demux->pf_demux   = Demux;
  323.     p_demux->pf_control = DemuxControl;
  324.     // Test that we have a valid .vlt or .wsz file, based on the extension
  325.     // TODO: an actual check of the contents would be better...
  326.     if( ( ext = strchr( p_demux->psz_path, '.' ) ) == NULL ||
  327.         ( strcasecmp( ext, ".vlt" ) && strcasecmp( ext, ".wsz" ) ) )
  328.     {
  329.         return VLC_EGENERIC;
  330.     }
  331.     vlc_mutex_lock( &skin_load.mutex );
  332.     p_intf = skin_load.intf;
  333.     if( p_intf )
  334.         vlc_object_hold( p_intf );
  335.     vlc_mutex_unlock( &skin_load.mutex );
  336.     if( p_intf != NULL )
  337.     {
  338.         playlist_t *p_playlist = pl_Hold( p_this );
  339.         // Make sure the item is deleted afterwards
  340.         /// bug does not always work
  341.         playlist_CurrentPlayingItem( p_playlist )->i_flags |= PLAYLIST_REMOVE_FLAG;
  342.         vlc_object_release( p_playlist );
  343.         var_SetString( p_intf, "skin-to-load", p_demux->psz_path );
  344.         vlc_object_release( p_intf );
  345.     }
  346.     else
  347.     {
  348.         msg_Warn( p_this,
  349.                   "skin could not be loaded (not using skins2 intf)" );
  350.     }
  351.     return VLC_SUCCESS;
  352. }
  353. //---------------------------------------------------------------------------
  354. // Demux: return EOF
  355. //---------------------------------------------------------------------------
  356. static int Demux( demux_t *p_demux )
  357. {
  358.     return 0;
  359. }
  360. //---------------------------------------------------------------------------
  361. // DemuxControl
  362. //---------------------------------------------------------------------------
  363. static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
  364. {
  365.     return demux_vaControlHelper( p_demux->s, 0, 0, 0, 1, i_query, args );
  366. }
  367. //---------------------------------------------------------------------------
  368. // Callbacks
  369. //---------------------------------------------------------------------------
  370. /// Callback for the systray configuration option
  371. static int onSystrayChange( vlc_object_t *pObj, const char *pVariable,
  372.                             vlc_value_t oldVal, vlc_value_t newVal,
  373.                             void *pParam )
  374. {
  375.     intf_thread_t *pIntf;
  376.     vlc_mutex_lock( &skin_load.mutex );
  377.     pIntf = skin_load.intf;
  378.     if( pIntf )
  379.         vlc_object_hold( pIntf );
  380.     vlc_mutex_unlock( &skin_load.mutex );
  381.     if( pIntf == NULL )
  382.     {
  383.         return VLC_EGENERIC;
  384.     }
  385.     AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
  386.     if( newVal.b_bool )
  387.     {
  388.         CmdAddInTray *pCmd = new CmdAddInTray( pIntf );
  389.         pQueue->push( CmdGenericPtr( pCmd ) );
  390.     }
  391.     else
  392.     {
  393.         CmdRemoveFromTray *pCmd = new CmdRemoveFromTray( pIntf );
  394.         pQueue->push( CmdGenericPtr( pCmd ) );
  395.     }
  396.     vlc_object_release( pIntf );
  397.     return VLC_SUCCESS;
  398. }
  399. /// Callback for the systray configuration option
  400. static int onTaskBarChange( vlc_object_t *pObj, const char *pVariable,
  401.                             vlc_value_t oldVal, vlc_value_t newVal,
  402.                             void *pParam )
  403. {
  404.     intf_thread_t *pIntf;
  405.     vlc_mutex_lock( &skin_load.mutex );
  406.     pIntf = skin_load.intf;
  407.     if( pIntf )
  408.         vlc_object_hold( pIntf );
  409.     vlc_mutex_unlock( &skin_load.mutex );
  410.     if( pIntf == NULL )
  411.     {
  412.         return VLC_EGENERIC;
  413.     }
  414.     AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
  415.     if( newVal.b_bool )
  416.     {
  417.         CmdAddInTaskBar *pCmd = new CmdAddInTaskBar( pIntf );
  418.         pQueue->push( CmdGenericPtr( pCmd ) );
  419.     }
  420.     else
  421.     {
  422.         CmdRemoveFromTaskBar *pCmd = new CmdRemoveFromTaskBar( pIntf );
  423.         pQueue->push( CmdGenericPtr( pCmd ) );
  424.     }
  425.     vlc_object_release( pIntf );
  426.     return VLC_SUCCESS;
  427. }
  428. //---------------------------------------------------------------------------
  429. // Module descriptor
  430. //---------------------------------------------------------------------------
  431. #define SKINS2_LAST      N_("Skin to use")
  432. #define SKINS2_LAST_LONG N_("Path to the skin to use.")
  433. #define SKINS2_CONFIG      N_("Config of last used skin")
  434. #define SKINS2_CONFIG_LONG N_("Windows configuration of the last skin used. " 
  435.         "This option is updated automatically, do not touch it." )
  436. #define SKINS2_SYSTRAY      N_("Systray icon")
  437. #define SKINS2_SYSTRAY_LONG N_("Show a systray icon for VLC")
  438. #define SKINS2_TASKBAR      N_("Show VLC on the taskbar")
  439. #define SKINS2_TASKBAR_LONG N_("Show VLC on the taskbar")
  440. #define SKINS2_TRANSPARENCY      N_("Enable transparency effects")
  441. #define SKINS2_TRANSPARENCY_LONG N_("You can disable all transparency effects"
  442.     " if you want. This is mainly useful when moving windows does not behave" 
  443.     " correctly.")
  444. #define SKINS2_PLAYLIST N_("Use a skinned playlist")
  445. #define SKINS2_PLAYLIST_LONG N_("Use a skinned playlist")
  446. #define SKINS2_VIDEO N_("Display video in a skinned window if any")
  447. #define SKINS2_VIDEO_LONG N_( 
  448.     "When set to 'no', this parameter is intended to give old skins a chance" 
  449.     " to play back video even though no video tag is implemented")
  450. vlc_module_begin ()
  451.     set_category( CAT_INTERFACE )
  452.     set_subcategory( SUBCAT_INTERFACE_MAIN )
  453.     add_file( "skins2-last", "", NULL, SKINS2_LAST, SKINS2_LAST_LONG,
  454.               true )
  455.         change_autosave ()
  456.     add_string( "skins2-config", "", NULL, SKINS2_CONFIG, SKINS2_CONFIG_LONG,
  457.                 true )
  458.         change_autosave ()
  459.         change_internal ()
  460. #ifdef WIN32
  461.     add_bool( "skins2-systray", false, onSystrayChange, SKINS2_SYSTRAY,
  462.               SKINS2_SYSTRAY_LONG, false );
  463.     add_bool( "skins2-taskbar", true, onTaskBarChange, SKINS2_TASKBAR,
  464.               SKINS2_TASKBAR_LONG, false );
  465.     add_bool( "skins2-transparency", false, NULL, SKINS2_TRANSPARENCY,
  466.               SKINS2_TRANSPARENCY_LONG, false );
  467. #endif
  468.     add_bool( "skinned-playlist", true, NULL, SKINS2_PLAYLIST,
  469.               SKINS2_PLAYLIST_LONG, false );
  470.     add_bool( "skinned-video", true, NULL, SKINS2_VIDEO,
  471.               SKINS2_VIDEO_LONG, false );
  472.     set_shortname( N_("Skins"))
  473.     set_description( N_("Skinnable Interface") )
  474.     set_capability( "interface", 30 )
  475.     set_callbacks( Open, Close )
  476.     add_shortcut( "skins" )
  477.     add_submodule ()
  478. #ifndef WIN32
  479.         set_capability( "xwindow", 51 )
  480. #else
  481.         set_capability( "hwnd", 51 )
  482. #endif
  483.         set_callbacks( WindowOpen, WindowClose )
  484.     add_submodule ()
  485.         set_description( N_("Skins loader demux") )
  486.         set_capability( "demux", 5 )
  487.         set_callbacks( DemuxOpen, NULL )
  488.         add_shortcut( "skins" )
  489. vlc_module_end ()