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 *****************************************************************************/
26 #include <vlc_devices.h>
28 #include <hal/libhal.h>
30 /*****************************************************************************
32 *****************************************************************************/
37 device_t **pp_devices;
40 static int Open ( vlc_object_t * );
41 static void Close( vlc_object_t * );
43 static void Update ( device_probe_t *p_probe );
44 static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev );
45 static void AddDevice( device_probe_t * p_probe, device_t *p_dev );
46 static device_t * ParseDisc( device_probe_t *p_probe, char *psz_device );
48 /*****************************************************************************
50 *****************************************************************************/
52 set_description( _("HAL devices detection") );
53 set_capability( "devices probe", 0 );
54 set_callbacks( Open, Close );
58 /*****************************************************************************
59 * Open: initialize and create stuff
60 *****************************************************************************/
61 static int Open( vlc_object_t *p_this )
63 device_probe_t *p_probe = (device_probe_t *)p_this;
65 DBusConnection *p_connection;
68 p_probe->p_sys = p_sys = (probe_sys_t*)malloc( sizeof( probe_sys_t ) );
69 p_probe->p_sys->i_devices = 0;
70 p_probe->p_sys->pp_devices = NULL;
72 p_probe->pf_run = Update;
74 dbus_error_init( &dbus_error );
76 p_sys->p_ctx = libhal_ctx_new();
79 msg_Err( p_probe, "unable to create HAL context") ;
80 free( p_probe->p_sys );
83 p_connection = dbus_bus_get( DBUS_BUS_SYSTEM, &dbus_error );
84 if( dbus_error_is_set( &dbus_error ) )
86 msg_Err( p_probe, "unable to connect to DBUS: %s", dbus_error.message );
87 dbus_error_free( &dbus_error );
88 free( p_probe->p_sys );
91 libhal_ctx_set_dbus_connection( p_probe->p_sys->p_ctx, p_connection );
92 if( !libhal_ctx_init( p_probe->p_sys->p_ctx, &dbus_error ) )
94 msg_Err( p_probe, "hal not available : %s", dbus_error.message );
95 dbus_error_free( &dbus_error );
102 /*****************************************************************************
104 *****************************************************************************/
105 static void Close( vlc_object_t *p_this )
107 device_probe_t *p_probe = (device_probe_t *) p_this;
108 probe_sys_t *p_sys = p_probe->p_sys;
112 static int GetAllDevices( device_probe_t *p_probe, device_t ***ppp_devices )
114 /// \todo : fill the dst array
115 return p_probe->p_sys->i_devices;
118 static void Update( device_probe_t * p_probe )
120 probe_sys_t *p_sys = p_probe->p_sys;
125 for ( j = 0 ; j < p_sys->i_devices; j++ )
126 p_sys->pp_devices[j]->b_seen = VLC_FALSE;
129 if( ( devices = libhal_find_device_by_capability( p_sys->p_ctx,
131 &i_devices, NULL ) ) )
133 for( i = 0; i < i_devices; i++ )
135 device_t *p_dev = ParseDisc( p_probe, devices[ i ] );
136 b_exists = VLC_FALSE;
138 for ( j = 0 ; j < p_sys->i_devices; j++ )
140 if( !strcmp( p_sys->pp_devices[j]->psz_uri,
144 p_dev->b_seen = VLC_TRUE;
145 UpdateMedia( p_probe, p_dev );
149 AddDevice( p_probe, p_dev );
153 /// \todo Remove unseen devices
157 static void AddDevice( device_probe_t * p_probe, device_t *p_dev )
159 INSERT_ELEM( p_probe->p_sys->pp_devices,
160 p_probe->p_sys->i_devices,
161 p_probe->p_sys->i_devices,
163 /// \todo : emit variable
166 static device_t * ParseDisc( device_probe_t *p_probe, char *psz_device )
168 probe_sys_t *p_sys = p_probe->p_sys;
173 if( !libhal_device_property_exists( p_sys->p_ctx, psz_device,
174 "storage.cdrom.dvd", NULL ) )
177 p_dev = (device_t *)malloc( sizeof( device_t ) );
178 p_dev->i_media_type = p_dev->i_capabilities = 0;
179 p_dev->psz_name = p_dev->psz_uri = NULL;
181 block_dev = libhal_device_get_property_string( p_sys->p_ctx, psz_device,
182 "block.device" , NULL );
185 p_dev->psz_uri = strdup( block_dev );
186 libhal_free_string( block_dev );
189 b_dvd = libhal_device_get_property_bool( p_sys->p_ctx, psz_device,
190 "storage.cdrom.dvd", NULL );
192 p_dev->i_capabilities = DEVICE_CAN_DVD | DEVICE_CAN_CD;
194 p_dev->i_capabilities = DEVICE_CAN_CD;
196 UpdateMedia( p_probe, p_dev );
200 static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev )
202 probe_sys_t *p_sys = p_probe->p_sys;
203 char **matching_media;
205 vlc_bool_t b_changed = VLC_FALSE;;
206 int i_old_type = p_dev->i_media_type;
207 p_dev->i_media_type = 0;
209 /* Find the media in the drive */
210 matching_media = libhal_manager_find_device_string_match( p_sys->p_ctx,
211 "block.device", p_dev->psz_uri,
213 for( i = 0; i < i_matching; i++ )
215 if( libhal_device_property_exists( p_sys->p_ctx, matching_media[i],
216 "volume.disc.type", NULL ) )
218 char *psz_media_name = libhal_device_get_property_string(
221 "volume.label", NULL );
224 if( p_dev->psz_name && strcmp( p_dev->psz_name, psz_media_name))
226 free( p_dev->psz_name );
227 p_dev->psz_name = NULL;
228 b_changed = VLC_TRUE;
230 if( !p_dev->psz_name )
231 p_dev->psz_name = strdup( psz_media_name );
232 libhal_free_string( psz_media_name );
235 if( libhal_device_get_property_bool( p_sys->p_ctx,
237 "volume.disc.is_videodvd", NULL) )
238 p_dev->i_media_type = MEDIA_TYPE_DVD;
239 else if( libhal_device_get_property_bool( p_sys->p_ctx,
241 "volume.disc.is_vcd", NULL) ||
242 libhal_device_get_property_bool( p_sys->p_ctx,
244 "volume.disc.is_svcd", NULL) )
245 p_dev->i_media_type = MEDIA_TYPE_VCD;
246 else if( libhal_device_get_property_bool( p_sys->p_ctx,
248 "volume.disc.has_audio", NULL) )
249 p_dev->i_media_type = MEDIA_TYPE_CDDA;
254 if( b_changed || p_dev->i_media_type != i_old_type )
256 /// \todo emit changed signal