]> git.sesse.net Git - vlc/blob - modules/misc/probe/hal.c
Move the meta readers to the correct folder, and use them for all parsing
[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 #include <vlc/vlc.h>
25 #include <vlc/intf.h>
26 #include <vlc_devices.h>
27
28 #include <hal/libhal.h>
29
30 /*****************************************************************************
31  * Local prototypes
32  *****************************************************************************/
33 struct probe_sys_t
34 {
35     LibHalContext *p_ctx;
36     int            i_devices;
37     device_t     **pp_devices;
38 };
39
40 static int  Open ( vlc_object_t * );
41 static void Close( vlc_object_t * );
42
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 );
47
48 /*****************************************************************************
49  * Module descriptor
50  *****************************************************************************/
51 vlc_module_begin();
52     set_description( _("HAL devices detection") );
53     set_capability( "devices probe", 0 );
54     set_callbacks( Open, Close );
55 vlc_module_end();
56
57
58 /*****************************************************************************
59  * Open: initialize and create stuff
60  *****************************************************************************/
61 static int Open( vlc_object_t *p_this )
62 {
63     device_probe_t *p_probe = (device_probe_t *)p_this;
64     DBusError           dbus_error;
65     DBusConnection      *p_connection;
66     probe_sys_t          *p_sys;
67
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;
71
72     p_probe->pf_run = Update;
73
74     dbus_error_init( &dbus_error );
75
76     p_sys->p_ctx = libhal_ctx_new();
77     if( !p_sys->p_ctx )
78     {
79         msg_Err( p_probe, "unable to create HAL context") ;
80         free( p_probe->p_sys );
81         return VLC_EGENERIC;
82     }
83     p_connection = dbus_bus_get( DBUS_BUS_SYSTEM, &dbus_error );
84     if( dbus_error_is_set( &dbus_error ) )
85     {
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 );
89         return VLC_EGENERIC;
90     }
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 ) )
93     {
94         msg_Err( p_probe, "hal not available : %s", dbus_error.message );
95         dbus_error_free( &dbus_error );
96         free( p_sys );
97         return VLC_EGENERIC;
98     }
99     return VLC_SUCCESS;
100 }
101
102 /*****************************************************************************
103  * Close:
104  *****************************************************************************/
105 static void Close( vlc_object_t *p_this )
106 {
107     device_probe_t *p_probe = (device_probe_t *) p_this;
108     probe_sys_t *p_sys = p_probe->p_sys;
109     free( p_sys );
110 }
111
112 static int GetAllDevices( device_probe_t *p_probe, device_t ***ppp_devices )
113 {
114     /// \todo : fill the dst array 
115     return p_probe->p_sys->i_devices;
116 }
117
118 static void Update( device_probe_t * p_probe )
119 {
120     probe_sys_t *p_sys = p_probe->p_sys;
121     int i, i_devices, j;
122     char **devices;
123     vlc_bool_t b_exists;
124
125     for ( j = 0 ; j < p_sys->i_devices; j++ )
126         p_sys->pp_devices[j]->b_seen = VLC_FALSE;
127
128     /* CD/DVD */
129     if( ( devices = libhal_find_device_by_capability( p_sys->p_ctx,
130                                                       "storage.cdrom",
131                                                       &i_devices, NULL ) ) )
132     {
133         for( i = 0; i < i_devices; i++ )
134         {
135             device_t *p_dev = ParseDisc( p_probe, devices[ i ] );
136             b_exists = VLC_FALSE;
137
138             for ( j = 0 ; j < p_sys->i_devices; j++ )
139             {
140                 if( !strcmp( p_sys->pp_devices[j]->psz_uri,
141                              p_dev->psz_uri ) )
142                 {
143                     b_exists = VLC_TRUE;
144                     p_dev->b_seen = VLC_TRUE;
145                     UpdateMedia( p_probe, p_dev );
146                     break;
147                 }
148                 if( !b_exists )
149                     AddDevice( p_probe, p_dev );
150             }
151         }
152     }
153     /// \todo Remove unseen devices
154 }
155
156
157 static void AddDevice( device_probe_t * p_probe, device_t *p_dev )
158 {
159     INSERT_ELEM( p_probe->p_sys->pp_devices,
160                  p_probe->p_sys->i_devices,
161                  p_probe->p_sys->i_devices,
162                  p_dev );
163     /// \todo : emit variable
164 }
165
166 static device_t * ParseDisc( device_probe_t *p_probe,  char *psz_device )
167 {
168     probe_sys_t *p_sys = p_probe->p_sys;
169     device_t *p_dev;
170     char *block_dev;
171     dbus_bool_t b_dvd;
172     
173     if( !libhal_device_property_exists( p_sys->p_ctx, psz_device,
174                                        "storage.cdrom.dvd", NULL ) )
175         return NULL;
176
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;
180
181     block_dev =  libhal_device_get_property_string( p_sys->p_ctx, psz_device,
182                                                    "block.device" , NULL );
183     if( block_dev )
184     {
185         p_dev->psz_uri = strdup( block_dev );
186         libhal_free_string( block_dev );
187     }
188
189     b_dvd = libhal_device_get_property_bool( p_sys->p_ctx, psz_device,
190                                             "storage.cdrom.dvd", NULL  );
191     if( b_dvd )
192         p_dev->i_capabilities = DEVICE_CAN_DVD | DEVICE_CAN_CD;
193     else
194         p_dev->i_capabilities = DEVICE_CAN_CD;
195
196     UpdateMedia( p_probe, p_dev );
197     return p_dev;
198 }
199
200 static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev )
201 {
202     probe_sys_t *p_sys = p_probe->p_sys;
203     char **matching_media;
204     int i_matching, i;
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;
208
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,
212                                                                 &i_matching, NULL );
213     for( i = 0; i < i_matching; i++ )
214     {
215         if( libhal_device_property_exists( p_sys->p_ctx, matching_media[i],
216                                            "volume.disc.type", NULL ) )
217         {
218             char *psz_media_name = libhal_device_get_property_string(
219                                                                         p_sys->p_ctx,
220                                                                         matching_media[i],
221                                                                         "volume.label", NULL );
222             if( psz_media_name )
223             {
224                 if( p_dev->psz_name && strcmp( p_dev->psz_name, psz_media_name))
225                 {
226                     free( p_dev->psz_name );
227                     p_dev->psz_name = NULL;
228                     b_changed = VLC_TRUE;
229                 }
230                 if( !p_dev->psz_name )
231                     p_dev->psz_name = strdup( psz_media_name );
232                 libhal_free_string( psz_media_name );
233             }
234
235             if( libhal_device_get_property_bool( p_sys->p_ctx,
236                                              matching_media[i],
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,
240                                              matching_media[i],
241                                              "volume.disc.is_vcd", NULL) ||
242                      libhal_device_get_property_bool( p_sys->p_ctx,
243                                              matching_media[i],
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,
247                                              matching_media[i],
248                                              "volume.disc.has_audio", NULL) )
249                p_dev->i_media_type = MEDIA_TYPE_CDDA;
250
251             break;
252         }
253     }
254     if( b_changed || p_dev->i_media_type != i_old_type )
255     {
256         /// \todo emit changed signal
257     }
258 }