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 *****************************************************************************/
28 #include <vlc_common.h>
29 #include <vlc_plugin.h>
30 #include <vlc_interface.h>
31 #include <vlc_devices.h>
33 #include <hal/libhal.h>
35 /*****************************************************************************
37 *****************************************************************************/
40 DBusConnection *p_connection;
43 device_t **pp_devices;
46 static int Open ( vlc_object_t * );
47 static void Close( vlc_object_t * );
49 static void Update ( device_probe_t *p_probe );
50 static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev );
51 static void AddDevice( device_probe_t * p_probe, device_t *p_dev );
52 static device_t * ParseDisc( device_probe_t *p_probe, char *psz_device );
54 /*****************************************************************************
56 *****************************************************************************/
58 set_description( N_("HAL devices detection") );
59 set_capability( "devices probe", 0 );
60 set_callbacks( Open, Close );
64 /*****************************************************************************
65 * Open: initialize and create stuff
66 *****************************************************************************/
67 static int Open( vlc_object_t *p_this )
69 device_probe_t *p_probe = (device_probe_t *)p_this;
71 DBusConnection *p_connection;
74 p_probe->p_sys = p_sys = (probe_sys_t*)malloc( sizeof( probe_sys_t ) );
75 p_probe->p_sys->i_devices = 0;
76 p_probe->p_sys->pp_devices = NULL;
78 p_probe->pf_run = Update;
80 dbus_error_init( &dbus_error );
82 p_sys->p_ctx = libhal_ctx_new();
85 msg_Err( p_probe, "unable to create HAL context") ;
86 free( p_probe->p_sys );
89 p_connection = dbus_bus_get( DBUS_BUS_SYSTEM, &dbus_error );
90 if( dbus_error_is_set( &dbus_error ) )
92 msg_Err( p_probe, "unable to connect to DBUS: %s", dbus_error.message );
93 dbus_error_free( &dbus_error );
94 free( p_probe->p_sys );
97 p_sys->p_connection = p_connection;
98 libhal_ctx_set_dbus_connection( p_probe->p_sys->p_ctx, p_connection );
99 if( !libhal_ctx_init( p_probe->p_sys->p_ctx, &dbus_error ) )
101 msg_Err( p_probe, "hal not available : %s", dbus_error.message );
102 dbus_connection_unref( p_connection );
103 dbus_error_free( &dbus_error );
110 /*****************************************************************************
112 *****************************************************************************/
113 static void Close( vlc_object_t *p_this )
115 device_probe_t *p_probe = (device_probe_t *) p_this;
116 probe_sys_t *p_sys = p_probe->p_sys;
117 dbus_connection_unref( p_sys->p_connection );
121 static int GetAllDevices( device_probe_t *p_probe, device_t ***ppp_devices )
123 /// \todo : fill the dst array
124 return p_probe->p_sys->i_devices;
127 static void Update( device_probe_t * p_probe )
129 probe_sys_t *p_sys = p_probe->p_sys;
134 for ( j = 0 ; j < p_sys->i_devices; j++ )
135 p_sys->pp_devices[j]->b_seen = false;
138 if( ( devices = libhal_find_device_by_capability( p_sys->p_ctx,
140 &i_devices, NULL ) ) )
142 for( i = 0; i < i_devices; i++ )
144 device_t *p_dev = ParseDisc( p_probe, devices[ i ] );
147 for ( j = 0 ; j < p_sys->i_devices; j++ )
149 if( !strcmp( p_sys->pp_devices[j]->psz_uri,
153 p_dev->b_seen = true;
154 UpdateMedia( p_probe, p_dev );
158 AddDevice( p_probe, p_dev );
162 /// \todo Remove unseen devices
166 static void AddDevice( device_probe_t * p_probe, device_t *p_dev )
168 INSERT_ELEM( p_probe->p_sys->pp_devices,
169 p_probe->p_sys->i_devices,
170 p_probe->p_sys->i_devices,
172 /// \todo : emit variable
175 static device_t * ParseDisc( device_probe_t *p_probe, char *psz_device )
177 probe_sys_t *p_sys = p_probe->p_sys;
182 if( !libhal_device_property_exists( p_sys->p_ctx, psz_device,
183 "storage.cdrom.dvd", NULL ) )
186 p_dev = (device_t *)malloc( sizeof( device_t ) );
187 p_dev->i_media_type = p_dev->i_capabilities = 0;
188 p_dev->psz_name = p_dev->psz_uri = NULL;
190 block_dev = libhal_device_get_property_string( p_sys->p_ctx, psz_device,
191 "block.device" , NULL );
194 p_dev->psz_uri = strdup( block_dev );
195 libhal_free_string( block_dev );
198 b_dvd = libhal_device_get_property_bool( p_sys->p_ctx, psz_device,
199 "storage.cdrom.dvd", NULL );
201 p_dev->i_capabilities = DEVICE_CAN_DVD | DEVICE_CAN_CD;
203 p_dev->i_capabilities = DEVICE_CAN_CD;
205 UpdateMedia( p_probe, p_dev );
209 static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev )
211 probe_sys_t *p_sys = p_probe->p_sys;
212 char **matching_media;
214 bool b_changed = false;;
215 int i_old_type = p_dev->i_media_type;
216 p_dev->i_media_type = 0;
218 /* Find the media in the drive */
219 matching_media = libhal_manager_find_device_string_match( p_sys->p_ctx,
220 "block.device", p_dev->psz_uri,
222 for( i = 0; i < i_matching; i++ )
224 if( libhal_device_property_exists( p_sys->p_ctx, matching_media[i],
225 "volume.disc.type", NULL ) )
227 char *psz_media_name = libhal_device_get_property_string(
230 "volume.label", NULL );
233 if( p_dev->psz_name && strcmp( p_dev->psz_name, psz_media_name))
235 free( p_dev->psz_name );
236 p_dev->psz_name = NULL;
239 if( !p_dev->psz_name )
240 p_dev->psz_name = strdup( psz_media_name );
241 libhal_free_string( psz_media_name );
244 if( libhal_device_get_property_bool( p_sys->p_ctx,
246 "volume.disc.is_videodvd", NULL) )
247 p_dev->i_media_type = MEDIA_TYPE_DVD;
248 else if( libhal_device_get_property_bool( p_sys->p_ctx,
250 "volume.disc.is_vcd", NULL) ||
251 libhal_device_get_property_bool( p_sys->p_ctx,
253 "volume.disc.is_svcd", NULL) )
254 p_dev->i_media_type = MEDIA_TYPE_VCD;
255 else if( libhal_device_get_property_bool( p_sys->p_ctx,
257 "volume.disc.has_audio", NULL) )
258 p_dev->i_media_type = MEDIA_TYPE_CDDA;
263 if( b_changed || p_dev->i_media_type != i_old_type )
265 /// \todo emit changed signal