]> git.sesse.net Git - vlc/blob - modules/misc/probe/hal.c
update module LIST file.
[vlc] / modules / misc / probe / hal.c
1 /*****************************************************************************
2  * hal.c :  HAL probing module
3  *****************************************************************************
4  * Copyright (C) 2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include <vlc/vlc.h>
29 #include <vlc_interface.h>
30 #include <vlc_devices.h>
31
32 #include <hal/libhal.h>
33
34 /*****************************************************************************
35  * Local prototypes
36  *****************************************************************************/
37 struct probe_sys_t
38 {
39     DBusConnection *p_connection;
40     LibHalContext *p_ctx;
41     int            i_devices;
42     device_t     **pp_devices;
43 };
44
45 static int  Open ( vlc_object_t * );
46 static void Close( vlc_object_t * );
47
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 );
52
53 /*****************************************************************************
54  * Module descriptor
55  *****************************************************************************/
56 vlc_module_begin();
57     set_description( _("HAL devices detection") );
58     set_capability( "devices probe", 0 );
59     set_callbacks( Open, Close );
60 vlc_module_end();
61
62
63 /*****************************************************************************
64  * Open: initialize and create stuff
65  *****************************************************************************/
66 static int Open( vlc_object_t *p_this )
67 {
68     device_probe_t *p_probe = (device_probe_t *)p_this;
69     DBusError           dbus_error;
70     DBusConnection      *p_connection;
71     probe_sys_t          *p_sys;
72
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;
76
77     p_probe->pf_run = Update;
78
79     dbus_error_init( &dbus_error );
80
81     p_sys->p_ctx = libhal_ctx_new();
82     if( !p_sys->p_ctx )
83     {
84         msg_Err( p_probe, "unable to create HAL context") ;
85         free( p_probe->p_sys );
86         return VLC_EGENERIC;
87     }
88     p_connection = dbus_bus_get( DBUS_BUS_SYSTEM, &dbus_error );
89     if( dbus_error_is_set( &dbus_error ) )
90     {
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 );
94         return VLC_EGENERIC;
95     }
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 ) )
99     {
100         msg_Err( p_probe, "hal not available : %s", dbus_error.message );
101         dbus_connection_unref( p_connection );
102         dbus_error_free( &dbus_error );
103         free( p_sys );
104         return VLC_EGENERIC;
105     }
106     return VLC_SUCCESS;
107 }
108
109 /*****************************************************************************
110  * Close:
111  *****************************************************************************/
112 static void Close( vlc_object_t *p_this )
113 {
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 );
117     free( p_sys );
118 }
119 #if 0
120 static int GetAllDevices( device_probe_t *p_probe, device_t ***ppp_devices )
121 {
122     /// \todo : fill the dst array
123     return p_probe->p_sys->i_devices;
124 }
125 #endif
126 static void Update( device_probe_t * p_probe )
127 {
128     probe_sys_t *p_sys = p_probe->p_sys;
129     int i, i_devices, j;
130     char **devices;
131     vlc_bool_t b_exists;
132
133     for ( j = 0 ; j < p_sys->i_devices; j++ )
134         p_sys->pp_devices[j]->b_seen = VLC_FALSE;
135
136     /* CD/DVD */
137     if( ( devices = libhal_find_device_by_capability( p_sys->p_ctx,
138                               "storage.cdrom",
139                               &i_devices, NULL ) ) )
140     {
141         for( i = 0; i < i_devices; i++ )
142         {
143             device_t *p_dev = ParseDisc( p_probe, devices[ i ] );
144             b_exists = VLC_FALSE;
145
146             for ( j = 0 ; j < p_sys->i_devices; j++ )
147             {
148                 if( !strcmp( p_sys->pp_devices[j]->psz_uri,
149                              p_dev->psz_uri ) )
150                 {
151                     b_exists = VLC_TRUE;
152                     p_dev->b_seen = VLC_TRUE;
153                     UpdateMedia( p_probe, p_dev );
154                     break;
155                 }
156                 if( !b_exists )
157                     AddDevice( p_probe, p_dev );
158             }
159         }
160     }
161     /// \todo Remove unseen devices
162 }
163
164
165 static void AddDevice( device_probe_t * p_probe, device_t *p_dev )
166 {
167     INSERT_ELEM( p_probe->p_sys->pp_devices,
168                  p_probe->p_sys->i_devices,
169                  p_probe->p_sys->i_devices,
170                  p_dev );
171     /// \todo : emit variable
172 }
173
174 static device_t * ParseDisc( device_probe_t *p_probe,  char *psz_device )
175 {
176     probe_sys_t *p_sys = p_probe->p_sys;
177     device_t *p_dev;
178     char *block_dev;
179     dbus_bool_t b_dvd;
180
181     if( !libhal_device_property_exists( p_sys->p_ctx, psz_device,
182                                         "storage.cdrom.dvd", NULL ) )
183         return NULL;
184
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;
188
189     block_dev =  libhal_device_get_property_string( p_sys->p_ctx, psz_device,
190                                                    "block.device" , NULL );
191     if( block_dev )
192     {
193         p_dev->psz_uri = strdup( block_dev );
194         libhal_free_string( block_dev );
195     }
196
197     b_dvd = libhal_device_get_property_bool( p_sys->p_ctx, psz_device,
198                                             "storage.cdrom.dvd", NULL  );
199     if( b_dvd )
200         p_dev->i_capabilities = DEVICE_CAN_DVD | DEVICE_CAN_CD;
201     else
202         p_dev->i_capabilities = DEVICE_CAN_CD;
203
204     UpdateMedia( p_probe, p_dev );
205     return p_dev;
206 }
207
208 static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev )
209 {
210     probe_sys_t *p_sys = p_probe->p_sys;
211     char **matching_media;
212     int i_matching, i;
213     vlc_bool_t b_changed = VLC_FALSE;;
214     int i_old_type = p_dev->i_media_type;
215     p_dev->i_media_type = 0;
216
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,
220                                             &i_matching, NULL );
221     for( i = 0; i < i_matching; i++ )
222     {
223         if( libhal_device_property_exists( p_sys->p_ctx, matching_media[i],
224                                            "volume.disc.type", NULL ) )
225         {
226             char *psz_media_name = libhal_device_get_property_string(
227                                             p_sys->p_ctx,
228                                             matching_media[i],
229                                             "volume.label", NULL );
230             if( psz_media_name )
231             {
232                 if( p_dev->psz_name && strcmp( p_dev->psz_name, psz_media_name))
233                 {
234                     free( p_dev->psz_name );
235                     p_dev->psz_name = NULL;
236                     b_changed = VLC_TRUE;
237                 }
238                 if( !p_dev->psz_name )
239                     p_dev->psz_name = strdup( psz_media_name );
240                 libhal_free_string( psz_media_name );
241             }
242
243             if( libhal_device_get_property_bool( p_sys->p_ctx,
244                                              matching_media[i],
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,
248                                              matching_media[i],
249                                              "volume.disc.is_vcd", NULL) ||
250                      libhal_device_get_property_bool( p_sys->p_ctx,
251                                              matching_media[i],
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,
255                                              matching_media[i],
256                                              "volume.disc.has_audio", NULL) )
257                p_dev->i_media_type = MEDIA_TYPE_CDDA;
258
259             break;
260         }
261     }
262     if( b_changed || p_dev->i_media_type != i_old_type )
263     {
264         /// \todo emit changed signal
265     }
266 }