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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * gtk_callbacks.c : Callbacks for the Gtk+ plugin.
  3.  *****************************************************************************
  4.  * Copyright (C) 2000, 2001, 2003 VideoLAN
  5.  * $Id: gtk_callbacks.c 7950 2004-06-07 21:53:03Z fenrir $
  6.  *
  7.  * Authors: Sam Hocevar <sam@zoy.org>
  8.  *          St閜hane Borel <stef@via.ecp.fr>
  9.  *          Julien BLACHE <jb@technologeek.org>
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  24.  *****************************************************************************/
  25. /*****************************************************************************
  26.  * Preamble
  27.  *****************************************************************************/
  28. #include <sys/types.h>                                              /* off_t */
  29. #include <stdlib.h>
  30. #include <vlc/vlc.h>
  31. #include <vlc/intf.h>
  32. #include <vlc/vout.h>
  33. #include <vlc/aout.h>
  34. #include <unistd.h>
  35. #include <gtk/gtk.h>
  36. #include <string.h>
  37. #include "gtk_callbacks.h"
  38. #include "gtk_interface.h"
  39. #include "gtk_support.h"
  40. #include "common.h"
  41. #ifdef HAVE_CDDAX
  42. #define CDDA_MRL "cddax://"
  43. #else
  44. #define CDDA_MRL "cdda://"
  45. #endif
  46. #ifdef HAVE_VCDX
  47. #define VCD_MRL "vcdx://"
  48. #else
  49. #define VCD_MRL "vcdx://"
  50. #endif
  51. /*****************************************************************************
  52.  * Useful function to retrieve p_intf
  53.  ****************************************************************************/
  54. void * E_(__GtkGetIntf)( GtkWidget * widget )
  55. {
  56.     void *p_data;
  57.     if( GTK_IS_MENU_ITEM( widget ) )
  58.     {
  59.         /* Look for a GTK_MENU */
  60.         while( widget->parent && !GTK_IS_MENU( widget ) )
  61.         {
  62.             widget = widget->parent;
  63.         }
  64.         /* Maybe this one has the data */
  65.         p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
  66.         if( p_data )
  67.         {
  68.             return p_data;
  69.         }
  70.         /* Otherwise, the parent widget has it */
  71.         widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
  72.         p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
  73.         if( p_data )
  74.         {
  75.             return p_data;
  76.         }
  77.     }
  78.     /* We look for the top widget */
  79.     widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
  80.     p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
  81.     return p_data;
  82. }
  83. /*****************************************************************************
  84.  * Callbacks
  85.  *****************************************************************************/
  86. /*
  87.  * Main interface callbacks
  88.  */
  89. #ifdef MODULE_NAME_IS_gtk
  90. #   define GTKEXIT GtkExit
  91. #else
  92. #   define GTKEXIT GnomeExit
  93. #endif
  94. gboolean GTKEXIT( GtkWidget       *widget,
  95.                   gpointer         user_data )
  96. {
  97.     intf_thread_t *p_intf = GtkGetIntf( widget );
  98.     vlc_mutex_lock( &p_intf->change_lock );
  99.     p_intf->p_vlc->b_die = VLC_TRUE;
  100.     vlc_mutex_unlock( &p_intf->change_lock );
  101.     return TRUE;
  102. }
  103. void GtkClose( GtkMenuItem     *menuitem,
  104.                gpointer         user_data )
  105. {
  106.     intf_thread_t *p_intf = GtkGetIntf( menuitem );
  107.     p_intf->b_die = VLC_TRUE;
  108. }
  109. gboolean GtkWindowDelete( GtkWidget       *widget,
  110.                           GdkEvent        *event,
  111.                           gpointer         user_data )
  112. {
  113.     GTKEXIT( GTK_WIDGET( widget ), user_data );
  114.     return TRUE;
  115. }
  116. gboolean GtkWindowToggle( GtkWidget       *widget,
  117.                           gpointer         user_data )
  118. {
  119.     intf_thread_t *p_intf = GtkGetIntf( widget );
  120.     if( GTK_WIDGET_VISIBLE(p_intf->p_sys->p_window) )
  121.     {
  122.         gtk_widget_hide( p_intf->p_sys->p_window);
  123.     }
  124.     else
  125.     {
  126.         gtk_widget_show( p_intf->p_sys->p_window );
  127.     }
  128.     return TRUE;
  129. }
  130. gboolean GtkFullscreen( GtkWidget       *widget,
  131.                         gpointer         user_data)
  132. {
  133.     intf_thread_t *p_intf = GtkGetIntf( widget );
  134.     vout_thread_t *p_vout;
  135.     if( p_intf->p_sys->p_input == NULL )
  136.     {
  137.         return FALSE;
  138.     }
  139.     p_vout = vlc_object_find( p_intf->p_sys->p_input,
  140.                               VLC_OBJECT_VOUT, FIND_CHILD );
  141.     if( p_vout == NULL )
  142.     {
  143.         return FALSE;
  144.     }
  145.     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
  146.     vlc_object_release( p_vout );
  147.     return TRUE;
  148. }
  149. void GtkWindowDrag( GtkWidget       *widget,
  150.                     GdkDragContext  *drag_context,
  151.                     gint             x,
  152.                     gint             y,
  153.                     GtkSelectionData *data,
  154.                     guint            info,
  155.                     guint            time,
  156.                     gpointer         user_data)
  157. {
  158.     intf_thread_t * p_intf = GtkGetIntf( widget );
  159.     GtkDropDataReceived( p_intf, data, info, PLAYLIST_END );
  160. }
  161. /****************************************************************************
  162.  * Slider management
  163.  ****************************************************************************/
  164. gboolean GtkSliderRelease( GtkWidget       *widget,
  165.                            GdkEventButton  *event,
  166.                            gpointer         user_data )
  167. {
  168.     intf_thread_t *p_intf = GtkGetIntf( widget );
  169.     vlc_mutex_lock( &p_intf->change_lock );
  170.     p_intf->p_sys->b_slider_free = VLC_TRUE;
  171.     vlc_mutex_unlock( &p_intf->change_lock );
  172.     return FALSE;
  173. }
  174. gboolean GtkSliderPress( GtkWidget       *widget,
  175.                          GdkEventButton  *event,
  176.                          gpointer         user_data)
  177. {
  178.     intf_thread_t *p_intf = GtkGetIntf( widget );
  179.     vlc_mutex_lock( &p_intf->change_lock );
  180.     p_intf->p_sys->b_slider_free = VLC_FALSE;
  181.     vlc_mutex_unlock( &p_intf->change_lock );
  182.     return FALSE;
  183. }
  184. /****************************************************************************
  185.  * DVD specific items
  186.  ****************************************************************************/
  187. void GtkTitlePrev( GtkButton * button, gpointer user_data )
  188. {
  189.     intf_thread_t *  p_intf = GtkGetIntf( button );
  190.     var_SetVoid( p_intf->p_sys->p_input, "prev-title" );
  191.     p_intf->p_sys->b_title_update = VLC_TRUE;
  192.     vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
  193.     GtkSetupMenus( p_intf );
  194.     vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
  195. }
  196. void GtkTitleNext( GtkButton * button, gpointer user_data )
  197. {
  198.     intf_thread_t * p_intf = GtkGetIntf( button );
  199.     var_SetVoid( p_intf->p_sys->p_input, "next-title" );
  200.     p_intf->p_sys->b_title_update = VLC_TRUE;
  201.     vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
  202.     GtkSetupMenus( p_intf );
  203.     vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
  204. }
  205. void GtkChapterPrev( GtkButton * button, gpointer user_data )
  206. {
  207.     intf_thread_t *  p_intf = GtkGetIntf( button );
  208.     var_SetVoid( p_intf->p_sys->p_input, "prev-chapter" );
  209.     p_intf->p_sys->b_chapter_update = VLC_TRUE;
  210.     vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
  211.     GtkSetupMenus( p_intf );
  212.     vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
  213. }
  214. void GtkChapterNext( GtkButton * button, gpointer user_data )
  215. {
  216.     intf_thread_t *  p_intf = GtkGetIntf( button );
  217.     var_SetVoid( p_intf->p_sys->p_input, "next-chapter" );
  218.     p_intf->p_sys->b_chapter_update = VLC_TRUE;
  219.     vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
  220.     GtkSetupMenus( p_intf );
  221.     vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
  222. }
  223. /****************************************************************************
  224.  * About box
  225.  ****************************************************************************/
  226. gboolean GtkAboutShow( GtkWidget       *widget,
  227.                        gpointer         user_data)
  228. {
  229.     intf_thread_t *p_intf = GtkGetIntf( widget );
  230.     if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
  231.     {
  232.         p_intf->p_sys->p_about = create_intf_about();
  233.         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
  234.                              "p_intf", p_intf );
  235.     }
  236.     gtk_widget_show( p_intf->p_sys->p_about );
  237.     gdk_window_raise( p_intf->p_sys->p_about->window );
  238.     return TRUE;
  239. }
  240. void GtkAboutOk( GtkButton * button, gpointer user_data)
  241. {
  242.     intf_thread_t *p_intf = GtkGetIntf( button );
  243.     gtk_widget_hide( p_intf->p_sys->p_about );
  244. }
  245. /****************************************************************************
  246.  * Jump box
  247.  ****************************************************************************/
  248. gboolean GtkJumpShow( GtkWidget       *widget,
  249.                       gpointer         user_data)
  250. {
  251.     intf_thread_t *p_intf = GtkGetIntf( widget );
  252.     if( !GTK_IS_WIDGET( p_intf->p_sys->p_jump ) )
  253.     {
  254.         p_intf->p_sys->p_jump = create_intf_jump();
  255.         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_jump ),
  256.                              "p_intf", p_intf );
  257.     }
  258.     gtk_widget_show( p_intf->p_sys->p_jump );
  259.     gdk_window_raise( p_intf->p_sys->p_jump->window );
  260.     return FALSE;
  261. }
  262. void GtkJumpOk( GtkButton       *button,
  263.                 gpointer         user_data)
  264. {
  265.     intf_thread_t * p_intf = GtkGetIntf( button );
  266.     int i_hours, i_minutes, i_seconds;
  267.     if( p_intf->p_sys->p_input == NULL )
  268.     {
  269.         return;
  270.     }
  271. #define GET_VALUE( name )                                                   
  272.     gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( gtk_object_get_data( 
  273.         GTK_OBJECT( p_intf->p_sys->p_jump ), name ) ) )
  274.     i_hours   = GET_VALUE( "jump_hour_spinbutton" );
  275.     i_minutes = GET_VALUE( "jump_minute_spinbutton" );
  276.     i_seconds = GET_VALUE( "jump_second_spinbutton" );
  277. #undef GET_VALUE
  278.     var_SetTime( p_intf->p_sys->p_input, "time",
  279.                  (int64_t)(i_seconds+60*i_minutes+3600*i_hours)*I64C(1000000));
  280.     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
  281. }
  282. void GtkJumpCancel( GtkButton       *button,
  283.                     gpointer         user_data)
  284. {
  285.     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
  286. }
  287. /****************************************************************************
  288.  * Callbacks for disc ejection
  289.  ****************************************************************************/
  290. gboolean GtkDiscEject ( GtkWidget *widget, gpointer user_data )
  291. {
  292.     char *psz_device = NULL;
  293.     char *psz_parser;
  294.     char *psz_current;
  295.     intf_thread_t *p_intf = GtkGetIntf( widget );
  296.     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
  297.                                                        FIND_ANYWHERE );
  298.     if( p_playlist == NULL )
  299.     {
  300.         return FALSE;
  301.     }
  302.     vlc_mutex_lock( &p_playlist->object_lock );
  303.     if( p_playlist->i_index < 0 )
  304.     {
  305.         vlc_mutex_unlock( &p_playlist->object_lock );
  306.         vlc_object_release( p_playlist );
  307.         return FALSE;
  308.     }
  309.     psz_current = p_playlist->pp_items[ p_playlist->i_index ]->input.psz_name;
  310.     /*
  311.      * Get the active input
  312.      * Determine whether we can eject a media, ie it's a VCD or DVD
  313.      * If it's neither a VCD nor a DVD, then return
  314.      */
  315.     /*
  316.      * Don't really know if I must lock the stuff here, we're using it read-only
  317.      */
  318.     if( psz_current != NULL )
  319.     {
  320.         if( !strncmp(psz_current, "dvd://", 4) )
  321.         {
  322.             switch( psz_current[strlen("dvd://")] )
  323.             {
  324.             case '':
  325.             case '@':
  326.                 psz_device = config_GetPsz( p_intf, "dvd" );
  327.                 break;
  328.             default:
  329.                 /* Omit the first MRL-selector characters */
  330.                 psz_device = strdup( psz_current + strlen("dvd://" ) );
  331.                 break;
  332.             }
  333.         }
  334.         else if( !strncmp(psz_current, "vcd:", strlen("vcd:")) )
  335.         {
  336.             switch( psz_current[strlen("vcd:")] )
  337.             {
  338.             case '':
  339.             case '@':
  340.                 psz_device = config_GetPsz( p_intf, VCD_MRL );
  341.                 break;
  342.             default:
  343.                 /* Omit the beginning MRL-selector characters */
  344.                 psz_device = strdup( psz_current + strlen(VCD_MRL) );
  345.                 break;
  346.             }
  347.         }
  348.         else if( !strncmp(psz_current, CDDA_MRL, strlen(CDDA_MRL) ) )
  349.         {
  350.             switch( psz_current[strlen(CDDA_MRL)] )
  351.             {
  352.             case '':
  353.             case '@':
  354.                 psz_device = config_GetPsz( p_intf, "cd-audio" );
  355.                 break;
  356.             default:
  357.                 /* Omit the beginning MRL-selector characters */
  358.                 psz_device = strdup( psz_current + strlen(CDDA_MRL) );
  359.                 break;
  360.             }
  361.         }
  362.         else
  363.         {
  364.             psz_device = strdup( psz_current );
  365.         }
  366.     }
  367.     vlc_mutex_unlock( &p_playlist->object_lock );
  368.     vlc_object_release( p_playlist );
  369.     if( psz_device == NULL )
  370.     {
  371.         return TRUE;
  372.     }
  373.     /* Remove what we have after @ */
  374.     psz_parser = psz_device;
  375.     for( psz_parser = psz_device ; *psz_parser ; psz_parser++ )
  376.     {
  377.         if( *psz_parser == '@' )
  378.         {
  379.             *psz_parser = '';
  380.             break;
  381.         }
  382.     }
  383.     /* If there's a stream playing, we aren't allowed to eject ! */
  384.     if( p_intf->p_sys->p_input == NULL )
  385.     {
  386.         msg_Dbg( p_intf, "ejecting %s", psz_device );
  387.         intf_Eject( p_intf, psz_device );
  388.     }
  389.     free(psz_device);
  390.     return TRUE;
  391. }
  392. /****************************************************************************
  393.  * Messages window
  394.  ****************************************************************************/
  395. gboolean GtkMessagesShow( GtkWidget       *widget,
  396.                           gpointer         user_data)
  397. {
  398.     static GdkColor black = { 0, 0x0000, 0x0000, 0x0000 };
  399.     static GdkColormap *colormap;
  400.     intf_thread_t *p_intf = GtkGetIntf( widget );
  401.     gtk_widget_show( p_intf->p_sys->p_messages );
  402.     colormap = gdk_colormap_get_system ();
  403.     gdk_color_alloc( colormap, &black );
  404.     gdk_window_set_background( p_intf->p_sys->p_messages_text->text_area,
  405.                                &black );
  406.     gdk_window_raise( p_intf->p_sys->p_messages->window );
  407.     gtk_text_set_point( p_intf->p_sys->p_messages_text,
  408.                     gtk_text_get_length( p_intf->p_sys->p_messages_text ) );
  409.     return TRUE;
  410. }
  411. void
  412. GtkMessagesOk                          (GtkButton       *button,
  413.                                         gpointer         user_data)
  414. {
  415.     intf_thread_t *p_intf = GtkGetIntf( button );
  416.     gtk_widget_hide( p_intf->p_sys->p_messages );
  417. }
  418. gboolean
  419. GtkMessagesDelete                      (GtkWidget       *widget,
  420.                                         GdkEvent        *event,
  421.                                         gpointer         user_data)
  422. {
  423.     intf_thread_t *p_intf = GtkGetIntf( widget );
  424.     gtk_widget_hide( p_intf->p_sys->p_messages );
  425.     return TRUE;
  426. }
  427. void
  428. GtkOpenNotebookChanged                 (GtkNotebook     *notebook,
  429.                                         GtkNotebookPage *page,
  430.                                         gint             page_num,
  431.                                         gpointer         user_data)
  432. {
  433.     GtkOpenChanged( GTK_WIDGET( notebook ), user_data );
  434. }
  435. /****************************************************************************
  436.  * Audio management
  437.  ****************************************************************************/
  438. void GtkVolumeUp                      ( GtkMenuItem     *menuitem,
  439.                                         gpointer         user_data )
  440. {
  441.     intf_thread_t   *p_intf = GtkGetIntf( menuitem );
  442.     audio_volume_t  i_volume;
  443.     aout_VolumeUp( p_intf, 1, &i_volume );
  444.     p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
  445. }
  446. void GtkVolumeDown                    ( GtkMenuItem     *menuitem,
  447.                                         gpointer         user_data )
  448. {
  449.     intf_thread_t   *p_intf = GtkGetIntf( menuitem );
  450.     audio_volume_t  i_volume;
  451.     aout_VolumeDown( p_intf, 1, &i_volume );
  452.     p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
  453. }
  454. void GtkVolumeMute                    ( GtkMenuItem     *menuitem,
  455.                                         gpointer         user_data )
  456. {
  457.     intf_thread_t   *p_intf = GtkGetIntf( menuitem );
  458.     audio_volume_t i_volume;
  459.     aout_VolumeMute( p_intf, &i_volume );
  460.     p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
  461. }
  462. void
  463. GtkMenubarDeinterlace                  ( GtkMenuItem     *menuitem,
  464.                                         gpointer         user_data)
  465. {
  466.     intf_thread_t   *p_intf = GtkGetIntf( menuitem );
  467.     if( p_intf )
  468.         msg_Dbg( p_intf, "GtkMenubarDeinterlace" );
  469. }
  470. void
  471. GtkPopupDeinterlace                    (GtkRadioMenuItem *radiomenuitem,
  472.                                         gpointer         user_data)
  473. {
  474.     intf_thread_t   *p_intf = GtkGetIntf( radiomenuitem );
  475.     if( p_intf )
  476.         msg_Dbg( p_intf, "GtkPopupDeinterlace" );
  477. }