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 = 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") ;
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 );
95 p_sys->p_connection = p_connection;
96 libhal_ctx_set_dbus_connection( p_sys->p_ctx, p_connection );
97 if( !libhal_ctx_init( p_sys->p_ctx, &dbus_error ) )
99 msg_Err( p_probe, "hal not available : %s", dbus_error.message );
100 dbus_connection_unref( p_connection );
105 dbus_error_free( &dbus_error );
106 libhal_ctx_free( p_sys->p_ctx );
111 /*****************************************************************************
113 *****************************************************************************/
114 static void Close( vlc_object_t *p_this )
116 device_probe_t *p_probe = (device_probe_t *) p_this;
117 probe_sys_t *p_sys = p_probe->p_sys;
118 dbus_connection_unref( p_sys->p_connection );
119 libhal_ctx_free( p_sys->p_ctx );
123 static int GetAllDevices( device_probe_t *p_probe, device_t ***ppp_devices )
125 /// \todo : fill the dst array
126 return p_probe->p_sys->i_devices;
129 static void Update( device_probe_t * p_probe )
131 probe_sys_t *p_sys = p_probe->p_sys;
135 int canc = vlc_savecancel();
137 for ( j = 0 ; j < p_sys->i_devices; j++ )
138 p_sys->pp_devices[j]->b_seen = false;
141 if( ( devices = libhal_find_device_by_capability( p_sys->p_ctx,
143 &i_devices, NULL ) ) )
145 for( i = 0; i < i_devices; i++ )
147 device_t *p_dev = ParseDisc( p_probe, devices[ i ] );
150 for ( j = 0 ; j < p_sys->i_devices; j++ )
152 if( !strcmp( p_sys->pp_devices[j]->psz_uri,
156 p_dev->b_seen = true;
157 UpdateMedia( p_probe, p_dev );
161 AddDevice( p_probe, p_dev );
165 /// \todo Remove unseen devices
166 vlc_restorecancel( canc );
170 static void AddDevice( device_probe_t * p_probe, device_t *p_dev )
172 INSERT_ELEM( p_probe->p_sys->pp_devices,
173 p_probe->p_sys->i_devices,
174 p_probe->p_sys->i_devices,
176 /// \todo : emit variable
179 static device_t * ParseDisc( device_probe_t *p_probe, char *psz_device )
181 probe_sys_t *p_sys = p_probe->p_sys;
186 if( !libhal_device_property_exists( p_sys->p_ctx, psz_device,
187 "storage.cdrom.dvd", NULL ) )
190 p_dev = (device_t *)malloc( sizeof( device_t ) );
191 p_dev->i_media_type = p_dev->i_capabilities = 0;
192 p_dev->psz_name = p_dev->psz_uri = NULL;
194 block_dev = libhal_device_get_property_string( p_sys->p_ctx, psz_device,
195 "block.device" , NULL );
198 p_dev->psz_uri = strdup( block_dev );
199 libhal_free_string( block_dev );
202 b_dvd = libhal_device_get_property_bool( p_sys->p_ctx, psz_device,
203 "storage.cdrom.dvd", NULL );
205 p_dev->i_capabilities = DEVICE_CAN_DVD | DEVICE_CAN_CD;
207 p_dev->i_capabilities = DEVICE_CAN_CD;
209 UpdateMedia( p_probe, p_dev );
213 static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev )
215 probe_sys_t *p_sys = p_probe->p_sys;
216 char **matching_media;
218 bool b_changed = false;;
219 int i_old_type = p_dev->i_media_type;
220 p_dev->i_media_type = 0;
222 /* Find the media in the drive */
223 matching_media = libhal_manager_find_device_string_match( p_sys->p_ctx,
224 "block.device", p_dev->psz_uri,
226 for( i = 0; i < i_matching; i++ )
228 if( libhal_device_property_exists( p_sys->p_ctx, matching_media[i],
229 "volume.disc.type", NULL ) )
231 char *psz_media_name = libhal_device_get_property_string(
234 "volume.label", NULL );
237 if( p_dev->psz_name && strcmp( p_dev->psz_name, psz_media_name))
239 free( p_dev->psz_name );
240 p_dev->psz_name = NULL;
243 if( !p_dev->psz_name )
244 p_dev->psz_name = strdup( psz_media_name );
245 libhal_free_string( psz_media_name );
248 if( libhal_device_get_property_bool( p_sys->p_ctx,
250 "volume.disc.is_videodvd", NULL) )
251 p_dev->i_media_type = MEDIA_TYPE_DVD;
252 else if( libhal_device_get_property_bool( p_sys->p_ctx,
254 "volume.disc.is_vcd", NULL) ||
255 libhal_device_get_property_bool( p_sys->p_ctx,
257 "volume.disc.is_svcd", NULL) )
258 p_dev->i_media_type = MEDIA_TYPE_VCD;
259 else if( libhal_device_get_property_bool( p_sys->p_ctx,
261 "volume.disc.has_audio", NULL) )
262 p_dev->i_media_type = MEDIA_TYPE_CDDA;
267 if( b_changed || p_dev->i_media_type != i_old_type )
269 /// \todo emit changed signal