Commit b8cbfbe0 authored by Bastien Nocera's avatar Bastien Nocera
Browse files

pnp-ids: Use udev's hwdb to query PNP IDs

hwdb has its own database which it compiles to binary, so that:
1) initialisation is practically free
See https://git.gnome.org/browse/gnome-settings-daemon/commit/gnome-settings-daemon/gnome-settings-manager.c?id=d8c158e74caea048dea5a38232bd87c1c7a78a70
2) lookups are also quick, as they use a binary DB
3) we don't have to maintain our own copy of the database
4) allows model lookup rather than simply vendor lookup, when the
   database contains that information

The only problem being that non-Linux OSes will need reimplement this
section of the code. This will be on top of the usual downstream patches
they ship for a number of components.

https://bugzilla.gnome.org/show_bug.cgi?id=590059
parent 7bba17f1
......@@ -98,23 +98,6 @@ AC_ARG_ENABLE([debug-tools],
[],[enable_debug_tools=yes])
AM_CONDITIONAL(DEBUG_TOOLS_ENABLED, test "x$enable_debug_tools" = "xyes")
# Path to the pnp.ids file -- to know if we use one shipped with another
# package, or an internal file
AC_ARG_WITH(pnp-ids-path,
[AC_HELP_STRING([--with-pnp-ids-path],
[Specify the path to pnp.ids @<:@default=(internal)@:>@])],,
[with_pnp_ids_path="\${pnpdatadir}/pnp.ids"])
AM_CONDITIONAL(USE_INTERNAL_PNP_IDS, test "x$with_pnp_ids_path" = "x\${pnpdatadir}/pnp.ids")
PNP_IDS=$with_pnp_ids_path
AC_SUBST(PNP_IDS)
if test "x$with_pnp_ids_path" = "x\${pnpdatadir}/pnp.ids"; then
EXTERNAL_PNP_IDS="no (internal)"
else
EXTERNAL_PNP_IDS="$with_pnp_ids_path"
fi
GLIB_TESTS
dnl If you add a version number here, you *must* add an AC_SUBST line for
......@@ -167,7 +150,8 @@ PKG_CHECK_MODULES(GNOME_DESKTOP, gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQUIRED
xrandr >= $XRANDR_REQUIRED
xext >= $XEXT_REQUIRED
xkeyboard-config
iso-codes)
iso-codes
libudev)
XKB_BASE=$($PKG_CONFIG --variable xkb_base xkeyboard-config)
AC_SUBST(XKB_BASE)
......@@ -254,7 +238,6 @@ echo "
Build desktop-wide docs: ${enable_desktop_docs}
Build debug tools: ${enable_debug_tools}
Date in gnome-version.xml: ${enable_date_in_gnome_version}
Use external pnp.ids: ${EXTERNAL_PNP_IDS}
Build gtk-doc documentation: ${enable_gtk_doc}
"
......@@ -94,18 +94,6 @@ libgnome_desktop_HEADERS = \
gnome-idle-monitor.h \
gnome-languages.h
if USE_INTERNAL_PNP_IDS
pnpdatadir = $(datadir)/libgnome-desktop-3.0
pnpdata_DATA = pnp.ids
endif
pnpdata_DATA_dist = pnp.ids
update-pnp-ids:
wget -O $(top_srcdir)/libgnome-desktop/pnp.ids "http://git.fedorahosted.org/git/?p=hwdata.git;a=blob_plain;f=pnp.ids;hb=HEAD"
check:
test -s $(top_srcdir)/libgnome-desktop/pnp.ids
-include $(INTROSPECTION_MAKEFILE)
INTROSPECTION_GIRS =
INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) --warn-all
......@@ -137,11 +125,7 @@ EXTRA_DIST += \
idle-monitor.xml \
xrandr.xml \
gnome-desktop-3.0.pc.in \
gnome-desktop-3.0-uninstalled.pc.in \
$(pnpdata_DATA_dist)
MAINTAINERCLEANFILES = \
pnp.ids
gnome-desktop-3.0-uninstalled.pc.in
gnome_rr_debug_SOURCES = \
gnome-rr-debug.c
......
......@@ -20,8 +20,8 @@
#include "config.h"
#include <glib-object.h>
#include <libgnome-desktop/gnome-pnp-ids.h>
#include <libudev.h>
static void gnome_pnp_ids_finalize (GObject *object);
......@@ -29,221 +29,12 @@ static void gnome_pnp_ids_finalize (GObject *object);
struct _GnomePnpIdsPrivate
{
gchar *table_data;
GHashTable *pnp_table;
struct udev *udev;
struct udev_hwdb *hwdb;
};
static gpointer gnome_pnp_ids_object = NULL;
G_DEFINE_TYPE (GnomePnpIds, gnome_pnp_ids, G_TYPE_OBJECT)
typedef struct Vendor Vendor;
struct Vendor
{
const char vendor_id[4];
const char vendor_name[28];
};
/* This list of vendor codes derived from lshw
*
* http://ezix.org/project/wiki/HardwareLiSter
*
* Note: we now prefer to use data coming from hwdata (and shipped with
* gnome-desktop). See
* http://git.fedorahosted.org/git/?p=hwdata.git;a=blob_plain;f=pnp.ids;hb=HEAD
* All contributions to the list of vendors should go there.
*/
static const struct Vendor vendors[] =
{
{ "AIC", "AG Neovo" },
{ "ACR", "Acer" },
{ "DEL", "DELL" },
{ "SAM", "SAMSUNG" },
{ "SNY", "SONY" },
{ "SEC", "Epson" },
{ "WAC", "Wacom" },
{ "NEC", "NEC" },
{ "CMO", "CMO" }, /* Chi Mei */
{ "BNQ", "BenQ" },
{ "ABP", "Advansys" },
{ "ACC", "Accton" },
{ "ACE", "Accton" },
{ "ADP", "Adaptec" },
{ "ADV", "AMD" },
{ "AIR", "AIR" },
{ "AMI", "AMI" },
{ "ASU", "ASUS" },
{ "ATI", "ATI" },
{ "ATK", "Allied Telesyn" },
{ "AZT", "Aztech" },
{ "BAN", "Banya" },
{ "BRI", "Boca Research" },
{ "BUS", "Buslogic" },
{ "CCI", "Cache Computers Inc." },
{ "CHA", "Chase" },
{ "CMD", "CMD Technology, Inc." },
{ "COG", "Cogent" },
{ "CPQ", "Compaq" },
{ "CRS", "Crescendo" },
{ "CSC", "Crystal" },
{ "CSI", "CSI" },
{ "CTL", "Creative Labs" },
{ "DBI", "Digi" },
{ "DEC", "Digital Equipment" },
{ "DBK", "Databook" },
{ "EGL", "Eagle Technology" },
{ "ELS", "ELSA" },
{ "ESS", "ESS" },
{ "FAR", "Farallon" },
{ "FDC", "Future Domain" },
{ "HWP", "Hewlett-Packard" },
{ "IBM", "IBM" },
{ "INT", "Intel" },
{ "ISA", "Iomega" },
{ "LEN", "Lenovo" },
{ "MDG", "Madge" },
{ "MDY", "Microdyne" },
{ "MET", "Metheus" },
{ "MIC", "Micronics" },
{ "MLX", "Mylex" },
{ "NVL", "Novell" },
{ "OLC", "Olicom" },
{ "PRO", "Proteon" },
{ "RII", "Racal" },
{ "RTL", "Realtek" },
{ "SCM", "SCM" },
{ "SKD", "SysKonnect" },
{ "SGI", "SGI" },
{ "SMC", "SMC" },
{ "SNI", "Siemens Nixdorf" },
{ "STL", "Stallion Technologies" },
{ "SUN", "Sun" },
{ "SUP", "SupraExpress" },
{ "SVE", "SVEC" },
{ "TCC", "Thomas-Conrad" },
{ "TCI", "Tulip" },
{ "TCM", "3Com" },
{ "TCO", "Thomas-Conrad" },
{ "TEC", "Tecmar" },
{ "TRU", "Truevision" },
{ "TOS", "Toshiba" },
{ "TYN", "Tyan" },
{ "UBI", "Ungermann-Bass" },
{ "USC", "UltraStor" },
{ "VDM", "Vadem" },
{ "VMI", "Vermont" },
{ "WDC", "Western Digital" },
{ "ZDS", "Zeos" },
/* From http://faydoc.tripod.com/structures/01/0136.htm */
{ "ACT", "Targa" },
{ "ADI", "ADI" },
{ "AOC", "AOC Intl" },
{ "API", "Acer America" },
{ "APP", "Apple Computer" },
{ "ART", "ArtMedia" },
{ "AST", "AST Research" },
{ "CPL", "Compal" },
{ "CTX", "Chuntex Electronic Co." },
{ "DPC", "Delta Electronics" },
{ "DWE", "Daewoo" },
{ "ECS", "ELITEGROUP" },
{ "EIZ", "EIZO" },
{ "FCM", "Funai" },
{ "GSM", "LG Electronics" },
{ "GWY", "Gateway 2000" },
{ "HEI", "Hyundai" },
{ "HIT", "Hitachi" },
{ "HSL", "Hansol" },
{ "HTC", "Hitachi" },
{ "ICL", "Fujitsu ICL" },
{ "IVM", "Idek Iiyama" },
{ "KFC", "KFC Computek" },
{ "LKM", "ADLAS" },
{ "LNK", "LINK Tech" },
{ "LTN", "Lite-On" },
{ "MAG", "MAG InnoVision" },
{ "MAX", "Maxdata" },
{ "MEI", "Panasonic" },
{ "MEL", "Mitsubishi" },
{ "MIR", "miro" },
{ "MTC", "MITAC" },
{ "NAN", "NANAO" },
{ "NEC", "NEC Tech" },
{ "NOK", "Nokia" },
{ "OQI", "OPTIQUEST" },
{ "PBN", "Packard Bell" },
{ "PGS", "Princeton" },
{ "PHL", "Philips" },
{ "REL", "Relisys" },
{ "SDI", "Samtron" },
{ "SMI", "Smile" },
{ "SPT", "Sceptre" },
{ "SRC", "Shamrock Technology" },
{ "STP", "Sceptre" },
{ "TAT", "Tatung" },
{ "TRL", "Royal Information Company" },
{ "TSB", "Toshiba, Inc." },
{ "UNM", "Unisys" },
{ "VSC", "ViewSonic" },
{ "WTC", "Wen Tech" },
{ "ZCM", "Zenith Data Systems" },
{ "???", "Unknown" },
};
static gboolean
gnome_pnp_ids_load (GnomePnpIds *pnp_ids, GError **error)
{
gchar *retval = NULL;
GnomePnpIdsPrivate *priv = pnp_ids->priv;
guint i;
/* load the contents */
g_debug ("loading: %s", PNP_IDS);
if (g_file_get_contents (PNP_IDS, &priv->table_data, NULL, error) == FALSE)
return FALSE;
/* parse into lines */
retval = priv->table_data;
for (i = 0; priv->table_data[i] != '\0'; i++) {
/* ignore */
if (priv->table_data[i] != '\n')
continue;
/* convert newline to NULL */
priv->table_data[i] = '\0';
/* the ID to text is a fixed offset */
if (retval[0] && retval[1] && retval[2] && retval[3] == '\t' && retval[4]) {
retval[3] = '\0';
g_hash_table_insert (priv->pnp_table,
retval,
retval+4);
retval = &priv->table_data[i+1];
}
}
g_debug ("Added %i items to the vendor hashtable", i);
return TRUE;
}
static const char *
find_vendor (const char *pnp_id)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (vendors); i++) {
if (g_strcmp0 (vendors[i].vendor_id, pnp_id) == 0)
return vendors[i].vendor_name;
}
return NULL;
}
/**
* gnome_pnp_ids_get_pnp_id:
* @pnp_ids: a #GnomePnpIds object
......@@ -258,32 +49,27 @@ gchar *
gnome_pnp_ids_get_pnp_id (GnomePnpIds *pnp_ids, const gchar *pnp_id)
{
GnomePnpIdsPrivate *priv = pnp_ids->priv;
const char *found;
GError *error = NULL;
guint size;
struct udev_list_entry *list_entry, *l;
char *modalias;
char *ret = NULL;
g_return_val_if_fail (GNOME_IS_PNP_IDS (pnp_ids), NULL);
g_return_val_if_fail (pnp_id != NULL, NULL);
modalias = g_strdup_printf ("acpi:%s:", pnp_id);
list_entry = udev_hwdb_get_properties_list_entry(priv->hwdb, modalias, 0);
g_free (modalias);
if (list_entry == NULL)
return ret;
/* if table is empty, try to load it */
size = g_hash_table_size (priv->pnp_table);
if (size == 0) {
if (gnome_pnp_ids_load (pnp_ids, &error) == FALSE) {
g_warning ("Failed to load PNP ids: %s", error->message);
g_error_free (error);
return NULL;
}
}
/* Try to get the model specific string */
l = udev_list_entry_get_by_name (list_entry, "ID_MODEL_FROM_DATABASE");
if (l == NULL)
l = udev_list_entry_get_by_name (list_entry, "ID_VENDOR_FROM_DATABASE");
/* look this up in the table */
found = g_hash_table_lookup (priv->pnp_table, pnp_id);
if (found == NULL) {
found = find_vendor (pnp_id);
if (found == NULL)
return NULL;
}
if (l == NULL)
return ret;
return g_strdup (found);
ret = g_strdup (udev_list_entry_get_value (l));
return ret;
}
static void
......@@ -298,13 +84,8 @@ static void
gnome_pnp_ids_init (GnomePnpIds *pnp_ids)
{
pnp_ids->priv = GNOME_PNP_IDS_GET_PRIVATE (pnp_ids);
/* we don't keep malloc'd data in the hash; instead we read it
* out into priv->table_data and then link to it in the hash */
pnp_ids->priv->pnp_table = g_hash_table_new_full (g_str_hash,
g_str_equal,
NULL,
NULL);
pnp_ids->priv->udev = udev_new();
pnp_ids->priv->hwdb = udev_hwdb_new (pnp_ids->priv->udev);
}
static void
......@@ -313,8 +94,8 @@ gnome_pnp_ids_finalize (GObject *object)
GnomePnpIds *pnp_ids = GNOME_PNP_IDS (object);
GnomePnpIdsPrivate *priv = pnp_ids->priv;
g_free (priv->table_data);
g_hash_table_unref (priv->pnp_table);
g_clear_pointer (&priv->udev, udev_unref);
g_clear_pointer (&priv->hwdb, udev_hwdb_unref);
G_OBJECT_CLASS (gnome_pnp_ids_parent_class)->finalize (object);
}
......@@ -330,12 +111,6 @@ gnome_pnp_ids_finalize (GObject *object)
GnomePnpIds *
gnome_pnp_ids_new (void)
{
if (gnome_pnp_ids_object != NULL) {
g_object_ref (gnome_pnp_ids_object);
} else {
gnome_pnp_ids_object = g_object_new (GNOME_TYPE_PNP_IDS, NULL);
g_object_add_weak_pointer (gnome_pnp_ids_object, &gnome_pnp_ids_object);
}
return GNOME_PNP_IDS (gnome_pnp_ids_object);
return g_object_new (GNOME_TYPE_PNP_IDS, NULL);
}
This diff is collapsed.
......@@ -69,6 +69,7 @@ main (int argc, char *argv[])
if (argc < 2) {
show_vendor (ids, "ELO");
show_vendor (ids, "IBM");
show_vendor (ids, "DEL4085");
}
g_object_unref (ids);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment