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;
133 int canc = vlc_savecancel();
135 for ( j = 0 ; j < p_sys->i_devices; j++ )
136 p_sys->pp_devices[j]->b_seen = false;
139 if( ( devices = libhal_find_device_by_capability( p_sys->p_ctx,
141 &i_devices, NULL ) ) )
143 for( i = 0; i < i_devices; i++ )
145 device_t *p_dev = ParseDisc( p_probe, devices[ i ] );
148 for ( j = 0 ; j < p_sys->i_devices; j++ )
150 if( !strcmp( p_sys->pp_devices[j]->psz_uri,
154 p_dev->b_seen = true;
155 UpdateMedia( p_probe, p_dev );
159 AddDevice( p_probe, p_dev );
163 /// \todo Remove unseen devices
164 vlc_restorecancel( canc );
168 static void AddDevice( device_probe_t * p_probe, device_t *p_dev )
170 INSERT_ELEM( p_probe->p_sys->pp_devices,
171 p_probe->p_sys->i_devices,
172 p_probe->p_sys->i_devices,
174 /// \todo : emit variable
177 static device_t * ParseDisc( device_probe_t *p_probe, char *psz_device )
179 probe_sys_t *p_sys = p_probe->p_sys;
184 if( !libhal_device_property_exists( p_sys->p_ctx, psz_device,
185 "storage.cdrom.dvd", NULL ) )
188 p_dev = (device_t *)malloc( sizeof( device_t ) );
189 p_dev->i_media_type = p_dev->i_capabilities = 0;
190 p_dev->psz_name = p_dev->psz_uri = NULL;
192 block_dev = libhal_device_get_property_string( p_sys->p_ctx, psz_device,
193 "block.device" , NULL );
196 p_dev->psz_uri = strdup( block_dev );
197 libhal_free_string( block_dev );
200 b_dvd = libhal_device_get_property_bool( p_sys->p_ctx, psz_device,
201 "storage.cdrom.dvd", NULL );
203 p_dev->i_capabilities = DEVICE_CAN_DVD | DEVICE_CAN_CD;
205 p_dev->i_capabilities = DEVICE_CAN_CD;
207 UpdateMedia( p_probe, p_dev );
211 static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev )
213 probe_sys_t *p_sys = p_probe->p_sys;
214 char **matching_media;
216 bool b_changed = false;;
217 int i_old_type = p_dev->i_media_type;
218 p_dev->i_media_type = 0;
220 /* Find the media in the drive */
221 matching_media = libhal_manager_find_device_string_match( p_sys->p_ctx,
222 "block.device", p_dev->psz_uri,
224 for( i = 0; i < i_matching; i++ )
226 if( libhal_device_property_exists( p_sys->p_ctx, matching_media[i],
227 "volume.disc.type", NULL ) )
229 char *psz_media_name = libhal_device_get_property_string(
232 "volume.label", NULL );
235 if( p_dev->psz_name && strcmp( p_dev->psz_name, psz_media_name))
237 free( p_dev->psz_name );
238 p_dev->psz_name = NULL;
241 if( !p_dev->psz_name )
242 p_dev->psz_name = strdup( psz_media_name );
243 libhal_free_string( psz_media_name );
246 if( libhal_device_get_property_bool( p_sys->p_ctx,
248 "volume.disc.is_videodvd", NULL) )
249 p_dev->i_media_type = MEDIA_TYPE_DVD;
250 else if( libhal_device_get_property_bool( p_sys->p_ctx,
252 "volume.disc.is_vcd", NULL) ||
253 libhal_device_get_property_bool( p_sys->p_ctx,
255 "volume.disc.is_svcd", NULL) )
256 p_dev->i_media_type = MEDIA_TYPE_VCD;
257 else if( libhal_device_get_property_bool( p_sys->p_ctx,
259 "volume.disc.has_audio", NULL) )
260 p_dev->i_media_type = MEDIA_TYPE_CDDA;
265 if( b_changed || p_dev->i_media_type != i_old_type )
267 /// \todo emit changed signal