diff options
Diffstat (limited to 'src/udev-mgr.c')
-rw-r--r-- | src/udev-mgr.c | 546 |
1 files changed, 0 insertions, 546 deletions
diff --git a/src/udev-mgr.c b/src/udev-mgr.c deleted file mode 100644 index 5f197d6..0000000 --- a/src/udev-mgr.c +++ /dev/null @@ -1,546 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran <conor.curran@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <gudev/gudev.h> - -#include <glib/gi18n.h> - -#include "udev-mgr.h" -#include "sane-rules.h" - -static void udevice_mgr_device_list_iterator (gpointer data, - gpointer userdata); -static void udev_mgr_uevent_cb (GUdevClient *client, - gchar *action, - GUdevDevice *device, - gpointer user_data); -static void udev_mgr_update_menuitems (UdevMgr* self); -static void udev_mgr_check_if_usb_device_is_supported (UdevMgr* self, - GUdevDevice *device, - UdevMgrDeviceAction action); -static void udev_mgr_handle_webcam (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action); -static void udev_mgr_handle_scsi_device (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action); - -static void udev_mgr_cleanup_lists(gpointer data, gpointer self); -static void udev_mgr_cleanup_entries(gpointer data, gpointer self); - - -static void debug_device (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action); - -static gchar* format_device_name (UdevMgr* self, - const gchar* brand, - const gchar* generic, - const gchar* branded) G_GNUC_WARN_UNUSED_RESULT; -struct _UdevMgr -{ - GObject parent_instance; - DbusmenuMenuitem* scanner_item; - DbusmenuMenuitem* webcam_item; - GUdevClient* client; - GHashTable* supported_usb_scanners; - GHashTable* supported_scsi_scanners; - GHashTable* scanners_present; - GHashTable* webcams_present; -}; - -const char *subsystems[3] = {"usb", "scsi", "video4linux"}; -const gchar* usb_subsystem = "usb"; -const gchar* scsi_subsystem = "scsi"; -const gchar* video4linux_subsystem = "video4linux"; - - -G_DEFINE_TYPE (UdevMgr, udev_mgr, G_TYPE_OBJECT); - -static void -udev_mgr_init (UdevMgr* self) -{ - self->client = NULL; - self->supported_usb_scanners = NULL; - self->scanners_present = NULL; - self->webcams_present = NULL; - self->client = g_udev_client_new (subsystems); - self->supported_usb_scanners = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - (GDestroyNotify)udev_mgr_cleanup_lists); - self->supported_scsi_scanners = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - (GDestroyNotify)udev_mgr_cleanup_lists); - self->scanners_present = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_free); - self->webcams_present = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_free); - - // load into memory all supported scanners ... - populate_usb_scanners (self->supported_usb_scanners); - populate_scsi_scanners (self->supported_scsi_scanners); - g_signal_connect (G_OBJECT (self->client), - "uevent", - G_CALLBACK (udev_mgr_uevent_cb), - self); -} - -static void -udev_mgr_cleanup_lists(gpointer data, gpointer self) -{ - GList* scanners = (GList*)data; - g_list_foreach (scanners, udev_mgr_cleanup_entries, NULL); - g_list_free(scanners); -} - -static void -udev_mgr_cleanup_entries(gpointer data, gpointer self) -{ - gchar* entry = (gchar*)data; - g_free(entry); -} - -static void -udev_mgr_finalize (GObject *object) -{ - UdevMgr* self = UDEV_MGR (object); - g_hash_table_destroy (self->supported_scsi_scanners); - g_hash_table_destroy (self->supported_usb_scanners); - g_hash_table_destroy (self->scanners_present); - g_hash_table_destroy (self->webcams_present); - G_OBJECT_CLASS (udev_mgr_parent_class)->finalize (object); -} - -static void -udev_mgr_class_init (UdevMgrClass *klass) -{ - GObjectClass* object_class = G_OBJECT_CLASS (klass); - object_class->finalize = udev_mgr_finalize; -} - -static void -udevice_mgr_device_list_iterator (gpointer data, gpointer userdata) -{ - g_return_if_fail (G_UDEV_IS_DEVICE (data)); - g_return_if_fail (UDEV_IS_MGR (userdata)); - - UdevMgr* self = UDEV_MGR (userdata); - - GUdevDevice* device = G_UDEV_DEVICE (data); - - const gchar* subsystem = NULL; - subsystem = g_udev_device_get_subsystem (device); - - if (g_strcmp0 (subsystem, "usb") == 0){ - udev_mgr_check_if_usb_device_is_supported (self, device, ADD); - } - else if (g_strcmp0 (subsystem, "video4linux") == 0){ - udev_mgr_handle_webcam (self, device, ADD); - } - else if (g_strcmp0 (subsystem, "scsi") == 0){ - udev_mgr_handle_scsi_device (self, device, ADD); - } - - g_object_unref (device); -} - - -static void udev_mgr_update_menuitems (UdevMgr* self) -{ - dbusmenu_menuitem_property_set_bool (self->scanner_item, - DBUSMENU_MENUITEM_PROP_VISIBLE, - g_hash_table_size (self->scanners_present) > 0); - - dbusmenu_menuitem_property_set_bool (self->webcam_item, - DBUSMENU_MENUITEM_PROP_VISIBLE, - g_hash_table_size (self->webcams_present) > 0); - -} - -static void udev_mgr_uevent_cb (GUdevClient *client, - gchar *action, - GUdevDevice *device, - gpointer user_data) -{ - g_return_if_fail (UDEV_IS_MGR (user_data)); - UdevMgr* self = UDEV_MGR (user_data); - g_return_if_fail (device != NULL); - - g_debug ("just received a UEVENT with an action : %s", action); - - UdevMgrDeviceAction udev_mgr_action = ADD; - - if (g_strcmp0 (action, "remove") == 0){ - udev_mgr_action = REMOVE; - } - - const gchar* subsystem = NULL; - subsystem = g_udev_device_get_subsystem (device); - - if (g_strcmp0 (subsystem, "usb") == 0){ - udev_mgr_check_if_usb_device_is_supported (self, - device, - udev_mgr_action); - } - else if (g_strcmp0 (subsystem, "video4linux") == 0){ - udev_mgr_handle_webcam (self, device, udev_mgr_action); - } - else if (g_strcmp0 (subsystem, "scsi") == 0){ - udev_mgr_handle_scsi_device (self, device, udev_mgr_action); - } -} - - -static void -udev_mgr_handle_webcam (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action) -{ - if (FALSE) - debug_device (self, device, action); - - const gchar* vendor; - const gchar* product; - - vendor = g_udev_device_get_property (device, "ID_VENDOR_ID"); - product = g_udev_device_get_property (device, "ID_MODEL_ID"); - - if (!vendor || !product) { - return; - } - - if (action == REMOVE){ - if (g_hash_table_lookup (self->webcams_present, product) == NULL){ - g_warning ("Got a remove event on a webcam device but we don't have that device in our webcam cache"); - return; - } - g_hash_table_remove (self->webcams_present, - product); - dbusmenu_menuitem_property_set (self->webcam_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Webcam")); - } - else { - if (g_hash_table_lookup (self->webcams_present, product) != NULL){ - g_warning ("Got an ADD event on a webcam device but we already have that device in our webcam cache"); - return; - } - - const gchar* manufacturer = NULL; - manufacturer = g_udev_device_get_property (device, "ID_VENDOR"); - - if (manufacturer != NULL){ - gchar * label = format_device_name(self, manufacturer, _("Webcam"), _("%s Webcam")); - dbusmenu_menuitem_property_set (self->webcam_item, - DBUSMENU_MENUITEM_PROP_LABEL, - label); - g_free(label); - } - - g_hash_table_insert (self->webcams_present, - g_strdup (product), - g_strdup (vendor)); - } - udev_mgr_update_menuitems (self); -} - -static void -debug_device (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action) -{ - const gchar* vendor; - const gchar* product; - const gchar* number; - const gchar* name; - const gchar* manufacturer; - - vendor = g_udev_device_get_property (device, "ID_VENDOR_ID"); - manufacturer = g_udev_device_get_property (device, "ID_VENDOR"); - product = g_udev_device_get_property (device, "ID_MODEL_ID"); - number = g_udev_device_get_number (device); - name = g_udev_device_get_name (device); - - g_debug ("%s device vendor id %s , product id of %s , number of %s and name of %s", - g_strdup(manufacturer), - g_strdup(vendor), - g_strdup(product), - g_strdup(number), - g_strdup(name)); - - /*const gchar *const *list; - const gchar *const *iter; - char propstr[500]; - guint32 namelen = 0, i; - - list = g_udev_device_get_property_keys(device); - - for (iter = list; iter && *iter; iter++) { - if (strlen(*iter) > namelen) - namelen = strlen(*iter); - } - namelen++; - - for (iter = list; iter && *iter; iter++) { - strcpy(propstr, *iter); - strcat(propstr, ":"); - for (i = 0; i < namelen - strlen(*iter); i++) - strcat(propstr, " "); - strcat(propstr, g_udev_device_get_property(device, *iter)); - g_debug("%s", propstr); - }*/ -} -// TODO SCSI is not dynamic right ? -// i.e. just need to handle startup scan. -static void udev_mgr_handle_scsi_device (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action) -{ - const gchar* type = NULL; - type = g_udev_device_get_property (device, "TYPE"); - - if (!type) { - return; - } - - // apparently anything thats type 6 and SCSI is a Scanner - if (g_strcmp0 (type, "6") == 0 && action == ADD){ - - const gchar* manufacturer = NULL; - manufacturer = g_udev_device_get_property (device, "ID_VENDOR"); - - if (manufacturer != NULL){ - gchar * label = format_device_name(self, manufacturer, _("Scanner"), _("%s Scanner")); - dbusmenu_menuitem_property_set (self->scanner_item, - DBUSMENU_MENUITEM_PROP_LABEL, - label); - g_free(label); - } - - gchar* random_scanner_name = g_strdup_printf("%p--scanner", self); - g_hash_table_insert (self->scanners_present, - random_scanner_name, - g_strdup("Scanner")); - udev_mgr_update_menuitems (self); - return; - } - - // We only care about type 3 for the special cases below - if (g_strcmp0 (type, "3") != 0){ - return; - } - - const gchar* vendor = NULL; - vendor = g_udev_device_get_property (device, "VENDOR"); - - if (vendor == NULL) - return; - - GList* vendor_list = NULL; - vendor_list = g_hash_table_lookup (self->supported_scsi_scanners, - (gpointer)vendor); - if (vendor_list == NULL) - return; - - const gchar* model_id = NULL; - model_id = g_udev_device_get_property (device, "MODEL"); - - if (model_id == NULL) - return; - - GList* model_entry = NULL; - model_entry = g_list_find_custom (vendor_list, - model_id, - (GCompareFunc)g_strcmp0); - - if (model_entry != NULL){ - if (action == REMOVE){ - if (g_hash_table_lookup (self->scanners_present, g_strdup(vendor)) == NULL){ - g_warning ("Got an REMOVE event on a scanner device but we dont have that device in our scanners cache"); - } - else{ - g_hash_table_remove (self->scanners_present, vendor); - dbusmenu_menuitem_property_set (self->scanner_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Scanner")); - - } - } - else{ - if (g_hash_table_lookup (self->scanners_present, g_strdup(vendor)) != NULL){ - g_warning ("Got an ADD event on a scanner device but we already have that device in our scanners cache"); - } - else{ - const gchar* manufacturer = NULL; - manufacturer = g_udev_device_get_property (device, "ID_VENDOR"); - - if (manufacturer != NULL){ - gchar * label = format_device_name(self, manufacturer, _("Scanner"), _("%s Scanner")); - dbusmenu_menuitem_property_set (self->scanner_item, - DBUSMENU_MENUITEM_PROP_LABEL, - label); - g_free(label); - } - g_hash_table_insert (self->scanners_present, - g_strdup(vendor), - g_strdup(model_id)); - } - } - udev_mgr_update_menuitems (self); - } -} - -static void -udev_mgr_check_if_usb_device_is_supported (UdevMgr* self, - GUdevDevice *device, - UdevMgrDeviceAction action) -{ - const gchar* vendor = NULL; - //debug_device (self, device, action); - - vendor = g_udev_device_get_property (device, "ID_VENDOR_ID"); - - if (vendor == NULL) - return; - - //g_debug ("vendor = %s", vendor); - - GList* vendor_list = NULL; - vendor_list = g_hash_table_lookup (self->supported_usb_scanners, - (gpointer)vendor); - if (vendor_list == NULL) - return; - - const gchar* model_id = NULL; - model_id = g_udev_device_get_property (device, "ID_MODEL_ID"); - - if (model_id == NULL) - return; - - GList* model_entry = NULL; - model_entry = g_list_find_custom(vendor_list, model_id, (GCompareFunc)g_strcmp0); - - if (model_entry != NULL){ - if (action == REMOVE){ - if (g_hash_table_lookup (self->scanners_present, g_strdup(vendor)) == NULL){ - g_warning ("Got an REMOVE event on a scanner device but we dont have that device in our scanners cache"); - } - else{ - g_hash_table_remove (self->scanners_present, vendor); - dbusmenu_menuitem_property_set (self->scanner_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Scanner")); - } - } - else{ - if (g_hash_table_lookup (self->scanners_present, g_strdup(vendor)) != NULL){ - g_warning ("Got an ADD event on a scanner device but we already have that device in our scanners cache"); - } - else{ - const gchar* manufacturer = NULL; - - manufacturer = g_udev_device_get_property (device, "ID_VENDOR"); - if (manufacturer != NULL){ - gchar * label = format_device_name(self, manufacturer, _("Scanner"), _("%s Scanner")); - dbusmenu_menuitem_property_set (self->scanner_item, - DBUSMENU_MENUITEM_PROP_LABEL, - label); - g_free(label); - } - - g_hash_table_insert (self->scanners_present, - g_strdup(vendor), - g_strdup(model_id)); - } - } - udev_mgr_update_menuitems (self); - } -} - -UdevMgr* udev_mgr_new (DbusmenuMenuitem* scanner, - DbusmenuMenuitem* webcam) -{ - UdevMgr* mgr = g_object_new (UDEV_TYPE_MGR, NULL); - mgr->scanner_item = scanner; - mgr->webcam_item = webcam; - - // Check for USB devices - GList* usb_devices_available = NULL; - usb_devices_available = g_udev_client_query_by_subsystem (mgr->client, - usb_subsystem); - if (usb_devices_available != NULL){ - g_list_foreach (usb_devices_available, - udevice_mgr_device_list_iterator, - mgr); - - g_list_free (usb_devices_available); - } - // Check for webcams - GList* video_devices_available = NULL; - video_devices_available = g_udev_client_query_by_subsystem (mgr->client, - video4linux_subsystem); - if (video_devices_available != NULL){ - g_list_foreach (video_devices_available, - udevice_mgr_device_list_iterator, - mgr); - - g_list_free (video_devices_available); - } - // Check for SCSI devices - GList* scsi_devices_available = NULL; - scsi_devices_available = g_udev_client_query_by_subsystem (mgr->client, - scsi_subsystem); - if (scsi_devices_available != NULL){ - g_list_foreach (scsi_devices_available, - udevice_mgr_device_list_iterator, - mgr); - g_list_free (scsi_devices_available); - } - return mgr; -} - -static gchar* format_device_name (UdevMgr* self, - const gchar* brand, - const gchar* generic, - const gchar* branded) -{ - // We don't want to accommodate long names - if (strlen(brand) > 7) - return g_strdup(generic); - - gint i = 0; - - // If it contains something other than an alphabetic entry ignore it. - for(i = 0; i < sizeof(brand); i++){ - if ( !g_ascii_isalpha (brand[i]) ) - return g_strdup(generic); - } - - gchar* lowered = g_ascii_strdown (brand, -1); - lowered[0] = g_ascii_toupper (lowered[0]); - gchar* label = g_strdup_printf(branded, lowered); - g_free (lowered); - return label; -} |