diff options
Diffstat (limited to 'hardinfo')
-rw-r--r-- | hardinfo/hardinfo.c | 21 | ||||
-rw-r--r-- | hardinfo/info.c | 248 | ||||
-rw-r--r-- | hardinfo/util.c | 219 | ||||
-rw-r--r-- | hardinfo/vendor.c | 64 |
4 files changed, 400 insertions, 152 deletions
diff --git a/hardinfo/hardinfo.c b/hardinfo/hardinfo.c index 3d7a9c6f..4401a551 100644 --- a/hardinfo/hardinfo.c +++ b/hardinfo/hardinfo.c @@ -33,7 +33,8 @@ int main(int argc, char **argv) { GSList *modules; - bindtextdomain("hardinfo", "/usr/share/locale"); + setlocale(LC_ALL, ""); + bindtextdomain("hardinfo", LOCALEDIR); textdomain("hardinfo"); DEBUG("HardInfo version " VERSION ". Debug version."); @@ -43,19 +44,19 @@ int main(int argc, char **argv) /* show version information and quit */ if (params.show_version) { - g_print("HardInfo version " VERSION "\n"); - g_print - (_("Copyright (C) 2003-2009 Leandro A. F. Pereira. See COPYING for details.\n\n")); + g_print("HardInfo version " VERSION "\n"); + g_print + (_(/*/ %d will be latest year of copyright*/ "Copyright (C) 2003-%d Leandro A. F. Pereira. See COPYING for details.\n\n"), HARDINFO_COPYRIGHT_LATEST_YEAR ); g_print(_("Compile-time options:\n" " Release version: %s (%s)\n" " BinReloc enabled: %s\n" " Data prefix: %s\n" " Library prefix: %s\n" - " Compiled on: %s %s (%s)\n"), + " Compiled for: %s\n"), RELEASE ? _("Yes") : "No (" VERSION ")", ARCH, ENABLE_BINRELOC ? _("Yes") : _("No"), - PREFIX, LIBPREFIX, PLATFORM, KERNEL, HOSTNAME); + PREFIX, LIBPREFIX, PLATFORM); DEBUG(" Debugging is enabled."); @@ -73,7 +74,7 @@ int main(int argc, char **argv) /* list all module names */ if (params.list_modules) { g_print(_("Modules:\n" - "%-20s%-15s%-12s\n"), _("File Name"), _("Name"), _("Version")); + "%-20s %-15s %-12s\n"), _("File Name"), _("Name"), _("Version")); for (modules = modules_load_all(); modules; modules = modules->next) { @@ -81,7 +82,7 @@ int main(int argc, char **argv) ModuleAbout *ma = module_get_about(module); gchar *name = g_path_get_basename(g_module_name(module->dll)); - g_print("%-20s%-15s%-12s\n", name, module->name, ma->version); + g_print("%-20s %-15s %-12s\n", name, module->name, ma->version); g_free(name); } @@ -111,13 +112,13 @@ int main(int argc, char **argv) /* initialize vendor database */ vendor_init(); - + /* initialize moreinfo */ moreinfo_init(); if (params.run_benchmark) { gchar *result; - + result = module_call_method_param("benchmark::runBenchmark", params.run_benchmark); if (!result) { g_error(_("Unknown benchmark ``%s'' or libbenchmark.so not loaded"), params.run_benchmark); diff --git a/hardinfo/info.c b/hardinfo/info.c new file mode 100644 index 00000000..ef64a420 --- /dev/null +++ b/hardinfo/info.c @@ -0,0 +1,248 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2017 Leandro A. F. Pereira <leandro@hardinfo.org> + * + * 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. + * + * 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 + */ + +#include "hardinfo.h" + +static const gchar *info_column_titles[] = { + "TextValue", "Value", "Progress", "Extra1", "Extra2" +}; + +struct Info *info_new(void) +{ + struct Info *info = g_new0(struct Info, 1); + + info->groups = g_array_new(FALSE, FALSE, sizeof(struct InfoGroup)); + info->view_type = SHELL_VIEW_NORMAL; + info->column_headers_visible = FALSE; + info->zebra_visible = FALSE; + info->normalize_percentage = TRUE; + + return info; +} + +void info_add_group(struct Info *info, const gchar *group_name, ...) +{ + struct InfoGroup group = { + .name = group_name, + .fields = g_array_new(FALSE, FALSE, sizeof(struct InfoField)) + }; + va_list ap; + + va_start(ap, group_name); + while (1) { + struct InfoField field = va_arg(ap, struct InfoField ); + + if (!field.name) + break; + g_array_append_val(group.fields, field); + } + va_end(ap); + + g_array_append_val(info->groups, group); +} + +struct InfoField info_field(const gchar *name, gchar *value) +{ + return (struct InfoField) { + .name = name, + .value = value, + }; +} + +struct InfoField info_field_update(const gchar *name, int update_interval) +{ + return (struct InfoField) { + .name = name, + .value = "...", + .update_interval = update_interval, + }; +} + +struct InfoField info_field_printf(const gchar *name, const gchar *format, ...) +{ + gchar *value; + va_list ap; + + va_start(ap, format); + value = g_strdup_vprintf(format, ap); + va_end(ap); + + return (struct InfoField) { + .name = name, + .value = value, + .free_value_on_flatten = TRUE, + }; +} + +struct InfoField info_field_last(void) +{ + return (struct InfoField) {}; +} + +void info_add_computed_group(struct Info *info, const gchar *name, const gchar *value) +{ + /* This is a scaffolding method: HardInfo should move away from pre-computing + * the strings in favor of storing InfoGroups instead; while modules are not + * fully converted, use this instead. */ + struct InfoGroup group = { + .name = name, + .computed = value, + }; + + g_array_append_val(info->groups, group); +} + +void info_set_column_title(struct Info *info, const gchar *column, const gchar *title) +{ + int i; + + for (i = 0; i < G_N_ELEMENTS(info_column_titles); i++) { + if (g_str_equal(info_column_titles[i], column)) { + info->column_titles[i] = title; + return; + } + } +} + +void info_set_column_headers_visible(struct Info *info, gboolean setting) +{ + info->column_headers_visible = setting; +} + +void info_set_zebra_visible(struct Info *info, gboolean setting) +{ + info->zebra_visible = setting; +} + +void info_set_normalize_percentage(struct Info *info, gboolean setting) +{ + info->normalize_percentage = setting; +} + +void info_set_view_type(struct Info *info, ShellViewType setting) +{ + info->view_type = setting; +} + +void info_set_reload_interval(struct Info *info, int setting) +{ + info->reload_interval = setting; +} + +static void flatten_group(GString *output, const struct InfoGroup *group) +{ + guint i; + + g_string_append_printf(output, "[%s]\n", group->name); + + if (group->fields) { + for (i = 0; i < group->fields->len; i++) { + struct InfoField field; + + field = g_array_index(group->fields, struct InfoField, i); + + g_string_append_printf(output, "%s=%s\n", field.name, field.value); + + if (field.free_value_on_flatten) + g_free(field.value); + } + } else if (group->computed) { + g_string_append_printf(output, "%s\n", group->computed); + } +} + +static void flatten_shell_param(GString *output, const struct InfoGroup *group) +{ + guint i; + + if (!group->fields) + return; + + for (i = 0; i < group->fields->len; i++) { + struct InfoField field; + + field = g_array_index(group->fields, struct InfoField, i); + + if (field.update_interval) { + g_string_append_printf(output, "UpdateInterval$%s=%d\n", + field.name, field.update_interval); + } + } +} + +static void flatten_shell_param_global(GString *output, const struct Info *info) +{ + int i; + + g_string_append_printf(output, "ViewType=%d\n", info->view_type); + g_string_append_printf(output, "ShowColumnHeaders=%s\n", + info->column_headers_visible ? "true" : "false"); + + if (info->zebra_visible) + g_string_append(output, "Zebra=1\n"); + + if (info->reload_interval) + g_string_append_printf(output, "ReloadInterval=%d\n", info->reload_interval); + + if (!info->normalize_percentage) + g_string_append(output, "NormalizePercentage=false\n"); + + for (i = 0; i < G_N_ELEMENTS(info_column_titles); i++) { + if (!info->column_titles[i]) + continue; + + g_string_append_printf(output, "ColumnTitle$%s=%s\n", + info_column_titles[i], info->column_titles[i]); + } +} + +gchar *info_flatten(struct Info *info) +{ + /* This is a scaffolding method: eventually the HardInfo shell should + * understand a struct Info instead of parsing these strings, which are + * brittle and unnecessarily complicates things. Being a temporary + * method, no attention is paid to improve the memory allocation + * strategy. */ + GString *values; + GString *shell_param; + guint i; + + values = g_string_new(NULL); + shell_param = g_string_new(NULL); + + if (info->groups) { + for (i = 0; i < info->groups->len; i++) { + struct InfoGroup group = + g_array_index(info->groups, struct InfoGroup, i); + + flatten_group(values, &group); + flatten_shell_param(shell_param, &group); + + if (group.fields) + g_array_free(group.fields, TRUE); + } + + g_array_free(info->groups, TRUE); + } + + flatten_shell_param_global(shell_param, info); + g_string_append_printf(values, "[$ShellParam$]\n%s", shell_param->str); + + g_string_free(shell_param, TRUE); + return g_string_free(values, FALSE); +} diff --git a/hardinfo/util.c b/hardinfo/util.c index dd5af1a4..6ddf56ad 100644 --- a/hardinfo/util.c +++ b/hardinfo/util.c @@ -91,40 +91,49 @@ gchar *find_program(gchar *program_name) gchar *seconds_to_string(unsigned int seconds) { unsigned int hours, minutes, days; + const gchar *days_fmt, *hours_fmt, *minutes_fmt, *seconds_fmt; + gchar *full_fmt, *ret = g_strdup(""); minutes = seconds / 60; + seconds %= 60; hours = minutes / 60; minutes %= 60; days = hours / 24; hours %= 24; - gchar *wminutes; - gchar *whours; - gchar *wdays; - - wdays = ngettext("%d day, ", "%d days, ", days); - whours = ngettext("%d hour, ", "%d hours, ", hours); - wminutes = ngettext("%d minute", "%d minutes", minutes); - if (days < 1) { - if (hours < 1) - return g_strdup_printf(ngettext("%d minute", "%d minutes", minutes), minutes); - return g_strdup_printf(whours, wminutes); + days_fmt = ngettext("%d day", "%d days", days); + hours_fmt = ngettext("%d hour", "%d hours", hours); + minutes_fmt = ngettext("%d minute", "%d minutes", minutes); + seconds_fmt = ngettext("%d second", "%d seconds", seconds); + + if (days) { + full_fmt = g_strdup_printf("%s %s %s %s", days_fmt, hours_fmt, minutes_fmt, seconds_fmt); + ret = g_strdup_printf(full_fmt, days, hours, minutes, seconds); + } else if (hours) { + full_fmt = g_strdup_printf("%s %s %s", hours_fmt, minutes_fmt, seconds_fmt); + ret = g_strdup_printf(full_fmt, hours, minutes, seconds); + } else if (minutes) { + full_fmt = g_strdup_printf("%s %s", minutes_fmt, seconds_fmt); + ret = g_strdup_printf(full_fmt, minutes, seconds); + } else { + ret = g_strdup_printf(seconds_fmt, seconds); } - return g_strdup_printf(wdays, whours, wminutes); + g_free(full_fmt); + return ret; } gchar *size_human_readable(gfloat size) { if (size < KiB) - return g_strdup_printf(_("%.1f B"), size); + return g_strdup_printf(_("%.1f B"), size); if (size < MiB) - return g_strdup_printf(_("%.1f KiB"), size / KiB); + return g_strdup_printf(_("%.1f KiB"), size / KiB); if (size < GiB) - return g_strdup_printf(_("%.1f MiB"), size / MiB); + return g_strdup_printf(_("%.1f MiB"), size / MiB); if (size < TiB) - return g_strdup_printf(_("%.1f GiB"), size / GiB); + return g_strdup_printf(_("%.1f GiB"), size / GiB); if (size < PiB) - return g_strdup_printf(_("%.1f TiB"), size / TiB); + return g_strdup_printf(_("%.1f TiB"), size / TiB); return g_strdup_printf(_("%.1f PiB"), size / PiB); } @@ -160,15 +169,24 @@ void remove_linefeed(gchar * str) void widget_set_cursor(GtkWidget * widget, GdkCursorType cursor_type) { GdkCursor *cursor; - - if ((cursor = gdk_cursor_new(cursor_type))) { - gdk_window_set_cursor(GDK_WINDOW(widget->window), cursor); - gdk_display_flush(gtk_widget_get_display(widget)); + GdkDisplay *display; + GdkWindow *gdk_window; + + display = gtk_widget_get_display(widget); + cursor = gdk_cursor_new_for_display(display, cursor_type); + gdk_window = gtk_widget_get_window(widget); + if (cursor) { + gdk_window_set_cursor(gdk_window, cursor); + gdk_display_flush(display); +#if GTK_CHECK_VERSION(3, 0, 0) + g_object_unref(cursor); +#else gdk_cursor_unref(cursor); +#endif } while (gtk_events_pending()) - gtk_main_iteration(); + gtk_main_iteration(); } static gboolean __nonblock_cb(gpointer data) @@ -721,6 +739,8 @@ static ShellModule *module_load(gchar * filename) entries = get_module_entries(); while (entries[i].name) { + if (*entries[i].name == '#') { i++; continue; } /* skip */ + ShellModuleEntry *entry = g_new0(ShellModuleEntry, 1); if (params.gui_running) { @@ -966,105 +986,6 @@ gint tree_view_get_visible_height(GtkTreeView * tv) return nrows * rect.height; } -void tree_view_save_image(gchar * filename) -{ - /* this is ridiculously complicated :/ why in the hell gtk+ makes this kind of - thing so difficult? */ - - /* FIXME: this does not work if the window (or part of it) isn't visible. does - anyone know how to fix this? :/ */ - Shell *shell = shell_get_main_shell(); - GtkWidget *widget = shell->info->view; - - PangoLayout *layout; - PangoContext *context; - PangoRectangle rect; - - GdkPixmap *pm; - GdkPixbuf *pb; - GdkGC *gc; - GdkColor black = { 0, 0, 0, 0 }; - GdkColor white = { 0, 65535, 65535, 65535 }; - - gint w, h, visible_height; - gchar *tmp; - - gboolean tv_enabled; - - /* present the window */ - gtk_window_present(GTK_WINDOW(shell->window)); - - /* if the treeview is disabled, we need to enable it so we get the - correct colors when saving. we make it insensitive later on if it - was this way before entering this function */ - tv_enabled = GTK_WIDGET_IS_SENSITIVE(widget); - gtk_widget_set_sensitive(widget, TRUE); - - gtk_widget_queue_draw(widget); - - /* unselect things in the information treeview */ - gtk_range_set_value(GTK_RANGE - (GTK_SCROLLED_WINDOW(shell->info->scroll)-> - vscrollbar), 0.0); - gtk_tree_selection_unselect_all(gtk_tree_view_get_selection - (GTK_TREE_VIEW(widget))); - while (gtk_events_pending()) - gtk_main_iteration(); - - /* initialize stuff */ - gc = gdk_gc_new(widget->window); - gdk_gc_set_background(gc, &black); - gdk_gc_set_foreground(gc, &white); - - context = gtk_widget_get_pango_context(widget); - layout = pango_layout_new(context); - - visible_height = tree_view_get_visible_height(GTK_TREE_VIEW(widget)); - - /* draw the title */ - tmp = g_strdup_printf("<b><big>%s</big></b>\n<small>%s</small>", - shell->selected->name, - shell->selected->notefunc(shell->selected-> - number)); - pango_layout_set_markup(layout, tmp, -1); - pango_layout_set_width(layout, widget->allocation.width * PANGO_SCALE); - pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); - pango_layout_get_pixel_extents(layout, NULL, &rect); - - w = widget->allocation.width; - h = visible_height + rect.height; - - pm = gdk_pixmap_new(widget->window, w, rect.height, -1); - gdk_draw_rectangle(GDK_DRAWABLE(pm), gc, TRUE, 0, 0, w, rect.height); - gdk_draw_layout_with_colors(GDK_DRAWABLE(pm), gc, 0, 0, layout, - &white, &black); - - /* copy the pixmap from the treeview and from the title */ - pb = gdk_pixbuf_get_from_drawable(NULL, - widget->window, - NULL, 0, 0, 0, 0, w, h); - pb = gdk_pixbuf_get_from_drawable(pb, - pm, - NULL, - 0, 0, - 0, visible_height, w, rect.height); - - /* save the pixbuf to a png file */ - gdk_pixbuf_save(pb, filename, "png", NULL, - "compression", "9", - "tEXt::hardinfo::version", VERSION, - "tEXt::hardinfo::arch", ARCH, NULL); - - /* unref */ - g_object_unref(pb); - g_object_unref(layout); - g_object_unref(pm); - g_object_unref(gc); - g_free(tmp); - - gtk_widget_set_sensitive(widget, tv_enabled); -} - static gboolean __idle_free_do(gpointer ptr) { g_free(ptr); @@ -1402,3 +1323,59 @@ gboolean g_strv_contains(const gchar * const * strv, const gchar *str) { return 0; } #endif + +/* Hardinfo labels that have # are truncated and/or hidden. + * Labels can't have $ because that is the delimiter in + * moreinfo. */ +gchar *hardinfo_clean_label(const gchar *v, int replacing) { + gchar *clean, *p; + + p = clean = g_strdup(v); + while (*p != 0) { + switch(*p) { + case '#': case '$': + *p = '_'; + break; + default: + break; + } + p++; + } + if (replacing) + g_free((gpointer)v); + return clean; +} + +/* hardinfo uses the values as {ht,x}ml, apparently */ +gchar *hardinfo_clean_value(const gchar *v, int replacing) { + gchar *clean, *tmp; + gchar **vl; + if (v == NULL) return NULL; + + vl = g_strsplit(v, "&", -1); + if (g_strv_length(vl) > 1) + clean = g_strjoinv("&", vl); + else + clean = g_strdup(v); + g_strfreev(vl); + + vl = g_strsplit(clean, "<", -1); + if (g_strv_length(vl) > 1) { + tmp = g_strjoinv("<", vl); + g_free(clean); + clean = tmp; + } + g_strfreev(vl); + + vl = g_strsplit(clean, ">", -1); + if (g_strv_length(vl) > 1) { + tmp = g_strjoinv(">", vl); + g_free(clean); + clean = tmp; + } + g_strfreev(vl); + + if (replacing) + g_free((gpointer)v); + return clean; +} diff --git a/hardinfo/vendor.c b/hardinfo/vendor.c index 86dba97a..47def3f9 100644 --- a/hardinfo/vendor.c +++ b/hardinfo/vendor.c @@ -28,7 +28,8 @@ static const Vendor vendors[] = { {"ATI", "ATI Technologies", "www.ati.com"}, - {"nVidia", "NVIDIA", "www.nvidia.com"}, + {"nVidia", "nVidia", "www.nvidia.com"}, + {"NVidia", "nVidia", "www.nvidia.com"}, {"3Com", "3Com", "www.3com.com"}, {"Intel", "Intel", "www.intel.com"}, {"Cirrus Logic", "Cirrus Logic", "www.cirrus.com"}, @@ -93,6 +94,27 @@ static const Vendor vendors[] = { {"American Megatrends", "American Megatrends", "www.ami.com"}, {"Award", "Award Software International", "www.award-bios.com"}, {"Phoenix", "Phoenix Technologies", "www.phoenix.com"}, + /* x86 vendor strings */ + { "AMDisbetter!", "Advanced Micro Devices", "www.amd.com" }, + { "AuthenticAMD", "Advanced Micro Devices", "www.amd.com" }, + { "CentaurHauls", "VIA (formerly Centaur Technology)", "www.via.tw" }, + { "CyrixInstead", "Cyrix", "" }, + { "GenuineIntel", "Intel", "www.intel.com" }, + { "TransmetaCPU", "Transmeta", "" }, + { "GenuineTMx86", "Transmeta", "" }, + { "Geode by NSC", "National Semiconductor", "" }, + { "NexGenDriven", "NexGen", "" }, + { "RiseRiseRise", "Rise Technology", "" }, + { "SiS SiS SiS", "Silicon Integrated Systems", "" }, + { "UMC UMC UMC", "United Microelectronics Corporation", "" }, + { "VIA VIA VIA", "VIA", "www.via.tw" }, + { "Vortex86 SoC", "DMP Electronics", "" }, + /* x86 VM vendor strings */ + { "KVMKVMKVM", "KVM", "" }, + { "Microsoft Hv", "Microsoft Hyper-V", "www.microsoft.com" }, + { "lrpepyh vr", "Parallels", "" }, + { "VMwareVMware", "VMware", "" }, + { "XenVMMXenVMM", "Xen HVM", "" }, }; static GSList *vendor_list = NULL; @@ -110,48 +132,48 @@ void vendor_init(void) DEBUG("initializing vendor list"); sync_manager_add_entry(&se); - + path = g_build_filename(g_get_home_dir(), ".hardinfo", "vendor.conf", NULL); if (!g_file_test(path, G_FILE_TEST_EXISTS)) { DEBUG("local vendor.conf not found, trying system-wise"); g_free(path); path = g_build_filename(params.path_data, "vendor.conf", NULL); } - + if (g_file_test(path, G_FILE_TEST_EXISTS)) { GKeyFile *vendors; gchar *tmp; gint num_vendors; - + DEBUG("loading %s", path); - + vendors = g_key_file_new(); if (g_key_file_load_from_file(vendors, path, 0, NULL)) { num_vendors = g_key_file_get_integer(vendors, "vendors", "number", NULL); - + for (i = num_vendors - 1; i >= 0; i--) { Vendor *v = g_new0(Vendor, 1); - + tmp = g_strdup_printf("vendor%d", i); - + v->id = g_key_file_get_string(vendors, tmp, "id", NULL); v->name = g_key_file_get_string(vendors, tmp, "name", NULL); v->url = g_key_file_get_string(vendors, tmp, "url", NULL); - + vendor_list = g_slist_prepend(vendor_list, v); - + g_free(tmp); } } - + g_key_file_free(vendors); } else { DEBUG("system-wise vendor.conf not found, using internal database"); - + for (i = G_N_ELEMENTS(vendors) - 1; i >= 0; i--) { vendor_list = g_slist_prepend(vendor_list, (gpointer) &vendors[i]); } - } + } g_free(path); } @@ -159,20 +181,20 @@ void vendor_init(void) const gchar *vendor_get_name(const gchar * id) { GSList *vendor; - + if (!id) { return NULL; } - + for (vendor = vendor_list; vendor; vendor = vendor->next) { Vendor *v = (Vendor *)vendor->data; - + if (v && v->id && strstr(id, v->id)) { - return g_strdup(v->name); + return v->name; } } - return id; + return id; /* What about const? */ } const gchar *vendor_get_url(const gchar * id) @@ -182,12 +204,12 @@ const gchar *vendor_get_url(const gchar * id) if (!id) { return NULL; } - + for (vendor = vendor_list; vendor; vendor = vendor->next) { Vendor *v = (Vendor *)vendor->data; - + if (v && v->id && strstr(id, v->id)) { - return g_strdup(v->url); + return v->url; } } |