hal.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:9k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * hal.c :  HAL probing module
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 the VideoLAN team
  5.  * $Id: 7bb6dcbb5d72a0a6c22908d9ac159db47a645ad4 $
  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. #ifdef HAVE_CONFIG_H
  24. # include "config.h"
  25. #endif
  26. #include <vlc_common.h>
  27. #include <vlc_plugin.h>
  28. #include <vlc_interface.h>
  29. #include <vlc_devices.h>
  30. #include <hal/libhal.h>
  31. /*****************************************************************************
  32.  * Local prototypes
  33.  *****************************************************************************/
  34. struct probe_sys_t
  35. {
  36.     DBusConnection *p_connection;
  37.     LibHalContext *p_ctx;
  38.     int            i_devices;
  39.     device_t     **pp_devices;
  40. };
  41. static int  Open ( vlc_object_t * );
  42. static void Close( vlc_object_t * );
  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.  * Module descriptor
  49.  *****************************************************************************/
  50. vlc_module_begin ()
  51.     set_description( N_("HAL devices detection") )
  52.     set_capability( "devices probe", 0 )
  53.     set_callbacks( Open, Close )
  54. vlc_module_end ()
  55. /*****************************************************************************
  56.  * Open: initialize and create stuff
  57.  *****************************************************************************/
  58. static int Open( vlc_object_t *p_this )
  59. {
  60.     device_probe_t *p_probe = (device_probe_t *)p_this;
  61.     DBusError       dbus_error;
  62.     DBusConnection *p_connection;
  63.     probe_sys_t    *p_sys;
  64.     p_probe->p_sys = p_sys = malloc( sizeof( probe_sys_t ) );
  65.     p_probe->p_sys->i_devices = 0;
  66.     p_probe->p_sys->pp_devices = NULL;
  67.     p_probe->pf_run = Update;
  68.     dbus_error_init( &dbus_error );
  69.     p_sys->p_ctx = libhal_ctx_new();
  70.     if( !p_sys->p_ctx )
  71.     {
  72.         msg_Err( p_probe, "unable to create HAL context") ;
  73.         free( p_sys );
  74.         return VLC_EGENERIC;
  75.     }
  76.     p_connection = dbus_bus_get( DBUS_BUS_SYSTEM, &dbus_error );
  77.     if( dbus_error_is_set( &dbus_error ) )
  78.     {
  79.         msg_Err( p_probe, "unable to connect to DBUS: %s", dbus_error.message );
  80.         goto error;
  81.     }
  82.     p_sys->p_connection = p_connection;
  83.     libhal_ctx_set_dbus_connection( p_sys->p_ctx, p_connection );
  84.     if( !libhal_ctx_init( p_sys->p_ctx, &dbus_error ) )
  85.     {
  86.         msg_Err( p_probe, "hal not available : %s", dbus_error.message );
  87.         dbus_connection_unref( p_connection );
  88.         goto error;
  89.     }
  90.     return VLC_SUCCESS;
  91. error:
  92.     dbus_error_free( &dbus_error );
  93.     libhal_ctx_free( p_sys->p_ctx );
  94.     free( p_sys );
  95.     return VLC_EGENERIC;
  96. }
  97. /*****************************************************************************
  98.  * Close:
  99.  *****************************************************************************/
  100. static void Close( vlc_object_t *p_this )
  101. {
  102.     device_probe_t *p_probe = (device_probe_t *) p_this;
  103.     probe_sys_t *p_sys = p_probe->p_sys;
  104.     dbus_connection_unref( p_sys->p_connection );
  105.     libhal_ctx_free( p_sys->p_ctx );
  106.     free( p_sys );
  107. }
  108. #if 0
  109. static int GetAllDevices( device_probe_t *p_probe, device_t ***ppp_devices )
  110. {
  111.     /// todo : fill the dst array
  112.     return p_probe->p_sys->i_devices;
  113. }
  114. #endif
  115. static void Update( device_probe_t * p_probe )
  116. {
  117.     probe_sys_t *p_sys = p_probe->p_sys;
  118.     int i, i_devices, j;
  119.     char **devices;
  120.     bool b_exists;
  121.     int canc = vlc_savecancel();
  122.     for ( j = 0 ; j < p_sys->i_devices; j++ )
  123.         p_sys->pp_devices[j]->b_seen = false;
  124.     /* CD/DVD */
  125.     if( ( devices = libhal_find_device_by_capability( p_sys->p_ctx,
  126.                               "storage.cdrom",
  127.                               &i_devices, NULL ) ) )
  128.     {
  129.         for( i = 0; i < i_devices; i++ )
  130.         {
  131.             device_t *p_dev = ParseDisc( p_probe, devices[ i ] );
  132.             b_exists = false;
  133.             for ( j = 0 ; j < p_sys->i_devices; j++ )
  134.             {
  135.                 if( !strcmp( p_sys->pp_devices[j]->psz_uri,
  136.                              p_dev->psz_uri ) )
  137.                 {
  138.                     b_exists = true;
  139.                     p_dev->b_seen = true;
  140.                     UpdateMedia( p_probe, p_dev );
  141.                     break;
  142.                 }
  143.                 if( !b_exists )
  144.                     AddDevice( p_probe, p_dev );
  145.             }
  146.         }
  147.     }
  148.     /// todo Remove unseen devices
  149.     vlc_restorecancel( canc );
  150. }
  151. static void AddDevice( device_probe_t * p_probe, device_t *p_dev )
  152. {
  153.     INSERT_ELEM( p_probe->p_sys->pp_devices,
  154.                  p_probe->p_sys->i_devices,
  155.                  p_probe->p_sys->i_devices,
  156.                  p_dev );
  157.     /// todo : emit variable
  158. }
  159. static device_t * ParseDisc( device_probe_t *p_probe,  char *psz_device )
  160. {
  161.     probe_sys_t *p_sys = p_probe->p_sys;
  162.     device_t *p_dev;
  163.     char *block_dev;
  164.     dbus_bool_t b_dvd;
  165.     if( !libhal_device_property_exists( p_sys->p_ctx, psz_device,
  166.                                         "storage.cdrom.dvd", NULL ) )
  167.         return NULL;
  168.     p_dev = (device_t *)malloc( sizeof( device_t ) );
  169.     p_dev->i_media_type = p_dev->i_capabilities = 0;
  170.     p_dev->psz_name = p_dev->psz_uri = NULL;
  171.     block_dev =  libhal_device_get_property_string( p_sys->p_ctx, psz_device,
  172.                                                    "block.device" , NULL );
  173.     if( block_dev )
  174.     {
  175.         p_dev->psz_uri = strdup( block_dev );
  176.         libhal_free_string( block_dev );
  177.     }
  178.     b_dvd = libhal_device_get_property_bool( p_sys->p_ctx, psz_device,
  179.                                             "storage.cdrom.dvd", NULL  );
  180.     if( b_dvd )
  181.         p_dev->i_capabilities = DEVICE_CAN_DVD | DEVICE_CAN_CD;
  182.     else
  183.         p_dev->i_capabilities = DEVICE_CAN_CD;
  184.     UpdateMedia( p_probe, p_dev );
  185.     return p_dev;
  186. }
  187. static void UpdateMedia( device_probe_t *p_probe, device_t *p_dev )
  188. {
  189.     probe_sys_t *p_sys = p_probe->p_sys;
  190.     char **matching_media;
  191.     int i_matching, i;
  192.     bool b_changed = false;;
  193.     int i_old_type = p_dev->i_media_type;
  194.     p_dev->i_media_type = 0;
  195.     /* Find the media in the drive */
  196.     matching_media = libhal_manager_find_device_string_match( p_sys->p_ctx,
  197.                                             "block.device", p_dev->psz_uri,
  198.                                             &i_matching, NULL );
  199.     for( i = 0; i < i_matching; i++ )
  200.     {
  201.         if( libhal_device_property_exists( p_sys->p_ctx, matching_media[i],
  202.                                            "volume.disc.type", NULL ) )
  203.         {
  204.             char *psz_media_name = libhal_device_get_property_string(
  205.                                             p_sys->p_ctx,
  206.                                             matching_media[i],
  207.                                             "volume.label", NULL );
  208.             if( psz_media_name )
  209.             {
  210.                 if( p_dev->psz_name && strcmp( p_dev->psz_name, psz_media_name))
  211.                 {
  212.                     free( p_dev->psz_name );
  213.                     p_dev->psz_name = NULL;
  214.                     b_changed = true;
  215.                 }
  216.                 if( !p_dev->psz_name )
  217.                     p_dev->psz_name = strdup( psz_media_name );
  218.                 libhal_free_string( psz_media_name );
  219.             }
  220.             if( libhal_device_get_property_bool( p_sys->p_ctx,
  221.                                              matching_media[i],
  222.                                              "volume.disc.is_videodvd", NULL) )
  223.                 p_dev->i_media_type = MEDIA_TYPE_DVD;
  224.             else if( libhal_device_get_property_bool( p_sys->p_ctx,
  225.                                              matching_media[i],
  226.                                              "volume.disc.is_vcd", NULL) ||
  227.                      libhal_device_get_property_bool( p_sys->p_ctx,
  228.                                              matching_media[i],
  229.                                              "volume.disc.is_svcd", NULL) )
  230.                p_dev->i_media_type = MEDIA_TYPE_VCD;
  231.             else if( libhal_device_get_property_bool( p_sys->p_ctx,
  232.                                              matching_media[i],
  233.                                              "volume.disc.has_audio", NULL) )
  234.                p_dev->i_media_type = MEDIA_TYPE_CDDA;
  235.             break;
  236.         }
  237.     }
  238.     if( b_changed || p_dev->i_media_type != i_old_type )
  239.     {
  240.         /// todo emit changed signal
  241.     }
  242. }