diff options
Diffstat (limited to 'modules/devices.c')
-rw-r--r-- | modules/devices.c | 946 |
1 files changed, 946 insertions, 0 deletions
diff --git a/modules/devices.c b/modules/devices.c new file mode 100644 index 00000000..574896ee --- /dev/null +++ b/modules/devices.c @@ -0,0 +1,946 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 L. A. F. Pereira <l@tia.mat.br> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 or later. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __USE_XOPEN +#define __USE_XOPEN +#endif /* __USE_XOPEN */ + +#include <gtk/gtk.h> +#include <config.h> +#include <string.h> + +#include <hardinfo.h> +#include <shell.h> +#include <iconcache.h> +#include <syncmanager.h> + +#include <expr.h> +#include <socket.h> + +#include "devices.h" +#include "dt_util.h" +#include "udisks2_util.h" +#include "storage_util.h" +#include "pci_util.h" + +gchar *callback_processors(); +gchar *callback_gpu(); +gchar *callback_monitors(); +gchar *callback_battery(); +gchar *callback_pci(); +gchar *callback_sensors(); +gchar *callback_printers(); +gchar *callback_storage(); +gchar *callback_input(); +gchar *callback_usb(); +gchar *callback_dmi(); +gchar *callback_dmi_mem(); +gchar *callback_firmware(); +gchar *callback_dtree(); +gchar *callback_device_resources(); + +void scan_processors(gboolean reload); +void scan_gpu(gboolean reload); +void scan_monitors(gboolean reload); +void scan_battery(gboolean reload); +void scan_pci(gboolean reload); +void scan_sensors(gboolean reload); +void scan_printers(gboolean reload); +void scan_storage(gboolean reload); +void scan_input(gboolean reload); +void scan_usb(gboolean reload); +void scan_dmi(gboolean reload); +void scan_dmi_mem(gboolean reload); +void scan_firmware(gboolean reload); +void scan_dtree(gboolean reload); +void scan_device_resources(gboolean reload); + +gboolean root_required_for_resources(void); +gboolean spd_decode_show_hinote(const char**); + +gchar *hi_more_info(gchar *entry); + +enum { + ENTRY_DTREE, + ENTRY_DMI, + ENTRY_PROCESSOR, + ENTRY_GPU, + ENTRY_MONITORS, + ENTRY_DMI_MEM, + ENTRY_PCI, + ENTRY_USB, + ENTRY_FW, + ENTRY_PRINTERS, + ENTRY_BATTERY, + ENTRY_SENSORS, + ENTRY_INPUT, + ENTRY_STORAGE, + ENTRY_RESOURCES +}; + +static ModuleEntry entries[] = { + [ENTRY_PROCESSOR] = {N_("Processor"), "processor.png", callback_processors, scan_processors, MODULE_FLAG_NONE}, + [ENTRY_GPU] = {N_("Graphics Processors"), "devices.png", callback_gpu, scan_gpu, MODULE_FLAG_NONE}, + [ENTRY_MONITORS] = {N_("Monitors"), "monitor.png", callback_monitors, scan_monitors, MODULE_FLAG_NONE}, + [ENTRY_PCI] = {N_("PCI Devices"), "devices.png", callback_pci, scan_pci, MODULE_FLAG_NONE}, + [ENTRY_USB] = {N_("USB Devices"), "usb.png", callback_usb, scan_usb, MODULE_FLAG_NONE}, + [ENTRY_FW] = {N_("Firmware"), "processor.png", callback_firmware, scan_firmware, MODULE_FLAG_NONE}, + [ENTRY_PRINTERS] = {N_("Printers"), "printer.png", callback_printers, scan_printers, MODULE_FLAG_NONE}, + [ENTRY_BATTERY] = {N_("Battery"), "battery.png", callback_battery, scan_battery, MODULE_FLAG_NONE}, + [ENTRY_SENSORS] = {N_("Sensors"), "therm.png", callback_sensors, scan_sensors, MODULE_FLAG_NONE}, + [ENTRY_INPUT] = {N_("Input Devices"), "inputdevices.png", callback_input, scan_input, MODULE_FLAG_NONE}, + [ENTRY_STORAGE] = {N_("Storage"), "hdd.png", callback_storage, scan_storage, MODULE_FLAG_NONE}, + [ENTRY_DMI] = {N_("System DMI"), "computer.png", callback_dmi, scan_dmi, MODULE_FLAG_NONE}, + [ENTRY_DMI_MEM] = {N_("Memory Devices"), "memory.png", callback_dmi_mem, scan_dmi_mem, MODULE_FLAG_NONE}, +#if defined(ARCH_x86) || defined(ARCH_x86_64) + [ENTRY_DTREE] = {N_("Device Tree"), "devices.png", callback_dtree, scan_dtree, MODULE_FLAG_HIDE}, +#else + [ENTRY_DTREE] = {N_("Device Tree"), "devices.png", callback_dtree, scan_dtree, MODULE_FLAG_NONE}, +#endif /* x86 or x86_64 */ + [ENTRY_RESOURCES] = {N_("Resources"), "resources.png", callback_device_resources, scan_device_resources, MODULE_FLAG_NONE}, + { NULL } +}; + +static GSList *processors = NULL; +gchar *printer_list = NULL; +gchar *printer_icons = NULL; +gchar *pci_list = NULL; +gchar *input_list = NULL; +gboolean storage_no_nvme = FALSE; +gchar *storage_list = NULL; +gchar *battery_list = NULL; + +/* in dmi_memory.c */ +gchar *memory_devices_get_info(); +gboolean memory_devices_hinote(const char **msg); +gchar *memory_devices_info = NULL; + +/* in firmware.c */ +gchar *firmware_get_info(); +gboolean firmware_hinote(const char **msg); +gchar *firmware_info = NULL; + +/* in monitors.c */ +gchar *monitors_get_info(); +gboolean monitors_hinote(const char **msg); +gchar *monitors_info = NULL; + +#include <vendor.h> + +extern gchar *gpu_summary; +const gchar *get_gpu_summary() { + if (gpu_summary == NULL) + scan_gpu(FALSE); + return gpu_summary; +} + +static gint proc_cmp_model_name(Processor *a, Processor *b) { + return g_strcmp0(a->model_name, b->model_name); +} + +static gint proc_cmp_max_freq(Processor *a, Processor *b) { + if (a->cpu_mhz == b->cpu_mhz) + return 0; + if (a->cpu_mhz > b->cpu_mhz) + return -1; + return 1; +} + +gchar *processor_describe_default(GSList * processors) +{ + int packs, cores, threads, nodes; + const gchar *packs_fmt, *cores_fmt, *threads_fmt, *nodes_fmt; + gchar *ret, *full_fmt; + + cpu_procs_cores_threads_nodes(&packs, &cores, &threads, &nodes); + + /* NOTE: If this is changed, look at get_cpu_desc() in bench_results.c! */ + + /* if topology info was available, else fallback to old method */ + if (cores > 0) { + packs_fmt = ngettext("%d physical processor", "%d physical processors", packs); + cores_fmt = ngettext("%d core", "%d cores", cores); + threads_fmt = ngettext("%d thread", "%d threads", threads); + if (nodes > 1) { + nodes_fmt = ngettext("%d NUMA node", "%d NUMA nodes", nodes); + full_fmt = g_strdup_printf(_(/*/NP procs; NC cores across NN nodes; NT threads*/ "%s; %s across %s; %s"), packs_fmt, cores_fmt, nodes_fmt, threads_fmt); + ret = g_strdup_printf(full_fmt, packs, cores * nodes, nodes, threads); + } else { + full_fmt = g_strdup_printf(_(/*/NP procs; NC cores; NT threads*/ "%s; %s; %s"), packs_fmt, cores_fmt, threads_fmt); + ret = g_strdup_printf(full_fmt, packs, cores, threads); + } + g_free(full_fmt); + return ret; + } else { + return processor_describe_by_counting_names(processors); + } +} + +gchar *processor_name_default(GSList * processors) +{ + gchar *ret = g_strdup(""); + GSList *tmp, *l; + Processor *p; + gchar *cur_str = NULL; + gint cur_count = 0; + + tmp = g_slist_copy(processors); + tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_model_name); + + for (l = tmp; l; l = l->next) { + p = (Processor*)l->data; + if (cur_str == NULL) { + cur_str = p->model_name; + cur_count = 1; + } else { + if(g_strcmp0(cur_str, p->model_name)) { + ret = h_strdup_cprintf("%s%s", ret, strlen(ret) ? "; " : "", cur_str); + cur_str = p->model_name; + cur_count = 1; + } else { + cur_count++; + } + } + } + ret = h_strdup_cprintf("%s%s", ret, strlen(ret) ? "; " : "", cur_str); + g_slist_free(tmp); + return ret; +} + +/* TODO: prefix counts are threads when they should be cores. */ +gchar *processor_describe_by_counting_names(GSList * processors) +{ + gchar *ret = g_strdup(""); + GSList *tmp, *l; + Processor *p; + gchar *cur_str = NULL; + gint cur_count = 0; + + tmp = g_slist_copy(processors); + tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_model_name); + + for (l = tmp; l; l = l->next) { + p = (Processor*)l->data; + if (cur_str == NULL) { + cur_str = p->model_name; + cur_count = 1; + } else { + if(g_strcmp0(cur_str, p->model_name)) { + ret = h_strdup_cprintf("%s%dx %s", ret, strlen(ret) ? " + " : "", cur_count, cur_str); + cur_str = p->model_name; + cur_count = 1; + } else { + cur_count++; + } + } + } + ret = h_strdup_cprintf("%s%dx %s", ret, strlen(ret) ? " + " : "", cur_count, cur_str); + g_slist_free(tmp); + return ret; +} + +gchar *get_processor_name(void) +{ + scan_processors(FALSE); + return processor_name(processors); +} + +gchar *get_processor_desc(void) +{ + scan_processors(FALSE); + return processor_describe(processors); +} + +gchar *get_processor_name_and_desc(void) +{ + scan_processors(FALSE); + gchar* name = processor_name(processors); + gchar* desc = processor_describe(processors); + gchar* nd = g_strdup_printf("%s\n%s", name, desc); + g_free(name); + g_free(desc); + return nd; +} + +gchar *get_storage_devices_simple(void) +{ + scan_storage(FALSE); + + struct Info *info = info_unflatten(storage_list); + if (!info) { + return ""; + } + + guint i, fi; + struct InfoGroup *group; + struct InfoField *field; + gchar *storage_devs = NULL, *tmp; + const gchar *dev_label, *model_wo_tags; + + GRegex *regex; + regex = g_regex_new ("<.*>", 0, 0, NULL); + + for (i = 0; i < info->groups->len; i++) { + group = &g_array_index(info->groups, struct InfoGroup, info->groups->len - 1); + if (!group) + continue; + + info_group_strip_extra(group); + for (fi = 0; fi < group->fields->len; fi++) { + field = &g_array_index(group->fields, struct InfoField, fi); + if (!field->value) + continue; + + tmp = g_regex_replace(regex, field->value, -1, 0, "", 0, NULL); // remove html tags + storage_devs = h_strdup_cprintf("%s\n", storage_devs, g_strchug(tmp)); + g_free(tmp); + } + } + g_free(info); + + return storage_devs; +} + +gchar *get_storage_devices(void) +{ + scan_storage(FALSE); + + return storage_list; +} + +gchar *get_printers(void) +{ + scan_printers(FALSE); + + return printer_list; +} + +gchar *get_input_devices(void) +{ + scan_input(FALSE); + + return input_list; +} + +gchar *get_processor_count(void) +{ + scan_processors(FALSE); + + return g_strdup_printf("%d", g_slist_length(processors)); +} + +/* TODO: maybe move into processor.c along with processor_name() etc. + * Could mention the big.LITTLE cluster arangement for ARM that kind of thing. + * TODO: prefix counts are threads when they should be cores. */ +gchar *processor_frequency_desc(GSList * processors) +{ + gchar *ret = g_strdup(""); + GSList *tmp, *l; + Processor *p; + float cur_val = -1; + gint cur_count = 0; + + tmp = g_slist_copy(processors); + tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_max_freq); + + for (l = tmp; l; l = l->next) { + p = (Processor*)l->data; + if (cur_val == -1) { + cur_val = p->cpu_mhz; + cur_count = 1; + } else { + if(cur_val != p->cpu_mhz) { + ret = h_strdup_cprintf("%s%dx %.2f %s", ret, strlen(ret) ? " + " : "", cur_count, cur_val, _("MHz") ); + cur_val = p->cpu_mhz; + cur_count = 1; + } else { + cur_count++; + } + } + } + ret = h_strdup_cprintf("%s%dx %.2f %s", ret, strlen(ret) ? " + " : "", cur_count, cur_val, _("MHz")); + g_slist_free(tmp); + return ret; +} + +gchar *get_processor_frequency_desc(void) +{ + scan_processors(FALSE); + return processor_frequency_desc(processors); +} + +gchar *get_processor_max_frequency(void) +{ + GSList *l; + Processor *p; + float max_freq = 0; + + scan_processors(FALSE); + + for (l = processors; l; l = l->next) { + p = (Processor*)l->data; + if (p->cpu_mhz > max_freq) + max_freq = p->cpu_mhz; + } + + if (max_freq == 0.0f) { + return g_strdup(N_("Unknown")); + } else { + return g_strdup_printf("%.2f %s", max_freq, _("MHz") ); + } +} + +gchar *get_motherboard(void) +{ + gchar *board_name, *board_vendor, *board_version; + gchar *product_name, *product_vendor, *product_version; + gchar *board_part = NULL, *product_part = NULL; + const gchar *tmp; + int b = 0, p = 0; + + gchar *ret; + +#if defined(ARCH_x86) || defined(ARCH_x86_64) + scan_dmi(FALSE); + + board_name = dmi_get_str("baseboard-product-name"); + board_version = dmi_get_str("baseboard-version"); + board_vendor = dmi_get_str("baseboard-manufacturer"); + if (board_vendor) { + /* attempt to shorten */ + tmp = vendor_get_shortest_name(board_vendor); + if (tmp && tmp != board_vendor) { + g_free(board_vendor); + board_vendor = g_strdup(tmp); + } + } + + product_name = dmi_get_str("system-product-name"); + product_version = dmi_get_str("system-version"); + product_vendor = dmi_get_str("system-manufacturer"); + if (product_vendor) { + /* attempt to shorten */ + tmp = vendor_get_shortest_name(product_vendor); + if (tmp && tmp != product_vendor) { + g_free(product_vendor); + product_vendor = g_strdup(tmp); + } + } + + if (board_vendor && product_vendor && + strcmp(board_vendor, product_vendor) == 0) { + /* ignore duplicate vendor */ + g_free(product_vendor); + product_vendor = NULL; + } + + if (board_name && product_name && + strcmp(board_name, product_name) == 0) { + /* ignore duplicate name */ + g_free(product_name); + product_name = NULL; + } + + if (board_version && product_version && + strcmp(board_version, product_version) == 0) { + /* ignore duplicate version */ + g_free(product_version); + product_version = NULL; + } + + if (board_name) b += 1; + if (board_vendor) b += 2; + if (board_version) b += 4; + + switch(b) { + case 1: /* only name */ + board_part = g_strdup(board_name); + break; + case 2: /* only vendor */ + board_part = g_strdup(board_vendor); + break; + case 3: /* only name and vendor */ + board_part = g_strdup_printf("%s %s", board_vendor, board_name); + break; + case 4: /* only version? Seems unlikely */ + board_part = g_strdup(board_version); + break; + case 5: /* only name and version? */ + board_part = g_strdup_printf("%s %s", board_name, board_version); + break; + case 6: /* only vendor and version (like lpereira's Thinkpad) */ + board_part = g_strdup_printf("%s %s", board_vendor, board_version); + break; + case 7: /* all */ + board_part = g_strdup_printf("%s %s %s", board_vendor, board_name, board_version); + break; + } + + if (product_name) p += 1; + if (product_vendor) p += 2; + if (product_version) p += 4; + + switch(p) { + case 1: /* only name */ + product_part = g_strdup(product_name); + break; + case 2: /* only vendor */ + product_part = g_strdup(product_vendor); + break; + case 3: /* only name and vendor */ + product_part = g_strdup_printf("%s %s", product_vendor, product_name); + break; + case 4: /* only version? Seems unlikely */ + product_part = g_strdup(product_version); + break; + case 5: /* only name and version? */ + product_part = g_strdup_printf("%s %s", product_name, product_version); + break; + case 6: /* only vendor and version? */ + product_part = g_strdup_printf("%s %s", product_vendor, product_version); + break; + case 7: /* all */ + product_part = g_strdup_printf("%s %s %s", product_vendor, product_name, product_version); + break; + } + + if (board_part && product_part) { + ret = g_strdup_printf("%s (%s)", board_part, product_part); + g_free(board_part); + g_free(product_part); + } else if (board_part) + ret = board_part; + else if (product_part) + ret = product_part; + else + ret = g_strdup(_("(Unknown)")); + + g_free(board_name); + g_free(board_vendor); + g_free(board_version); + g_free(product_name); + g_free(product_vendor); + g_free(product_version); + + return ret; +#endif + + /* use device tree "model" */ + board_vendor = dtr_get_string("/model", 0); + if (board_vendor != NULL) + return board_vendor; + + return g_strdup(_("Unknown")); +} + +const ShellModuleMethod *hi_exported_methods(void) +{ + static const ShellModuleMethod m[] = { + {"getProcessorCount", get_processor_count}, + {"getProcessorName", get_processor_name}, + {"getProcessorDesc", get_processor_desc}, + {"getProcessorNameAndDesc", get_processor_name_and_desc}, + {"getProcessorFrequency", get_processor_max_frequency}, + {"getProcessorFrequencyDesc", get_processor_frequency_desc}, + {"getStorageDevices", get_storage_devices}, + {"getStorageDevicesSimple", get_storage_devices_simple}, + {"getPrinters", get_printers}, + {"getInputDevices", get_input_devices}, + {"getMotherboard", get_motherboard}, + {"getGPUList", get_gpu_summary}, + {NULL}, + }; + + return m; +} + +gchar *hi_more_info(gchar * entry) +{ + gchar *info = moreinfo_lookup_with_prefix("DEV", entry); + + if (info) + return g_strdup(info); + + return g_strdup("?"); +} + +gchar *hi_get_field(gchar * field) +{ + gchar *info = moreinfo_lookup_with_prefix("DEV", field); + if (info) + return g_strdup(info); + + return g_strdup(field); +} + +void scan_dmi(gboolean reload) +{ + SCAN_START(); + __scan_dmi(); + SCAN_END(); +} + +void scan_dmi_mem(gboolean reload) +{ + SCAN_START(); + if (memory_devices_info) + g_free(memory_devices_info); + memory_devices_info = memory_devices_get_info(); + SCAN_END(); +} + +void scan_monitors(gboolean reload) +{ + SCAN_START(); + if (monitors_info) + g_free(monitors_info); + monitors_info = monitors_get_info(); + SCAN_END(); +} + +void scan_firmware(gboolean reload) +{ + SCAN_START(); + if (firmware_info) + g_free(firmware_info); + firmware_info = firmware_get_info(); + SCAN_END(); +} + +void scan_dtree(gboolean reload) +{ + SCAN_START(); + __scan_dtree(); + SCAN_END(); +} + +void scan_processors(gboolean reload) +{ + SCAN_START(); + if (!processors) + processors = processor_scan(); + SCAN_END(); +} + +void scan_battery(gboolean reload) +{ + SCAN_START(); + scan_battery_do(); + SCAN_END(); +} + +void scan_gpu(gboolean reload) +{ + SCAN_START(); + scan_gpu_do(); + SCAN_END(); +} + +void scan_pci(gboolean reload) +{ + SCAN_START(); + scan_pci_do(); + SCAN_END(); +} + +void scan_sensors(gboolean reload) +{ + SCAN_START(); + scan_sensors_do(); + SCAN_END(); +} + +void scan_printers(gboolean reload) +{ + SCAN_START(); + scan_printers_do(); + SCAN_END(); +} + +void scan_storage(gboolean reload) +{ + SCAN_START(); + g_free(storage_list); + storage_list = g_strdup(""); + storage_no_nvme = FALSE; + if (!__scan_udisks2_devices()) { + storage_no_nvme = TRUE; + __scan_ide_devices(); + __scan_scsi_devices(); + } + SCAN_END(); +} + +void scan_input(gboolean reload) +{ + SCAN_START(); + __scan_input_devices(); + SCAN_END(); +} + +void scan_usb(gboolean reload) +{ + SCAN_START(); + __scan_usb(); + SCAN_END(); +} + +gchar *callback_processors() +{ + return processor_get_info(processors); +} + +gchar *callback_dmi() +{ + return g_strdup_printf("%s" + "[$ShellParam$]\n" + "ViewType=5\n", + dmi_info); +} + +gchar *callback_dmi_mem() +{ + return g_strdup(memory_devices_info); +} + +gchar *callback_monitors() +{ + return g_strdup(monitors_info); +} + +gchar *callback_firmware() +{ + return g_strdup(firmware_info); +} + +gchar *callback_dtree() +{ + return g_strdup_printf("%s" + "[$ShellParam$]\n" + "ViewType=1\n", dtree_info); +} + +gchar *callback_battery() +{ + return g_strdup_printf("%s\n" + "[$ShellParam$]\n" + "ViewType=5\n" + "ReloadInterval=4000\n", battery_list); +} + +gchar *callback_pci() +{ + return g_strdup(pci_list); +} + +gchar *callback_gpu() +{ + return g_strdup(gpu_list); +} + +gchar *callback_sensors() +{ + return g_strdup_printf("%s\n" + "[$ShellParam$]\n" + "ViewType=2\n" + "LoadGraphSuffix=\n" + "ColumnTitle$TextValue=%s\n" + "ColumnTitle$Value=%s\n" + "ColumnTitle$Extra1=%s\n" + "ShowColumnHeaders=true\n" + "RescanInterval=5000\n" + "%s\n" + "%s", + sensors, + _("Sensor"), _("Value"), + SENSORS_GROUP_BY_TYPE ? _("Driver"): _("Type"), + lginterval, + sensor_icons); +} + +gchar *callback_printers() +{ + return g_strdup_printf("%s\n" + "[$ShellParam$]\n" + "ViewType=1\n" + "ReloadInterval=5000\n" + "%s", printer_list, printer_icons); +} + +gchar *callback_storage() +{ + return g_strdup_printf("%s\n" + "[$ShellParam$]\n" + "ReloadInterval=5000\n" + "ColumnTitle$TextValue=%s\n" + "ColumnTitle$Value=%s\n" + "ColumnTitle$Extra1=%s\n" + "ShowColumnHeaders=true\n" + "ViewType=1\n%s", storage_list, _("Device"), _("Size"), _("Model"), storage_icons); +} + +gchar *callback_input() +{ + return g_strdup_printf("[Input Devices]\n" + "%s" + "[$ShellParam$]\n" + "ViewType=1\n" + "ColumnTitle$TextValue=%s\n" + "ColumnTitle$Value=%s\n" + "ColumnTitle$Extra1=%s\n" + "ShowColumnHeaders=true\n" + "ReloadInterval=5000\n%s", + input_list, _("Device"), _("Vendor"), _("Type"), + input_icons); +} + +gchar *callback_usb() +{ + return g_strdup_printf("%s" + "[$ShellParam$]\n" + "ViewType=1\n" + "ReloadInterval=5000\n%s", usb_list, usb_icons); + +} + +ModuleEntry *hi_module_get_entries(void) +{ + return entries; +} + +gchar *hi_module_get_name(void) +{ + return g_strdup(_("Devices")); +} + +guchar hi_module_get_weight(void) +{ + return 85; +} + +void hi_module_init(void) +{ + static SyncEntry entries[] = { + { + .name = N_("Update PCI ID listing"), + .file_name = "pci.ids", + }, + { + .name = N_("Update USB ID listing"), + .file_name = "usb.ids", + }, + { + .name = N_("Update EDID vendor codes"), + .file_name = "edid.ids", + }, + { + .name = N_("Update IEEE OUI vendor codes"), + .file_name = "ieee_oui.ids", + }, + { + .name = N_("Update SD card manufacturer information"), + .file_name = "sdcard.ids", + }, +#ifdef ARCH_x86 + { + .name = N_("Update CPU flags database"), + .file_name = "cpuflags.json", + }, +#endif + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS(entries); i++) + sync_manager_add_entry(&entries[i]); + + init_cups(); + sensor_init(); + udisks2_init(); + +#ifdef ARCH_x86 + void cpuflags_x86_init(void); + cpuflags_x86_init(); +#endif +} + +void hi_module_deinit(void) +{ + moreinfo_del_with_prefix("DEV"); + sensor_shutdown(); + storage_shutdown(); + udisks2_shutdown(); + if(cups) g_module_close(cups); +} + +const ModuleAbout *hi_module_get_about(void) +{ + static const ModuleAbout ma = { + .author = "L. A. F. Pereira", + .description = N_("Gathers information about hardware devices"), + .version = VERSION, + .license = "GNU GPL version 2 or later.", + }; + + return &ma; +} + +gchar **hi_module_get_dependencies(void) +{ + static gchar *deps[] = { "computer.so", NULL }; + + return deps; +} + +const gchar *hi_note_func(gint entry) +{ + if (entry == ENTRY_PCI + || entry == ENTRY_GPU) { + const gchar *ids = find_pci_ids_file(); + if (!ids) { + return g_strdup(_("A copy of <i><b>pci.ids</b></i> is not available on the system.")); + } + if (ids && strstr(ids, ".min")) { + return g_strdup(_("A full <i><b>pci.ids</b></i> is not available on the system.")); + } + } + if (entry == ENTRY_RESOURCES) { + if (root_required_for_resources()) { + return g_strdup(_("Resource information requires superuser privileges")); + } + } + else if (entry == ENTRY_STORAGE){ + if (storage_no_nvme) { + return g_strdup( + _("Any NVMe storage devices present are not listed.\n" + "<b><i>udisksd</i></b> is required for NVMe devices.")); + } + } + else if (entry == ENTRY_DMI_MEM){ + const char *msg; + if (memory_devices_hinote(&msg)) { + return msg; + } + } + else if (entry == ENTRY_FW) { + const char *msg; + if (firmware_hinote(&msg)) { + return msg; + } + } + return NULL; +} |