]> git.sesse.net Git - vlc/blob - modules/misc/probe/hal.c
Remove most stray semi-colons in module descriptions
[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_common.h>
29 #include <vlc_plugin.h>
30 #include <vlc_interface.h>
31 #include <vlc_devices.h>
32
33 #include <hal/libhal.h>
34
35 /*****************************************************************************
36  * Local prototypes
37  *****************************************************************************/
38 struct probe_sys_t
39 {
40     DBusConnection *p_connection;
41     LibHalContext *p_ctx;
42     int            i_devices;
43     device_t     **pp_devices;
44 };
45
46 static int  Open ( vlc_object_t * );
47 static void Close( vlc_object_t * );
48
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 );
53
54 /*****************************************************************************
55  * Module descriptor
56  *****************************************************************************/
57 vlc_module_begin ()
58     set_description( N_("HAL devices detection") )
59     set_capability( "devices probe", 0 )
60     set_callbacks( Open, Close )
61 vlc_module_end ()
62
63
64 /*****************************************************************************
65  * Open: initialize and create stuff
66  *****************************************************************************/
67 static int Open( vlc_object_t *p_this )
68 {
69     device_probe_t *p_probe = (device_probe_t *)p_this;
70     DBusError           dbus_error;
71     DBusConnection      *p_connection;
72     probe_sys_t          *p_sys;
73
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;
77
78     p_probe->pf_run = Update;
79
80     dbus_error_init( &dbus_error );
81
82     p_sys->p_ctx = libhal_ctx_new();
83     if( !p_sys->p_ctx )
84     {
85         msg_Err( p_probe, "unable to create HAL context") ;
86         free( p_probe->p_sys );
87         return VLC_EGENERIC;
88     }
89     p_connection = dbus_bus_get( DBUS_BUS_SYSTEM, &dbus_error );
90     if( dbus_error_is_set( &dbus_error ) )
91     {
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 );
95         return VLC_EGENERIC;
96     }
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 ) )
100     {
101         msg_Err( p_probe, "hal not available : %s", dbus_error.message );
102         dbus_connection_unref( p_connection );
103         dbus_error_free( &dbus_error );
104         free( p_sys );
105         return VLC_EGENERIC;
106     }
107     return VLC_SUCCESS;
108 }
109
110 /*****************************************************************************
111  * Close:
112  *****************************************************************************/
113 static void Close( vlc_object_t *p_this )
114 {
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 );
118     free( p_sys );
119 }
120 #if 0
121 static int GetAllDevices( device_probe_t *p_probe, device_t ***ppp_devices )
122 {
123     /// \todo : fill the dst array
124     return p_probe->p_sys->i_devices;
125 }
126 #endif
127 static void Update( device_probe_t * p_probe )
128 {
129     probe_sys_t *p_sys = p_probe->p_sys;
130     int i, i_devices, j;
131     char **devices;
132     bool b_exists;
133     int canc = vlc_savecancel();
134
135     for ( j = 0 ; j < p_sys->i_devices; j++ )
136         p_sys->pp_devices[j]->b_seen = false;
137
138     /* CD/DVD */
139     if( ( devices = libhal_find_device_by_capability( p_sys->p_ctx,
140                               "storage.cdrom",
141                               &i_devices, NULL ) ) )
142     {
143         for( i = 0; i < i_devices; i++ )
144         {
145             device_t *p_dev = ParseDisc( p_probe, devices[ i ] );
146             b_exists = false;
147
148             for ( j = 0 ; j < p_sys->i_devices; j++ )
149             {
150                 if( !strcmp( p_sys->pp_devices[j]->psz_uri,
151                              p_dev->psz_uri ) )
152                 {
153                     b_exists = true;
154                     p_dev->b_seen = true;
155                     UpdateMedia( p_probe, p_dev );
156                     break;
157                 }
158                 if( !b_exists )
159                     AddDevice( p_probe, p_dev );
160             }
161         }
162     }
163     /// \todo Remove unseen devices
164     vlc_restorecancel( canc );
165 }
166
167
168 static void AddDevice( device_probe_t * p_probe, device_t *p_dev )
169 {
170     INSERT_ELEM( p_probe->p_sys->pp_devices,
171                  p_probe->p_sys->i_devices,
172                  p_probe->p_sys->i_devices,
173                  p_dev );
174     /// \todo : emit variable
175 }
176
177 static device_t * ParseDisc( device_probe_t *p_probe,  char *psz_device )
178 {
179     probe_sys_t *p_sys = p_probe->p_sys;
180     device_t *p_dev;
181     char *block_dev;
182     dbus_bool_t b_dvd;
183
184     if( !libhal_device_property_exists( p_sys->p_ctx, psz_device,
185                                         "storage.cdrom.dvd", NULL ) )
186         return NULL;
187
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;
191
192     block_dev =  libhal_device_get_property_string( p_sys->p_ctx, psz_device,
193                                                    "block.device" , NULL );
194     if( block_dev )
195     {
196         p_dev->psz_uri = strdup( block_dev );
197         libhal_free_string( block_dev );
198     }
199
200     b_dvd = libhal_device_get_property_bool( p_sys->p_ctx, psz_device,
201                                             "storage.cdrom.dvd", NULL  );
202     if( b_dvd )
203         p_dev->i_capabilities = DEVICE_CAN_DVD | DEVICE_CAN_CD;
204     else
205         p_dev->i_capabilities = DEVICE_CAN_CD;
206
207     UpdateMedia( p_probe, p_dev );
208     return p_dev;
209 }
210
211 static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev )
212 {
213     probe_sys_t *p_sys = p_probe->p_sys;
214     char **matching_media;
215     int i_matching, i;
216     bool b_changed = false;;
217     int i_old_type = p_dev->i_media_type;
218     p_dev->i_media_type = 0;
219
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,
223                                             &i_matching, NULL );
224     for( i = 0; i < i_matching; i++ )
225     {
226         if( libhal_device_property_exists( p_sys->p_ctx, matching_media[i],
227                                            "volume.disc.type", NULL ) )
228         {
229             char *psz_media_name = libhal_device_get_property_string(
230                                             p_sys->p_ctx,
231                                             matching_media[i],
232                                             "volume.label", NULL );
233             if( psz_media_name )
234             {
235                 if( p_dev->psz_name && strcmp( p_dev->psz_name, psz_media_name))
236                 {
237                     free( p_dev->psz_name );
238                     p_dev->psz_name = NULL;
239                     b_changed = true;
240                 }
241                 if( !p_dev->psz_name )
242                     p_dev->psz_name = strdup( psz_media_name );
243                 libhal_free_string( psz_media_name );
244             }
245
246             if( libhal_device_get_property_bool( p_sys->p_ctx,
247                                              matching_media[i],
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,
251                                              matching_media[i],
252                                              "volume.disc.is_vcd", NULL) ||
253                      libhal_device_get_property_bool( p_sys->p_ctx,
254                                              matching_media[i],
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,
258                                              matching_media[i],
259                                              "volume.disc.has_audio", NULL) )
260                p_dev->i_media_type = MEDIA_TYPE_CDDA;
261
262             break;
263         }
264     }
265     if( b_changed || p_dev->i_media_type != i_old_type )
266     {
267         /// \todo emit changed signal
268     }
269 }