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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2. * maemo.c : Maemo plugin for VLC
  3. *****************************************************************************
  4. * Copyright (C) 2008 the VideoLAN team
  5. * $Id: 4d2234c2cf232d6dea11f58730ebb6fa3727d15d $
  6. *
  7. * Authors: Antoine Lejeune <phytos@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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22. *****************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. # include "config.h"
  25. #endif
  26. #include <assert.h>
  27. #include <vlc_common.h>
  28. #include <vlc_plugin.h>
  29. #include <vlc_interface.h>
  30. #include <vlc_window.h>
  31. #include <hildon/hildon-program.h>
  32. #include <hildon/hildon-banner.h>
  33. #include <gtk/gtk.h>
  34. #include <stdio.h>
  35. #include <inttypes.h>
  36. #include "maemo.h"
  37. #include "maemo_callbacks.h"
  38. #include "maemo_input.h"
  39. #include "maemo_interface.h"
  40. /*****************************************************************************
  41.  * Local prototypes.
  42.  *****************************************************************************/
  43. static int      Open               ( vlc_object_t * );
  44. static void     Close              ( vlc_object_t * );
  45. static void     Run                ( intf_thread_t * );
  46. static gboolean should_die         ( gpointer );
  47. static int      OpenWindow         ( vlc_object_t * );
  48. static void     CloseWindow        ( vlc_object_t * );
  49. static int      ControlWindow      ( vout_window_t *, int, va_list );
  50. static void*    request_video      ( intf_thread_t *, vout_thread_t * );
  51. static void     release_video      ( intf_thread_t * );
  52. static gboolean video_widget_ready ( gpointer data );
  53. /*****************************************************************************
  54. * Module descriptor
  55. *****************************************************************************/
  56. vlc_module_begin();
  57.     set_shortname( "Maemo" );
  58.     set_description( N_("Maemo hildon interface") );
  59.     set_category( CAT_INTERFACE );
  60.     set_subcategory( SUBCAT_INTERFACE_MAIN );
  61.     set_capability( "interface", 70 );
  62.     set_callbacks( Open, Close );
  63.     add_shortcut( "maemo" );
  64.     add_submodule();
  65.         set_capability( "xwindow", 50 );
  66.         set_callbacks( OpenWindow, CloseWindow );
  67. vlc_module_end();
  68. /*****************************************************************************
  69.  * Module callbacks
  70.  *****************************************************************************/
  71. static int Open( vlc_object_t *p_this )
  72. {
  73.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  74.     /* Allocate instance and initialize some members */
  75.     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
  76.     if( p_intf->p_sys == NULL )
  77.     {
  78.         msg_Err( p_intf, "out of memory" );
  79.         return VLC_ENOMEM;
  80.     }
  81.     p_intf->pf_run = Run;
  82.     p_intf->p_sys->p_playlist = pl_Hold( p_intf );
  83.     p_intf->p_sys->p_input = NULL;
  84.     p_intf->p_sys->p_vout = NULL;
  85.     p_intf->p_sys->p_main_window = NULL;
  86.     p_intf->p_sys->p_video_window = NULL;
  87.     vlc_spin_init( &p_intf->p_sys->event_lock );
  88.     vlc_mutex_init( &p_intf->p_sys->p_video_mutex );
  89.     vlc_cond_init( &p_intf->p_sys->p_video_cond );
  90.     return VLC_SUCCESS;
  91. }
  92. static void Close( vlc_object_t *p_this )
  93. {
  94.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  95.     vlc_object_release( p_intf->p_sys->p_playlist );
  96.     vlc_spin_destroy( &p_intf->p_sys->event_lock );
  97.     /* Destroy structure */
  98.     free( p_intf->p_sys );
  99. }
  100. /*****************************************************************************
  101. * Initialize and launch the interface
  102. *****************************************************************************/
  103. static void Run( intf_thread_t *p_intf )
  104. {
  105.     char  *p_args[] = { "", NULL };
  106.     char **pp_args  = p_args;
  107.     int    i_args   = 1;
  108.     HildonProgram *program;
  109.     HildonWindow *window;
  110.     GtkWidget *main_vbox;
  111.     GtkWidget *tabs;
  112.     GtkWidget *video;
  113.     GtkWidget *bottom_hbox;
  114.     GtkWidget *play_button;
  115.     GtkWidget *prev_button;
  116.     GtkWidget *next_button;
  117.     GtkWidget *stop_button;
  118.     GtkWidget *seekbar;
  119.     gtk_init( &i_args, &pp_args );
  120.     program = HILDON_PROGRAM( hildon_program_get_instance() );
  121.     g_set_application_name( "VLC Media Player" );
  122.     window = HILDON_WINDOW( hildon_window_new() );
  123.     hildon_program_add_window( program, window );
  124.     gtk_object_set_data( GTK_OBJECT( window ),
  125.                          "p_intf", p_intf );
  126.     p_intf->p_sys->p_main_window = window;
  127.     // A little theming
  128.     char *psz_rc_file = NULL;
  129.     if( asprintf( &psz_rc_file, "%s/maemo/vlc_intf.rc",
  130.                   config_GetDataDir() ) != -1 )
  131.     {
  132.         gtk_rc_parse( psz_rc_file );
  133.         free( psz_rc_file );
  134.     }
  135.     // We create the main vertical box
  136.     main_vbox = gtk_vbox_new( FALSE, 0 );
  137.     gtk_container_add( GTK_CONTAINER( window ), main_vbox );
  138.     tabs = gtk_notebook_new();
  139.     p_intf->p_sys->p_tabs = tabs;
  140.     gtk_notebook_set_tab_pos( GTK_NOTEBOOK( tabs ), GTK_POS_LEFT );
  141.     gtk_notebook_set_show_border( GTK_NOTEBOOK( tabs ), FALSE );
  142.     gtk_box_pack_start( GTK_BOX( main_vbox ), tabs, TRUE, TRUE, 0 );
  143.     // We put first the embedded video
  144.     video = gtk_event_box_new();
  145.     gtk_notebook_append_page( GTK_NOTEBOOK( tabs ),
  146.                 video,
  147.                 gtk_image_new_from_stock( "vlc",
  148.                                           GTK_ICON_SIZE_DIALOG ) );
  149.     gtk_notebook_set_tab_label_packing( GTK_NOTEBOOK( tabs ),
  150.                                         video,
  151.                                         FALSE, FALSE, 0 );
  152.     create_playlist( p_intf );
  153.     // We put the horizontal box which contains all the buttons
  154.     bottom_hbox = gtk_hbox_new( FALSE, 0 );
  155.     // We create the buttons
  156.     play_button = gtk_button_new();
  157.     gtk_button_set_image( GTK_BUTTON( play_button ),
  158.                    gtk_image_new_from_stock( "vlc-play", GTK_ICON_SIZE_BUTTON ) );
  159.     gtk_widget_set_size_request( play_button, 60, 60);
  160.     p_intf->p_sys->p_play_button = play_button;
  161.     stop_button = gtk_button_new();
  162.     gtk_button_set_image( GTK_BUTTON( stop_button ),
  163.                           gtk_image_new_from_stock( "vlc-stop", GTK_ICON_SIZE_BUTTON ) );
  164.     prev_button = gtk_button_new();
  165.     gtk_button_set_image( GTK_BUTTON( prev_button ),
  166.                       gtk_image_new_from_stock( "vlc-previous", GTK_ICON_SIZE_BUTTON ) );
  167.     next_button = gtk_button_new();
  168.     gtk_button_set_image( GTK_BUTTON( next_button ),
  169.                       gtk_image_new_from_stock( "vlc-next", GTK_ICON_SIZE_BUTTON ) );
  170.     seekbar = hildon_seekbar_new();
  171.     p_intf->p_sys->p_seekbar = HILDON_SEEKBAR( seekbar );
  172.     // We add them to the hbox
  173.     gtk_box_pack_start( GTK_BOX( bottom_hbox ), play_button, FALSE, FALSE, 5 );
  174.     gtk_box_pack_start( GTK_BOX( bottom_hbox ), stop_button, FALSE, FALSE, 0 );
  175.     gtk_box_pack_start( GTK_BOX( bottom_hbox ), prev_button, FALSE, FALSE, 0 );
  176.     gtk_box_pack_start( GTK_BOX( bottom_hbox ), next_button, FALSE, FALSE, 0 );
  177.     gtk_box_pack_start( GTK_BOX( bottom_hbox ), seekbar    , TRUE , TRUE , 5 );
  178.     // We add the hbox to the main vbox
  179.     gtk_box_pack_start( GTK_BOX( main_vbox ), bottom_hbox, FALSE, FALSE, 0 );
  180.     g_signal_connect( window, "delete_event",
  181.                       G_CALLBACK( delete_event_cb ), NULL );
  182.     g_signal_connect( play_button, "clicked", G_CALLBACK( play_cb ), NULL );
  183.     g_signal_connect( stop_button, "clicked", G_CALLBACK( stop_cb ), NULL );
  184.     g_signal_connect( prev_button, "clicked", G_CALLBACK( prev_cb ), NULL );
  185.     g_signal_connect( next_button, "clicked", G_CALLBACK( next_cb ), NULL );
  186.     g_signal_connect( seekbar, "change-value",
  187.                       G_CALLBACK( seekbar_changed_cb ), NULL );
  188.     gtk_widget_show_all( GTK_WIDGET( window ) );
  189.     create_menu( p_intf );
  190.     // Set callback with the vlc core
  191.     g_timeout_add( INTF_IDLE_SLEEP / 1000, process_events, p_intf );
  192.     g_timeout_add( 150 /* miliseconds */, should_die, p_intf );
  193.     var_AddCallback( p_intf->p_sys->p_playlist, "item-change",
  194.                      item_changed_cb, p_intf );
  195.     var_AddCallback( p_intf->p_sys->p_playlist, "item-current",
  196.                      playlist_current_cb, p_intf );
  197.     var_AddCallback( p_intf->p_sys->p_playlist, "activity",
  198.                      activity_cb, p_intf );
  199.     // Look if the playlist is already started
  200.     item_changed_pl( p_intf );
  201.     // The embedded video is only ready after gtk_main and windows are shown
  202.     g_idle_add( video_widget_ready, video );
  203.     gtk_main();
  204.     delete_input( p_intf );
  205.     var_DelCallback( p_intf->p_sys->p_playlist, "item-change",
  206.                      item_changed_cb, p_intf );
  207.     var_DelCallback( p_intf->p_sys->p_playlist, "item-current",
  208.                      playlist_current_cb, p_intf );
  209.     var_DelCallback( p_intf->p_sys->p_playlist, "activity",
  210.                      activity_cb, p_intf );
  211.     assert( !p_intf->p_sys->p_vout ); /* too late */
  212.     gtk_object_destroy( GTK_OBJECT( window ) );
  213. }
  214. static gboolean should_die( gpointer data )
  215. {
  216.     intf_thread_t *p_intf = (intf_thread_t *)data;
  217.     if( !vlc_object_alive( p_intf ) )
  218.         gtk_main_quit();
  219.     return TRUE;
  220. }
  221. /**
  222. * Video output window provider
  223. */
  224. static int OpenWindow (vlc_object_t *obj)
  225. {
  226.     vout_window_t *wnd = (vout_window_t *)obj;
  227.     /* TODO: should probably be in the libvlc core instead: */
  228.     if (!config_GetInt (obj, "embedded-video"))
  229.         return VLC_EGENERIC;
  230.     intf_thread_t *intf = (intf_thread_t *)
  231.     vlc_object_find_name (obj, "maemo", FIND_ANYWHERE);
  232.     if (intf == NULL)
  233.     {
  234.         msg_Err( obj, "Maemo interface not found" );
  235.         return VLC_EGENERIC; /* Maemo not in use */
  236.     }
  237.     wnd->handle.xid = request_video( intf, wnd->vout );
  238.     msg_Dbg( intf, "Using handle %"PRIu32, wnd->handle.xid );
  239.     wnd->control = ControlWindow;
  240.     wnd->p_private = intf;
  241.     // Signaling that the window is not at the requested sizeof
  242.     int i_width, i_height, i_x_top, i_y_top, i_x, i_y;
  243.     gdk_drawable_get_size( GDK_DRAWABLE( intf->p_sys->p_video_window->window ),
  244.                            &i_width, &i_height );
  245.     gdk_window_get_position( GTK_WIDGET(intf->p_sys->p_main_window)->window,
  246.                              &i_x_top, &i_y_top );
  247.     gdk_window_get_position( intf->p_sys->p_video_window->window, &i_x, &i_y );
  248.     wnd->width = i_width;
  249.     wnd->height = i_height;
  250.     wnd->pos_x = i_x_top + i_x;
  251.     wnd->pos_y = i_y_top + i_y;
  252.     return VLC_SUCCESS;
  253. }
  254. static int ControlWindow (vout_window_t *wnd, int query, va_list args)
  255. {
  256.     (void)wnd; (void)query; (void)args;
  257.     return VLC_EGENERIC;
  258. }
  259. static void CloseWindow (vlc_object_t *obj)
  260. {
  261.     intf_thread_t *intf = (intf_thread_t *)obj->p_private;
  262.     release_video( intf );
  263.     vlc_object_release (intf);
  264. }
  265. static void *request_video( intf_thread_t *p_intf, vout_thread_t *p_nvout )
  266. {
  267.     if( p_intf->p_sys->p_vout )
  268.     {
  269.         msg_Dbg( p_intf, "Embedded video already in use" );
  270.         return NULL;
  271.     }
  272.     vlc_mutex_lock( &p_intf->p_sys->p_video_mutex );
  273.     mutex_cleanup_push( &p_intf->p_sys->p_video_mutex );
  274.     // We wait until the p_video_window is set
  275.     while( p_intf->p_sys->p_video_window == NULL )
  276.         vlc_cond_wait( &p_intf->p_sys->p_video_cond,
  277.                        &p_intf->p_sys->p_video_mutex );
  278.     vlc_cleanup_run();
  279.     p_intf->p_sys->p_vout = p_nvout;
  280.     return ( void * )GDK_WINDOW_XID( p_intf->p_sys->p_video_window->window );
  281. }
  282. static void release_video( intf_thread_t *p_intf )
  283. {
  284.     msg_Dbg( p_intf, "Releasing embedded video" );
  285.     p_intf->p_sys->p_vout = NULL;
  286. }
  287. static gboolean video_widget_ready( gpointer data )
  288. {
  289.     intf_thread_t *p_intf = NULL;
  290.     GtkWidget *top_window = NULL;
  291.     GtkWidget *video = (GtkWidget *)data;
  292.     top_window = gtk_widget_get_toplevel( GTK_WIDGET( video ) );
  293.     p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT( top_window ),
  294.                                                    "p_intf" );
  295.     p_intf->p_sys->p_video_window = video;
  296.     gtk_widget_grab_focus( video );
  297.     vlc_cond_signal( &p_intf->p_sys->p_video_cond );
  298.     // We rewind the input
  299.     if( p_intf->p_sys->p_input )
  300.     {
  301.         input_Control( p_intf->p_sys->p_input, INPUT_SET_POSITION, 0.0 );
  302.     }
  303.     // We want it to be executed only one time
  304.     return FALSE;
  305. }