1 /*****************************************************************************
2 * hal.c : HAL probing module
3 *****************************************************************************
4 * Copyright (C) 2004 the VideoLAN team
7 * Authors: Clément Stenac <zorglub@videolan.org>
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.
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.
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 *****************************************************************************/
29 #include <vlc_interface.h>
30 #include <vlc_devices.h>
32 #include <hal/libhal.h>
34 /*****************************************************************************
36 *****************************************************************************/
39 DBusConnection *p_connection;
42 device_t **pp_devices;
45 static int Open ( vlc_object_t * );
46 static void Close( vlc_object_t * );
48 static void Update ( device_probe_t *p_probe );
49 static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev );
50 static void AddDevice( device_probe_t * p_probe, device_t *p_dev );
51 static device_t * ParseDisc( device_probe_t *p_probe, char *psz_device );
53 /*****************************************************************************
55 *****************************************************************************/
57 set_description( _("HAL devices detection") );
58 set_capability( "devices probe", 0 );
59 set_callbacks( Open, Close );
63 /*****************************************************************************
64 * Open: initialize and create stuff
65 *****************************************************************************/
66 static int Open( vlc_object_t *p_this )
68 device_probe_t *p_probe = (device_probe_t *)p_this;
70 DBusConnection *p_connection;
73 p_probe->p_sys = p_sys = (probe_sys_t*)malloc( sizeof( probe_sys_t ) );
74 p_probe->p_sys->i_devices = 0;
75 p_probe->p_sys->pp_devices = NULL;
77 p_probe->pf_run = Update;
79 dbus_error_init( &dbus_error );
81 p_sys->p_ctx = libhal_ctx_new();
84 msg_Err( p_probe, "unable to create HAL context") ;
85 free( p_probe->p_sys );
88 p_connection = dbus_bus_get( DBUS_BUS_SYSTEM, &dbus_error );
89 if( dbus_error_is_set( &dbus_error ) )
91 msg_Err( p_probe, "unable to connect to DBUS: %s", dbus_error.message );
92 dbus_error_free( &dbus_error );
93 free( p_probe->p_sys );
96 p_sys->p_connection = p_connection;
97 libhal_ctx_set_dbus_connection( p_probe->p_sys->p_ctx, p_connection );
98 if( !libhal_ctx_init( p_probe->p_sys->p_ctx, &dbus_error ) )
100 msg_Err( p_probe, "hal not available : %s", dbus_error.message );
101 dbus_connection_unref( p_connection );
102 dbus_error_free( &dbus_error );
109 /*****************************************************************************
111 *****************************************************************************/
112 static void Close( vlc_object_t *p_this )
114 device_probe_t *p_probe = (device_probe_t *) p_this;
115 probe_sys_t *p_sys = p_probe->p_sys;
116 dbus_connection_unref( p_sys->p_connection );
120 static int GetAllDevices( device_probe_t *p_probe, device_t ***ppp_devices )
122 /// \todo : fill the dst array
123 return p_probe->p_sys->i_devices;
126 static void Update( device_probe_t * p_probe )
128 probe_sys_t *p_sys = p_probe->p_sys;
133 for ( j = 0 ; j < p_sys->i_devices; j++ )
134 p_sys->pp_devices[j]->b_seen = false;
137 if( ( devices = libhal_find_device_by_capability( p_sys->p_ctx,
139 &i_devices, NULL ) ) )
141 for( i = 0; i < i_devices; i++ )
143 device_t *p_dev = ParseDisc( p_probe, devices[ i ] );
146 for ( j = 0 ; j < p_sys->i_devices; j++ )
148 if( !strcmp( p_sys->pp_devices[j]->psz_uri,
152 p_dev->b_seen = true;
153 UpdateMedia( p_probe, p_dev );
157 AddDevice( p_probe, p_dev );
161 /// \todo Remove unseen devices
165 static void AddDevice( device_probe_t * p_probe, device_t *p_dev )
167 INSERT_ELEM( p_probe->p_sys->pp_devices,
168 p_probe->p_sys->i_devices,
169 p_probe->p_sys->i_devices,
171 /// \todo : emit variable
174 static device_t * ParseDisc( device_probe_t *p_probe, char *psz_device )
176 probe_sys_t *p_sys = p_probe->p_sys;
181 if( !libhal_device_property_exists( p_sys->p_ctx, psz_device,
182 "storage.cdrom.dvd", NULL ) )
185 p_dev = (device_t *)malloc( sizeof( device_t ) );
186 p_dev->i_media_type = p_dev->i_capabilities = 0;
187 p_dev->psz_name = p_dev->psz_uri = NULL;
189 block_dev = libhal_device_get_property_string( p_sys->p_ctx, psz_device,
190 "block.device" , NULL );
193 p_dev->psz_uri = strdup( block_dev );
194 libhal_free_string( block_dev );
197 b_dvd = libhal_device_get_property_bool( p_sys->p_ctx, psz_device,
198 "storage.cdrom.dvd", NULL );
200 p_dev->i_capabilities = DEVICE_CAN_DVD | DEVICE_CAN_CD;
202 p_dev->i_capabilities = DEVICE_CAN_CD;
204 UpdateMedia( p_probe, p_dev );
208 static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev )
210 probe_sys_t *p_sys = p_probe->p_sys;
211 char **matching_media;
213 bool b_changed = false;;
214 int i_old_type = p_dev->i_media_type;
215 p_dev->i_media_type = 0;
217 /* Find the media in the drive */
218 matching_media = libhal_manager_find_device_string_match( p_sys->p_ctx,
219 "block.device", p_dev->psz_uri,
221 for( i = 0; i < i_matching; i++ )
223 if( libhal_device_property_exists( p_sys->p_ctx, matching_media[i],
224 "volume.disc.type", NULL ) )
226 char *psz_media_name = libhal_device_get_property_string(
229 "volume.label", NULL );
232 if( p_dev->psz_name && strcmp( p_dev->psz_name, psz_media_name))
234 free( p_dev->psz_name );
235 p_dev->psz_name = NULL;
238 if( !p_dev->psz_name )
239 p_dev->psz_name = strdup( psz_media_name );
240 libhal_free_string( psz_media_name );
243 if( libhal_device_get_property_bool( p_sys->p_ctx,
245 "volume.disc.is_videodvd", NULL) )
246 p_dev->i_media_type = MEDIA_TYPE_DVD;
247 else if( libhal_device_get_property_bool( p_sys->p_ctx,
249 "volume.disc.is_vcd", NULL) ||
250 libhal_device_get_property_bool( p_sys->p_ctx,
252 "volume.disc.is_svcd", NULL) )
253 p_dev->i_media_type = MEDIA_TYPE_VCD;
254 else if( libhal_device_get_property_bool( p_sys->p_ctx,
256 "volume.disc.has_audio", NULL) )
257 p_dev->i_media_type = MEDIA_TYPE_CDDA;
262 if( b_changed || p_dev->i_media_type != i_old_type )
264 /// \todo emit changed signal