X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fservices_discovery%2Fhal.c;h=5b84eeced6ebf02a60f2ba62599e5b6ea8680fc8;hb=6ee1e193fd896ab9a4729fde14f009d9ce629815;hp=30cb7044a44fab2ccb41e53e0dd3b38764ab830e;hpb=ebcd548797fa60603637f162b8871626a6f0a2be;p=vlc diff --git a/modules/services_discovery/hal.c b/modules/services_discovery/hal.c index 30cb7044a4..5b84eeced6 100644 --- a/modules/services_discovery/hal.c +++ b/modules/services_discovery/hal.c @@ -2,9 +2,11 @@ * hal.c : HAL interface module ***************************************************************************** * Copyright (C) 2004 the VideoLAN team + * Copyright (C) 2006 Rafaël Carré * $Id$ * * Authors: Clément Stenac + * Rafaël Carré * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,11 +24,9 @@ *****************************************************************************/ #include -#include +#include -#include - -#include "network.h" +#include #include /* ENOMEM */ @@ -44,18 +44,39 @@ /***************************************************************************** * Local prototypes *****************************************************************************/ +#ifdef HAVE_HAL_1 +/* store relation between item id and udi for ejection */ +struct udi_input_id_t +{ + char *psz_udi; + int i_id; +}; +#endif + struct services_discovery_sys_t { - LibHalContext *p_ctx; - playlist_item_t *p_node_cat; - playlist_item_t *p_node_one; + LibHalContext *p_ctx; + playlist_item_t *p_node_cat; + playlist_item_t *p_node_one; +#ifdef HAVE_HAL_1 + DBusConnection *p_connection; + int i_devices_number; + struct udi_input_id_t **pp_devices; +#endif }; -static void AddItem( services_discovery_t *p_sd, input_item_t * p_input ); static void Run ( services_discovery_t *p_intf ); static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); +#ifdef HAVE_HAL_1 +/* HAL callbacks */ +void DeviceAdded( LibHalContext *p_ctx, const char *psz_udi ); +void DeviceRemoved( LibHalContext *p_ctx, const char *psz_udi ); +/* to retrieve p_sd in HAL callbacks */ +services_discovery_t *p_sd_global; +#endif + /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -84,6 +105,10 @@ static int Open( vlc_object_t *p_this ) #ifdef HAVE_HAL_1 DBusError dbus_error; DBusConnection *p_connection; + + p_sd_global = p_sd; + p_sys->i_devices_number = 0; + p_sys->pp_devices = NULL; #endif p_sd->pf_run = Run; @@ -108,6 +133,7 @@ static int Open( vlc_object_t *p_this ) return VLC_EGENERIC; } libhal_ctx_set_dbus_connection( p_sys->p_ctx, p_connection ); + p_sys->p_connection = p_connection; if( !libhal_ctx_init( p_sys->p_ctx, &dbus_error ) ) #else if( !(p_sys->p_ctx = hal_initialize( NULL, FALSE ) ) ) @@ -123,6 +149,17 @@ static int Open( vlc_object_t *p_this ) return VLC_EGENERIC; } +#ifdef HAVE_HAL_1 + if( !libhal_ctx_set_device_added( p_sys->p_ctx, DeviceAdded ) || + !libhal_ctx_set_device_removed( p_sys->p_ctx, DeviceRemoved ) ) + { + msg_Err( p_sd, "unable to add callback" ); + dbus_error_free( &dbus_error ); + free( p_sys ); + return VLC_EGENERIC; + } +#endif + /* Create our playlist node */ p_playlist = (playlist_t *)vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); @@ -156,6 +193,60 @@ static void Close( vlc_object_t *p_this ) vlc_object_release( p_playlist ); } free( p_sys ); +#ifdef HAVE_HAL_1 + dbus_connection_unref( p_sys->p_connection ); + + struct udi_input_id_t *p_udi_entry; + + while( p_sys->i_devices_number > 0 ) + { + p_udi_entry = p_sys->pp_devices[0]; + if( p_udi_entry->psz_udi ) free( p_udi_entry->psz_udi ); + TAB_REMOVE( p_sys->i_devices_number, p_sys->pp_devices, + p_sys->pp_devices[0] ); + if( p_udi_entry ) free( p_udi_entry ); + } + p_sys->pp_devices = NULL; +#endif +} + +static void AddItem( services_discovery_t *p_sd, input_item_t * p_input +#ifdef HAVE_HAL_1 + ,char* psz_device +#endif + ) +{ + playlist_item_t *p_item_cat, *p_item_one; + services_discovery_sys_t *p_sys = p_sd->p_sys; + playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_sd, + VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); + if( !p_playlist ) + { + msg_Err( p_sd, "playlist not found" ); + return; + } + p_item_cat = playlist_NodeAddInput( p_playlist, + p_input,p_sd->p_sys->p_node_cat, PLAYLIST_APPEND, PLAYLIST_END, + VLC_FALSE ); + p_item_cat->i_flags &= ~PLAYLIST_SKIP_FLAG; + p_item_one = playlist_NodeAddInput( p_playlist, + p_input,p_sd->p_sys->p_node_one, PLAYLIST_APPEND, PLAYLIST_END, + VLC_FALSE ); + p_item_one->i_flags &= ~PLAYLIST_SKIP_FLAG; + + vlc_object_release( p_playlist ); + +#ifdef HAVE_HAL_1 + struct udi_input_id_t *p_udi_entry; + p_udi_entry = malloc( sizeof( struct udi_input_id_t ) ); + if( !p_udi_entry ) + { + return; + } + p_udi_entry->i_id = p_item_cat->i_id; + p_udi_entry->psz_udi = strdup( psz_device ); + TAB_APPEND( p_sys->i_devices_number, p_sys->pp_devices, p_udi_entry ); +#endif } static void AddDvd( services_discovery_t *p_sd, char *psz_device ) @@ -179,21 +270,24 @@ static void AddDvd( services_discovery_t *p_sd, char *psz_device ) /* Create the playlist item here */ p_input = input_ItemNew( p_sd, psz_uri, psz_name ); free( psz_uri ); -#ifdef HAVE_HAL_1 - libhal_free_string( psz_device ); -#else - hal_free_string( psz_device ); -#endif if( !p_input ) { return; } +#ifdef HAVE_HAL_1 + AddItem( p_sd, p_input, psz_device ); +#else AddItem( p_sd, p_input ); +#endif } -static void AddItem( services_discovery_t *p_sd, input_item_t * p_input ) +#ifdef HAVE_HAL_1 +static void DelItem( services_discovery_t *p_sd, char* psz_udi ) { - playlist_item_t *p_item; + services_discovery_sys_t *p_sys = p_sd->p_sys; + int i,j; + playlist_item_t *p_pl_item; + playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( !p_playlist ) @@ -201,19 +295,45 @@ static void AddItem( services_discovery_t *p_sd, input_item_t * p_input ) msg_Err( p_sd, "playlist not found" ); return; } - p_item = playlist_NodeAddInput( p_playlist, p_input,p_sd->p_sys->p_node_cat, - PLAYLIST_APPEND, PLAYLIST_END ); - p_item->i_flags &= ~PLAYLIST_SKIP_FLAG; - p_item = playlist_NodeAddInput( p_playlist, p_input,p_sd->p_sys->p_node_one, - PLAYLIST_APPEND, PLAYLIST_END ); - p_item->i_flags &= ~PLAYLIST_SKIP_FLAG; + + for( i = 0; i < p_sys->i_devices_number; i++ ) + { /* looks for a matching udi */ + if( strcmp( psz_udi, p_sys->pp_devices[i]->psz_udi ) == 0 ) + { /* delete the corresponding item */ + p_pl_item = playlist_ItemGetById( p_playlist, + p_sys->pp_devices[i]->i_id, VLC_FALSE ); + if( p_pl_item ) + { + j = 0; + while( p_pl_item->i_children > 0 ) + { /* delete all childs */ + playlist_DeleteFromInput( p_playlist, + p_pl_item->pp_children[j]->p_input->i_id, VLC_FALSE ); + } + /* delete parent item */ + + /* HACK: if i_children == 0 the item won't be deleted + * That means that it _had_ children but they were deleted */ + if( p_pl_item->i_children == 0 ) + p_pl_item->i_children = -1; + + playlist_DeleteFromInput( p_playlist, + p_pl_item->p_input->i_id, VLC_FALSE ); + } + + if( p_sys->pp_devices[i]->psz_udi ) + free( p_sys->pp_devices[i]->psz_udi ); + TAB_REMOVE( p_sys->i_devices_number, p_sys->pp_devices, + p_sys->pp_devices[i] ); + } + } vlc_object_release( p_playlist ); } +#endif static void AddCdda( services_discovery_t *p_sd, char *psz_device ) { - char *psz_name = "Audio CD"; char *psz_uri; char *psz_blockdevice; input_item_t *p_input; @@ -226,16 +346,15 @@ static void AddCdda( services_discovery_t *p_sd, char *psz_device ) #endif asprintf( &psz_uri, "cdda://%s", psz_blockdevice ); /* Create the playlist item here */ - p_input = input_ItemNew( p_sd, psz_uri, psz_name ); + p_input = input_ItemNew( p_sd, psz_uri, "Audio CD" ); free( psz_uri ); -#ifdef HAVE_HAL_1 - libhal_free_string( psz_device ); -#else - hal_free_string( psz_device ); -#endif if( !p_input ) return; +#ifdef HAVE_HAL_1 + AddItem( p_sd, p_input, psz_device ); +#else AddItem( p_sd, p_input ); +#endif } static void ParseDevice( services_discovery_t *p_sd, char *psz_device ) @@ -258,11 +377,17 @@ static void ParseDevice( services_discovery_t *p_sd, char *psz_device ) psz_device, "volume.disc.type" ); #endif - if( !strcmp( psz_disc_type, "dvd_rom" ) ) + if( !strncmp( psz_disc_type, "dvd_r", 5 ) ) { +#ifdef HAVE_HAL_1 + /* hal 0.2.9.7 (HAVE_HAL) has not is_videodvd + * but hal 0.5.0 (HAVE_HAL_1) has */ + if (libhal_device_get_property_bool( p_sys->p_ctx, psz_device, + "volume.disc.is_videodvd", NULL ) ) +#endif AddDvd( p_sd, psz_device ); } - else if( !strcmp( psz_disc_type, "cd_rom" ) ) + else if( !strncmp( psz_disc_type, "cd_r", 4 ) ) { #ifdef HAVE_HAL_1 if( libhal_device_get_property_bool( p_sys->p_ctx, psz_device, @@ -275,11 +400,6 @@ static void ParseDevice( services_discovery_t *p_sd, char *psz_device ) AddCdda( p_sd, psz_device ); } } -#ifdef HAVE_HAL_1 - libhal_free_string( psz_disc_type ); -#else - hal_free_string( psz_disc_type ); -#endif } } @@ -302,11 +422,33 @@ static void Run( services_discovery_t *p_sd ) for( i = 0; i < i_devices; i++ ) { ParseDevice( p_sd, devices[ i ] ); +#ifdef HAVE_HAL_1 + libhal_free_string( devices[ i ] ); +#else + hal_free_string( devices[ i ] ); +#endif + } } - +#ifdef HAVE_HAL_1 while( !p_sd->b_die ) { - msleep( 100000 ); + /* look for events on the bus, blocking 1 second */ + dbus_connection_read_write_dispatch( p_sys->p_connection, 1000 ); + /* HAL 0.5.8.1 can use libhal_ctx_get_dbus_connection(p_sys->p_ctx) */ } +#endif + } + +#ifdef HAVE_HAL_1 +void DeviceAdded( LibHalContext *p_ctx, const char *psz_udi ) +{ + ParseDevice( p_sd_global, (char*) psz_udi ); +} +void DeviceRemoved( LibHalContext *p_ctx, const char *psz_udi ) +{ + DelItem( p_sd_global, (char*) psz_udi ); +} +#endif +