summaryrefslogtreecommitdiff
path: root/hardinfo2
diff options
context:
space:
mode:
Diffstat (limited to 'hardinfo2')
-rw-r--r--hardinfo2/Makefile.in42
-rw-r--r--hardinfo2/arch/common/display.h137
-rw-r--r--hardinfo2/arch/common/fib.h50
-rw-r--r--hardinfo2/arch/common/languages.h99
-rw-r--r--hardinfo2/arch/common/md5.h62
-rw-r--r--hardinfo2/arch/common/printers.h67
-rw-r--r--hardinfo2/arch/common/sha1.h61
-rw-r--r--hardinfo2/arch/common/zlib.h81
-rw-r--r--hardinfo2/arch/linux/common/alsa.h69
-rw-r--r--hardinfo2/arch/linux/common/filesystem.h103
-rw-r--r--hardinfo2/arch/linux/common/inputdevices.h117
-rw-r--r--hardinfo2/arch/linux/common/loadavg.h47
-rw-r--r--hardinfo2/arch/linux/common/memory.h56
-rw-r--r--hardinfo2/arch/linux/common/modules.h129
-rw-r--r--hardinfo2/arch/linux/common/os.h186
-rw-r--r--hardinfo2/arch/linux/common/pci.h189
-rw-r--r--hardinfo2/arch/linux/common/samba.h80
-rw-r--r--hardinfo2/arch/linux/common/sensors.h237
-rw-r--r--hardinfo2/arch/linux/common/storage.h268
-rw-r--r--hardinfo2/arch/linux/common/uptime.h75
-rw-r--r--hardinfo2/arch/linux/common/usb.h132
l---------hardinfo2/arch/linux/x86/alsa.h1
l---------hardinfo2/arch/linux/x86/filesystem.h1
l---------hardinfo2/arch/linux/x86/inputdevices.h1
l---------hardinfo2/arch/linux/x86/loadavg.h1
l---------hardinfo2/arch/linux/x86/memory.h1
l---------hardinfo2/arch/linux/x86/modules.h1
l---------hardinfo2/arch/linux/x86/os.h1
l---------hardinfo2/arch/linux/x86/pci.h1
-rw-r--r--hardinfo2/arch/linux/x86/processor.h257
l---------hardinfo2/arch/linux/x86/samba.h1
l---------hardinfo2/arch/linux/x86/sensors.h1
l---------hardinfo2/arch/linux/x86/storage.h1
l---------hardinfo2/arch/linux/x86/uptime.h1
l---------hardinfo2/arch/linux/x86/usb.h1
l---------hardinfo2/arch/linux/x86_641
-rw-r--r--hardinfo2/benchmark.c150
-rw-r--r--hardinfo2/benchmark.conf29
-rw-r--r--hardinfo2/benchmark.databin0 -> 65536 bytes
-rw-r--r--hardinfo2/callbacks.c72
-rw-r--r--hardinfo2/callbacks.h29
-rw-r--r--hardinfo2/computer.c363
-rw-r--r--hardinfo2/computer.h165
-rwxr-xr-xhardinfo2/configure162
-rw-r--r--hardinfo2/devices.c193
-rw-r--r--hardinfo2/expr.c241
-rw-r--r--hardinfo2/expr.h48
-rw-r--r--hardinfo2/hardinfo.c41
-rw-r--r--hardinfo2/hardinfo.h35
-rw-r--r--hardinfo2/iconcache.c80
-rw-r--r--hardinfo2/iconcache.h30
-rw-r--r--hardinfo2/loadgraph.c266
-rw-r--r--hardinfo2/loadgraph.h61
-rw-r--r--hardinfo2/md5.c313
-rw-r--r--hardinfo2/md5.h26
-rw-r--r--hardinfo2/menu.c125
-rw-r--r--hardinfo2/menu.h24
-rw-r--r--hardinfo2/modules.conf7
-rw-r--r--hardinfo2/pixmaps/2computer.pngbin0 -> 988 bytes
-rw-r--r--hardinfo2/pixmaps/athlon.pngbin0 -> 836 bytes
-rw-r--r--hardinfo2/pixmaps/audio.pngbin0 -> 1414 bytes
-rw-r--r--hardinfo2/pixmaps/benchmark.pngbin0 -> 946 bytes
-rw-r--r--hardinfo2/pixmaps/cdrom.pngbin0 -> 1235 bytes
-rw-r--r--hardinfo2/pixmaps/compress.pngbin0 -> 689 bytes
-rw-r--r--hardinfo2/pixmaps/computer.pngbin0 -> 937 bytes
-rw-r--r--hardinfo2/pixmaps/dev_removable.pngbin0 -> 815 bytes
-rw-r--r--hardinfo2/pixmaps/devices.pngbin0 -> 1005 bytes
-rw-r--r--hardinfo2/pixmaps/gnome-dev-removable-usb.pngbin0 -> 966 bytes
-rw-r--r--hardinfo2/pixmaps/gnome-devel.pngbin0 -> 959 bytes
-rw-r--r--hardinfo2/pixmaps/gnome-terminal.pngbin0 -> 1077 bytes
-rw-r--r--hardinfo2/pixmaps/gnome-window-manager.pngbin0 -> 550 bytes
-rw-r--r--hardinfo2/pixmaps/graphics.pngbin0 -> 1499 bytes
-rw-r--r--hardinfo2/pixmaps/hdd.pngbin0 -> 793 bytes
-rw-r--r--hardinfo2/pixmaps/joystick.pngbin0 -> 754 bytes
-rw-r--r--hardinfo2/pixmaps/kblayout.pngbin0 -> 899 bytes
-rw-r--r--hardinfo2/pixmaps/keyboard.pngbin0 -> 1164 bytes
-rw-r--r--hardinfo2/pixmaps/language.pngbin0 -> 1145 bytes
-rw-r--r--hardinfo2/pixmaps/logo.pngbin0 -> 3182 bytes
-rw-r--r--hardinfo2/pixmaps/memory.pngbin0 -> 1044 bytes
-rw-r--r--hardinfo2/pixmaps/modem.pngbin0 -> 1669 bytes
-rw-r--r--hardinfo2/pixmaps/module.pngbin0 -> 1049 bytes
-rw-r--r--hardinfo2/pixmaps/monitor.pngbin0 -> 981 bytes
-rw-r--r--hardinfo2/pixmaps/mouse.pngbin0 -> 922 bytes
-rw-r--r--hardinfo2/pixmaps/network.pngbin0 -> 739 bytes
-rw-r--r--hardinfo2/pixmaps/os.pngbin0 -> 1094 bytes
-rw-r--r--hardinfo2/pixmaps/pcmcia.pngbin0 -> 873 bytes
-rw-r--r--hardinfo2/pixmaps/printer.pngbin0 -> 1015 bytes
-rw-r--r--hardinfo2/pixmaps/processor.pngbin0 -> 1409 bytes
-rw-r--r--hardinfo2/pixmaps/report.pngbin0 -> 853 bytes
-rw-r--r--hardinfo2/pixmaps/shares.pngbin0 -> 990 bytes
-rw-r--r--hardinfo2/pixmaps/stock_channel.pngbin0 -> 1156 bytes
-rw-r--r--hardinfo2/pixmaps/stock_insert-floating-frame.pngbin0 -> 321 bytes
-rw-r--r--hardinfo2/pixmaps/stock_landline-phone.pngbin0 -> 1488 bytes
-rw-r--r--hardinfo2/pixmaps/stock_macro-watch-variable.pngbin0 -> 543 bytes
-rw-r--r--hardinfo2/pixmaps/summary.pngbin0 -> 966 bytes
-rw-r--r--hardinfo2/pixmaps/therm.pngbin0 -> 954 bytes
-rw-r--r--hardinfo2/pixmaps/usb.pngbin0 -> 936 bytes
-rw-r--r--hardinfo2/pixmaps/users.pngbin0 -> 1499 bytes
-rw-r--r--hardinfo2/pixmaps/videocap.pngbin0 -> 1724 bytes
-rw-r--r--hardinfo2/sha1.c336
-rw-r--r--hardinfo2/sha1.h21
-rw-r--r--hardinfo2/shell.c1071
-rw-r--r--hardinfo2/shell.h137
-rw-r--r--hardinfo2/stock.c81
-rw-r--r--hardinfo2/stock.h29
-rw-r--r--hardinfo2/uidefs.xml29
-rw-r--r--hardinfo2/util.c50
107 files changed, 6772 insertions, 0 deletions
diff --git a/hardinfo2/Makefile.in b/hardinfo2/Makefile.in
new file mode 100644
index 00000000..b4284da1
--- /dev/null
+++ b/hardinfo2/Makefile.in
@@ -0,0 +1,42 @@
+
+CC = gcc -fPIC
+CFLAGS = -Wall -g $(GTK_CFLAGS) $(GLADE_CFLAGS) -I.
+
+# ----------------------------------------------------------------------------
+
+OBJECTS = hardinfo.o shell.o util.o iconcache.o loadgraph.o sha1.o md5.o \
+ menu.o stock.o callbacks.o expr.o
+MODULES = computer.so devices.so benchmark.so
+
+all: $(OBJECTS) $(MODULES)
+ $(CC) $(CFLAGS) -o hardinfo -Wl,-export-dynamic $(OBJECTS) $(GTK_LIBS) $(GTK_FLAGS) \
+ $(GLADE_LIBS) $(GLADE_FLAGS)
+
+ # Creating FIXME file
+ rm -fr FIXME && fgrep -nir "FIXME" * |grep -v Makefile |grep -v svn \
+ > FIXME || true
+
+%.so: %.c
+ @echo "--- Module: $< ($@)"
+ $(CC) $(CFLAGS) -o $@ -shared $< $(GTK_FLAGS) $(GTK_LIBS) \
+ $(GLADE_LIBS) $(GLADE_FLAGS)
+ mv $@ modules
+
+clean:
+ rm -rf .xvpics pixmaps/.xvpics *.o *.so hardinfo modules/*.so report
+ find . -name \*~ -exec rm -v {} \;
+ find . -name x86 -type l -exec rm -v {} \;
+
+dist-clean: clean
+ rm -rf Makefile debian/hardinfo/ config.h arch/this
+
+package: dist-clean
+ @echo "Creating tar.gz..."
+ cd .. && tar czf $(PACKAGE).tar.gz $(PACKAGE)/* && cd $(PACKAGE)
+ @echo "Creating tar.bz2..."
+ cd .. && tar cjf $(PACKAGE).tar.bz2 $(PACKAGE)/* && cd $(PACKAGE)
+
+deb: dist-clean
+ @echo "Creating deb..."
+ dpkg-buildpackage -rfakeroot -k${USER}
+
diff --git a/hardinfo2/arch/common/display.h b/hardinfo2/arch/common/display.h
new file mode 100644
index 00000000..6731e3e3
--- /dev/null
+++ b/hardinfo2/arch/common/display.h
@@ -0,0 +1,137 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static void
+get_glx_info(DisplayInfo *di)
+{
+ gchar *output;
+ if (g_spawn_command_line_sync("glxinfo", &output, NULL, NULL, NULL)) {
+ gchar **output_lines, **old;
+
+ output_lines = g_strsplit(output, "\n", 0);
+ g_free(output);
+
+ old = output_lines;
+ while (*(++output_lines)) {
+ if (strstr(*output_lines, "OpenGL")) {
+ gchar **tmp = g_strsplit(*output_lines, ":", 0);
+
+ tmp[1] = g_strchug(tmp[1]);
+
+ get_str("OpenGL vendor str", di->ogl_vendor);
+ get_str("OpenGL renderer str", di->ogl_renderer);
+ get_str("OpenGL version str", di->ogl_version);
+
+ g_strfreev(tmp);
+ }
+ }
+
+ g_strfreev(old);
+
+ if (!di->ogl_vendor)
+ di->ogl_vendor = "Unknown";
+ if (!di->ogl_renderer)
+ di->ogl_renderer = "Unknown";
+ if (!di->ogl_version)
+ di->ogl_version = "Unknown";
+ } else {
+ di->ogl_vendor = di->ogl_renderer = di->ogl_version = "Unknown";
+ }
+
+}
+
+static void
+get_x11_info(DisplayInfo *di)
+{
+ gchar *output;
+
+ if (g_spawn_command_line_sync("xdpyinfo", &output, NULL, NULL, NULL)) {
+ gchar **output_lines, **old;
+
+ output_lines = g_strsplit(output, "\n", 0);
+ g_free(output);
+
+ old = output_lines;
+ while (*(output_lines++)) {
+ gchar **tmp = g_strsplit(*output_lines, ":", 0);
+
+ if (tmp[1] && tmp[0]) {
+ tmp[1] = g_strchug(tmp[1]);
+
+ get_str("vendor string", di->vendor);
+ get_str("X.Org version", di->version);
+ get_str("XFree86 version", di->version);
+
+ if (g_str_has_prefix(tmp[0], "number of extensions")) {
+ int n;
+
+ di->extensions = "";
+
+ for (n = atoi(tmp[1]); n; n--) {
+ di->extensions = g_strconcat(di->extensions,
+ g_strstrip(*(++output_lines)),
+ "=\n",
+ NULL);
+ }
+ g_strfreev(tmp);
+
+ break;
+ }
+ }
+
+ g_strfreev(tmp);
+ }
+
+ g_strfreev(old);
+ }
+
+ GdkScreen *screen = gdk_screen_get_default();
+
+ if (screen && GDK_IS_SCREEN(screen)) {
+ gint n_monitors = gdk_screen_get_n_monitors(screen);
+ gint i;
+
+ di->monitors = "";
+ for (i = 0; i < n_monitors; i++) {
+ GdkRectangle rect;
+
+ gdk_screen_get_monitor_geometry(screen, i, &rect);
+
+ di->monitors = g_strdup_printf("%sMonitor %d=%dx%d pixels\n",
+ di->monitors, i, rect.width, rect.height);
+ }
+ } else {
+ di->monitors = "";
+ }
+}
+
+static DisplayInfo *
+computer_get_display(void)
+{
+ DisplayInfo *di = g_new0(DisplayInfo, 1);
+
+ GdkScreen *screen = gdk_screen_get_default();
+
+ di->width = gdk_screen_get_width(screen);
+ di->height = gdk_screen_get_height(screen);
+
+ get_glx_info(di);
+ get_x11_info(di);
+
+ return di;
+}
diff --git a/hardinfo2/arch/common/fib.h b/hardinfo2/arch/common/fib.h
new file mode 100644
index 00000000..493cfd0f
--- /dev/null
+++ b/hardinfo2/arch/common/fib.h
@@ -0,0 +1,50 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static unsigned long long
+fib(unsigned long long n)
+{
+ if (n == 0)
+ return 0;
+ else if (n == 1 || n == 2)
+ return 1;
+ return fib(n - 1) + fib(n - 2);
+}
+
+static gchar *
+benchmark_fib(void)
+{
+ GTimer *timer = g_timer_new();
+ gdouble elapsed = 0;
+
+ shell_view_set_enabled(FALSE);
+ shell_status_update("Calculating the 42<sup>th</sup> Fibonacci number...");
+
+ g_timer_start(timer);
+ fib(42); /* the answer? :) */
+ g_timer_stop(timer);
+
+ elapsed = g_timer_elapsed(timer, NULL);
+
+ g_timer_destroy(timer);
+
+ gchar *retval = g_strdup_printf("[Results <i>(in seconds; lower is better)</i>]\n"
+ "<b>This Machine</b>=<b>%.2f</b>\n", elapsed);
+ return benchmark_include_results(retval, "Fibonacci");
+}
+
diff --git a/hardinfo2/arch/common/languages.h b/hardinfo2/arch/common/languages.h
new file mode 100644
index 00000000..9e1439d1
--- /dev/null
+++ b/hardinfo2/arch/common/languages.h
@@ -0,0 +1,99 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+void
+scan_languages(OperatingSystem * os)
+{
+ FILE *locale;
+ gchar buf[128], *retval = "";
+
+ locale = popen("locale -va", "r");
+ if (!locale)
+ return;
+
+ gchar name[32];
+ gchar *title = NULL,
+ *source = NULL,
+ *address = NULL,
+ *email = NULL,
+ *language = NULL,
+ *territory = NULL,
+ *revision = NULL,
+ *date = NULL,
+ *codeset = NULL;
+
+ while (fgets(buf, 128, locale)) {
+ if (!strncmp(buf, "locale:", 7)) {
+ sscanf(buf, "locale: %s", name);
+ fgets(buf, 128, locale);
+ } else if (strchr(buf, '|')) {
+ gchar **tmp = g_strsplit(buf, "|", 2);
+
+ tmp[0] = g_strstrip(tmp[0]);
+
+ if (tmp[1]) {
+ tmp[1] = g_strstrip(tmp[1]);
+
+ get_str("title", title);
+ get_str("source", source);
+ get_str("address", address);
+ get_str("email", email);
+ get_str("language", language);
+ get_str("territory", territory);
+ get_str("revision", revision);
+ get_str("date", date);
+ get_str("codeset", codeset);
+ }
+
+ g_strfreev(tmp);
+ } else {
+ gchar *currlocale;
+
+ retval = g_strdup_printf("%s$%s$%s=\n", retval, name, name);
+
+ currlocale = g_strdup_printf("[Locale Information]\n"
+ "Name=%s (%s)\n"
+ "Source=%s\n"
+ "Address=%s\n"
+ "Email=%s\n"
+ "Language=%s\n"
+ "Territory=%s\n"
+ "Revision=%s\n"
+ "Date=%s\n"
+ "Codeset=%s\n", name, title,
+ source, address, email, language,
+ territory, revision, date,
+ codeset);
+
+ g_hash_table_insert(moreinfo, g_strdup(name), currlocale);
+
+ g_free(title);
+ g_free(source);
+ g_free(address);
+ g_free(email);
+ g_free(language);
+ g_free(territory);
+ g_free(revision);
+ g_free(date);
+ g_free(codeset);
+ }
+ }
+
+ fclose(locale);
+
+ os->languages = retval;
+}
diff --git a/hardinfo2/arch/common/md5.h b/hardinfo2/arch/common/md5.h
new file mode 100644
index 00000000..f61aef0f
--- /dev/null
+++ b/hardinfo2/arch/common/md5.h
@@ -0,0 +1,62 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 <md5.h>
+
+gchar *
+benchmark_md5(void)
+{
+ struct MD5Context ctx;
+ guchar checksum[16];
+ int i;
+ GTimer *timer = g_timer_new();
+ gdouble elapsed = 0;
+ gchar src[65536], *tmpsrc;
+ glong srclen = 65536;
+
+ tmpsrc = src;
+
+ if (!g_file_get_contents(PREFIX "benchmark.data",
+ &tmpsrc, NULL, NULL)) {
+ return g_strdup("[Error]\n"
+ PREFIX "benchmark.data not found=\n");
+ }
+
+ shell_view_set_enabled(FALSE);
+ shell_status_update("Generating MD5 sum for 312MiB of data...");
+
+ for (i = 0; i <= 5000; i++) {
+ g_timer_start(timer);
+
+ MD5Init(&ctx);
+ MD5Update(&ctx, (guchar*)tmpsrc, srclen);
+ MD5Final(checksum, &ctx);
+
+ g_timer_stop(timer);
+ elapsed += g_timer_elapsed(timer, NULL);
+
+ shell_status_set_percentage(i/50);
+ }
+
+ g_timer_destroy(timer);
+
+ gchar *retval = g_strdup_printf("[Results <i>(in seconds; lower is better)</i>]\n"
+ "<b>This Machine</b>=<b>%.2f</b>\n", elapsed);
+ return benchmark_include_results(retval, "MD5");
+}
+
diff --git a/hardinfo2/arch/common/printers.h b/hardinfo2/arch/common/printers.h
new file mode 100644
index 00000000..8632ea18
--- /dev/null
+++ b/hardinfo2/arch/common/printers.h
@@ -0,0 +1,67 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+void
+scan_printers(void)
+{
+ GModule *cups;
+ static int (*cupsGetPrinters) (char ***printers) = NULL;
+ static char *(*cupsGetDefault) (void) = NULL;
+
+ if (printer_list)
+ g_free(printer_list);
+
+ if (!(cupsGetPrinters && cupsGetDefault)) {
+ cups = g_module_open("libcups", G_MODULE_BIND_LAZY);
+ if (!cups) {
+ printer_list = g_strdup("[Printers]\n"
+ "CUPS libraries cannot be found=");
+ return;
+ }
+
+ if (!g_module_symbol(cups, "cupsGetPrinters", (gpointer) & cupsGetPrinters)
+ || !g_module_symbol(cups, "cupsGetDefault",
+ (gpointer) & cupsGetDefault)) {
+ printer_list =
+ g_strdup("[Printers]\n" "No suitable CUPS library found=");
+ g_module_close(cups);
+ return;
+ }
+ }
+
+ gchar **printers;
+ int noprinters, i;
+ const char *default_printer;
+
+ noprinters = cupsGetPrinters(&printers);
+ default_printer = cupsGetDefault();
+
+ if (noprinters > 0) {
+ printer_list = g_strdup_printf("[Printers (CUPS)]\n");
+ for (i = 0; i < noprinters; i++) {
+ printer_list = g_strconcat(printer_list, printers[i],
+ !strcmp(default_printer,
+ printers[i]) ?
+ "=<i>(Default)</i>\n" : "=\n",
+ NULL);
+ g_free(printers[i]);
+ }
+ } else {
+ printer_list = g_strdup("[Printers]\n" "No printers found");
+ }
+}
diff --git a/hardinfo2/arch/common/sha1.h b/hardinfo2/arch/common/sha1.h
new file mode 100644
index 00000000..521cbcae
--- /dev/null
+++ b/hardinfo2/arch/common/sha1.h
@@ -0,0 +1,61 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 <sha1.h>
+
+gchar *
+benchmark_sha1(void)
+{
+ SHA1_CTX ctx;
+ guchar checksum[20];
+ int i;
+ GTimer *timer = g_timer_new();
+ gdouble elapsed = 0;
+ gchar src[65536], *tmpsrc;
+ glong srclen = 65536;
+
+ tmpsrc = src;
+
+ if (!g_file_get_contents(PREFIX "benchmark.data",
+ &tmpsrc, NULL, NULL)) {
+ return g_strdup("[Error]\n"
+ PREFIX "benchmark.data not found=\n");
+ }
+
+ shell_view_set_enabled(FALSE);
+ shell_status_update("Generating SHA1 sum for 312MiB of data...");
+
+ for (i = 0; i <= 5000; i++) {
+ g_timer_start(timer);
+
+ SHA1Init(&ctx);
+ SHA1Update(&ctx, (guchar*)tmpsrc, srclen);
+ SHA1Final(checksum, &ctx);
+
+ g_timer_stop(timer);
+ elapsed += g_timer_elapsed(timer, NULL);
+
+ shell_status_set_percentage(i/50);
+ }
+
+ g_timer_destroy(timer);
+
+ gchar *retval = g_strdup_printf("[Results <i>(in seconds; lower is better)</i>]\n"
+ "<b>This Machine</b>=<b>%.2f</b>\n", elapsed);
+ return benchmark_include_results(retval, "SHA1");
+}
+
diff --git a/hardinfo2/arch/common/zlib.h b/hardinfo2/arch/common/zlib.h
new file mode 100644
index 00000000..74145cae
--- /dev/null
+++ b/hardinfo2/arch/common/zlib.h
@@ -0,0 +1,81 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static gchar *
+benchmark_zlib(void)
+{
+ GModule *libz;
+ static gulong (*compressBound) (glong srclen) = NULL;
+ static gint (*compress) (gchar *dst, glong *dstlen,
+ const gchar *src, glong srclen) = NULL;
+
+ if (!(compress && compressBound)) {
+ libz = g_module_open("libz", G_MODULE_BIND_LAZY);
+ if (!libz) {
+ return g_strdup("[Error]\n"
+ "ZLib not found=");
+ }
+
+ if (!g_module_symbol(libz, "compress", (gpointer) & compress)
+ || !g_module_symbol(libz, "compressBound", (gpointer) & compressBound)) {
+
+ g_module_close(libz);
+ return g_strdup("[Error]\n"
+ "Invalid Z-Lib found=");
+ }
+ }
+
+ shell_view_set_enabled(FALSE);
+
+ int i;
+ GTimer *timer = g_timer_new();
+ gdouble elapsed = 0;
+ gchar src[65536], *tmpsrc;
+ glong srclen = 65536;
+
+ if (!g_file_get_contents(PREFIX "benchmark.data",
+ &tmpsrc, NULL, NULL)) {
+ return g_strdup("[Error]\n"
+ PREFIX "benchmark.data not found=\n");
+ }
+
+ shell_status_update("Compressing 64MB with default options...");
+
+ for (i = 0; i <= 1000; i++) {
+ g_timer_start(timer);
+
+ gchar *dst;
+ glong dstlen = compressBound(srclen);
+
+ dst = g_new0(gchar, dstlen);
+ compress(dst, &dstlen, src, srclen);
+
+ g_timer_stop(timer);
+ elapsed += g_timer_elapsed(timer, NULL);
+ g_free(dst);
+
+ shell_status_set_percentage(i/10);
+ }
+
+ g_timer_destroy(timer);
+
+ gchar *retval = g_strdup_printf("[Results <i>(in seconds; lower is better)</i>]\n"
+ "<b>This Machine</b>=<b>%.2f</b>\n", elapsed);
+ return benchmark_include_results(retval, "ZLib");
+}
+
diff --git a/hardinfo2/arch/linux/common/alsa.h b/hardinfo2/arch/linux/common/alsa.h
new file mode 100644
index 00000000..0c0744ae
--- /dev/null
+++ b/hardinfo2/arch/linux/common/alsa.h
@@ -0,0 +1,69 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+gchar *
+computer_get_alsacards(Computer * computer)
+{
+ GSList *p;
+ gchar *tmp = "";
+ gint n = 0;
+
+ if (computer->alsa) {
+ for (p = computer->alsa->cards; p; p = p->next) {
+ AlsaCard *ac = (AlsaCard *) p->data;
+
+ tmp =
+ g_strdup_printf("Audio Adapter#%d=%s\n%s", ++n,
+ ac->friendly_name, tmp);
+ }
+ }
+
+ return tmp;
+}
+
+static AlsaInfo *
+computer_get_alsainfo(void)
+{
+ AlsaInfo *ai;
+ AlsaCard *ac;
+ FILE *cards;
+ gchar buffer[128];
+
+ cards = fopen("/proc/asound/cards", "r");
+ if (!cards)
+ return NULL;
+
+ ai = g_new0(AlsaInfo, 1);
+
+ while (fgets(buffer, 128, cards)) {
+ gchar **tmp;
+
+ ac = g_new0(AlsaCard, 1);
+
+ tmp = g_strsplit(buffer, ":", 0);
+
+ ac->friendly_name = g_strdup(tmp[1]);
+ ai->cards = g_slist_append(ai->cards, ac);
+
+ g_strfreev(tmp);
+ fgets(buffer, 128, cards); /* skip next line */
+ }
+ fclose(cards);
+
+ return ai;
+}
diff --git a/hardinfo2/arch/linux/common/filesystem.h b/hardinfo2/arch/linux/common/filesystem.h
new file mode 100644
index 00000000..37e5a730
--- /dev/null
+++ b/hardinfo2/arch/linux/common/filesystem.h
@@ -0,0 +1,103 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ *
+ * Some code from xfce4-mount-plugin, version 0.4.3
+ * Copyright (C) 2005 Jean-Baptiste jb_dul@yahoo.com
+ * Distributed under the terms of GNU GPL 2.
+ */
+#include <sys/vfs.h>
+#define KB 1024
+#define MB 1048576
+#define GB 1073741824
+
+static gchar *fs_list = NULL;
+
+static gchar *
+fs_human_readable(gfloat size)
+{
+ if (size < KB)
+ return g_strdup_printf("%.1f B", size);
+ if (size < MB)
+ return g_strdup_printf("%.1f KiB", size / KB);
+ if (size < GB)
+ return g_strdup_printf("%.1f MiB", size / MB);
+
+ return g_strdup_printf("%.1f GiB", size / GB);
+}
+
+static void
+scan_filesystems(void)
+{
+ FILE *mtab;
+ gchar buf[128];
+ struct statfs sfs;
+
+ g_free(fs_list);
+ fs_list = g_strdup("");
+
+ mtab = fopen("/etc/mtab", "r");
+ if (!mtab)
+ return;
+
+ while (fgets(buf, 128, mtab)) {
+ gfloat size, used, avail;
+ gchar **tmp;
+
+ tmp = g_strsplit(buf, " ", 0);
+ statfs(tmp[1], &sfs);
+
+ size = (float) sfs.f_bsize * (float) sfs.f_blocks;
+ avail = (float) sfs.f_bsize * (float) sfs.f_bavail;
+ used = size - avail;
+
+ gchar *strsize = fs_human_readable(size),
+ *stravail = fs_human_readable(avail),
+ *strused = fs_human_readable(used);
+
+ gchar *strhash;
+ if ((strhash = g_hash_table_lookup(moreinfo, tmp[0]))) {
+ g_hash_table_remove(moreinfo, tmp[0]);
+ g_free(strhash);
+ }
+
+ strhash = g_strdup_printf("[%s]\n"
+ "Filesystem=%s\n"
+ "Mounted As=%s\n"
+ "Mount Point=%s\n"
+ "Size=%s\n"
+ "Used=%s\n"
+ "Available=%s\n",
+ tmp[0],
+ tmp[2],
+ strstr(tmp[3],
+ "rw") ? "Read-Write" :
+ "Read-Only", tmp[1], strsize, strused,
+ stravail);
+ g_hash_table_insert(moreinfo, g_strdup(tmp[0]), strhash);
+
+ fs_list = g_strdup_printf("%s$%s$%s=%s total, %s free\n",
+ fs_list,
+ tmp[0], tmp[0], strsize, stravail);
+
+ g_free(strsize);
+ g_free(stravail);
+ g_free(strused);
+ g_strfreev(tmp);
+ }
+
+ fclose(mtab);
+}
diff --git a/hardinfo2/arch/linux/common/inputdevices.h b/hardinfo2/arch/linux/common/inputdevices.h
new file mode 100644
index 00000000..c32015a2
--- /dev/null
+++ b/hardinfo2/arch/linux/common/inputdevices.h
@@ -0,0 +1,117 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static gchar *input_icons = NULL;
+
+static gboolean
+remove_input_devices(gpointer key, gpointer value, gpointer data)
+{
+ if (!strncmp((gchar *) key, "INP", 3)) {
+ g_free((gchar *) key);
+ g_free((GtkTreeIter *) value);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static struct {
+ char *name;
+ char *icon;
+} input_devices[] = {
+ { "Keyboard", "keyboard.png" },
+ { "Joystick", "joystick.png" },
+ { "Mouse", "mouse.png" },
+ { "Unknown", "module.png" },
+};
+
+void
+scan_inputdevices(void)
+{
+ FILE *dev;
+ gchar buffer[128];
+ gchar *tmp, *name = NULL, *phys = NULL;
+ gint bus, vendor, product, version;
+ int d = 0, n = 0;
+
+ dev = fopen("/proc/bus/input/devices", "r");
+ if (!dev)
+ return;
+
+ if (input_list) {
+ g_hash_table_foreach_remove(devices, remove_input_devices, NULL);
+ g_free(input_list);
+ g_free(input_icons);
+ }
+ input_list = g_strdup("");
+ input_icons = g_strdup("");
+
+ while (fgets(buffer, 128, dev)) {
+ tmp = buffer;
+
+ switch (*tmp) {
+ case 'N':
+ name = g_strdup(tmp + strlen("N: Name="));
+ remove_quotes(name);
+ break;
+ case 'P':
+ phys = g_strdup(tmp + strlen("P: Phys="));
+ break;
+ case 'I':
+ sscanf(tmp, "I: Bus=%x Vendor=%x Product=%x Version=%x",
+ &bus, &vendor, &product, &version);
+ break;
+ case 'H':
+ if (strstr(tmp, "kbd"))
+ d = 0; //INPUT_KEYBOARD;
+ else if (strstr(tmp, "js"))
+ d = 1; //INPUT_JOYSTICK;
+ else if (strstr(tmp, "mouse"))
+ d = 2; //INPUT_MOUSE;
+ else
+ d = 3; //INPUT_UNKNOWN;
+ break;
+ case '\n':
+ tmp = g_strdup_printf("INP%d", ++n);
+ input_list = g_strdup_printf("%s$%s$%s=\n",
+ input_list,
+ tmp, name);
+ input_icons = g_strdup_printf("%sIcon$%s$%s=%s\n",
+ input_icons,
+ tmp, name,
+ input_devices[d].icon);
+ gchar *strhash = g_strdup_printf("[Device Information]\n"
+ "Name=%s\n"
+ "Type=%s\n"
+ "Bus=0x%x\n"
+ "Vendor=0x%x\n"
+ "Product=0x%x\n"
+ "Version=0x%x\n"
+ "Connected to=%s\n",
+ name, input_devices[d].name,
+ bus, vendor, product,
+ version, phys);
+ g_hash_table_insert(devices, tmp, strhash);
+
+ g_free(phys);
+ g_free(name);
+ }
+ }
+
+ fclose(dev);
+}
diff --git a/hardinfo2/arch/linux/common/loadavg.h b/hardinfo2/arch/linux/common/loadavg.h
new file mode 100644
index 00000000..28132b5f
--- /dev/null
+++ b/hardinfo2/arch/linux/common/loadavg.h
@@ -0,0 +1,47 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static LoadInfo *
+computer_get_loadinfo(void)
+{
+ LoadInfo *li = g_new0(LoadInfo, 1);
+ FILE *procloadavg;
+
+ procloadavg = fopen("/proc/loadavg", "r");
+ fscanf(procloadavg, "%f %f %f", &(li->load1), &(li->load5),
+ &(li->load15));
+ fclose(procloadavg);
+
+ return li;
+}
+
+static gchar *
+computer_get_formatted_loadavg()
+{
+ LoadInfo *li;
+ gchar *tmp;
+
+ li = computer_get_loadinfo();
+
+ tmp =
+ g_strdup_printf("%.2f, %.2f, %.2f", li->load1, li->load5,
+ li->load15);
+
+ g_free(li);
+ return tmp;
+}
diff --git a/hardinfo2/arch/linux/common/memory.h b/hardinfo2/arch/linux/common/memory.h
new file mode 100644
index 00000000..def4cc1d
--- /dev/null
+++ b/hardinfo2/arch/linux/common/memory.h
@@ -0,0 +1,56 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static MemoryInfo *
+computer_get_memory(void)
+{
+ MemoryInfo *mi;
+ FILE *procmem;
+ gchar buffer[128];
+
+ procmem = fopen("/proc/meminfo", "r");
+ if (!procmem)
+ return NULL;
+ mi = g_new0(MemoryInfo, 1);
+
+ while (fgets(buffer, 128, procmem)) {
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
+
+ get_int("MemTotal", mi->total);
+ get_int("MemFree", mi->free);
+ get_int("Cached", mi->cached);
+
+ g_strfreev(tmp);
+ }
+ fclose(procmem);
+
+ mi->used = mi->total - mi->free;
+
+ mi->total /= 1000;
+ mi->cached /= 1000;
+ mi->used /= 1000;
+ mi->free /= 1000;
+
+ mi->used -= mi->cached;
+ mi->ratio = 1 - (gdouble) mi->used / mi->total;
+
+ return mi;
+}
diff --git a/hardinfo2/arch/linux/common/modules.h b/hardinfo2/arch/linux/common/modules.h
new file mode 100644
index 00000000..69f7ebd6
--- /dev/null
+++ b/hardinfo2/arch/linux/common/modules.h
@@ -0,0 +1,129 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+void
+scan_modules(void)
+{
+ FILE *lsmod;
+ gchar buffer[1024];
+
+ lsmod = popen("/sbin/lsmod", "r");
+ if (!lsmod)
+ return;
+
+ fgets(buffer, 1024, lsmod); /* Discards the first line */
+
+ while (fgets(buffer, 1024, lsmod)) {
+ gchar *buf, *strmodule, *hashkey;
+ gchar *author = NULL,
+ *description = NULL,
+ *license = NULL,
+ *deps = NULL, *vermagic = NULL, *filename = NULL, modname[64];
+ FILE *modi;
+ glong memory;
+
+ shell_status_pulse();
+
+ buf = buffer;
+
+ sscanf(buf, "%s %ld", modname, &memory);
+
+ hashkey = g_strdup_printf("MOD%s", modname);
+ buf = g_strdup_printf("/sbin/modinfo %s", modname);
+
+ modi = popen(buf, "r");
+ while (fgets(buffer, 1024, modi)) {
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+
+ GET_STR("author", author);
+ GET_STR("description", description);
+ GET_STR("license", license);
+ GET_STR("depends", deps);
+ GET_STR("vermagic", vermagic);
+ GET_STR("filename", filename);
+
+ g_strfreev(tmp);
+ }
+ pclose(modi);
+ g_free(buf);
+
+ /* old modutils includes quotes in some strings; strip them */
+ /*remove_quotes(modname);
+ remove_quotes(description);
+ remove_quotes(vermagic);
+ remove_quotes(author);
+ remove_quotes(license); */
+
+ /* old modutils displays <none> when there's no value for a
+ given field; this is not desirable in the module name
+ display, so change it to an empty string */
+ if (description && !strcmp(description, "&lt;none&gt;")) {
+ g_free(description);
+ description = g_strdup("");
+ }
+
+ /* append this module to the list of modules */
+ module_list = g_strdup_printf("%s$%s$%s=%s\n",
+ module_list,
+ hashkey,
+ modname,
+ description ? description : "");
+
+#define NONE_IF_NULL(var) (var) ? (var) : "N/A"
+
+ /* create the module information string */
+ strmodule = g_strdup_printf("[Module Information]\n"
+ "Path=%s\n"
+ "Used Memory=%.2fKiB\n"
+ "[Description]\n"
+ "Name=%s\n"
+ "Description=%s\n"
+ "Version Magic=%s\n"
+ "[Copyright]\n"
+ "Author=%s\n"
+ "License=%s\n",
+ NONE_IF_NULL(filename),
+ memory / 1024.0,
+ NONE_IF_NULL(modname),
+ NONE_IF_NULL(description),
+ NONE_IF_NULL(vermagic),
+ NONE_IF_NULL(author),
+ NONE_IF_NULL(license));
+
+ /* if there are dependencies, append them to that string */
+ if (deps && strlen(deps)) {
+ gchar **tmp = g_strsplit(deps, ",", 0);
+
+ strmodule = g_strconcat(strmodule,
+ "\n[Dependencies]\n",
+ g_strjoinv("=\n", tmp),
+ "=\n", NULL);
+ g_strfreev(tmp);
+ g_free(deps);
+ }
+
+ g_hash_table_insert(devices, hashkey, strmodule);
+
+ g_free(license);
+ g_free(description);
+ g_free(author);
+ g_free(vermagic);
+ g_free(filename);
+ }
+ pclose(lsmod);
+}
diff --git a/hardinfo2/arch/linux/common/os.h b/hardinfo2/arch/linux/common/os.h
new file mode 100644
index 00000000..c8204e92
--- /dev/null
+++ b/hardinfo2/arch/linux/common/os.h
@@ -0,0 +1,186 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static gchar *
+get_libc_version(void)
+{
+ FILE *libc;
+ gchar buf[256], *tmp, *p;
+
+ libc = popen("/lib/libc.so.6", "r");
+ if (!libc) goto err;
+
+ fgets(buf, 256, libc);
+ if (pclose(libc)) goto err;
+
+ tmp = strstr(buf, "version ");
+ if (!tmp) goto err;
+
+ p = strchr(tmp, ',');
+ if (p) *p = '\0';
+ else goto err;
+
+ return g_strdup_printf("GNU C Library version %s (%sstable)",
+ strchr(tmp, ' ') + 1,
+ strstr(buf, " stable ") ? "" : "un");
+ err:
+ return g_strdup("Unknown");
+}
+
+static gchar *
+get_os_compiled_date(void)
+{
+ FILE *procversion;
+ gchar buf[512];
+
+ procversion = fopen("/proc/sys/kernel/version", "r");
+ if (!procversion)
+ return g_strdup("Unknown");
+
+ fgets(buf, 512, procversion);
+ fclose(procversion);
+
+ return g_strdup(buf);
+}
+
+void
+detect_desktop_environment(OperatingSystem * os)
+{
+ const gchar *tmp = g_getenv("GNOME_DESKTOP_SESSION_ID");
+ FILE *version;
+ int maj, min;
+
+ if (tmp) {
+ /* FIXME: this might not be true, as the gnome-panel in path may not be the one that's running.
+ see where the user's running panel is and run *that* to obtain the version.
+
+ the same applies do kcontrol --version. */
+ version = popen("gnome-panel --version", "r");
+ if (version) {
+ fscanf(version, "Gnome gnome-panel %d.%d", &maj, &min);
+ if (pclose(version)) goto unknown;
+ } else {
+ goto unknown;
+ }
+
+ os->desktop =
+ g_strdup_printf("GNOME %d.%d (session name: %s)", maj, min,
+ tmp);
+ } else if (g_getenv("KDE_FULL_SESSION")) {
+ version = popen("kcontrol --version", "r");
+ if (version) {
+ char buf[32];
+
+ fgets(buf, 32, version);
+
+ fscanf(version, "KDE: %d.%d", &maj, &min);
+ if (pclose(version)) goto unknown;
+ } else {
+ goto unknown;
+ }
+
+ os->desktop = g_strdup_printf("KDE %d.%d", maj, min);
+ } else {
+ unknown:
+ if (!g_getenv("DISPLAY")) {
+ os->desktop = g_strdup("Terminal");
+ } else {
+ os->desktop = g_strdup("Unknown");
+ }
+ }
+}
+
+static OperatingSystem *
+computer_get_os(void)
+{
+ struct utsname utsbuf;
+ OperatingSystem *os;
+ int i;
+
+ os = g_new0(OperatingSystem, 1);
+
+ os->compiled_date = get_os_compiled_date();
+
+ /* Attempt to get the Distribution name; try using /etc/lsb-release first,
+ then doing the legacy method (checking for /etc/$DISTRO-release files) */
+ if (g_file_test("/etc/lsb-release", G_FILE_TEST_EXISTS)) {
+ FILE *release;
+ gchar buffer[128];
+
+ release = popen("lsb_release -d", "r");
+ fgets(buffer, 128, release);
+ pclose(release);
+
+ os->distro = buffer;
+ os->distro = g_strdup(os->distro + strlen("Description:\t"));
+ }
+
+ for (i = 0;; i++) {
+ if (distro_db[i].file == NULL) {
+ os->distrocode = g_strdup("unk");
+ os->distro = g_strdup("Unknown distribution");
+ break;
+ }
+
+ if (g_file_test(distro_db[i].file, G_FILE_TEST_EXISTS)) {
+
+
+ FILE *distro_ver;
+ char buf[128];
+
+ distro_ver = fopen(distro_db[i].file, "r");
+ fgets(buf, 128, distro_ver);
+ fclose(distro_ver);
+
+ buf[strlen(buf) - 1] = 0;
+
+ if (!os->distro) {
+ /*
+ * HACK: Some Debian systems doesn't include
+ * the distribuition name in /etc/debian_release,
+ * so add them here.
+ */
+ if (!strncmp(distro_db[i].codename, "deb", 3) &&
+ ((buf[0] >= '0' && buf[0] <= '9') || buf[0] != 'D')) {
+ os->distro = g_strdup_printf
+ ("Debian GNU/Linux %s", buf);
+ } else {
+ os->distro = g_strdup(buf);
+ }
+ }
+ os->distrocode = g_strdup(distro_db[i].codename);
+
+ break;
+ }
+ }
+
+ /* Kernel and hostname info */
+ uname(&utsbuf);
+ os->kernel = g_strdup_printf("%s %s (%s)", utsbuf.sysname,
+ utsbuf.release, utsbuf.machine);
+ os->hostname = g_strdup(utsbuf.nodename);
+ os->language = g_strdup(g_getenv("LC_MESSAGES"));
+ os->homedir = g_strdup(g_get_home_dir());
+ os->username = g_strdup_printf("%s (%s)",
+ g_get_user_name(), g_get_real_name());
+ os->libc = get_libc_version();
+ scan_languages(os);
+ detect_desktop_environment(os);
+
+ return os;
+}
diff --git a/hardinfo2/arch/linux/common/pci.h b/hardinfo2/arch/linux/common/pci.h
new file mode 100644
index 00000000..8f3216e2
--- /dev/null
+++ b/hardinfo2/arch/linux/common/pci.h
@@ -0,0 +1,189 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+void
+scan_pci(void)
+{
+ FILE *lspci;
+ gchar buffer[256], *buf, *strhash = NULL, *strdevice = NULL;
+ gchar *category = NULL, *name = NULL;
+ gint n = 0;
+
+ //if (g_file_test("/usr/bin/gksudo", G_FILE_TEST_EXISTS)) {
+ // lspci = popen("gksudo '/bin/lspci -v'", "r");
+ //} else {
+ lspci = popen(LSPCI, "r");
+ //}
+
+ if (!lspci) {
+ return;
+ }
+
+ gchar *icon;
+
+ int x = 0; /* unique Memory, Capability and I/O port */
+ while (fgets(buffer, 256, lspci)) {
+ buf = g_strstrip(buffer);
+
+ if (!strncmp(buf, "Flags", 5)) {
+ gint irq = 0, freq = 0, latency = 0, i;
+ gchar **list;
+ gboolean bus_master;
+
+ buf += 7;
+
+ bus_master = FALSE;
+
+ list = g_strsplit(buf, ", ", 10);
+ for (i = 0; i <= 10; i++) {
+ if (!list[i])
+ break;
+
+ if (!strncmp(list[i], "IRQ", 3))
+ sscanf(list[i], "IRQ %d", &irq);
+ else if (strstr(list[i], "Mhz"))
+ sscanf(list[i], "%dMhz", &freq);
+ else if (!strncmp(list[i], "bus master", 10))
+ bus_master = TRUE;
+ else if (!strncmp(list[i], "latency", 7))
+ sscanf(list[i], "latency %d", &latency);
+ }
+ g_strfreev(list);
+
+ if (irq)
+ strdevice = g_strdup_printf("%sIRQ=%d\n", strdevice, irq);
+ if (freq)
+ strdevice =
+ g_strdup_printf("%sFrequency=%dMHz\n", strdevice,
+ freq);
+ if (latency)
+ strdevice =
+ g_strdup_printf("%sLatency=%d\n", strdevice, latency);
+
+ strdevice =
+ g_strdup_printf("%sBus Master=%s\n", strdevice,
+ bus_master ? "Yes" : "No");
+ } else if (!strncmp(buf, "Subsystem", 9)) {
+ WALK_UNTIL(' ');
+ buf++;
+ strdevice =
+ g_strdup_printf("%sOEM Vendor=%s\n", strdevice, buf);
+ } else if (!strncmp(buf, "Capabilities", 12)
+ && !strstr(buf, "only to root")) {
+ WALK_UNTIL(' ');
+ WALK_UNTIL(']');
+ buf++;
+ strdevice =
+ g_strdup_printf("%sCapability#%d=%s\n", strdevice, ++x,
+ buf);
+ } else if (!strncmp(buf, "Memory at", 9) && strstr(buf, "[size=")) {
+ gint mem;
+ gchar unit;
+ gboolean prefetch;
+ gboolean _32bit;
+
+ prefetch = strstr(buf, "non-prefetchable") ? FALSE : TRUE;
+ _32bit = strstr(buf, "32-bit") ? TRUE : FALSE;
+
+ WALK_UNTIL('[');
+ sscanf(buf, "[size=%d%c", &mem, &unit);
+
+ strdevice = g_strdup_printf("%sMemory#%d=%d%cB (%s%s)\n",
+ strdevice, ++x,
+ mem,
+ (unit == ']') ? ' ' : unit,
+ _32bit ? "32-bit, " : "",
+ prefetch ? "prefetchable" :
+ "non-prefetchable");
+
+ } else if (!strncmp(buf, "I/O", 3)) {
+ guint io_addr, io_size;
+
+ sscanf(buf, "I/O ports at %x [size=%d]", &io_addr, &io_size);
+
+ strdevice =
+ g_strdup_printf("%sI/O ports at#%d=0x%x - 0x%x\n",
+ strdevice, ++x, io_addr,
+ io_addr + io_size);
+ } else if ((buf[0] >= '0' && buf[0] <= '9') && (buf[4] == ':' || buf[2] == ':')) {
+ gint bus, device, function, domain;
+ gpointer start, end;
+
+ if (strdevice != NULL && strhash != NULL) {
+ g_hash_table_insert(devices, strhash, strdevice);
+ g_free(category);
+ g_free(name);
+ }
+
+ if (buf[4] == ':') {
+ sscanf(buf, "%x:%x:%x.%d", &domain, &bus, &device, &function);
+ } else {
+ /* lspci without domain field */
+ sscanf(buf, "%x:%x.%x", &bus, &device, &function);
+ domain = 0;
+ }
+
+ WALK_UNTIL(' ');
+
+ start = buf;
+
+ WALK_UNTIL(':');
+ end = buf + 1;
+ *buf = 0;
+
+ buf = start + 1;
+ category = g_strdup(buf);
+
+ buf = end;
+ start = buf;
+ WALK_UNTIL('(');
+ *buf = 0;
+ buf = start + 1;
+
+ if (strstr(category, "RAM memory")) icon = "mem";
+ else if (strstr(category, "Multimedia")) icon = "media";
+ else if (strstr(category, "USB")) icon = "usb";
+ else icon = "pci";
+
+ name = g_strdup(buf);
+
+ strhash = g_strdup_printf("PCI%d", n);
+ strdevice = g_strdup_printf("[Device Information]\n"
+ "Name=%s\n"
+ "Class=%s\n"
+ "Domain=%d\n"
+ "Bus, device, function=%d, %d, %d\n",
+ name, category, domain, bus,
+ device, function);
+ pci_list = g_strdup_printf("%s$PCI%d$%s=%s\n", pci_list, n, category,
+ name);
+
+ n++;
+ }
+ }
+
+ if (pclose(lspci)) {
+ /* error (no pci, perhaps?) */
+ pci_list = g_strconcat(pci_list, "No PCI devices found=\n", NULL);
+ } else if (strhash) {
+ /* insert the last device */
+ g_hash_table_insert(devices, strhash, strdevice);
+ g_free(category);
+ g_free(name);
+ }
+}
diff --git a/hardinfo2/arch/linux/common/samba.h b/hardinfo2/arch/linux/common/samba.h
new file mode 100644
index 00000000..538659a6
--- /dev/null
+++ b/hardinfo2/arch/linux/common/samba.h
@@ -0,0 +1,80 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static gchar *shares_list = NULL;
+void
+scan_shared_directories(void)
+{
+ GKeyFile *keyfile;
+ GError *error = NULL;
+ gchar **groups;
+ gchar *smbconf;
+ gsize length;
+
+ if (shares_list) {
+ g_free(shares_list);
+ }
+
+ keyfile = g_key_file_new();
+
+ if (!g_file_get_contents("/etc/samba/smb.conf", &smbconf, &length, &error)) {
+ shares_list = g_strdup("Cannot open /etc/samba/smb.conf=\n");
+ g_error_free(error);
+ goto cleanup;
+ }
+
+ gchar *_smbconf = smbconf;
+ for (; *_smbconf; _smbconf++)
+ if (*_smbconf == ';') *_smbconf = '\0';
+
+ if (!g_key_file_load_from_data(keyfile, smbconf, length, 0, &error)) {
+ shares_list = g_strdup("Cannot parse smb.conf=\n");
+ g_error_free(error);
+ goto cleanup;
+ }
+
+ shares_list = g_strdup("");
+
+ groups = g_key_file_get_groups(keyfile, NULL);
+ gchar **_groups = groups;
+ while (*groups) {
+ if (g_key_file_has_key(keyfile, *groups, "path", NULL) &&
+ g_key_file_has_key(keyfile, *groups, "available", NULL)) {
+
+ gchar *available = g_key_file_get_string(keyfile, *groups, "available", NULL);
+
+ if (g_str_equal(available, "yes")) {
+ gchar *path = g_key_file_get_string(keyfile, *groups, "path", NULL);
+ shares_list = g_strconcat(shares_list, *groups, "=",
+ path, "\n", NULL);
+ g_free(path);
+ }
+
+ g_free(available);
+ }
+
+ *groups++;
+ }
+
+ g_strfreev(_groups);
+
+ cleanup:
+ g_key_file_free(keyfile);
+ g_free(smbconf);
+}
+
diff --git a/hardinfo2/arch/linux/common/sensors.h b/hardinfo2/arch/linux/common/sensors.h
new file mode 100644
index 00000000..ef834de2
--- /dev/null
+++ b/hardinfo2/arch/linux/common/sensors.h
@@ -0,0 +1,237 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static gchar *sensors = NULL;
+static GHashTable *sensor_labels = NULL;
+static GHashTable *sensor_compute = NULL;
+
+static void
+read_sensor_labels(gchar *driver)
+{
+ FILE *conf;
+ gchar buf[256], *line, *p;
+ gboolean lock = FALSE;
+ gint i;
+
+ sensor_labels = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, g_free);
+ sensor_compute = g_hash_table_new(g_str_hash, g_str_equal);
+
+ conf = fopen("/etc/sensors.conf", "r");
+ if (!conf)
+ return;
+
+ while (fgets(buf, 256, conf)) {
+ line = buf;
+
+ remove_linefeed(line);
+ strend(line, '#');
+
+ if (*line == '\0') {
+ continue;
+ } else if (lock && strstr(line, "label")) { /* label lines */
+ gchar **names = g_strsplit(strstr(line, "label") + 5, " ", 0);
+ gchar *name = NULL, *value = NULL;
+
+ for (i = 0; names[i]; i++) {
+ if (names[i][0] == '\0')
+ continue;
+
+ if (!name) name = g_strdup(names[i]);
+ else if (!value) value = g_strdup(names[i]);
+ else value = g_strconcat(value, " ", names[i], NULL);
+ }
+
+ remove_quotes(value);
+ g_hash_table_insert(sensor_labels, name, value);
+
+ g_strfreev(names);
+ } else if (lock && strstr(line, "ignore")) { /* ignore lines */
+ p = strstr(line, "ignore") + 6;
+ if (!strchr(p, ' '))
+ continue;
+
+ while (*p == ' ') p++;
+ g_hash_table_insert(sensor_labels, g_strdup(p), "ignore");
+ } else if (lock && strstr(line, "compute")) { /* compute lines */
+ gchar **formulas = g_strsplit(strstr(line, "compute") + 7, " ", 0);
+ gchar *name = NULL, *formula = NULL;
+
+ for (i = 0; formulas[i]; i++) {
+ if (formulas[i][0] == '\0')
+ continue;
+ if (formulas[i][0] == ',')
+ break;
+
+ if (!name) name = g_strdup(formulas[i]);
+ else if (!formula) formula = g_strdup(formulas[i]);
+ else formula = g_strconcat(formula, formulas[i], NULL);
+ }
+
+ g_strfreev(formulas);
+ g_hash_table_insert(sensor_compute, name, math_string_to_postfix(formula));
+ } else if (g_str_has_prefix(line, "chip")) { /* chip lines (delimiter) */
+ if (lock == FALSE) {
+ gchar **chips = g_strsplit(line, " ", 0);
+
+ for (i = 1; chips[i]; i++) {
+ strend(chips[i], '*');
+
+ if (g_str_has_prefix(driver, chips[i] + 1)) {
+ lock = TRUE;
+ break;
+ }
+ }
+
+ g_strfreev(chips);
+ } else {
+ break;
+ }
+ }
+ }
+
+ fclose(conf);
+}
+
+static gchar *
+get_sensor_label(gchar *sensor)
+{
+ gchar *ret;
+
+ ret = g_hash_table_lookup(sensor_labels, sensor);
+ if (!ret) ret = g_strdup(sensor);
+ else ret = g_strdup(ret);
+
+ return ret;
+}
+
+static float
+adjust_sensor(gchar *name, float value)
+{
+ GSList *postfix;
+
+ postfix = g_hash_table_lookup(sensor_compute, name);
+ if (!postfix) return value;
+
+ return math_postfix_eval(postfix, value);
+}
+
+static void
+read_sensors(void)
+{
+ gchar *path_hwmon, *path_sensor, *tmp, *driver, *name, *mon;
+ int hwmon, count;
+
+ if (sensors)
+ g_free(sensors);
+
+ hwmon = 0;
+ sensors = g_strdup("");
+
+ path_hwmon = g_strdup_printf("/sys/class/hwmon/hwmon%d/device/", hwmon);
+ while (g_file_test(path_hwmon, G_FILE_TEST_EXISTS)) {
+ tmp = g_strdup_printf("%sdriver", path_hwmon);
+ driver = g_file_read_link(tmp, NULL);
+ g_free(tmp);
+
+ tmp = g_path_get_basename(driver);
+ g_free(driver);
+ driver = tmp;
+
+ if (!sensor_labels) {
+ read_sensor_labels(driver);
+ }
+
+ sensors = g_strdup_printf("%s[Driver Info]\n"
+ "Name=%s\n", sensors, driver);
+
+ sensors = g_strconcat(sensors, "[Cooling Fans]\n", NULL);
+ for (count = 1; ; count++) {
+ path_sensor = g_strdup_printf("%sfan%d_input", path_hwmon, count);
+ if (!g_file_get_contents(path_sensor, &tmp, NULL, NULL)) {
+ g_free(path_sensor);
+ break;
+ }
+
+ mon = g_strdup_printf("fan%d", count);
+ name = get_sensor_label(mon);
+ if (!g_str_equal(name, "ignore")) {
+ sensors = g_strdup_printf("%s%s=%.0fRPM\n",
+ sensors, name,
+ adjust_sensor(mon, atof(tmp)));
+ }
+
+ g_free(name);
+ g_free(mon);
+ g_free(tmp);
+ g_free(path_sensor);
+ }
+
+ sensors = g_strconcat(sensors, "[Temperatures]\n", NULL);
+ for (count = 1; ; count++) {
+ path_sensor = g_strdup_printf("%stemp%d_input", path_hwmon, count);
+ if (!g_file_get_contents(path_sensor, &tmp, NULL, NULL)) {
+ g_free(path_sensor);
+ break;
+ }
+
+ mon = g_strdup_printf("temp%d", count);
+ name = get_sensor_label(mon);
+ if (!g_str_equal(name, "ignore")) {
+ sensors = g_strdup_printf("%s%s=%.2f\302\260C\n",
+ sensors, name,
+ adjust_sensor(mon, atof(tmp) / 1000.0));
+ }
+
+ g_free(tmp);
+ g_free(name);
+ g_free(path_sensor);
+ g_free(mon);
+ }
+
+ sensors = g_strconcat(sensors, "[Voltage Values]\n", NULL);
+ for (count = 0; ; count++) {
+ path_sensor = g_strdup_printf("%sin%d_input", path_hwmon, count);
+ if (!g_file_get_contents(path_sensor, &tmp, NULL, NULL)) {
+ g_free(path_sensor);
+ break;
+ }
+
+
+ mon = g_strdup_printf("in%d", count);
+ name = get_sensor_label(mon);
+ if (!g_str_equal(name, "ignore")) {
+ sensors = g_strdup_printf("%s%s=%.3fV\n",
+ sensors, name,
+ adjust_sensor(mon, atof(tmp) / 1000.0));
+ }
+
+ g_free(tmp);
+ g_free(mon);
+ g_free(name);
+ g_free(path_sensor);
+ }
+
+ g_free(path_hwmon);
+ g_free(driver);
+ path_hwmon = g_strdup_printf("/sys/class/hwmon/hwmon%d/device/", ++hwmon);
+ }
+
+ g_free(path_hwmon);
+}
+
diff --git a/hardinfo2/arch/linux/common/storage.h b/hardinfo2/arch/linux/common/storage.h
new file mode 100644
index 00000000..4fb682a9
--- /dev/null
+++ b/hardinfo2/arch/linux/common/storage.h
@@ -0,0 +1,268 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static gchar *storage_icons = "";
+
+static gboolean
+remove_scsi_devices(gpointer key, gpointer value, gpointer data)
+{
+ if (!strncmp((gchar *) key, "SCSI", 4)) {
+ g_free((gchar *) key);
+ g_free((GtkTreeIter *) value);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* SCSI support by Pascal F.Martin <pascalmartin@earthlink.net> */
+void
+scan_scsi(void)
+{
+ FILE *proc_scsi;
+ gchar buffer[256], *buf;
+ gint n = 0;
+ gint scsi_controller;
+ gint scsi_channel;
+ gint scsi_id;
+ gint scsi_lun;
+ gchar *vendor = NULL, *revision = NULL, *model = NULL;
+
+ /* remove old devices from global device table */
+ g_hash_table_foreach_remove(devices, remove_scsi_devices, NULL);
+
+ if (!g_file_test("/proc/scsi/scsi", G_FILE_TEST_EXISTS))
+ return;
+
+ storage_list = g_strconcat(storage_list, "\n[SCSI Disks]\n", NULL);
+
+ proc_scsi = fopen("/proc/scsi/scsi", "r");
+ while (fgets(buffer, 256, proc_scsi)) {
+ buf = g_strstrip(buffer);
+ if (!strncmp(buf, "Host: scsi", 10)) {
+ sscanf(buf,
+ "Host: scsi%d Channel: %d Id: %d Lun: %d",
+ &scsi_controller, &scsi_channel, &scsi_id, &scsi_lun);
+
+ n++;
+ } else if (!strncmp(buf, "Vendor: ", 8)) {
+ char *p;
+ char *rev = strstr(buf, "Rev: ");
+
+ model = strstr(buf, "Model: ");
+
+ if (model == NULL) {
+ model = buf + strlen(buf);
+ }
+ p = model;
+ while (*(--p) == ' ');
+ *(++p) = 0;
+ vendor = g_strdup(buf + 8);
+
+ if (rev != NULL) {
+ revision = g_strdup(rev + 5);
+ } else {
+ rev = model + strlen(model);
+ }
+ p = rev;
+ while (*(--p) == ' ');
+ *(++p) = 0;
+ model = g_strdup_printf("%s %s", vendor, model + 7);
+
+ } else if (!strncmp(buf, "Type: ", 8)) {
+ char *p = strstr(buf, "ANSI SCSI revi");
+ gchar *type = NULL, *icon = NULL;
+
+ if (p != NULL) {
+ while (*(--p) == ' ');
+ *(++p) = 0;
+
+ static struct {
+ char *type;
+ char *label;
+ char *icon;
+ } type2icon[] = {
+ { "Direct-Access", "Disk", "hdd"},
+ { "Sequential-Access", "Tape", "tape"},
+ { "Printer", "Printer", "lpr"},
+ { "WORM", "CD-ROM", "cd"},
+ { "CD-ROM", "CD-ROM", "cd"},
+ { "Scanner", "Scanner", "scanner"},
+ { NULL, "Generic", "scsi"}
+ };
+ int i;
+
+ for (i = 0; type2icon[i].type != NULL; i++)
+ if (!strcmp(buf + 8, type2icon[i].type))
+ break;
+
+ type = type2icon[i].label;
+ icon = type2icon[i].icon;
+ }
+
+ gchar *devid = g_strdup_printf("SCSI%d", n);
+ storage_list = g_strdup_printf("%s$%s$%s=\n", storage_list, devid, model);
+ storage_icons = g_strdup_printf("%sIcon$%s$%s=%s.png\n", storage_icons, devid, model, icon);
+
+ gchar *strhash = g_strdup_printf("[Device Information]\n"
+ "Model=%s\n"
+ "Type=%s\n"
+ "Revision=%s\n"
+ "[SCSI Controller]\n"
+ "Controller=scsi%d\n"
+ "Channel=%d\n"
+ "ID=%d\n" "LUN=%d\n",
+ model,
+ type,
+ revision,
+ scsi_controller,
+ scsi_channel,
+ scsi_id,
+ scsi_lun);
+ g_hash_table_insert(devices, devid, strhash);
+
+ g_free(model);
+ g_free(revision);
+ g_free(vendor);
+ }
+ }
+ fclose(proc_scsi);
+}
+
+static gboolean
+remove_ide_devices(gpointer key, gpointer value, gpointer data)
+{
+ if (!strncmp((gchar *) key, "IDE", 3)) {
+ g_free((gchar *) key);
+ g_free((gchar *) value);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void
+scan_ide(void)
+{
+ FILE *proc_ide;
+ gchar *device, iface, *model, *media, *pgeometry = NULL, *lgeometry =
+ NULL;
+ gint n = 0, i = 0, cache;
+
+ /* remove old devices from global device table */
+ g_hash_table_foreach_remove(devices, remove_ide_devices, NULL);
+
+ storage_list = g_strdup_printf("%s\n[IDE Disks]\n", storage_list);
+
+ iface = 'a';
+ for (i = 0; i <= 16; i++) {
+ device = g_strdup_printf("/proc/ide/hd%c/model", iface);
+ if (g_file_test(device, G_FILE_TEST_EXISTS)) {
+ gchar buf[64];
+
+ cache = 0;
+
+ proc_ide = fopen(device, "r");
+ fgets(buf, 64, proc_ide);
+ fclose(proc_ide);
+
+ buf[strlen(buf) - 1] = 0;
+
+ model = g_strdup(buf);
+
+ g_free(device);
+
+ device = g_strdup_printf("/proc/ide/hd%c/media", iface);
+ proc_ide = fopen(device, "r");
+ fgets(buf, 64, proc_ide);
+ fclose(proc_ide);
+ buf[strlen(buf) - 1] = 0;
+
+ media = g_strdup(buf);
+
+ g_free(device);
+
+ device = g_strdup_printf("/proc/ide/hd%c/cache", iface);
+ if (g_file_test(device, G_FILE_TEST_EXISTS)) {
+ proc_ide = fopen(device, "r");
+ fscanf(proc_ide, "%d", &cache);
+ fclose(proc_ide);
+ }
+ g_free(device);
+
+ device = g_strdup_printf("/proc/ide/hd%c/geometry", iface);
+ if (g_file_test(device, G_FILE_TEST_EXISTS)) {
+ gchar *tmp;
+
+ proc_ide = fopen(device, "r");
+
+ fgets(buf, 64, proc_ide);
+ for (tmp = buf; *tmp; tmp++) {
+ if (*tmp >= '0' && *tmp <= '9')
+ break;
+ }
+
+ pgeometry = g_strdup(g_strstrip(tmp));
+
+ fgets(buf, 64, proc_ide);
+ for (tmp = buf; *tmp; tmp++) {
+ if (*tmp >= '0' && *tmp <= '9')
+ break;
+ }
+ lgeometry = g_strdup(g_strstrip(tmp));
+
+ fclose(proc_ide);
+ }
+ g_free(device);
+
+ n++;
+
+ gchar *devid = g_strdup_printf("IDE%d", n);
+
+ storage_list = g_strdup_printf("%s$%s$%s=\n", storage_list,
+ devid, model);
+ storage_icons = g_strdup_printf("%sIcon$%s$%s=%s.png\n", storage_icons, devid,
+ model, g_str_equal(media, "cdrom") ? \
+ "cdrom" : "hdd");
+
+ gchar *strhash = g_strdup_printf("[Device Information]\n"
+ "Model=%s\n"
+ "Device Name=hd%c\n"
+ "Media=%s\n" "Cache=%dkb\n",
+ model, iface, media, cache);
+ if (pgeometry && lgeometry)
+ strhash = g_strdup_printf("%s[Geometry]\n"
+ "Physical=%s\n"
+ "Logical=%s\n",
+ strhash, pgeometry, lgeometry);
+
+ g_hash_table_insert(devices, devid, strhash);
+
+ g_free(model);
+ model = "";
+
+ g_free(pgeometry);
+ pgeometry = NULL;
+ g_free(lgeometry);
+ lgeometry = NULL;
+ } else
+ g_free(device);
+
+ iface++;
+ }
+}
diff --git a/hardinfo2/arch/linux/common/uptime.h b/hardinfo2/arch/linux/common/uptime.h
new file mode 100644
index 00000000..cf339bf3
--- /dev/null
+++ b/hardinfo2/arch/linux/common/uptime.h
@@ -0,0 +1,75 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static UptimeInfo *
+computer_get_uptime(void)
+{
+ UptimeInfo *ui = g_new0(UptimeInfo, 1);
+ FILE *procuptime;
+ gulong minutes;
+
+ if ((procuptime = fopen("/proc/uptime", "r")) != NULL) {
+ fscanf(procuptime, "%lu", &minutes);
+ ui->minutes = minutes / 60;
+ fclose(procuptime);
+ } else {
+ return NULL;
+ }
+
+ ui->hours = ui->minutes / 60;
+ ui->minutes %= 60;
+ ui->days = ui->hours / 24;
+ ui->hours %= 24;
+
+ return ui;
+}
+
+static gchar *
+computer_get_formatted_uptime()
+{
+ UptimeInfo *ui;
+ gchar *tmp;
+
+ ui = computer_get_uptime();
+
+ /* FIXME: Use ngettext */
+#define plural(x) ((x > 1) ? "s" : "")
+
+
+ if (ui->days < 1) {
+ if (ui->hours < 1) {
+ tmp =
+ g_strdup_printf("%d minute%s", ui->minutes,
+ plural(ui->minutes));
+ } else {
+ tmp =
+ g_strdup_printf("%d hour%s, %d minute%s", ui->hours,
+ plural(ui->hours), ui->minutes,
+ plural(ui->minutes));
+ }
+ } else {
+ tmp =
+ g_strdup_printf("%d day%s, %d hour%s and %d minute%s",
+ ui->days, plural(ui->days), ui->hours,
+ plural(ui->hours), ui->minutes,
+ plural(ui->minutes));
+ }
+
+ g_free(ui);
+ return tmp;
+}
diff --git a/hardinfo2/arch/linux/common/usb.h b/hardinfo2/arch/linux/common/usb.h
new file mode 100644
index 00000000..a52be2cb
--- /dev/null
+++ b/hardinfo2/arch/linux/common/usb.h
@@ -0,0 +1,132 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+static gboolean
+remove_usb_devices(gpointer key, gpointer value, gpointer data)
+{
+ if (!strncmp((gchar *) key, "USB", 3)) {
+ GtkTreeIter *iter = (GtkTreeIter *) data;
+
+ g_free((gchar *) value);
+ g_free(iter);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gchar *usb_list = NULL;
+void
+scan_usb(void)
+{
+ FILE *dev;
+ gchar buffer[128];
+ gchar *tmp, *manuf = NULL, *product = NULL, *mxpwr;
+ gint bus, level, port, classid, trash;
+ gint vendor, prodid;
+ gfloat ver, rev, speed;
+ int n = 0;
+
+ dev = fopen("/proc/bus/usb/devices", "r");
+ if (!dev)
+ return;
+
+ if (usb_list) {
+ g_hash_table_foreach_remove(devices, remove_usb_devices, NULL);
+ g_free(usb_list);
+ }
+ usb_list = g_strdup("");
+
+ while (fgets(buffer, 128, dev)) {
+ tmp = buffer;
+
+ switch (*tmp) {
+ case 'T':
+ sscanf(tmp,
+ "T: Bus=%d Lev=%d Prnt=%d Port=%d Cnt=%d Dev#=%d Spd=%f",
+ &bus, &level, &trash, &port, &trash, &trash, &speed);
+ break;
+ case 'D':
+ sscanf(tmp, "D: Ver=%f Cls=%x", &ver, &classid);
+ break;
+ case 'P':
+ sscanf(tmp, "P: Vendor=%x ProdID=%x Rev=%f",
+ &vendor, &prodid, &rev);
+ break;
+ case 'S':
+ if (strstr(tmp, "Manufacturer=")) {
+ manuf = g_strdup(strchr(tmp, '=') + 1);
+ remove_linefeed(manuf);
+ } else if (strstr(tmp, "Product=")) {
+ product = g_strdup(strchr(tmp, '=') + 1);
+ remove_linefeed(product);
+ }
+ break;
+ case 'C':
+ mxpwr = strstr(buffer, "MxPwr=") + 6;
+
+ tmp = g_strdup_printf("USB%d", ++n);
+
+ if (*product == '\0') {
+ g_free(product);
+ if (classid == 9) {
+ product = g_strdup_printf("USB %.2f Hub", ver);
+ } else {
+ product = g_strdup_printf("Unknown USB %.2f Device (class %d)",
+ ver, classid);
+ }
+ }
+
+
+ if (classid == 9) { /* hub */
+ usb_list = g_strdup_printf("%s[%s#%d]\n",
+ usb_list, product, n);
+ } else { /* everything else */
+ usb_list = g_strdup_printf("%s$%s$%s=\n",
+ usb_list, tmp, product);
+
+ gchar *strhash = g_strdup_printf("[Device Information]\n"
+ "Product=%s\n"
+ "Manufacturer=%s\n"
+ "[Port #%d]\n"
+ "Speed=%.2fMbit/s\n"
+ "Max Current=%s\n"
+ "[Misc]\n"
+ "USB Version=%.2f\n"
+ "Revision=%.2f\n"
+ "Class=0x%x\n"
+ "Vendor=0x%x\n"
+ "Product ID=0x%x\n"
+ "Bus=%d\n" "Level=%d\n",
+ product, manuf,
+ port, speed, mxpwr,
+ ver, rev, classid,
+ vendor, prodid, bus, level);
+
+ g_hash_table_insert(devices, tmp, strhash);
+ }
+
+ g_free(manuf);
+ g_free(product);
+ manuf = g_strdup("");
+ product = g_strdup("");
+ }
+ }
+
+ fclose(dev);
+}
diff --git a/hardinfo2/arch/linux/x86/alsa.h b/hardinfo2/arch/linux/x86/alsa.h
new file mode 120000
index 00000000..0216845a
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/alsa.h
@@ -0,0 +1 @@
+../../linux/common/alsa.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/filesystem.h b/hardinfo2/arch/linux/x86/filesystem.h
new file mode 120000
index 00000000..6b325b40
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/filesystem.h
@@ -0,0 +1 @@
+../../linux/common/filesystem.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/inputdevices.h b/hardinfo2/arch/linux/x86/inputdevices.h
new file mode 120000
index 00000000..b9226a29
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/inputdevices.h
@@ -0,0 +1 @@
+../../linux/common/inputdevices.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/loadavg.h b/hardinfo2/arch/linux/x86/loadavg.h
new file mode 120000
index 00000000..daaed6d5
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/loadavg.h
@@ -0,0 +1 @@
+../../linux/common/loadavg.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/memory.h b/hardinfo2/arch/linux/x86/memory.h
new file mode 120000
index 00000000..5ffc013e
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/memory.h
@@ -0,0 +1 @@
+../../linux/common/memory.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/modules.h b/hardinfo2/arch/linux/x86/modules.h
new file mode 120000
index 00000000..8ce5a808
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/modules.h
@@ -0,0 +1 @@
+../../linux/common/modules.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/os.h b/hardinfo2/arch/linux/x86/os.h
new file mode 120000
index 00000000..ef547be5
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/os.h
@@ -0,0 +1 @@
+../../linux/common/os.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/pci.h b/hardinfo2/arch/linux/x86/pci.h
new file mode 120000
index 00000000..63760048
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/pci.h
@@ -0,0 +1 @@
+../../linux/common/pci.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/processor.h b/hardinfo2/arch/linux/x86/processor.h
new file mode 100644
index 00000000..395b6aa3
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/processor.h
@@ -0,0 +1,257 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+
+/*
+ * This function is partly based on x86cpucaps
+ * by Osamu Kayasono <jacobi@jcom.home.ne.jp>
+ */
+static void
+get_processor_strfamily(Processor *processor)
+{
+ gint family = processor->family;
+ gint model = processor->model;
+
+ if (g_str_equal(processor->vendor_id, "GenuineIntel")) {
+ if (family == 4) {
+ processor->strmodel = g_strdup("i486 series");
+ } else if (family == 5) {
+ if (model < 4) {
+ processor->strmodel = g_strdup("Pentium Classic");
+ } else {
+ processor->strmodel = g_strdup("Pentium MMX");
+ }
+ } else if (family == 6) {
+ if (model <= 1) {
+ processor->strmodel = g_strdup("Pentium Pro");
+ } else if (model < 7) {
+ processor->strmodel = g_strdup("Pentium II/Pentium II Xeon/Celeron");
+ } else if (model == 9) {
+ processor->strmodel = g_strdup("Pentium M");
+ } else {
+ processor->strmodel = g_strdup("Pentium III/Pentium III Xeon/Celeron");
+ }
+ } else if (family > 6) {
+ processor->strmodel = g_strdup("Pentium 4");
+ } else {
+ processor->strmodel = g_strdup("i386 class");
+ }
+ } else if (g_str_equal(processor->vendor_id, "AuthenticAMD")) {
+ if (family == 4) {
+ if (model <= 9) {
+ processor->strmodel = g_strdup("AMD i80486 series");
+ } else {
+ processor->strmodel = g_strdup("AMD 5x86");
+ }
+ } else if (family == 5) {
+ if (model <= 3) {
+ processor->strmodel = g_strdup("AMD K5");
+ } else if (model <= 7) {
+ processor->strmodel = g_strdup("AMD K6");
+ } else if (model == 8) {
+ processor->strmodel = g_strdup("AMD K6-2");
+ } else if (model == 9) {
+ processor->strmodel = g_strdup("AMD K6-III");
+ } else {
+ processor->strmodel = g_strdup("AMD K6-2+/III+");
+ }
+ } else if (family == 6) {
+ if (model == 1) {
+ processor->strmodel = g_strdup("AMD Athlon (K7");
+ } else if (model == 2) {
+ processor->strmodel = g_strdup("AMD Athlon (K75)");
+ } else if (model == 3) {
+ processor->strmodel = g_strdup("AMD Duron (Spitfire)");
+ } else if (model == 4) {
+ processor->strmodel = g_strdup("AMD Athlon (Thunderbird)");
+ } else if (model == 6) {
+ processor->strmodel = g_strdup("AMD Athlon XP/MP/4 (Palomino)");
+ } else if (model == 7) {
+ processor->strmodel = g_strdup("AMD Duron (Morgan)");
+ } else if (model == 8) {
+ processor->strmodel = g_strdup("AMD Athlon XP/MP (Thoroughbred)");
+ } else if (model == 10) {
+ processor->strmodel = g_strdup("AMD Athlon XP/MP (Barton)");
+ } else {
+ processor->strmodel = g_strdup("AMD Athlon (unknown)");
+ }
+ } else if (family > 6) {
+ processor->strmodel = g_strdup("AMD Opteron/Athlon64/FX");
+ } else {
+ processor->strmodel = g_strdup("AMD i386 class");
+ }
+ } else if (g_str_equal(processor->vendor_id, "CyrixInstead")) {
+ if (family == 4) {
+ processor->strmodel = g_strdup("Cyrix 5x86");
+ } else if (family == 5) {
+ processor->strmodel = g_strdup("Cyrix M1 (6x86)");
+ } else if (family == 6) {
+ if (model == 0) {
+ processor->strmodel = g_strdup("Cyrix M2 (6x86MX)");
+ } else if (model <= 5) {
+ processor->strmodel = g_strdup("VIA Cyrix III (M2 core)");
+ } else if (model == 6) {
+ processor->strmodel = g_strdup("VIA Cyrix III (WinChip C5A)");
+ } else if (model == 7) {
+ processor->strmodel = g_strdup("VIA Cyrix III (WinChip C5B/C)");
+ } else {
+ processor->strmodel = g_strdup("VIA Cyrix III (WinChip C5C-T)");
+ }
+ } else {
+ processor->strmodel = g_strdup("Cyrix i386 class");
+ }
+ } else if (g_str_equal(processor->vendor_id, "CentaurHauls")) {
+ if (family == 5) {
+ if (model <= 4) {
+ processor->strmodel = g_strdup("Centaur WinChip C6");
+ } else if (model <= 8) {
+ processor->strmodel = g_strdup("Centaur WinChip 2");
+ } else {
+ processor->strmodel = g_strdup("Centaur WinChip 2A");
+ }
+ } else {
+ processor->strmodel = g_strdup("Centaur i386 class");
+ }
+ } else if (g_str_equal(processor->vendor_id, "GenuineTMx86")) {
+ processor->strmodel = g_strdup("Transmeta Crusoe TM3x00/5x00");
+ } else {
+ processor->strmodel = g_strdup("Unknown");
+ }
+}
+
+static Processor *
+computer_get_processor(void)
+{
+ Processor *processor;
+ FILE *cpuinfo;
+ gchar buffer[128];
+
+ cpuinfo = fopen("/proc/cpuinfo", "r");
+ if (!cpuinfo)
+ return NULL;
+
+ processor = g_new0(Processor, 1);
+ while (fgets(buffer, 128, cpuinfo)) {
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+
+ if (tmp[0] && tmp[1]) {
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
+
+ get_str("model name", processor->model_name);
+ get_str("vendor_id", processor->vendor_id);
+ get_str("flags", processor->flags);
+ get_int("cache size", processor->cache_size);
+ get_float("cpu MHz", processor->cpu_mhz);
+ get_float("bogomips", processor->bogomips);
+
+ get_str("fpu", processor->has_fpu);
+
+ get_str("fdiv_bug", processor->bug_fdiv);
+ get_str("hlt_bug", processor->bug_hlt);
+ get_str("f00f_bug", processor->bug_f00f);
+ get_str("coma_bug", processor->bug_coma);
+
+ get_int("model", processor->model);
+ get_int("cpu family", processor->family);
+ get_int("stepping", processor->stepping);
+ }
+ g_strfreev(tmp);
+ }
+
+ get_processor_strfamily(processor);
+
+ fclose(cpuinfo);
+
+ return processor;
+}
+
+static struct {
+ char *name, *meaning;
+} flag_meaning[] = {
+ { "3dnow", "3DNow! Technology" },
+ { "3dnowext", "Extended 3DNow! Technology" },
+ { "fpu", "Floating Point Unit" },
+ { "vme", "Virtual 86 Mode Extension" },
+ { "de", "Debug Extensions - I/O breakpoints" },
+ { "pse", "Page Size Extensions (4MB pages)" },
+ { "tsc", "Time Stamp Counter and RDTSC instruction" },
+ { "msr", "Model Specific Registers" },
+ { "pae", "Physical Address Extensions (36-bit address, 2MB pages)" },
+ { "mce", "Machine Check Architeture" },
+ { "cx8", "CMPXCHG8 instruction" },
+ { "apic", "Advanced Programmable Interrupt Controller" },
+ { "sep", "Fast System Call (SYSENTER/SYSEXIT instructions)" },
+ { "mtrr", "Memory Type Range Registers" },
+ { "pge", "Page Global Enable" },
+ { "mca", "Machine Check Architecture" },
+ { "cmov", "Conditional Move instruction" },
+ { "pat", "Page Attribute Table" },
+ { "pse36", "36bit Page Size Extensions" },
+ { "psn", "96 bit Processor Serial Number" },
+ { "mmx", "MMX technology" },
+ { "mmxext", "Extended MMX Technology" },
+ { "cflush", "Cache Flush" },
+ { "dtes", "Debug Trace Store" },
+ { "fxsr", "FXSAVE and FXRSTOR instructions" },
+ { "kni", "Streaming SIMD instructions" },
+ { "xmm", "Streaming SIMD instructions" },
+ { "ht", "HyperThreading" },
+ { "mp", "Multiprocessing Capable" },
+ { "sse", "SSE instructions" },
+ { "sse2", "SSE2 (WNI) instructions" },
+ { "acc", "Automatic Clock Control" },
+ { "ia64", "IA64 Instructions" },
+ { "syscall", "SYSCALL and SYSEXIT instructions" },
+ { "nx", "No-execute Page Protection" },
+ { "xd", "Execute Disable" },
+ { "clflush", "Cache Line Flush instruction" },
+ { "acpi", "Thermal Monitor and Software Controlled Clock Facilities" },
+ { "dts", "Debug Store" },
+ { "ss", "Self Snoop" },
+ { "tm", "Thermal Monitor" },
+ { "pb", "Pending Break Enable" },
+ { NULL, NULL}
+};
+
+gchar *
+processor_get_capabilities_from_flags(gchar * strflags)
+{
+ /* FIXME: * Separate between processor capabilities, additional instructions and whatnot. */
+ gchar **flags, **old;
+ gchar *tmp = "";
+ gint i;
+
+ flags = g_strsplit(strflags, " ", 0);
+ old = flags;
+
+ while (*flags) {
+ gchar *meaning = "";
+ for (i = 0; flag_meaning[i].name != NULL; i++) {
+ if (!strcmp(*flags, flag_meaning[i].name)) {
+ meaning = flag_meaning[i].meaning;
+ break;
+ }
+ }
+
+ tmp = g_strdup_printf("%s%s=%s\n", tmp, *flags, meaning);
+ *flags++;
+ }
+
+ g_strfreev(old);
+ return tmp;
+}
diff --git a/hardinfo2/arch/linux/x86/samba.h b/hardinfo2/arch/linux/x86/samba.h
new file mode 120000
index 00000000..9227f722
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/samba.h
@@ -0,0 +1 @@
+../../linux/common/samba.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/sensors.h b/hardinfo2/arch/linux/x86/sensors.h
new file mode 120000
index 00000000..35e5f37a
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/sensors.h
@@ -0,0 +1 @@
+../../linux/common/sensors.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/storage.h b/hardinfo2/arch/linux/x86/storage.h
new file mode 120000
index 00000000..55b68de3
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/storage.h
@@ -0,0 +1 @@
+../../linux/common/storage.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/uptime.h b/hardinfo2/arch/linux/x86/uptime.h
new file mode 120000
index 00000000..78c026ff
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/uptime.h
@@ -0,0 +1 @@
+../../linux/common/uptime.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86/usb.h b/hardinfo2/arch/linux/x86/usb.h
new file mode 120000
index 00000000..8b8fbb5d
--- /dev/null
+++ b/hardinfo2/arch/linux/x86/usb.h
@@ -0,0 +1 @@
+../../linux/common/usb.h \ No newline at end of file
diff --git a/hardinfo2/arch/linux/x86_64 b/hardinfo2/arch/linux/x86_64
new file mode 120000
index 00000000..f4bad791
--- /dev/null
+++ b/hardinfo2/arch/linux/x86_64
@@ -0,0 +1 @@
+x86 \ No newline at end of file
diff --git a/hardinfo2/benchmark.c b/hardinfo2/benchmark.c
new file mode 100644
index 00000000..e15c0dfe
--- /dev/null
+++ b/hardinfo2/benchmark.c
@@ -0,0 +1,150 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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>
+#include <iconcache.h>
+#include <shell.h>
+#include <config.h>
+
+enum {
+ BENCHMARK_ZLIB,
+ BENCHMARK_FIB,
+ BENCHMARK_MD5,
+ BENCHMARK_SHA1,
+} Entries;
+
+static ModuleEntry hi_entries[] = {
+ {"CPU ZLib", "compress.png"},
+ {"CPU Fibonacci", "module.png"},
+ {"CPU MD5", "module.png"},
+ {"CPU SHA1", "module.png"}
+};
+
+static gchar *
+benchmark_include_results(gchar *results, const gchar *benchmark)
+{
+ GKeyFile *conf;
+ gchar **machines;
+ int i;
+
+ conf = g_key_file_new();
+ g_key_file_load_from_file(conf, PREFIX "benchmark.conf", 0, NULL);
+
+ machines = g_key_file_get_keys(conf, benchmark, NULL, NULL);
+ for (i = 0; machines && machines[i]; i++) {
+ gchar *value = g_key_file_get_value(conf, benchmark, machines[i], NULL);
+ results = g_strconcat(results, machines[i], "=", value, "\n", NULL);
+ g_free(value);
+ }
+
+ results = g_strconcat(results, "[$ShellParam$]\n"
+ "Zebra=1\n", NULL);
+
+ g_strfreev(machines);
+ g_key_file_free(conf);
+
+ return results;
+}
+
+#include <arch/common/fib.h>
+#include <arch/common/zlib.h>
+#include <arch/common/md5.h>
+#include <arch/common/sha1.h>
+
+static gchar *bench_zlib = NULL,
+ *bench_fib = NULL,
+ *bench_md5 = NULL,
+ *bench_sha1 = NULL;
+
+gchar *
+hi_info(gint entry)
+{
+ switch (entry) {
+ case BENCHMARK_ZLIB:
+ if (bench_zlib)
+ return g_strdup(bench_zlib);
+
+ bench_zlib = benchmark_zlib();
+ return g_strdup(bench_zlib);
+
+ case BENCHMARK_MD5:
+ if (bench_md5)
+ return g_strdup(bench_md5);
+
+ bench_md5 = benchmark_md5();
+ return g_strdup(bench_md5);
+
+ case BENCHMARK_FIB:
+ if (bench_fib)
+ return g_strdup(bench_fib);
+
+ bench_fib = benchmark_fib();
+ return g_strdup(bench_fib);
+
+ case BENCHMARK_SHA1:
+ if (bench_sha1)
+ return g_strdup(bench_sha1);
+
+ bench_sha1 = benchmark_sha1();
+ return g_strdup(bench_sha1);
+
+ default:
+ return g_strdup("[Empty]\n");
+ }
+}
+
+void
+hi_reload(gint entry)
+{
+ switch (entry) {
+ case BENCHMARK_ZLIB:
+ if (bench_zlib) g_free(bench_zlib);
+ bench_zlib = benchmark_zlib();
+ break;
+ case BENCHMARK_MD5:
+ if (bench_md5) g_free(bench_md5);
+ bench_md5 = benchmark_md5();
+ break;
+ case BENCHMARK_FIB:
+ if (bench_fib) g_free(bench_fib);
+ bench_fib = benchmark_fib();
+ break;
+ case BENCHMARK_SHA1:
+ if (bench_sha1) g_free(bench_sha1);
+ bench_sha1 = benchmark_sha1();
+ break;
+ }
+}
+
+gint
+hi_n_entries(void)
+{
+ return G_N_ELEMENTS(hi_entries) - 1;
+}
+
+GdkPixbuf *
+hi_icon(gint entry)
+{
+ return icon_cache_get_pixbuf(hi_entries[entry].icon);
+}
+
+gchar *
+hi_name(gint entry)
+{
+ return hi_entries[entry].name;
+}
diff --git a/hardinfo2/benchmark.conf b/hardinfo2/benchmark.conf
new file mode 100644
index 00000000..0deda857
--- /dev/null
+++ b/hardinfo2/benchmark.conf
@@ -0,0 +1,29 @@
+[ZLib]
+# RAM:1024,Board:GA-7NNXP,OS:Linux 2.6.15
+AMD Athlon XP 3200+=4.33
+AMD Athlon XP 2200+=7.38
+# RAM:128,Board:XingLing,OS:Linux 2.4.20
+Intel Pentium 200MHz=117.79
+# RAM:1024,Board:GA-7NNXP,OS:Linux 2.6.15
+Valgrind/AMD Athlon XP 3200+=155.91
+# RAM:32,Board:Toshiba Libretto 50CT,OS:Linux 2.4.20
+Intel Pentium 75MHz=173.06
+
+[Fibonacci]
+# RAM:1024,Board:GA-7NNXP,OS:Linux 2.6.15
+AMD Athlon XP 3200+=6.64
+#AMD Athlon XP 2200+=3.54
+# RAM:128,Board:XingLing,OS:Linux 2.4.20
+#Intel Pentium 200MHz=35.02
+# RAM:32,Board:Toshiba Libretto 50CT,OS:Linux 2.4.20
+#Intel Pentium 75MHz=110.20
+# RAM:1024,Board:GA-7NNXP,OS:Linux 2.6.15
+#Valgrind/AMD Athlon XP 3200+=164.92
+
+[MD5]
+# RAM:1024,Board:GA-7NNXP,OS:Linux 2.6.15
+AMD Athlon XP 3200+=5.04
+
+[SHA1]
+# RAM:1024,Board:GA-7NNXP,OS:Linux 2.6.15
+AMD Athlon XP 3200+=4.88
diff --git a/hardinfo2/benchmark.data b/hardinfo2/benchmark.data
new file mode 100644
index 00000000..efb964db
--- /dev/null
+++ b/hardinfo2/benchmark.data
Binary files differ
diff --git a/hardinfo2/callbacks.c b/hardinfo2/callbacks.c
new file mode 100644
index 00000000..b4d80244
--- /dev/null
+++ b/hardinfo2/callbacks.c
@@ -0,0 +1,72 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 <gtk/gtk.h>
+#include <callbacks.h>
+#include <iconcache.h>
+#include <config.h>
+#include <shell.h>
+
+void cb_refresh()
+{
+ shell_do_reload();
+}
+
+void cb_left_pane()
+{
+ gboolean visible;
+
+ visible = shell_action_get_active("LeftPaneAction");
+ shell_set_left_pane_visible(visible);
+}
+
+void cb_toolbar()
+{
+ gboolean visible;
+
+ visible = shell_action_get_active("ToolbarAction");
+ shell_ui_manager_set_visible("/MainMenuBarAction", visible);
+}
+
+void cb_about()
+{
+ GtkWidget *about;
+
+ about = gtk_about_dialog_new();
+ gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(about), "HardInfo");
+ gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about), VERSION);
+ gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about),
+ "Copyright \302\251 2003-2006 "
+ "Leandro A. F. Pereira");
+ gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about),
+ "System information and benchmark tool");
+ gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about),
+ icon_cache_get_pixbuf("logo.png"));
+
+ gtk_dialog_run(GTK_DIALOG(about));
+ gtk_widget_destroy(about);
+}
+
+void cb_generate_report()
+{
+ g_print("generate report\n");
+}
+
+void cb_quit(void)
+{
+ gtk_main_quit();
+}
diff --git a/hardinfo2/callbacks.h b/hardinfo2/callbacks.h
new file mode 100644
index 00000000..f0f28322
--- /dev/null
+++ b/hardinfo2/callbacks.h
@@ -0,0 +1,29 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 __CALLBACKS_H__
+#define __CALLBACKS_H__
+
+void cb_about();
+void cb_generate_report();
+void cb_quit();
+void cb_refresh();
+void cb_left_pane();
+void cb_toolbar();
+
+#endif /* __CALLBACKS_H__ */
diff --git a/hardinfo2/computer.c b/hardinfo2/computer.c
new file mode 100644
index 00000000..9a721133
--- /dev/null
+++ b/hardinfo2/computer.c
@@ -0,0 +1,363 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <config.h>
+#include <time.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include <sys/stat.h>
+
+#include <hardinfo.h>
+#include <iconcache.h>
+#include <shell.h>
+
+#include <expr.h>
+
+enum {
+ COMPUTER_SUMMARY,
+ COMPUTER_PROCESSORS,
+ COMPUTER_OPERATING_SYSTEM,
+ COMPUTER_LANGUAGE,
+ COMPUTER_SENSORS,
+ COMPUTER_FILESYSTEMS,
+ COMPUTER_SHARES,
+ COMPUTER_DISPLAY,
+/* COMPUTER_LOADGRAPH,*/
+} Entries;
+
+static ModuleEntry hi_entries[] = {
+ {"Summary", "summary.png"},
+ {"Processor", "processor.png"},
+ {"Operating System", "os.png"},
+ {"Languages", "language.png"},
+ {"Sensors", "therm.png"},
+ {"Filesystems", "dev_removable.png"},
+ {"Shared Directories", "shares.png"},
+ {"Display", "monitor.png"},
+/* {"<s>LoadGraph</s>", "summary.png"}*/
+};
+
+#include "computer.h"
+
+static GHashTable *moreinfo = NULL;
+
+#include <arch/common/languages.h>
+#include <arch/this/alsa.h>
+#include <arch/common/display.h>
+#include <arch/this/loadavg.h>
+#include <arch/this/memory.h>
+#include <arch/this/uptime.h>
+#include <arch/this/processor.h>
+#include <arch/this/os.h>
+#include <arch/this/filesystem.h>
+#include <arch/this/samba.h>
+#include <arch/this/sensors.h>
+
+static Computer *
+computer_get_info(void)
+{
+ Computer *computer;
+
+ computer = g_new0(Computer, 1);
+
+ if (moreinfo) {
+#ifdef g_hash_table_unref
+ g_hash_table_unref(moreinfo);
+#else
+ g_free(moreinfo);
+#endif
+ }
+
+ moreinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+
+ shell_status_update("Getting processor information...");
+ computer->processor = computer_get_processor();
+
+ shell_status_update("Getting memory information...");
+ computer->memory = computer_get_memory();
+
+ shell_status_update("Getting operating system information...");
+ computer->os = computer_get_os();
+
+ shell_status_update("Getting display information...");
+ computer->display = computer_get_display();
+
+ shell_status_update("Getting sound card information...");
+ computer->alsa = computer_get_alsainfo();
+
+ shell_status_update("Getting mounted file system information...");
+ scan_filesystems();
+
+ shell_status_update("Getting shared directories...");
+ scan_shared_directories();
+
+ shell_status_update("Reading sensors...");
+ read_sensors();
+
+ computer->date_time = "...";
+ return computer;
+}
+
+void
+hi_reload(gint entry)
+{
+ switch (entry) {
+ case COMPUTER_FILESYSTEMS:
+ scan_filesystems();
+ break;
+ case COMPUTER_SENSORS:
+ read_sensors();
+ break;
+ }
+}
+
+gchar *
+hi_more_info(gchar * entry)
+{
+ gchar *info = (gchar *) g_hash_table_lookup(moreinfo, entry);
+
+ if (info)
+ return g_strdup(info);
+
+ return g_strdup_printf("[Empty %s]", entry);
+}
+
+gchar *
+hi_get_field(gchar * field)
+{
+ gchar *tmp;
+
+ if (!strcmp(field, "Memory")) {
+ MemoryInfo *mi;
+
+ mi = computer_get_memory();
+ tmp = g_strdup_printf("%dMB (%dMB used)", mi->total, mi->used);
+
+ g_free(mi);
+ } else if (!strcmp(field, "Random")) {
+ return g_strdup_printf("%d", rand() % 200);
+ /*} else if (!strcmp(field, "Used Memory")) {
+ MemoryInfo *mi;
+
+ mi = computer_get_memory();
+ tmp = g_strdup_printf("%d", mi->used);
+
+ g_free(mi);*/
+ } else if (!strcmp(field, "Uptime")) {
+ tmp = computer_get_formatted_uptime();
+ } else if (!strcmp(field, "Date/Time")) {
+ time_t t = time(NULL);
+
+ tmp = g_new0(gchar, 32);
+ strftime(tmp, 32, "%D / %R", localtime(&t));
+ } else if (!strcmp(field, "Load Average")) {
+ tmp = computer_get_formatted_loadavg();
+ } else {
+ tmp = g_strdup("");
+ }
+
+ return tmp;
+}
+
+gchar *
+hi_info(gint entry)
+{
+ static Computer *computer = NULL;
+ static gchar *tmp = NULL;
+
+ if (tmp != NULL) {
+ g_free(tmp);
+ tmp = NULL;
+ }
+
+ if (!computer) {
+ computer = computer_get_info();
+ }
+
+ switch (entry) {
+ case COMPUTER_SENSORS:
+ return g_strdup_printf("[$ShellParam$]\n"
+ "ReloadInterval=3000\n"
+ "%s", sensors);
+ case COMPUTER_SHARES:
+ return g_strdup_printf("[SAMBA]\n"
+ "%s", shares_list);
+/* case COMPUTER_LOADGRAPH:
+ return g_strdup_printf("[$ShellParam$]\n"
+ "ViewType=2\n"
+ "UpdateInterval$Used Memory=500\n"
+ "LoadGraphInterval$Used Memory=50\n"
+ "LoadGraphInterval$Random=50\n"
+ "[Doh]\n"
+ "Used Memory=bleh\n"
+ "Random=Select me! /o/");*/
+ case COMPUTER_FILESYSTEMS:
+ return g_strdup_printf("[$ShellParam$]\n"
+ "ViewType=1\n"
+ "ReloadInterval=5000\n"
+ "[Mounted File Systems]\n%s\n", fs_list);
+ case COMPUTER_SUMMARY:
+ tmp = computer_get_alsacards(computer);
+ return g_strdup_printf("[$ShellParam$]\n"
+ "UpdateInterval$Memory=1000\n"
+ "UpdateInterval$Date/Time=1000\n"
+ "[Computer]\n"
+ "Processor=%s\n"
+ "Memory=...\n"
+ "Operating System=%s\n"
+ "User Name=%s\n"
+ "Date/Time=%s\n"
+ "[Display]\n"
+ "Resolution=%dx%d pixels\n"
+ "OpenGL Renderer=%s\n"
+ "X11 Vendor=%s\n"
+ "[Multimedia]\n"
+ "%s\n"
+ "#[Storage]\n"
+ "#IDE Controller=\n"
+ "#SCSI Controller=\n"
+ "#Floppy Drive=\n"
+ "#Disk Drive=\n",
+ computer->processor->model_name,
+ computer->os->distro,
+ computer->os->username,
+ computer->date_time,
+ computer->display->width,
+ computer->display->height,
+ computer->display->ogl_renderer,
+ computer->display->vendor,
+ tmp);
+ case COMPUTER_DISPLAY:
+ return g_strdup_printf("[Display]\n"
+ "Resolution=%dx%d pixels\n"
+ "Vendor=%s\n"
+ "Version=%s\n"
+ "[Monitors]\n"
+ "%s"
+ "[Extensions]\n"
+ "%s"
+ "[OpenGL]\n"
+ "Vendor=%s\n"
+ "Renderer=%s\n"
+ "Version=%s\n",
+ computer->display->width,
+ computer->display->height,
+ computer->display->vendor,
+ computer->display->version,
+ computer->display->monitors,
+ computer->display->extensions,
+ computer->display->ogl_vendor,
+ computer->display->ogl_renderer,
+ computer->display->ogl_version);
+ case COMPUTER_OPERATING_SYSTEM:
+ tmp = computer_get_formatted_uptime();
+ return g_strdup_printf("[$ShellParam$]\n"
+ "UpdateInterval$Uptime=10000\n"
+ "UpdateInterval$Load Average=1000\n"
+ "[Version]\n"
+ "Kernel=%s\n"
+ "Compiled=%s\n"
+ "C Library=%s\n"
+ "Distribution=%s\n"
+ "[Current Session]\n"
+ "Computer Name=%s\n"
+ "User Name=%s\n"
+ "#Language=%s\n"
+ "Home Directory=%s\n"
+ "Desktop Environment=%s\n"
+ "[Misc]\n"
+ "Uptime=%s\n"
+ "Load Average=...",
+ computer->os->kernel,
+ computer->os->compiled_date,
+ computer->os->libc,
+ computer->os->distro,
+ computer->os->hostname,
+ computer->os->username,
+ computer->os->language,
+ computer->os->homedir,
+ computer->os->desktop, tmp);
+ case COMPUTER_LANGUAGE:
+ return g_strdup_printf("[$ShellParam$]\n"
+ "ViewType=1\n"
+ "[Available Languages]\n"
+ "%s", computer->os->languages);
+ case COMPUTER_PROCESSORS:
+ tmp = processor_get_capabilities_from_flags(computer->processor->
+ flags);
+ return g_strdup_printf("[Processor]\n"
+ "Name=%s\n"
+ "Specification=%s\n"
+ "Family, model, stepping=%d, %d, %d\n"
+ "Vendor=%s\n"
+ "Cache Size=%dkb\n"
+ "Frequency=%.2fMHz\n"
+ "BogoMips=%.2f\n"
+ "Byte Order=%s\n"
+ "[Features]\n"
+ "FDIV Bug=%s\n"
+ "HLT Bug=%s\n"
+ "F00F Bug=%s\n"
+ "Coma Bug=%s\n"
+ "Has FPU=%s\n"
+ "[Capabilities]\n" "%s",
+ computer->processor->strmodel,
+ computer->processor->model_name,
+ computer->processor->family,
+ computer->processor->model,
+ computer->processor->stepping,
+ computer->processor->vendor_id,
+ computer->processor->cache_size,
+ computer->processor->cpu_mhz,
+ computer->processor->bogomips,
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ "Little Endian",
+#else
+ "Big Endian",
+#endif
+ computer->processor->bug_fdiv,
+ computer->processor->bug_hlt,
+ computer->processor->bug_f00f,
+ computer->processor->bug_coma,
+ computer->processor->has_fpu,
+ tmp);
+ default:
+ return g_strdup("[Empty]\nNo info available=");
+ }
+}
+
+gint
+hi_n_entries(void)
+{
+ return G_N_ELEMENTS(hi_entries) - 1;
+}
+
+GdkPixbuf *
+hi_icon(gint entry)
+{
+ return icon_cache_get_pixbuf(hi_entries[entry].icon);
+}
+
+gchar *
+hi_name(gint entry)
+{
+ return hi_entries[entry].name;
+}
diff --git a/hardinfo2/computer.h b/hardinfo2/computer.h
new file mode 100644
index 00000000..3cb3d9e9
--- /dev/null
+++ b/hardinfo2/computer.h
@@ -0,0 +1,165 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 __COMPUTER_H__
+#define __COMPUTER_H__
+
+#define DB_PREFIX "/etc/"
+
+static struct {
+ gchar *file, *codename;
+} distro_db[] = {
+ {
+ DB_PREFIX "debian_version", "deb"}, {
+ DB_PREFIX "slackware-version", "slk"}, {
+ DB_PREFIX "mandrake-release", "mdk"}, {
+ DB_PREFIX "gentoo-release", "gnt"}, {
+ DB_PREFIX "conectiva-release", "cnc"}, {
+ DB_PREFIX "versão-conectiva", "cnc"}, {
+ DB_PREFIX "turbolinux-release", "tl"}, {
+ DB_PREFIX "yellowdog-release", "yd"}, {
+ DB_PREFIX "SuSE-release", "suse"}, {
+ DB_PREFIX "sun-release", "sun"},
+ /*
+ * RedHat must be the *last* one to be checked, since
+ * some distros (like Mandrake) includes a redhat-relase
+ * file too.
+ */
+ {
+ DB_PREFIX "redhat-release", "rh"}, {
+ NULL, NULL}
+};
+
+
+typedef struct _Computer Computer;
+typedef struct _Processor Processor;
+typedef struct _OperatingSystem OperatingSystem;
+typedef struct _MemoryInfo MemoryInfo;
+typedef struct _UptimeInfo UptimeInfo;
+typedef struct _LoadInfo LoadInfo;
+typedef struct _DisplayInfo DisplayInfo;
+
+typedef struct _AlsaInfo AlsaInfo;
+typedef struct _AlsaCard AlsaCard;
+
+typedef struct _FileSystem FileSystem;
+typedef struct _FileSystemEntry FileSystemEntry;
+
+struct _AlsaCard {
+ gchar *alsa_name;
+ gchar *friendly_name;
+/*
+ gchar *board;
+ gchar revision, compat_class;
+ gint subsys_vendorid, subsys_id;
+
+ gint cap_dac_res, cap_adc_res;
+ gboolean cap_3d_enh;
+
+ gint curr_mic_gain;
+ gboolean curr_3d_enh,
+ curr_loudness,
+ curr_simstereo;
+ gchar *curr_mic_select;
+*/
+};
+
+struct _AlsaInfo {
+ GSList *cards;
+};
+
+struct _DisplayInfo {
+ gchar *ogl_vendor, *ogl_renderer, *ogl_version;
+ gchar *display_name, *vendor, *version;
+ gchar *extensions;
+ gchar *monitors;
+
+ gint width, height;
+};
+
+struct _LoadInfo {
+ float load1, load5, load15;
+};
+
+struct _UptimeInfo {
+ int days, hours, minutes;
+};
+
+struct _Computer {
+ Processor *processor;
+ MemoryInfo *memory;
+ OperatingSystem *os;
+ DisplayInfo *display;
+ AlsaInfo *alsa;
+
+ gchar *date_time;
+};
+
+struct _Processor {
+ gchar *model_name;
+ gchar *vendor_id;
+ gchar *flags;
+ gint cache_size;
+ gfloat bogomips, cpu_mhz;
+
+ gchar *has_fpu;
+ gchar *bug_fdiv, *bug_hlt, *bug_f00f, *bug_coma;
+
+ gint model, family, stepping;
+ gchar *strmodel;
+};
+
+struct _OperatingSystem {
+ gchar *kernel;
+ gchar *libc;
+ gchar *distrocode, *distro;
+ gchar *hostname;
+ gchar *language;
+ gchar *homedir;
+ gchar *compiled_date;
+
+ gchar *languages;
+
+ gchar *desktop;
+ gchar *username;
+};
+
+struct _MemoryInfo {
+ gint total, used, free, cached;
+ gfloat ratio;
+};
+
+#define get_str(field_name,ptr) \
+ if (g_str_has_prefix(tmp[0], field_name)) { \
+ ptr = g_strdup(tmp[1]); \
+ g_strfreev(tmp); \
+ continue; \
+ }
+#define get_int(field_name,ptr) \
+ if (g_str_has_prefix(tmp[0], field_name)) { \
+ ptr = atoi(tmp[1]); \
+ g_strfreev(tmp); \
+ continue; \
+ }
+#define get_float(field_name,ptr) \
+ if (g_str_has_prefix(tmp[0], field_name)) { \
+ ptr = atof(tmp[1]); \
+ g_strfreev(tmp); \
+ continue; \
+ }
+
+#endif /* __COMPUTER_H__ */
diff --git a/hardinfo2/configure b/hardinfo2/configure
new file mode 100755
index 00000000..3d174597
--- /dev/null
+++ b/hardinfo2/configure
@@ -0,0 +1,162 @@
+#!/usr/bin/env bash
+#
+# ToscoConf 0.04
+# Copyright (c) 2003-2004 Leandro Pereira <leandro@linuxmag.com.br>
+# All rights reserved.
+#
+# This script is in the Tosco Public License. It may be copied and/or
+# modified, in whole or in part, provided that all copies must retain the
+# above copyright notice, this condition and the following disclaimer.
+#
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+#
+# (yes, I did a copy&paste from the BSD license, eat me)
+#
+# ---------------------------------------------------------------------------
+
+PACKAGE=`basename ${PWD} | cut -d"-" -f1`;
+VERSION=`basename ${PWD} | cut -d"-" -f2`;
+
+[ "$PACKAGE" == "$VERSION" ] && VERSION="SVN_$(date)"
+
+echo "ToscoConf (version 0.04) for $PACKAGE version $VERSION"
+
+# ---------------------------------------------------------------------------
+
+echo -n "Running: "
+OS=`uname`
+echo -n $OS
+case $OS in
+ Linux)
+ echo -n " (OK) " ;;
+ *)
+ echo " (not supported, yet!)"
+ exit ;;
+esac
+
+PROC=`uname -m`
+case $PROC in
+ i?86)
+ ln -sf linux/x86 arch/this
+ ARCH="ARCH_i386" ;;
+ ppc)
+ ln -sf linux/ppc arch/this
+ ARCH="ARCH_PPC" ;;
+ x86_64)
+ ln -sf linux/x86_64 arch/this
+ ARCH="ARCH_x86_64" ;;
+ mips)
+ ln -sf linux/mips arch/this
+ ARCH="ARCH_MIPS" ;;
+ parisc*)
+ ln -sf linux/parisc arch/this
+ ARCH="ARCH_PARISC" ;;
+ ia64)
+ ln -sf linux/ia64 arch/this
+ ARCH="ARCH_IA64" ;;
+ *)
+ # uname -m on m68k doesn't return anything useful :/
+ grep "680?0" /proc/cpuinfo > /dev/null
+ if [ "$?" == "0" ]; then
+ ln -sf linux/m68k arch/this
+ ARCH="ARCH_m68k"
+ else
+ echo "Architeture \"$ARCH\" not supported."
+ exit
+ fi
+
+ ;;
+esac
+
+echo "$PROC ($ARCH)"
+
+# ---------------------------------------------------------------------------
+
+echo -n "Checking for lspci... "
+LSPCIPATH="/sbin/lspci /usr/sbin/lspci /bin/lspci /usr/bin/lspci `which lspci`"
+for i in $LSPCIPATH; do
+ if [ -x "$i" ]; then
+ LSPCI=$i
+ break;
+ fi
+done
+
+if [ -e "$LSPCI" ]; then
+ echo $LSPCI
+else
+ echo "lspci cannot be found"
+fi
+
+# ---------------------------------------------------------------------------
+
+GTK2=-1
+MIN_VERSION="2.6.0"
+echo -n "Checking for GTK ${MIN_VERSION}... "
+for i in `which pkg-config`; do
+ pkg-config --errors-to-stdout gtk+-2.0 \
+ --atleast-version=$MIN_VERSION > /dev/null
+ case $? in
+ 0)
+ GTK_FLAGS=`pkg-config gtk+-2.0 --cflags`
+ GTK_LIBS=`pkg-config gtk+-2.0 --libs`
+ echo "OK (pkgconfig)"
+ GTK2=1 ;;
+ *)
+ echo "not found." ;;
+ esac
+done
+
+# --------------------------------------------------------------------------
+
+if [ $GTK2 -eq -1 ]; then
+ echo -e "\nYou need the GTK libraries, including the development stuff."
+ echo "If you're using Debian, running the command as root:"
+ echo -e "\n\tapt-get install libgtk2.0-dev\n"
+ echo "Will do the trick."
+ exit
+fi
+
+# --------------------------------------------------------------------------
+
+echo -e "\nWriting config.h..."
+rm -f config.h
+echo -e "#ifndef __CONFIG_H__\n#define __CONFIG_H__\n" > config.h
+
+echo "#define VERSION \"$VERSION\"" >> config.h
+
+if [ "$LSPCI" ]; then
+ echo "#define LSPCI \"$LSPCI -v\"" >> config.h
+fi
+
+echo "#define $ARCH" >> config.h
+
+echo "#define PLATFORM \"`uname`\"" >> config.h
+echo "#define KERNEL \"`uname -r`\"" >> config.h
+echo "#define HOSTNAME \"`hostname`\"" >> config.h
+
+echo "#define PREFIX \"./\"" >> config.h
+echo "#define DEBUG 1" >> config.h
+
+echo -e "\n#endif /* __CONFIG_H__ */" >> config.h
+
+echo "Writing Makefile..."
+rm -f Makefile
+
+echo "GTK_LIBS = ${GTK_LIBS}" > Makefile
+echo "GTK_CFLAGS = ${GTK_FLAGS}" >> Makefile
+echo "GLADE_LIBS = ${GLADE_LIBS}" >> Makefile
+echo "GLADE_CFLAGS = ${GLADE_FLAGS}" >> Makefile
+echo "PACKAGE = `basename ${PWD}`" >> Makefile
+
+cat Makefile.in >> Makefile
+
+echo -e "\nDone. Type \"make\" to compile the program.\n"
+echo "If you get errors, probably you don't have the right libraries,"
+echo "includes or utilities. However, if you're sure this is a bug in my"
+echo -e "code, please send a patch (use \"diff -u\") to <leandro@linuxmag.com.br>.\n"
diff --git a/hardinfo2/devices.c b/hardinfo2/devices.c
new file mode 100644
index 00000000..07946755
--- /dev/null
+++ b/hardinfo2/devices.c
@@ -0,0 +1,193 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 <gtk/gtk.h>
+#include <config.h>
+#include <string.h>
+
+#include <hardinfo.h>
+#include <shell.h>
+#include <iconcache.h>
+
+enum {
+ DEVICES_KERNEL_MODULES,
+ DEVICES_PCI,
+ DEVICES_USB,
+ DEVICES_PRINTERS,
+ DEVICES_INPUT,
+ DEVICES_STORAGE,
+} Entries;
+
+static ModuleEntry hi_entries[] = {
+ {"Kernel Modules", "module.png"},
+ {"PCI Devices", "devices.png"},
+ {"USB Devices", "usb.png"},
+ {"Printers", "printer.png"},
+ {"Input Devices", "keyboard.png"},
+ {"Storage", "hdd.png"},
+};
+
+static GHashTable *devices = NULL;
+static gchar *module_list = "";
+static gchar *printer_list = NULL;
+static gchar *pci_list = "";
+static gchar *input_list = NULL;
+static gchar *storage_list = "";
+
+#define WALK_UNTIL(x) while((*buf != '\0') && (*buf != x)) buf++
+
+#define GET_STR(field_name,ptr) \
+ if (strstr(tmp[0], field_name)) { \
+ ptr = g_markup_escape_text(g_strstrip(tmp[1]), strlen(tmp[1])); \
+ g_strfreev(tmp); \
+ continue; \
+ }
+
+#include <arch/this/pci.h>
+#include <arch/this/modules.h>
+#include <arch/common/printers.h>
+#include <arch/this/inputdevices.h>
+#include <arch/this/usb.h>
+#include <arch/this/storage.h>
+
+static void
+detect_devices(void)
+{
+ devices = g_hash_table_new(g_str_hash, g_str_equal);
+
+ shell_status_update("Getting loaded modules information...");
+ scan_modules();
+
+ shell_status_update("Scanning PCI devices...");
+ scan_pci();
+
+ shell_status_update("Searching for printers...");
+ scan_printers();
+
+ shell_status_update("Scanning input devices...");
+ scan_inputdevices();
+
+ shell_status_update("Scanning USB devices...");
+ scan_usb();
+
+ shell_status_update("Scanning IDE devices...");
+ scan_ide();
+
+ shell_status_update("Scanning SCSI devices...");
+ scan_scsi();
+}
+
+gchar *
+hi_more_info(gchar * entry)
+{
+ gchar *info = (gchar *) g_hash_table_lookup(devices, entry);
+
+ if (info)
+ return g_strdup(info);
+ return g_strdup("[Empty]");
+}
+
+void
+hi_reload(gint entry)
+{
+ switch (entry) {
+ case DEVICES_INPUT:
+ scan_inputdevices();
+ break;
+ case DEVICES_PRINTERS:
+ scan_printers();
+ break;
+ case DEVICES_USB:
+ scan_usb();
+ break;
+ case DEVICES_STORAGE:
+ if (storage_list) {
+ g_free(storage_list);
+ g_free(storage_icons);
+ storage_list = g_strdup("");
+ storage_icons = g_strdup("");
+ }
+ scan_ide();
+ scan_scsi();
+ break;
+ }
+}
+
+gchar *
+hi_info(gint entry)
+{
+ if (!devices) {
+ detect_devices();
+ }
+
+ switch (entry) {
+ case DEVICES_KERNEL_MODULES:
+ return g_strdup_printf("[Loaded Modules]\n"
+ "%s"
+ "[$ShellParam$]\n"
+ "ViewType=1",
+ module_list);
+ case DEVICES_PCI:
+ return g_strdup_printf("[PCI Devices]\n"
+ "%s"
+ "[$ShellParam$]\n"
+ "ViewType=1\n",
+ pci_list);
+ case DEVICES_PRINTERS:
+ return g_strdup_printf("%s\n"
+ "[$ShellParam$]\n"
+ "ReloadInterval=5000", printer_list);
+ case DEVICES_STORAGE:
+ return g_strdup_printf("%s\n"
+ "[$ShellParam$]\n"
+ "ReloadInterval=5000\n"
+ "ViewType=1\n%s", storage_list, storage_icons);
+ case DEVICES_INPUT:
+ return g_strdup_printf("[Input Devices]\n"
+ "%s"
+ "[$ShellParam$]\n"
+ "ViewType=1\n"
+ "ReloadInterval=5000\n%s", input_list, input_icons);
+ case DEVICES_USB:
+ return g_strdup_printf("%s"
+ "[$ShellParam$]\n"
+ "ViewType=1\n"
+ "ReloadInterval=5000\n",
+ usb_list);
+ default:
+ return g_strdup("[Empty]\nNo info available=");
+ }
+}
+
+gint
+hi_n_entries(void)
+{
+ return G_N_ELEMENTS(hi_entries) - 1;
+}
+
+GdkPixbuf *
+hi_icon(gint entry)
+{
+ return icon_cache_get_pixbuf(hi_entries[entry].icon);
+}
+
+gchar *
+hi_name(gint entry)
+{
+ return hi_entries[entry].name;
+}
diff --git a/hardinfo2/expr.c b/hardinfo2/expr.c
new file mode 100644
index 00000000..8727a63b
--- /dev/null
+++ b/hardinfo2/expr.c
@@ -0,0 +1,241 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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
+ */
+/*
+ * This is only used to compute sensor values, hence the only variable supported is '@'.
+ * The '`' operator (ln(x)) is not available, nor multi-line formulas.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <expr.h>
+
+static MathToken *new_operator(gchar op)
+{
+ MathToken *t = g_new0(MathToken, 1);
+
+ t->val.op = op;
+ t->type = TOKEN_OPERATOR; /* operator */
+
+ return t;
+}
+
+static MathToken *new_variable(gchar var)
+{
+ MathToken *t = g_new0(MathToken, 1);
+
+ t->val.op = '@';
+ t->type = TOKEN_VARIABLE; /* variable */
+
+ return t;
+}
+
+static MathToken *new_value(gfloat value)
+{
+ MathToken *t = g_new0(MathToken, 1);
+
+ t->val.value = value;
+ t->type = TOKEN_VALUE; /* value */
+
+ return t;
+}
+
+static inline gint priority(char operation)
+{
+ switch (operation) {
+ case '^':
+ return 3;
+ case '*':
+ case '/':
+ return 2;
+ case '+':
+ case '-':
+ return 1;
+ case '(':
+ return 0;
+ }
+
+ return 0;
+}
+
+GSList *math_infix_to_postfix(GSList *infix)
+{
+ MathToken *stack[500];
+ gint t_sp = 0;
+
+ GSList *postfix = NULL, *p;
+ MathToken *top;
+
+ for (p = infix; p; p = p->next) {
+ MathToken *t = (MathToken *) p->data;
+
+ if (t->type == TOKEN_OPERATOR && t->val.op == '(') {
+ stack[++t_sp] = t;
+ } else if (t->type == TOKEN_OPERATOR && t->val.op == ')') {
+ for (top = stack[t_sp]; t_sp != 0 && top->val.op != '('; top = stack[t_sp])
+ postfix = g_slist_append(postfix, stack[t_sp--]);
+ t_sp--;
+ } else if (t->type != TOKEN_OPERATOR) {
+ postfix = g_slist_append(postfix, t);
+ } else if (!stack) {
+ stack[++t_sp] = t;
+ } else {
+ while (t_sp != 0 && priority(t->val.op) <= priority(stack[t_sp]->val.op))
+ postfix = g_slist_append(postfix, stack[t_sp--]);
+ stack[++t_sp] = t;
+ }
+ }
+
+ while (t_sp)
+ postfix = g_slist_append(postfix, stack[t_sp--]);
+
+ return postfix;
+}
+
+static inline gfloat __result(gfloat op1, gfloat op2, gchar operation)
+{
+ switch (operation) {
+ case '^':
+ return powf(op1, op2);
+ case '+':
+ return op1 + op2;
+ case '-':
+ return op1 - op2;
+ case '/':
+ return op1 / op2;
+ case '*':
+ return op1 * op2;
+ }
+
+ return 0;
+}
+
+gfloat math_postfix_eval(GSList *postfix, gfloat at_value)
+{
+ GSList *p;
+ gfloat stack[500];
+ gint sp = 0;
+
+ stack[0] = 0.0;
+
+ for (p = postfix; p; p = p->next) {
+ MathToken *t = (MathToken *) p->data;
+
+ if (t->type == TOKEN_VARIABLE) {
+ stack[++sp] = at_value;
+ } else if (t->type == TOKEN_VALUE) {
+ stack[++sp] = t->val.value;
+ } else {
+ gfloat op1, op2;
+
+ op2 = stack[sp--];
+ op1 = stack[sp];
+
+ stack[sp] = __result(op1, op2, t->val.op);
+ }
+ }
+
+ return stack[sp];
+}
+
+GSList *math_string_to_infix(gchar *string)
+{
+ GSList *infix = NULL;
+ gchar *expr = string;
+
+ for (; *expr; expr++) {
+ if (strchr("+-/*^()", *expr)) {
+ infix = g_slist_append(infix, new_operator(*expr));
+ } else if (strchr("@", *expr)) {
+ infix = g_slist_append(infix, new_variable(*expr));
+ } else if (strchr("-.1234567890", *expr)) {
+ gfloat value;
+
+ sscanf(expr, "%f", &value);
+
+ while (*expr && strchr(".1234567890", *expr))
+ expr++;
+ expr--;
+
+ infix = g_slist_append(infix, new_value(value));
+ } else if (!isspace(*expr)) {
+ g_print("Invalid token: [%c][%d]\n", *expr, *expr);
+ math_infix_free(infix, TRUE);
+ return NULL;
+ }
+ }
+
+ return infix;
+}
+
+void math_infix_free(GSList *infix, gboolean free_tokens)
+{
+ GSList *p;
+
+ if (!free_tokens)
+ for (p = infix; p; p = g_slist_delete_link(p, p));
+ else
+ for (p = infix; p; p = g_slist_delete_link(p, p)) {
+ MathToken *t = (MathToken *)p->data;
+ g_free(t);
+ }
+}
+
+GSList *math_string_to_postfix(gchar *string)
+{
+ GSList *infix;
+ GSList *postfix;
+
+ infix = math_string_to_infix(string);
+ if (!infix)
+ return NULL;
+
+ postfix = math_infix_to_postfix(infix);
+ math_infix_free(infix, FALSE);
+
+ return postfix;
+}
+
+gfloat math_string_eval(gchar *string, gfloat at_value)
+{
+ GSList *postfix;
+ gfloat val;
+
+ postfix = math_string_to_postfix(string);
+ val = math_postfix_eval(postfix, at_value);
+ math_postfix_free(postfix, TRUE);
+
+ return val;
+}
+
+#ifdef MATH_TEST
+int main(void)
+{
+ GSList *postfix;
+
+ gchar *expr = "0.9*(@+(5.2*0.923+3*(2.0)))";
+
+ postfix = math_string_to_postfix(expr);
+ g_print("%s = %f (must be 18.71964)\n", expr, math_postfix_eval(postfix, 10));
+ math_postfix_free(postfix, TRUE);
+
+ return 0;
+}
+#endif
diff --git a/hardinfo2/expr.h b/hardinfo2/expr.h
new file mode 100644
index 00000000..2a5b15d4
--- /dev/null
+++ b/hardinfo2/expr.h
@@ -0,0 +1,48 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 __EXPR_H__
+#define __EXPR_H__
+
+typedef struct _MathToken MathToken;
+
+typedef enum {
+ TOKEN_OPERATOR,
+ TOKEN_VARIABLE,
+ TOKEN_VALUE
+} MathTokenType;
+
+struct _MathToken {
+ union {
+ gfloat value;
+ gchar op;
+ } val;
+ MathTokenType type;
+};
+
+#define math_postfix_free math_infix_free
+
+GSList *math_infix_to_postfix(GSList *infix);
+void math_infix_free(GSList *infix, gboolean free_tokens);
+
+GSList *math_string_to_infix(gchar *string);
+GSList *math_string_to_postfix(gchar *string);
+
+gfloat math_postfix_eval(GSList *postfix, gfloat at_value);
+gfloat math_string_eval(gchar *string, gfloat at_value);
+
+#endif /* __EXPR_H__ */
diff --git a/hardinfo2/hardinfo.c b/hardinfo2/hardinfo.c
new file mode 100644
index 00000000..80de3c87
--- /dev/null
+++ b/hardinfo2/hardinfo.c
@@ -0,0 +1,41 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 <config.h>
+#include <shell.h>
+
+#include <iconcache.h>
+#include <stock.h>
+
+int
+main(int argc, char **argv)
+{
+ gtk_init(&argc, &argv);
+
+#ifdef DEBUG
+ g_log_set_always_fatal(G_LOG_LEVEL_MASK);
+#endif
+
+ icon_cache_init();
+ stock_icons_init();
+ shell_init();
+
+ gtk_main();
+
+ return 0;
+}
diff --git a/hardinfo2/hardinfo.h b/hardinfo2/hardinfo.h
new file mode 100644
index 00000000..20697584
--- /dev/null
+++ b/hardinfo2/hardinfo.h
@@ -0,0 +1,35 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 __HARDINFO_H__
+#define __HARDINFO_H__
+
+#include <glib.h>
+
+typedef struct _ModuleEntry ModuleEntry;
+
+struct _ModuleEntry {
+ gchar *name;
+ gchar *icon;
+};
+
+inline void remove_quotes(gchar *str);
+inline void strend(gchar *str, gchar chr);
+inline void remove_linefeed(gchar *str);
+
+#endif /* __HARDINFO_H__ */
diff --git a/hardinfo2/iconcache.c b/hardinfo2/iconcache.c
new file mode 100644
index 00000000..5ef2bc3c
--- /dev/null
+++ b/hardinfo2/iconcache.c
@@ -0,0 +1,80 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 <iconcache.h>
+#include <config.h>
+
+static GHashTable *cache = NULL;
+
+void icon_cache_init(void)
+{
+ if (!cache) {
+ cache = g_hash_table_new(g_str_hash, g_str_equal);
+ }
+}
+
+GdkPixbuf *icon_cache_get_pixbuf(const gchar *file)
+{
+ GdkPixbuf *icon;
+
+ icon = g_hash_table_lookup(cache, file);
+
+ if (!icon) {
+ gchar *tmp = g_strdup_printf(PREFIX "pixmaps/%s", file);
+
+ icon = gdk_pixbuf_new_from_file(tmp, NULL);
+ g_hash_table_insert(cache, g_strdup(file), icon);
+
+ g_free(tmp);
+ }
+
+ return icon;
+}
+
+GtkWidget *icon_cache_get_image(const gchar *file)
+{
+ GdkPixbuf *icon;
+
+ icon = icon_cache_get_pixbuf(file);
+ return gtk_image_new_from_pixbuf(icon);
+}
+
+GdkPixbuf *icon_cache_get_pixbuf_at_size(const gchar *file, gint wid, gint hei)
+{
+ GdkPixbuf *icon;
+
+ icon = g_hash_table_lookup(cache, file);
+
+ if (!icon) {
+ gchar *tmp = g_strdup_printf(PREFIX "pixmaps/%s", file);
+
+ icon = gdk_pixbuf_new_from_file_at_size(tmp, wid, hei, NULL);
+ g_hash_table_insert(cache, g_strdup(file), icon);
+
+ g_free(tmp);
+ }
+
+ return icon;
+}
+
+GtkWidget *icon_cache_get_image_at_size(const gchar *file, gint wid, gint hei)
+{
+ GdkPixbuf *icon;
+
+ icon = icon_cache_get_pixbuf_at_size(file, wid, hei);
+ return gtk_image_new_from_pixbuf(icon);
+}
diff --git a/hardinfo2/iconcache.h b/hardinfo2/iconcache.h
new file mode 100644
index 00000000..e528b090
--- /dev/null
+++ b/hardinfo2/iconcache.h
@@ -0,0 +1,30 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 __ICONCACHE_H__
+#define __ICONCACHE_H__
+
+#include <gtk/gtk.h>
+
+void icon_cache_init(void);
+GdkPixbuf *icon_cache_get_pixbuf(const gchar *file);
+GtkWidget *icon_cache_get_image(const gchar *file);
+GdkPixbuf *icon_cache_get_pixbuf_at_size(const gchar *file, gint wid, gint hei);
+GtkWidget *icon_cache_get_image_at_size(const gchar *file, gint wid, gint hei);
+
+#endif /* __ICONCACHE_H__ */
diff --git a/hardinfo2/loadgraph.c b/hardinfo2/loadgraph.c
new file mode 100644
index 00000000..a15af347
--- /dev/null
+++ b/hardinfo2/loadgraph.c
@@ -0,0 +1,266 @@
+/*
+ * Simple Load Graph
+ * Version 0.1 - Wed, Jan 11 2006
+ * - initial release
+ * Version 0.1.1 - Fri, Jan 13 2006
+ * - fixes autoscaling
+ * - add color
+ *
+ * Copyright (C) 2006 Leandro A. F. Pereira <leandro@linuxmag.com.br>
+ *
+ * The Simple Load Graph is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License, version 2.1, as published by the Free Software Foundation.
+ *
+ * The Simple Load Graph 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the Simple Load Graph; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ */
+
+#include "loadgraph.h"
+
+static void _draw(LoadGraph *lg);
+
+LoadGraph *load_graph_new(gint size)
+{
+ LoadGraph *lg;
+
+ lg = g_new0(LoadGraph, 1);
+
+ lg->area = gtk_drawing_area_new();
+ lg->size = size;
+ lg->data = g_new0(gint, size);
+
+ lg->scale = 1.0;
+
+ lg->width = size * 4;
+ lg->height = size * 2;
+
+ gtk_widget_set_size_request(lg->area, lg->width, lg->height);
+ gtk_widget_show(lg->area);
+
+ return lg;
+}
+
+GtkWidget *load_graph_get_framed(LoadGraph *lg)
+{
+ GtkWidget *align, *frame;
+
+ align = gtk_alignment_new(0.5, 0.5, 0, 0);
+ gtk_widget_show(align);
+
+ frame = gtk_frame_new(NULL);
+ gtk_widget_show(frame);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
+
+ gtk_container_add(GTK_CONTAINER(align), frame);
+ gtk_container_add(GTK_CONTAINER(frame), lg->area);
+
+ return align;
+}
+
+void load_graph_clear(LoadGraph *lg)
+{
+ gint i;
+
+ for (i = 0; i < lg->size; i++)
+ lg->data[i] = 0;
+
+ lg->scale = 1.0;
+ _draw(lg);
+}
+
+void load_graph_set_color(LoadGraph *lg, LoadGraphColor color)
+{
+ lg->color = color;
+ gdk_rgb_gc_set_foreground(lg->trace, lg->color);
+}
+
+void load_graph_destroy(LoadGraph *lg)
+{
+ g_free(lg->data);
+ gtk_widget_destroy(lg->area);
+ gdk_pixmap_unref(lg->buf);
+ g_object_unref(lg->trace);
+ g_object_unref(lg->grid);
+ g_free(lg);
+}
+
+static gboolean _expose(GtkWidget *widget, GdkEventExpose *event,
+ gpointer user_data)
+{
+ LoadGraph *lg = (LoadGraph *)user_data;
+ GdkDrawable *draw = GDK_DRAWABLE(lg->buf);
+
+ gdk_draw_drawable(lg->area->window,
+ lg->area->style->white_gc,
+ draw,
+ 0, 0,
+ 0, 0,
+ lg->width, lg->height);
+ return FALSE;
+}
+
+void load_graph_configure_expose(LoadGraph *lg)
+{
+ /* creates the backing store pixmap */
+ gtk_widget_realize(lg->area);
+ lg->buf = gdk_pixmap_new(lg->area->window, lg->width, lg->height, -1);
+
+ /* create the graphic contexts */
+ lg->grid = gdk_gc_new(GDK_DRAWABLE(lg->buf));
+ lg->trace = gdk_gc_new(GDK_DRAWABLE(lg->buf));
+
+ /* the default color is green */
+ load_graph_set_color(lg, LG_COLOR_GREEN);
+
+ /* init graphic contexts */
+ gdk_gc_set_line_attributes(lg->grid,
+ 1, GDK_LINE_ON_OFF_DASH,
+ GDK_CAP_NOT_LAST,
+ GDK_JOIN_ROUND);
+ gdk_rgb_gc_set_foreground(lg->grid, 0x707070);
+
+ gdk_gc_set_line_attributes(lg->trace,
+ 2, GDK_LINE_SOLID,
+ GDK_CAP_NOT_LAST,
+ GDK_JOIN_ROUND);
+
+ /* configures the expose event */
+ g_signal_connect(G_OBJECT(lg->area), "expose-event",
+ (GCallback) _expose, lg);
+}
+
+static void
+_draw(LoadGraph *lg)
+{
+ GdkDrawable *draw = GDK_DRAWABLE(lg->buf);
+ gint i, d;
+
+ /* clears the drawing area */
+ gdk_draw_rectangle(draw, lg->area->style->black_gc,
+ TRUE, 0, 0, lg->width, lg->height);
+
+ /* horizontal bars; 25%, 50% and 75% */
+ d = lg->height / 4;
+ gdk_draw_line(draw, lg->grid, 0, d, lg->width, d);
+ d = lg->height / 2;
+ gdk_draw_line(draw, lg->grid, 0, d, lg->width, d);
+ d = 3 * (lg->height / 4);
+ gdk_draw_line(draw, lg->grid, 0, d, lg->width, d);
+
+ /* vertical bars */
+ for (i = lg->width, d = 0; i > 1; i--, d++)
+ if ((d % 45) == 0 && d)
+ gdk_draw_line(draw, lg->grid, i, 0, i, lg->height);
+
+ /* the graph */
+ for (i = 0; i < lg->size; i++) {
+ gint this = lg->height - lg->data[i];
+ gint next = lg->height - lg->data[i+1];
+
+ gdk_draw_line(draw, lg->trace, i * 4, this, i * 4 + 2,
+ (this + next) / 2);
+ gdk_draw_line(draw, lg->trace, i * 4 + 2, (this + next) / 2,
+ i * 4 + 4, next);
+ }
+
+ gtk_widget_queue_draw(lg->area);
+}
+
+static inline int
+_max(LoadGraph *lg)
+{
+ gint i;
+ gint max = 0;
+
+ for (i = 0; i < lg->size; i++) {
+ if (lg->data[i] > max)
+ max = lg->data[i];
+ }
+
+ return max;
+}
+
+void
+load_graph_update(LoadGraph *lg, gint value)
+{
+ gint i;
+
+ if (value < 0)
+ return;
+ else if (value > _max(lg) && value > lg->height) {
+ /* FIXME: make scale work correctly :P */
+ gfloat nscale = (gfloat)lg->height / ceilf((float)value * lg->scale);
+
+ while (value * nscale > lg->height) {
+ nscale *= .90;
+ }
+
+ if (nscale < lg->scale) {
+ lg->scale = nscale;
+
+ for (i = 0; i < lg->size; i++) {
+ lg->data[i] = (int)((float)lg->data[i] * lg->scale);
+ }
+ }
+ }
+
+ value = (int)ceilf((float)value * lg->scale);
+
+ /* shift-right our data */
+ for (i = 0; i < lg->size; i++) {
+ lg->data[i] = lg->data[i+1];
+ }
+
+ /* insert the updated value */
+ lg->data[i] = value;
+
+ /* redraw */
+ _draw(lg);
+}
+
+#ifdef LOADGRAPH_UNIT_TEST
+gboolean lg_update(gpointer d)
+{
+ LoadGraph *lg = (LoadGraph *)d;
+
+ int i = 0;
+ if ((rand() % 10) == 0) {
+ i = rand() % 1000 + 500;
+ }
+
+ load_graph_update(lg, rand() % 200 + i);
+
+ return TRUE;
+}
+
+int main(int argc, char **argv)
+{
+ LoadGraph *lg;
+ GtkWidget *window;
+
+ gtk_init(&argc, &argv);
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_widget_show(window);
+
+ lg = load_graph_new(100);
+ gtk_container_add(GTK_CONTAINER(window), lg->area);
+ load_graph_configure_expose(lg);
+
+ lg_update(lg);
+
+ g_timeout_add(100, lg_update, lg);
+
+ gtk_main();
+
+ return 0;
+}
+#endif
diff --git a/hardinfo2/loadgraph.h b/hardinfo2/loadgraph.h
new file mode 100644
index 00000000..81bdcde4
--- /dev/null
+++ b/hardinfo2/loadgraph.h
@@ -0,0 +1,61 @@
+/*
+ * Simple Load Graph
+ * Copyright (C) 2006 Leandro A. F. Pereira <leandro@linuxmag.com.br>
+ *
+ * The Simple Load Graph is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License, version 2.1, as published by the Free Software Foundation.
+ *
+ * The Simple Load Graph 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the Simple Load Graph; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ */
+
+
+#ifndef __LOADGRAPH_H__
+#define __LOADGRAPH_H__
+
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <math.h>
+
+typedef struct _LoadGraph LoadGraph;
+
+typedef enum {
+ LG_COLOR_GREEN = 0x4FB05A,
+ LG_COLOR_BLUE = 0x4F58B0,
+ LG_COLOR_RED = 0xB04F4F
+} LoadGraphColor;
+
+struct _LoadGraph {
+ GdkPixmap *buf;
+ GtkWidget *area;
+
+ GdkGC *grid;
+ GdkGC *trace;
+
+ gint *data;
+ gfloat scale;
+
+ gint size;
+ gint width, height;
+ LoadGraphColor color;
+
+};
+
+LoadGraph *load_graph_new(gint size);
+void load_graph_destroy(LoadGraph *lg);
+void load_graph_configure_expose(LoadGraph *lg);
+GtkWidget *load_graph_get_framed(LoadGraph *lg);
+
+void load_graph_update(LoadGraph *lg, gint value);
+void load_graph_set_color(LoadGraph *lg, LoadGraphColor color);
+void load_graph_clear(LoadGraph *lg);
+
+#endif /* __LOADGRAPH_H__ */
diff --git a/hardinfo2/md5.c b/hardinfo2/md5.c
new file mode 100644
index 00000000..7acddee3
--- /dev/null
+++ b/hardinfo2/md5.c
@@ -0,0 +1,313 @@
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+/* This code was modified in 1997 by Jim Kingdon of Cyclic Software to
+ not require an integer type which is exactly 32 bits. This work
+ draws on the changes for the same purpose by Tatu Ylonen
+ <ylo@cs.hut.fi> as part of SSH, but since I didn't actually use
+ that code, there is no copyright issue. I hereby disclaim
+ copyright in any changes I have made; this code remains in the
+ public domain. */
+
+#include <string.h> /* for memcpy() and memset() */
+
+/* Add prototype support. */
+#ifndef PROTO
+#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
+#define PROTO(ARGS) ARGS
+#else
+#define PROTO(ARGS) ()
+#endif
+#endif
+
+#include "md5.h"
+
+/* Little-endian byte-swapping routines. Note that these do not
+ depend on the size of datatypes such as uint32, nor do they require
+ us to detect the endianness of the machine we are running on. It
+ is possible they should be macros for speed, but I would be
+ surprised if they were a performance bottleneck for MD5. */
+
+static uint32 getu32(addr)
+const unsigned char *addr;
+{
+ return (((((unsigned long) addr[3] << 8) | addr[2]) << 8)
+ | addr[1]) << 8 | addr[0];
+}
+
+static void putu32(data, addr)
+uint32 data;
+unsigned char *addr;
+{
+ addr[0] = (unsigned char) data;
+ addr[1] = (unsigned char) (data >> 8);
+ addr[2] = (unsigned char) (data >> 16);
+ addr[3] = (unsigned char) (data >> 24);
+}
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(ctx)
+struct MD5Context *ctx;
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(ctx, buf, len)
+struct MD5Context *ctx;
+unsigned char const *buf;
+unsigned len;
+{
+ uint32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = (t + ((uint32) len << 3)) & 0xffffffff) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ MD5Transform(ctx->buf, ctx->in);
+ buf += t;
+ len -= t;
+ }
+
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ MD5Transform(ctx->buf, ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(digest, ctx)
+unsigned char digest[16];
+struct MD5Context *ctx;
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ MD5Transform(ctx->buf, ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+
+ /* Append length in bits and transform */
+ putu32(ctx->bits[0], ctx->in + 56);
+ putu32(ctx->bits[1], ctx->in + 60);
+
+ MD5Transform(ctx->buf, ctx->in);
+ putu32(ctx->buf[0], digest);
+ putu32(ctx->buf[1], digest + 4);
+ putu32(ctx->buf[2], digest + 8);
+ putu32(ctx->buf[3], digest + 12);
+ memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Transform(buf, inraw)
+uint32 buf[4];
+const unsigned char inraw[64];
+{
+ register uint32 a, b, c, d;
+ uint32 in[16];
+ int i;
+
+ for (i = 0; i < 16; ++i)
+ in[i] = getu32(inraw + 4 * i);
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+#endif
+
+#ifdef TEST
+/* Simple test program. Can use it to manually run the tests from
+ RFC1321 for example. */
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ struct MD5Context context;
+ unsigned char checksum[16];
+ int i;
+ int j;
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s string-to-hash\n", argv[0]);
+ exit(1);
+ }
+ for (j = 1; j < argc; ++j) {
+ printf("MD5 (\"%s\") = ", argv[j]);
+ MD5Init(&context);
+ MD5Update(&context, argv[j], strlen(argv[j]));
+ MD5Final(checksum, &context);
+ for (i = 0; i < 16; i++) {
+ printf("%02x", (unsigned int) checksum[i]);
+ }
+ printf("\n");
+ }
+ return 0;
+}
+#endif /* TEST */
diff --git a/hardinfo2/md5.h b/hardinfo2/md5.h
new file mode 100644
index 00000000..1522170c
--- /dev/null
+++ b/hardinfo2/md5.h
@@ -0,0 +1,26 @@
+/* See md5.c for explanation and copyright information. */
+
+#ifndef MD5_H
+#define MD5_H
+
+/* Unlike previous versions of this code, uint32 need not be exactly
+ 32 bits, merely 32 bits or more. Choosing a data type which is 32
+ bits instead of 64 is not important; speed is considerably more
+ important. ANSI guarantees that "unsigned long" will be big enough,
+ and always using it seems to have few disadvantages. */
+typedef unsigned long uint32;
+
+struct MD5Context {
+ uint32 buf[4];
+ uint32 bits[2];
+ unsigned char in[64];
+};
+
+void MD5Init (struct MD5Context *context);
+void MD5Update (struct MD5Context *context,
+ unsigned char const *buf, unsigned len);
+void MD5Final (unsigned char digest[16],
+ struct MD5Context *context);
+void MD5Transform (uint32 buf[4], const unsigned char in[64]);
+
+#endif /* !MD5_H */
diff --git a/hardinfo2/menu.c b/hardinfo2/menu.c
new file mode 100644
index 00000000..cc614ede
--- /dev/null
+++ b/hardinfo2/menu.c
@@ -0,0 +1,125 @@
+/*
+ * HardInfo
+ * Copyright(C) 2003-2006 Leandro A. F. Pereira.
+ *
+ * menu.c is based on UI Manager tutorial by Ryan McDougall
+ * Copyright(C) 2005 Ryan McDougall.
+ *
+ * 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <menu.h>
+#include <config.h>
+
+#include <stock.h>
+
+#include <callbacks.h>
+
+static GtkActionEntry entries[] =
+{
+ { "FileMenuAction", NULL, "_File" }, /* name, stock id, label */
+ { "ViewMenuAction", NULL, "_View" },
+ { "HelpMenuAction", NULL, "_Help" },
+ { "MainMenuBarAction", NULL, "" },
+
+ { "ReportAction", HI_STOCK_REPORT, /* name, stock id */
+ "Generate _Report", "<control>R", /* label, accelerator */
+ "Report", /* tooltip */
+ G_CALLBACK(cb_generate_report) },
+
+ { "RefreshAction", GTK_STOCK_REFRESH,
+ "_Refresh", "F5",
+ "Refresh",
+ G_CALLBACK(cb_refresh) },
+
+ { "AboutAction", GTK_STOCK_ABOUT,
+ "_About\342\200\246", NULL,
+ "Displays program version information",
+ G_CALLBACK(cb_about) },
+
+ { "QuitAction", GTK_STOCK_QUIT,
+ "_Quit", "<control>Q",
+ "Quit",
+ G_CALLBACK(cb_quit) }
+};
+
+static GtkToggleActionEntry toggle_entries[] =
+{
+ { "LeftPaneAction", NULL,
+ "_Left Pane", NULL,
+ "Toggles left pane visibility",
+ G_CALLBACK(cb_left_pane) },
+ { "ToolbarAction", NULL,
+ "_Toolbar", NULL,
+ NULL,
+ G_CALLBACK(cb_toolbar) },
+};
+
+/* Implement a handler for GtkUIManager's "add_widget" signal. The UI manager
+ * will emit this signal whenever it needs you to place a new widget it has. */
+static void
+menu_add_widget(GtkUIManager *ui, GtkWidget *widget, GtkContainer *container)
+{
+ gtk_box_pack_start(GTK_BOX(container), widget, FALSE, FALSE, 0);
+ gtk_widget_show(widget);
+}
+
+void menu_init(Shell *shell)
+{
+ GtkWidget *menu_box; /* Packing box for the menu and toolbars */
+ GtkActionGroup *action_group; /* Packing group for our Actions */
+ GtkUIManager *menu_manager; /* The magic widget! */
+ GError *error; /* For reporting exceptions or errors */
+
+ /* Create our objects */
+ menu_box = shell->vbox;
+ action_group = gtk_action_group_new("HardInfo");
+ menu_manager = gtk_ui_manager_new();
+
+ shell->action_group = action_group;
+ shell->ui_manager = menu_manager;
+
+ /* Pack up our objects:
+ * menu_box -> window
+ * actions -> action_group
+ * action_group -> menu_manager */
+ gtk_action_group_add_actions(action_group, entries, G_N_ELEMENTS(entries),
+ NULL);
+ gtk_action_group_add_toggle_actions(action_group, toggle_entries,
+ G_N_ELEMENTS(toggle_entries), NULL);
+ gtk_ui_manager_insert_action_group(menu_manager, action_group, 0);
+
+ /* Read in the UI from our XML file */
+ error = NULL;
+ gtk_ui_manager_add_ui_from_file(menu_manager, PREFIX "uidefs.xml", &error);
+
+ if (error) {
+ g_error("building menus failed: %s", error->message);
+ g_error_free(error);
+ }
+
+ /* Connect up important signals */
+ /* This signal is necessary in order to place widgets from the UI manager
+ * into the menu_box */
+ g_signal_connect(menu_manager, "add_widget",
+ G_CALLBACK(menu_add_widget),
+ menu_box);
+
+ /* Show the window and run the main loop, we're done! */
+ gtk_widget_show(menu_box);
+
+ gtk_toolbar_set_style(GTK_TOOLBAR(gtk_ui_manager_get_widget(shell->ui_manager, "/MainMenuBarAction")),
+ GTK_TOOLBAR_BOTH_HORIZ);
+}
diff --git a/hardinfo2/menu.h b/hardinfo2/menu.h
new file mode 100644
index 00000000..36aff3df
--- /dev/null
+++ b/hardinfo2/menu.h
@@ -0,0 +1,24 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 __MENU_H__
+#define __MENU_H__
+
+#include <shell.h>
+
+void menu_init(Shell *shell);
+#endif /* __MENU_H__ */
diff --git a/hardinfo2/modules.conf b/hardinfo2/modules.conf
new file mode 100644
index 00000000..1dbaf07f
--- /dev/null
+++ b/hardinfo2/modules.conf
@@ -0,0 +1,7 @@
+[general]
+version=2
+
+[categories]
+Computer=computer
+Devices=devices
+Benchmarks=benchmark
diff --git a/hardinfo2/pixmaps/2computer.png b/hardinfo2/pixmaps/2computer.png
new file mode 100644
index 00000000..46f29204
--- /dev/null
+++ b/hardinfo2/pixmaps/2computer.png
Binary files differ
diff --git a/hardinfo2/pixmaps/athlon.png b/hardinfo2/pixmaps/athlon.png
new file mode 100644
index 00000000..81a1b314
--- /dev/null
+++ b/hardinfo2/pixmaps/athlon.png
Binary files differ
diff --git a/hardinfo2/pixmaps/audio.png b/hardinfo2/pixmaps/audio.png
new file mode 100644
index 00000000..45096651
--- /dev/null
+++ b/hardinfo2/pixmaps/audio.png
Binary files differ
diff --git a/hardinfo2/pixmaps/benchmark.png b/hardinfo2/pixmaps/benchmark.png
new file mode 100644
index 00000000..1be159b7
--- /dev/null
+++ b/hardinfo2/pixmaps/benchmark.png
Binary files differ
diff --git a/hardinfo2/pixmaps/cdrom.png b/hardinfo2/pixmaps/cdrom.png
new file mode 100644
index 00000000..eb65bcbb
--- /dev/null
+++ b/hardinfo2/pixmaps/cdrom.png
Binary files differ
diff --git a/hardinfo2/pixmaps/compress.png b/hardinfo2/pixmaps/compress.png
new file mode 100644
index 00000000..e5dee194
--- /dev/null
+++ b/hardinfo2/pixmaps/compress.png
Binary files differ
diff --git a/hardinfo2/pixmaps/computer.png b/hardinfo2/pixmaps/computer.png
new file mode 100644
index 00000000..f0de0386
--- /dev/null
+++ b/hardinfo2/pixmaps/computer.png
Binary files differ
diff --git a/hardinfo2/pixmaps/dev_removable.png b/hardinfo2/pixmaps/dev_removable.png
new file mode 100644
index 00000000..2453d8dc
--- /dev/null
+++ b/hardinfo2/pixmaps/dev_removable.png
Binary files differ
diff --git a/hardinfo2/pixmaps/devices.png b/hardinfo2/pixmaps/devices.png
new file mode 100644
index 00000000..0ad1400b
--- /dev/null
+++ b/hardinfo2/pixmaps/devices.png
Binary files differ
diff --git a/hardinfo2/pixmaps/gnome-dev-removable-usb.png b/hardinfo2/pixmaps/gnome-dev-removable-usb.png
new file mode 100644
index 00000000..fb83bab2
--- /dev/null
+++ b/hardinfo2/pixmaps/gnome-dev-removable-usb.png
Binary files differ
diff --git a/hardinfo2/pixmaps/gnome-devel.png b/hardinfo2/pixmaps/gnome-devel.png
new file mode 100644
index 00000000..4c63e7dd
--- /dev/null
+++ b/hardinfo2/pixmaps/gnome-devel.png
Binary files differ
diff --git a/hardinfo2/pixmaps/gnome-terminal.png b/hardinfo2/pixmaps/gnome-terminal.png
new file mode 100644
index 00000000..2fe2d14d
--- /dev/null
+++ b/hardinfo2/pixmaps/gnome-terminal.png
Binary files differ
diff --git a/hardinfo2/pixmaps/gnome-window-manager.png b/hardinfo2/pixmaps/gnome-window-manager.png
new file mode 100644
index 00000000..d5f0d3d9
--- /dev/null
+++ b/hardinfo2/pixmaps/gnome-window-manager.png
Binary files differ
diff --git a/hardinfo2/pixmaps/graphics.png b/hardinfo2/pixmaps/graphics.png
new file mode 100644
index 00000000..a70492c1
--- /dev/null
+++ b/hardinfo2/pixmaps/graphics.png
Binary files differ
diff --git a/hardinfo2/pixmaps/hdd.png b/hardinfo2/pixmaps/hdd.png
new file mode 100644
index 00000000..bbcdc825
--- /dev/null
+++ b/hardinfo2/pixmaps/hdd.png
Binary files differ
diff --git a/hardinfo2/pixmaps/joystick.png b/hardinfo2/pixmaps/joystick.png
new file mode 100644
index 00000000..954cca4b
--- /dev/null
+++ b/hardinfo2/pixmaps/joystick.png
Binary files differ
diff --git a/hardinfo2/pixmaps/kblayout.png b/hardinfo2/pixmaps/kblayout.png
new file mode 100644
index 00000000..b99e27d1
--- /dev/null
+++ b/hardinfo2/pixmaps/kblayout.png
Binary files differ
diff --git a/hardinfo2/pixmaps/keyboard.png b/hardinfo2/pixmaps/keyboard.png
new file mode 100644
index 00000000..a716f07e
--- /dev/null
+++ b/hardinfo2/pixmaps/keyboard.png
Binary files differ
diff --git a/hardinfo2/pixmaps/language.png b/hardinfo2/pixmaps/language.png
new file mode 100644
index 00000000..ab82b50f
--- /dev/null
+++ b/hardinfo2/pixmaps/language.png
Binary files differ
diff --git a/hardinfo2/pixmaps/logo.png b/hardinfo2/pixmaps/logo.png
new file mode 100644
index 00000000..d2dee31e
--- /dev/null
+++ b/hardinfo2/pixmaps/logo.png
Binary files differ
diff --git a/hardinfo2/pixmaps/memory.png b/hardinfo2/pixmaps/memory.png
new file mode 100644
index 00000000..1ea66b8a
--- /dev/null
+++ b/hardinfo2/pixmaps/memory.png
Binary files differ
diff --git a/hardinfo2/pixmaps/modem.png b/hardinfo2/pixmaps/modem.png
new file mode 100644
index 00000000..8d1ea2b0
--- /dev/null
+++ b/hardinfo2/pixmaps/modem.png
Binary files differ
diff --git a/hardinfo2/pixmaps/module.png b/hardinfo2/pixmaps/module.png
new file mode 100644
index 00000000..8f1279d0
--- /dev/null
+++ b/hardinfo2/pixmaps/module.png
Binary files differ
diff --git a/hardinfo2/pixmaps/monitor.png b/hardinfo2/pixmaps/monitor.png
new file mode 100644
index 00000000..669086a4
--- /dev/null
+++ b/hardinfo2/pixmaps/monitor.png
Binary files differ
diff --git a/hardinfo2/pixmaps/mouse.png b/hardinfo2/pixmaps/mouse.png
new file mode 100644
index 00000000..4043722d
--- /dev/null
+++ b/hardinfo2/pixmaps/mouse.png
Binary files differ
diff --git a/hardinfo2/pixmaps/network.png b/hardinfo2/pixmaps/network.png
new file mode 100644
index 00000000..f8c623b6
--- /dev/null
+++ b/hardinfo2/pixmaps/network.png
Binary files differ
diff --git a/hardinfo2/pixmaps/os.png b/hardinfo2/pixmaps/os.png
new file mode 100644
index 00000000..166c2201
--- /dev/null
+++ b/hardinfo2/pixmaps/os.png
Binary files differ
diff --git a/hardinfo2/pixmaps/pcmcia.png b/hardinfo2/pixmaps/pcmcia.png
new file mode 100644
index 00000000..2baac660
--- /dev/null
+++ b/hardinfo2/pixmaps/pcmcia.png
Binary files differ
diff --git a/hardinfo2/pixmaps/printer.png b/hardinfo2/pixmaps/printer.png
new file mode 100644
index 00000000..dd814d6c
--- /dev/null
+++ b/hardinfo2/pixmaps/printer.png
Binary files differ
diff --git a/hardinfo2/pixmaps/processor.png b/hardinfo2/pixmaps/processor.png
new file mode 100644
index 00000000..7b2a3fb1
--- /dev/null
+++ b/hardinfo2/pixmaps/processor.png
Binary files differ
diff --git a/hardinfo2/pixmaps/report.png b/hardinfo2/pixmaps/report.png
new file mode 100644
index 00000000..48bd5d01
--- /dev/null
+++ b/hardinfo2/pixmaps/report.png
Binary files differ
diff --git a/hardinfo2/pixmaps/shares.png b/hardinfo2/pixmaps/shares.png
new file mode 100644
index 00000000..ab4e197d
--- /dev/null
+++ b/hardinfo2/pixmaps/shares.png
Binary files differ
diff --git a/hardinfo2/pixmaps/stock_channel.png b/hardinfo2/pixmaps/stock_channel.png
new file mode 100644
index 00000000..2a74f2e6
--- /dev/null
+++ b/hardinfo2/pixmaps/stock_channel.png
Binary files differ
diff --git a/hardinfo2/pixmaps/stock_insert-floating-frame.png b/hardinfo2/pixmaps/stock_insert-floating-frame.png
new file mode 100644
index 00000000..8f82250f
--- /dev/null
+++ b/hardinfo2/pixmaps/stock_insert-floating-frame.png
Binary files differ
diff --git a/hardinfo2/pixmaps/stock_landline-phone.png b/hardinfo2/pixmaps/stock_landline-phone.png
new file mode 100644
index 00000000..61da5dab
--- /dev/null
+++ b/hardinfo2/pixmaps/stock_landline-phone.png
Binary files differ
diff --git a/hardinfo2/pixmaps/stock_macro-watch-variable.png b/hardinfo2/pixmaps/stock_macro-watch-variable.png
new file mode 100644
index 00000000..2e52ddc9
--- /dev/null
+++ b/hardinfo2/pixmaps/stock_macro-watch-variable.png
Binary files differ
diff --git a/hardinfo2/pixmaps/summary.png b/hardinfo2/pixmaps/summary.png
new file mode 100644
index 00000000..5a2cd965
--- /dev/null
+++ b/hardinfo2/pixmaps/summary.png
Binary files differ
diff --git a/hardinfo2/pixmaps/therm.png b/hardinfo2/pixmaps/therm.png
new file mode 100644
index 00000000..3dac3913
--- /dev/null
+++ b/hardinfo2/pixmaps/therm.png
Binary files differ
diff --git a/hardinfo2/pixmaps/usb.png b/hardinfo2/pixmaps/usb.png
new file mode 100644
index 00000000..7c7c6746
--- /dev/null
+++ b/hardinfo2/pixmaps/usb.png
Binary files differ
diff --git a/hardinfo2/pixmaps/users.png b/hardinfo2/pixmaps/users.png
new file mode 100644
index 00000000..cbc62084
--- /dev/null
+++ b/hardinfo2/pixmaps/users.png
Binary files differ
diff --git a/hardinfo2/pixmaps/videocap.png b/hardinfo2/pixmaps/videocap.png
new file mode 100644
index 00000000..8bbea0ba
--- /dev/null
+++ b/hardinfo2/pixmaps/videocap.png
Binary files differ
diff --git a/hardinfo2/sha1.c b/hardinfo2/sha1.c
new file mode 100644
index 00000000..947a086c
--- /dev/null
+++ b/hardinfo2/sha1.c
@@ -0,0 +1,336 @@
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+ A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+ 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+
+/* #define SHA1HANDSOFF * Copies data before messing with it. */
+
+#include <stdio.h>
+#include <string.h>
+#include <sha1.h>
+
+#include <glib.h>
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define LITTLE_ENDIAN /* This should be #define'd if true. */
+#endif
+
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifdef LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+ |(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+ ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(unsigned long state[5], unsigned char buffer[64])
+{
+ unsigned long a, b, c, d, e;
+ typedef union {
+ unsigned char c[64];
+ unsigned long l[16];
+ } CHAR64LONG16;
+ CHAR64LONG16 *block;
+#ifdef SHA1HANDSOFF
+ static unsigned char workspace[64];
+ block = (CHAR64LONG16 *) workspace;
+ memcpy(block, buffer, 64);
+#else
+ block = (CHAR64LONG16 *) buffer;
+#endif
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a, b, c, d, e, 0);
+ R0(e, a, b, c, d, 1);
+ R0(d, e, a, b, c, 2);
+ R0(c, d, e, a, b, 3);
+ R0(b, c, d, e, a, 4);
+ R0(a, b, c, d, e, 5);
+ R0(e, a, b, c, d, 6);
+ R0(d, e, a, b, c, 7);
+ R0(c, d, e, a, b, 8);
+ R0(b, c, d, e, a, 9);
+ R0(a, b, c, d, e, 10);
+ R0(e, a, b, c, d, 11);
+ R0(d, e, a, b, c, 12);
+ R0(c, d, e, a, b, 13);
+ R0(b, c, d, e, a, 14);
+ R0(a, b, c, d, e, 15);
+ R1(e, a, b, c, d, 16);
+ R1(d, e, a, b, c, 17);
+ R1(c, d, e, a, b, 18);
+ R1(b, c, d, e, a, 19);
+ R2(a, b, c, d, e, 20);
+ R2(e, a, b, c, d, 21);
+ R2(d, e, a, b, c, 22);
+ R2(c, d, e, a, b, 23);
+ R2(b, c, d, e, a, 24);
+ R2(a, b, c, d, e, 25);
+ R2(e, a, b, c, d, 26);
+ R2(d, e, a, b, c, 27);
+ R2(c, d, e, a, b, 28);
+ R2(b, c, d, e, a, 29);
+ R2(a, b, c, d, e, 30);
+ R2(e, a, b, c, d, 31);
+ R2(d, e, a, b, c, 32);
+ R2(c, d, e, a, b, 33);
+ R2(b, c, d, e, a, 34);
+ R2(a, b, c, d, e, 35);
+ R2(e, a, b, c, d, 36);
+ R2(d, e, a, b, c, 37);
+ R2(c, d, e, a, b, 38);
+ R2(b, c, d, e, a, 39);
+ R3(a, b, c, d, e, 40);
+ R3(e, a, b, c, d, 41);
+ R3(d, e, a, b, c, 42);
+ R3(c, d, e, a, b, 43);
+ R3(b, c, d, e, a, 44);
+ R3(a, b, c, d, e, 45);
+ R3(e, a, b, c, d, 46);
+ R3(d, e, a, b, c, 47);
+ R3(c, d, e, a, b, 48);
+ R3(b, c, d, e, a, 49);
+ R3(a, b, c, d, e, 50);
+ R3(e, a, b, c, d, 51);
+ R3(d, e, a, b, c, 52);
+ R3(c, d, e, a, b, 53);
+ R3(b, c, d, e, a, 54);
+ R3(a, b, c, d, e, 55);
+ R3(e, a, b, c, d, 56);
+ R3(d, e, a, b, c, 57);
+ R3(c, d, e, a, b, 58);
+ R3(b, c, d, e, a, 59);
+ R4(a, b, c, d, e, 60);
+ R4(e, a, b, c, d, 61);
+ R4(d, e, a, b, c, 62);
+ R4(c, d, e, a, b, 63);
+ R4(b, c, d, e, a, 64);
+ R4(a, b, c, d, e, 65);
+ R4(e, a, b, c, d, 66);
+ R4(d, e, a, b, c, 67);
+ R4(c, d, e, a, b, 68);
+ R4(b, c, d, e, a, 69);
+ R4(a, b, c, d, e, 70);
+ R4(e, a, b, c, d, 71);
+ R4(d, e, a, b, c, 72);
+ R4(c, d, e, a, b, 73);
+ R4(b, c, d, e, a, 74);
+ R4(a, b, c, d, e, 75);
+ R4(e, a, b, c, d, 76);
+ R4(d, e, a, b, c, 77);
+ R4(c, d, e, a, b, 78);
+ R4(b, c, d, e, a, 79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX * context)
+{
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX * context, unsigned char *data, unsigned int len)
+{
+ unsigned int i, j;
+
+ j = (context->count[0] >> 3) & 63;
+ if ((context->count[0] += len << 3) < (len << 3))
+ context->count[1]++;
+ context->count[1] += (len >> 29);
+ if ((j + len) > 63) {
+ memcpy(&context->buffer[j], data, (i = 64 - j));
+ SHA1Transform(context->state, context->buffer);
+ for (; i + 63 < len; i += 64) {
+ SHA1Transform(context->state, &data[i]);
+ }
+ j = 0;
+ } else
+ i = 0;
+ memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(unsigned char digest[20], SHA1_CTX * context)
+{
+ unsigned long i, j;
+ unsigned char finalcount[8];
+
+ for (i = 0; i < 8; i++) {
+ finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)]
+ >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */
+ }
+ SHA1Update(context, (unsigned char *) "\200", 1);
+ while ((context->count[0] & 504) != 448) {
+ SHA1Update(context, (unsigned char *) "\0", 1);
+ }
+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
+ for (i = 0; i < 20; i++) {
+ digest[i] = (unsigned char)
+ ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
+ }
+ /* Wipe variables */
+ i = j = 0;
+ memset(context->buffer, 0, 64);
+ memset(context->state, 0, 20);
+ memset(context->count, 0, 8);
+ memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
+ SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+#ifdef SHA1_TEST
+static char *b32_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+
+void g_assert(int a)
+{
+ /* Bah, who needs testing anyway... ;) */
+}
+
+static void base32_encode_exactly(unsigned char *buf, int len,
+ unsigned char *encbuf, int enclen)
+{
+ int i = 0;
+ unsigned char *ip = buf + len;
+ unsigned char *op = encbuf + enclen;
+
+ switch (len % 5) {
+ case 0:
+ do {
+ g_assert(op - encbuf >= 8);
+ i = *--ip; /* Input #4 */
+ *--op = b32_alphabet[i & 0x1f]; /* Ouput #7 */
+ i >>= 5; /* upper <234>, input #4 */
+ /* FALLTHROUGH */
+ case 4:
+ i |= ((unsigned int) *--ip) << 3; /* had 3 bits in `i' */
+ *--op = b32_alphabet[i & 0x1f]; /* Output #6 */
+ i >>= 5; /* upper <401234>, input #3 */
+ *--op = b32_alphabet[i & 0x1f]; /* Output #5 */
+ i >>= 5; /* upper <4>, input #3 */
+ /* FALLTHROUGH */
+ case 3:
+ i |= ((unsigned int) *--ip) << 1; /* had 1 bits in `i' */
+ *--op = b32_alphabet[i & 0x1f]; /* Output #4 */
+ i >>= 5; /* upper <1234>, input #2 */
+ /* FALLTHROUGH */
+ case 2:
+ i |= ((unsigned int) *--ip) << 4; /* had 4 bits in `i' */
+ *--op = b32_alphabet[i & 0x1f]; /* Output #3 */
+ i >>= 5; /* upper <3401234>, input #1 */
+ *--op = b32_alphabet[i & 0x1f]; /* Output #2 */
+ i >>= 5; /* upper <34>, input #1 */
+ /* FALLTHROUGH */
+ case 1:
+ i |= ((unsigned int) *--ip) << 2; /* had 2 bits in `i' */
+ *--op = b32_alphabet[i & 0x1f]; /* Output #1 */
+ i >>= 5; /* upper <01234>, input #0 */
+ *--op = b32_alphabet[i & 0x1f]; /* Output #0 */
+ i >>= 5; /* Holds nothing, MBZ */
+ g_assert(i == 0);
+ g_assert(op >= encbuf);
+ } while (op > encbuf);
+ }
+}
+
+
+
+/*************************************************************/
+
+int main(int argc, char **argv)
+{
+ int i, j;
+ SHA1_CTX context;
+ unsigned char digest[20], buffer[16384];
+ FILE *file;
+
+ if (argc > 2) {
+ puts("Public domain SHA-1 implementation - by Steve Reid <steve@edmweb.com>");
+ puts("Produces the SHA-1 hash of a file, or stdin if no file is specified.");
+ exit(0);
+ }
+ if (argc < 2) {
+ file = stdin;
+ } else {
+ if (!(file = fopen(argv[1], "rb"))) {
+ fputs("Unable to open file.", stderr);
+ exit(-1);
+ }
+ }
+ SHA1Init(&context);
+ while (!feof(file)) { /* note: what if ferror(file) */
+ i = fread(buffer, 1, 16384, file);
+ SHA1Update(&context, buffer, i);
+ }
+ SHA1Final(digest, &context);
+ fclose(file);
+/*
+ for (i = 0; i < 5; i++) {
+ for (j = 0; j < 4; j++) {
+ printf("%02X", digest[i*4+j]);
+ }
+ putchar(' ');
+ }
+ putchar('\n');
+*/
+
+ {
+ unsigned char tmp[33];
+ tmp[32] = '\0';
+ base32_encode_exactly(digest, 20, tmp, 32);
+ printf("%s\n", tmp);
+ }
+
+ exit(0);
+}
+#endif /* SHA1_TEST */
diff --git a/hardinfo2/sha1.h b/hardinfo2/sha1.h
new file mode 100644
index 00000000..83f28df7
--- /dev/null
+++ b/hardinfo2/sha1.h
@@ -0,0 +1,21 @@
+/*
+ * SHA-1 in C
+ * By Steve Reid <steve@edmweb.com>
+ * 100% Public Domain
+ */
+
+#ifndef __SHA1_H__
+#define __SHA1_H__
+
+typedef struct {
+ unsigned long state[5];
+ unsigned long count[2];
+ unsigned char buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform(unsigned long state[5], unsigned char buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
+
+#endif /* __SHA1_H__ */
diff --git a/hardinfo2/shell.c b/hardinfo2/shell.c
new file mode 100644
index 00000000..1482a028
--- /dev/null
+++ b/hardinfo2/shell.c
@@ -0,0 +1,1071 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include <config.h>
+
+#include <hardinfo.h>
+
+#include <shell.h>
+#include <iconcache.h>
+#include <menu.h>
+#include <stock.h>
+
+/*
+ * Internal Prototypes ********************************************************
+ */
+
+static void shell_create_window();
+static ShellTree *shell_tree_new(void);
+static ShellInfoTree *shell_info_tree_new(gboolean extra);
+
+static void module_selected(GtkTreeSelection * ts, gpointer data);
+static void module_selected_show_info(ShellModuleEntry * entry,
+ gboolean reload);
+static void info_selected(GtkTreeSelection * ts, gpointer data);
+static void info_selected_show_extra(gchar * data);
+static gboolean reload_section(gpointer data);
+
+/*
+ * Globals ********************************************************************
+ */
+
+static Shell *shell = NULL;
+static GHashTable *update_tbl = NULL;
+
+/*
+ * Code :) ********************************************************************
+ */
+
+void shell_ui_manager_set_visible(const gchar *path,
+ gboolean setting)
+{
+ GtkWidget *widget;
+
+ widget = gtk_ui_manager_get_widget(shell->ui_manager, path);
+ if (!widget)
+ return;
+
+ if (setting)
+ gtk_widget_show(widget);
+ else
+ gtk_widget_hide(widget);
+}
+
+void shell_action_set_property(const gchar *action_name,
+ const gchar *property,
+ gboolean setting)
+{
+ GtkAction *action;
+
+ action = gtk_action_group_get_action(shell->action_group, action_name);
+ if (action) {
+ GValue value = {0};
+
+ g_value_init(&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean(&value, setting);
+
+ g_object_set_property(G_OBJECT(action), property, &value);
+
+ g_value_unset(&value);
+ }
+}
+
+void shell_action_set_enabled(const gchar *action_name, gboolean setting)
+{
+ GtkAction *action;
+
+ action = gtk_action_group_get_action(shell->action_group, action_name);
+ if (action) {
+ gtk_action_set_sensitive(action, setting);
+ }
+}
+
+void shell_set_left_pane_visible(gboolean setting)
+{
+ if (setting)
+ gtk_widget_show(shell->tree->scroll);
+ else
+ gtk_widget_hide(shell->tree->scroll);
+}
+
+gboolean shell_action_get_active(const gchar *action_name)
+{
+ GtkAction *action;
+ GSList *proxies;
+
+ /* FIXME: Ugh. Are you sure there isn't any simpler way? O_o */
+
+ action = gtk_action_group_get_action(shell->action_group, action_name);
+ if (action) {
+ proxies = gtk_action_get_proxies(action);
+
+ for (; proxies; proxies = proxies->next) {
+ GtkWidget *widget = (GtkWidget *)proxies->data;
+
+ if (GTK_IS_CHECK_MENU_ITEM(widget)) {
+ return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+void shell_action_set_active(const gchar *action_name, gboolean setting)
+{
+ GtkAction *action;
+ GSList *proxies;
+
+ /* FIXME: Ugh. Are you sure there isn't any simpler way? O_o */
+
+ action = gtk_action_group_get_action(shell->action_group, action_name);
+ if (action) {
+ proxies = gtk_action_get_proxies(action);
+
+ for (; proxies; proxies = proxies->next) {
+ GtkWidget *widget = (GtkWidget *)proxies->data;
+
+ if (GTK_IS_CHECK_MENU_ITEM(widget)) {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), setting);
+ return;
+ }
+ }
+ }
+}
+
+void
+shell_status_pulse(void)
+{
+ gtk_progress_bar_pulse(GTK_PROGRESS_BAR(shell->progress));
+ while (gtk_events_pending())
+ gtk_main_iteration();
+}
+
+void
+shell_status_set_percentage(gint percentage)
+{
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(shell->progress), (float)percentage/100.0);
+ while (gtk_events_pending())
+ gtk_main_iteration();
+}
+
+void
+shell_view_set_enabled(gboolean setting)
+{
+ gtk_widget_set_sensitive(shell->hpaned, setting);
+ shell_action_set_enabled("ViewMenuAction", setting);
+ shell_action_set_enabled("RefreshAction", setting);
+}
+
+void
+shell_status_set_enabled(gboolean setting)
+{
+ if (setting)
+ gtk_widget_show(shell->progress);
+ else {
+ gtk_widget_hide(shell->progress);
+ shell_view_set_enabled(TRUE);
+ }
+}
+
+void
+shell_do_reload(void)
+{
+ shell_action_set_enabled("RefreshAction", FALSE);
+
+ if (shell->selected && shell->selected->reloadfunc) {
+ GtkTreeSelection *ts;
+
+ ts = gtk_tree_view_get_selection(GTK_TREE_VIEW(shell->tree->view));
+ shell_status_set_enabled(TRUE);
+
+ shell->selected->reloadfunc(shell->selected->number);
+ module_selected(ts, NULL);
+ }
+
+ shell_action_set_enabled("RefreshAction", TRUE);
+}
+
+void
+shell_status_update(const gchar * message)
+{
+ gtk_label_set_markup(GTK_LABEL(shell->status), message);
+ gtk_progress_bar_pulse(GTK_PROGRESS_BAR(shell->progress));
+ while (gtk_events_pending())
+ gtk_main_iteration();
+}
+
+static void
+shell_create_window(void)
+{
+ GtkWidget *vbox, *hbox;
+
+ shell = g_new0(Shell, 1);
+
+ shell->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_icon(GTK_WINDOW(shell->window), icon_cache_get_pixbuf("logo.png"));
+ gtk_window_set_title(GTK_WINDOW(shell->window), "System Information");
+ gtk_widget_set_size_request(shell->window, 600, 400);
+ g_signal_connect(G_OBJECT(shell->window), "destroy", gtk_main_quit,
+ NULL);
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(vbox);
+ gtk_container_add(GTK_CONTAINER(shell->window), vbox);
+ shell->vbox = vbox;
+
+ menu_init(shell);
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_widget_show(hbox);
+ gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 3);
+
+ shell->progress = gtk_progress_bar_new();
+ gtk_widget_set_size_request(shell->progress, 70, 10);
+ gtk_widget_hide(shell->progress);
+ gtk_box_pack_end(GTK_BOX(hbox), shell->progress, FALSE, FALSE, 0);
+
+ shell->status = gtk_label_new("");
+ gtk_misc_set_alignment(GTK_MISC(shell->status), 0.0, 0.5);
+ gtk_widget_show(shell->status);
+ gtk_box_pack_start(GTK_BOX(hbox), shell->status, FALSE, FALSE, 0);
+
+ shell->hpaned = gtk_hpaned_new();
+ gtk_widget_show(shell->hpaned);
+ gtk_box_pack_end(GTK_BOX(vbox), shell->hpaned, TRUE, TRUE, 0);
+ gtk_paned_set_position(GTK_PANED(shell->hpaned), 210);
+
+ shell->vpaned = gtk_vpaned_new();
+ gtk_widget_show(shell->vpaned);
+ gtk_paned_add2(GTK_PANED(shell->hpaned), shell->vpaned);
+
+ shell->notebook = gtk_notebook_new();
+ gtk_paned_add2(GTK_PANED(shell->vpaned), shell->notebook);
+
+ gtk_widget_show(shell->window);
+ while (gtk_events_pending())
+ gtk_main_iteration();
+}
+
+/* FIXME: nao usar o modules.conf, ler os .so de um diretorio */
+static void
+shell_tree_modules_load(ShellTree * shelltree)
+{
+ GKeyFile *keyfile = g_key_file_new();
+ guint categories, i;
+
+ keyfile = g_key_file_new();
+ g_key_file_load_from_file(keyfile, PREFIX "modules.conf", 0, NULL);
+ if (g_key_file_get_integer(keyfile, "general", "version", NULL) != 2) {
+ g_error("Wrong version of modules.conf");
+ }
+
+ gchar **cat = g_key_file_get_keys(keyfile, "categories", &categories, NULL);
+ for (i = 0; i < categories; i++) {
+ ShellModule *module;
+ gchar *tmp, *iname;
+
+ module = g_new0(ShellModule, 1);
+ module->name = g_strdup(cat[i]);
+ iname = g_key_file_get_value(keyfile, "categories", cat[i], NULL);
+
+ tmp = g_strdup_printf("%s.png", iname);
+ module->icon = icon_cache_get_pixbuf(tmp);
+ g_free(tmp);
+
+ tmp = g_strdup_printf(PREFIX "modules/%s.so", iname);
+ module->dll = g_module_open(tmp, G_MODULE_BIND_LAZY);
+ g_free(tmp);
+
+ if (module->dll) {
+ gint(*n_entries) (void);
+ gint i;
+
+ if (!g_module_symbol
+ (module->dll, "hi_n_entries", (gpointer) & n_entries))
+ continue;
+
+ gint j = n_entries();
+ for (i = 0; i <= j; i++) {
+ GdkPixbuf *(*shell_icon) (gint);
+ const gchar *(*shell_name) (gint);
+ ShellModuleEntry *entry = g_new0(ShellModuleEntry, 1);
+ gpointer symbol;
+
+ if (g_module_symbol(module->dll, "hi_icon", &symbol)) {
+ shell_icon = symbol;
+ entry->icon = shell_icon(i);
+ }
+ if (g_module_symbol(module->dll, "hi_name", &symbol)) {
+ shell_name = symbol;
+ entry->name = g_strdup(shell_name(i));
+ }
+ g_module_symbol(module->dll, "hi_info",
+ (gpointer) & (entry->func));
+ g_module_symbol(module->dll, "hi_reload",
+ (gpointer) & (entry->reloadfunc));
+ g_module_symbol(module->dll, "hi_more_info",
+ (gpointer) & (entry->morefunc));
+ g_module_symbol(module->dll, "hi_get_field",
+ (gpointer) & (entry->fieldfunc));
+
+ entry->number = i;
+ module->entries = g_slist_append(module->entries, entry);
+ }
+
+ shelltree->modules =
+ g_slist_append(shelltree->modules, module);
+ } else {
+ g_free(module->name);
+ g_free(module->icon);
+ g_free(module);
+ }
+
+ g_free(iname);
+ }
+
+ g_strfreev(cat);
+ g_key_file_free(keyfile);
+}
+
+static void view_menu_select_entry(gpointer data, gpointer data2)
+{
+ GtkTreeSelection *ts;
+ GtkTreePath *path;
+ GtkTreeIter *iter = (GtkTreeIter*) data2;
+
+ ts = gtk_tree_view_get_selection(GTK_TREE_VIEW(shell->tree->view));
+ path = gtk_tree_model_get_path(shell->tree->model, iter);
+
+ gtk_tree_selection_select_path(ts, path);
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(shell->tree->view), path, NULL, FALSE);
+ gtk_tree_path_free(path);
+}
+
+static void
+add_module_to_view_menu(gchar *name, GdkPixbuf *pixbuf)
+{
+ stock_icon_register_pixbuf(pixbuf, name);
+
+ GtkActionEntry entries[] = {
+ { name, /* name */
+ name, /* stockid */
+ name, /* label */
+ NULL, /* accelerator */
+ NULL, /* tooltip */
+ NULL, /* callback */
+ },
+ };
+
+ gtk_action_group_add_actions(shell->action_group, entries, 1, NULL);
+
+ gtk_ui_manager_add_ui(shell->ui_manager,
+ gtk_ui_manager_new_merge_id(shell->ui_manager),
+ "/menubar/ViewMenu/LastSep",
+ name,
+ name,
+ GTK_UI_MANAGER_MENU,
+ TRUE);
+}
+
+static void
+add_module_entry_to_view_menu(gchar *module, gchar *name, GdkPixbuf *pixbuf, GtkTreeIter *iter)
+{
+ stock_icon_register_pixbuf(pixbuf, name);
+
+ GtkActionEntry entries[] = {
+ { name, /* name */
+ name, /* stockid */
+ name, /* label */
+ NULL, /* accelerator */
+ NULL, /* tooltip */
+ (GCallback)view_menu_select_entry,/* callback */
+ },
+ };
+
+ gtk_action_group_add_actions(shell->action_group, entries, 1, iter);
+
+ gtk_ui_manager_add_ui(shell->ui_manager,
+ gtk_ui_manager_new_merge_id(shell->ui_manager),
+ g_strdup_printf("/menubar/ViewMenu/%s", module),
+ name,
+ name,
+ GTK_UI_MANAGER_AUTO,
+ FALSE);
+}
+
+static void
+add_modules_to_gui(gpointer data, gpointer user_data)
+{
+ ShellTree *shelltree = (ShellTree *) user_data;
+ ShellModule *module = (ShellModule *) data;
+ GtkTreeStore *store = GTK_TREE_STORE(shelltree->model);
+ GtkTreeIter parent;
+
+ gtk_tree_store_append(store, &parent, NULL);
+ gtk_tree_store_set(store, &parent, TREE_COL_NAME, module->name,
+ TREE_COL_DATA, NULL, -1);
+
+ if (module->icon) {
+ gtk_tree_store_set(store, &parent, TREE_COL_PBUF, module->icon, -1);
+ }
+
+ add_module_to_view_menu(module->name, module->icon);
+
+ if (module->entries) {
+ ShellModuleEntry *entry;
+ GSList *p;
+
+ for (p = module->entries; p; p = g_slist_next(p)) {
+ GtkTreeIter child;
+ entry = (ShellModuleEntry *) p->data;
+
+ gtk_tree_store_append(store, &child, &parent);
+ gtk_tree_store_set(store, &child, TREE_COL_NAME, entry->name,
+ TREE_COL_DATA, entry, -1);
+
+ if (entry->icon) {
+ gtk_tree_store_set(store, &child, TREE_COL_PBUF,
+ entry->icon, -1);
+ }
+
+ add_module_entry_to_view_menu(module->name, entry->name, entry->icon,
+ gtk_tree_iter_copy(&child));
+
+ shell_status_pulse();
+ }
+
+ }
+}
+
+void
+shell_init(void)
+{
+ if (shell) {
+ g_error("Shell already created");
+ return;
+ }
+
+ shell_create_window();
+
+ shell->tree = shell_tree_new();
+ shell->info = shell_info_tree_new(FALSE);
+ shell->moreinfo = shell_info_tree_new(TRUE);
+ shell->loadgraph = load_graph_new(75);
+
+ gtk_paned_pack1(GTK_PANED(shell->hpaned), shell->tree->scroll,
+ SHELL_PACK_RESIZE, SHELL_PACK_SHRINK);
+ gtk_paned_pack1(GTK_PANED(shell->vpaned), shell->info->scroll,
+ SHELL_PACK_RESIZE, SHELL_PACK_SHRINK);
+
+ gtk_notebook_append_page(GTK_NOTEBOOK(shell->notebook),
+ shell->moreinfo->scroll, NULL);
+ gtk_notebook_append_page(GTK_NOTEBOOK(shell->notebook),
+ load_graph_get_framed(shell->loadgraph), NULL);
+
+ gtk_notebook_set_show_tabs(GTK_NOTEBOOK(shell->notebook), FALSE);
+ gtk_notebook_set_show_border(GTK_NOTEBOOK(shell->notebook), FALSE);
+
+ shell_status_set_enabled(TRUE);
+ shell_status_update("Loading modules...");
+
+ shell_tree_modules_load(shell->tree);
+ g_slist_foreach(shell->tree->modules, add_modules_to_gui, shell->tree);
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(shell->tree->view));
+
+ shell_status_update("Done.");
+ shell_status_set_enabled(FALSE);
+
+ gtk_widget_show_all(shell->hpaned);
+
+ load_graph_configure_expose(shell->loadgraph);
+
+ gtk_widget_hide(shell->notebook);
+
+ shell_action_set_enabled("RefreshAction", FALSE);
+ shell_action_set_enabled("ReportAction", FALSE);
+ shell_action_set_active("LeftPaneAction", TRUE);
+ shell_action_set_active("ToolbarAction", TRUE);
+ shell_action_set_property("RefreshAction", "is-important", TRUE);
+ shell_action_set_property("ReportAction", "is-important", TRUE);
+}
+
+static gboolean
+update_field(gpointer data)
+{
+ ShellFieldUpdate *fu = (ShellFieldUpdate *) data;
+
+ /* if the entry is still selected, update it */
+ if (fu->entry->selected && fu->entry->fieldfunc) {
+ gchar *value = fu->entry->fieldfunc(fu->field_name);
+ GtkTreeIter *iter = g_hash_table_lookup(update_tbl, fu->field_name);
+
+ /* this function is also used to feed the load graph when ViewType =
+ SHELL_VIEW_LOAD_GRAPH */
+ if (fu->loadgraph && shell->view_type == SHELL_VIEW_LOAD_GRAPH) {
+ GtkTreeSelection *ts;
+
+ ts = gtk_tree_view_get_selection(GTK_TREE_VIEW
+ (shell->info->view));
+
+ if (iter && gtk_tree_selection_iter_is_selected(ts, iter)) {
+ load_graph_update(shell->loadgraph, atoi(value));
+ }
+
+ g_free(value);
+
+ return TRUE;
+ }
+
+ GtkTreeStore *store = GTK_TREE_STORE(shell->info->model);
+
+ if (iter) {
+ gtk_tree_store_set(store, iter, INFO_TREE_COL_VALUE, value, -1);
+ g_free(value);
+
+ return TRUE;
+ }
+ }
+
+ /* otherwise, cleanup and destroy the timeout */
+ g_free(fu->field_name);
+ g_free(fu);
+
+ return FALSE;
+}
+
+static gboolean
+reload_section(gpointer data)
+{
+ ShellModuleEntry *entry = (ShellModuleEntry *) data;
+
+ /* if the entry is still selected, update it */
+ if (entry->selected && entry->reloadfunc) {
+ GtkTreePath *path = NULL;
+ GtkTreeSelection *ts;
+ GtkTreeIter iter;
+
+ /* gets the current selected path */
+ ts = gtk_tree_view_get_selection(GTK_TREE_VIEW
+ (shell->info->view));
+ if (gtk_tree_selection_get_selected(ts, &shell->info->model, &iter))
+ path = gtk_tree_model_get_path(shell->info->model, &iter);
+
+ /* update the information, clear the treeview and populate it again */
+ entry->reloadfunc(entry->number);
+ info_selected_show_extra(NULL); /* clears the more info store */
+ module_selected_show_info(entry, TRUE);
+
+ /* if there was a selection, reselect it */
+ if (path) {
+ gtk_tree_selection_select_path(ts, path);
+ gtk_tree_path_free(path);
+ }
+ }
+
+ /* destroy the timeout: it'll be set up again */
+ return FALSE;
+}
+
+static void
+shell_set_view_type(ShellViewType viewtype)
+{
+ gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(shell->info->view), FALSE);
+
+ if (viewtype == shell->view_type)
+ return;
+
+ switch (viewtype) {
+ default:
+ case SHELL_VIEW_NORMAL:
+ gtk_widget_hide(shell->notebook);
+
+ shell->view_type = SHELL_VIEW_NORMAL;
+ break;
+ case SHELL_VIEW_DUAL:
+ gtk_notebook_set_page(GTK_NOTEBOOK(shell->notebook), 0);
+ gtk_widget_show(shell->notebook);
+
+ shell->view_type = SHELL_VIEW_DUAL;
+ break;
+ case SHELL_VIEW_LOAD_GRAPH:
+ gtk_notebook_set_page(GTK_NOTEBOOK(shell->notebook), 1);
+ gtk_widget_show(shell->notebook);
+ load_graph_clear(shell->loadgraph);
+
+ gtk_paned_set_position(GTK_PANED(shell->vpaned),
+ shell->hpaned->allocation.height -
+ shell->loadgraph->height - 16);
+
+ shell->view_type = SHELL_VIEW_LOAD_GRAPH;
+ break;
+ }
+}
+
+static void
+group_handle_special(GKeyFile * key_file, ShellModuleEntry * entry,
+ gchar * group, gchar ** keys)
+{
+ if (g_str_equal(group, "$ShellParam$")) {
+ while (*keys) {
+ gchar *key = *keys;
+
+ if (g_str_has_prefix(key, "UpdateInterval")) {
+ gint ms;
+ ShellFieldUpdate *fu = g_new0(ShellFieldUpdate, 1);
+
+ ms = g_key_file_get_integer(key_file, group, key, NULL);
+
+ fu->field_name = g_strdup(strchr(key, '$') + 1);
+ fu->entry = entry;
+ fu->loadgraph = FALSE;
+
+ g_timeout_add(ms, update_field, fu);
+ } else if (g_str_has_prefix(key, "LoadGraphInterval")) {
+ gint ms;
+ ShellFieldUpdate *fu = g_new0(ShellFieldUpdate, 1);
+
+ ms = g_key_file_get_integer(key_file, group, key, NULL);
+
+ fu->field_name = g_strdup(strchr(key, '$') + 1);
+ fu->entry = entry;
+ fu->loadgraph = TRUE;
+
+ g_timeout_add(ms, update_field, fu);
+ } else if (g_str_equal(key, "ReloadInterval")) {
+ gint ms;
+
+ ms = g_key_file_get_integer(key_file, group, key, NULL);
+
+ g_timeout_add(ms, reload_section, entry);
+ } else if (g_str_equal(key, "ViewType")) {
+ shell_set_view_type(g_key_file_get_integer(key_file, group,
+ key, NULL));
+ } else if (g_str_has_prefix(key, "Icon")) {
+ GtkTreeIter *iter = g_hash_table_lookup(update_tbl,
+ strchr(key, '$') + 1);
+
+ if (iter) {
+ gchar *file = g_key_file_get_value(key_file, group, key, NULL);
+ gtk_tree_store_set(GTK_TREE_STORE(shell->info->model),
+ iter, INFO_TREE_COL_PBUF,
+ icon_cache_get_pixbuf_at_size(file, 24, 24),
+ -1);
+ g_free(file);
+ }
+ } else if (g_str_equal(key, "Zebra")) {
+ gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(shell->info->view),
+ g_key_file_get_boolean(key_file,
+ group,
+ key, NULL));
+ }
+
+ *keys++;
+ }
+ } else {
+ g_warning("Unknown parameter group '%s'", group);
+ }
+}
+
+static void
+group_handle_normal(GKeyFile * key_file, ShellModuleEntry * entry,
+ gchar * group, gchar ** keys)
+{
+ GtkTreeIter parent;
+ GtkTreeStore *store = GTK_TREE_STORE(shell->info->model);
+ gchar *tmp = g_strdup(group);
+
+ gtk_tree_store_append(store, &parent, NULL);
+
+ strend(tmp, '#');
+ gtk_tree_store_set(store, &parent, INFO_TREE_COL_NAME, tmp, -1);
+ g_free(tmp);
+
+ while (*keys) {
+ gchar *key = *keys;
+ gchar *value;
+ GtkTreeIter child;
+
+ value = g_key_file_get_value(key_file, group, key, NULL);
+
+ if (g_utf8_validate(key, -1, NULL) && g_utf8_validate(value, -1, NULL)) {
+ gtk_tree_store_append(store, &child, &parent);
+ gtk_tree_store_set(store, &child, INFO_TREE_COL_VALUE, value, -1);
+
+ strend(key, '#');
+
+ if (*key == '$') {
+ gchar **tmp;
+
+ tmp = g_strsplit(++key, "$", 0);
+
+ gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, tmp[1],
+ INFO_TREE_COL_DATA, tmp[0], -1);
+
+ g_strfreev(tmp);
+ } else {
+ gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, key,
+ INFO_TREE_COL_DATA, NULL, -1);
+ }
+
+ g_hash_table_insert(update_tbl, g_strdup(key),
+ gtk_tree_iter_copy(&child));
+
+ }
+
+ g_free(value);
+
+ *keys++;
+ }
+}
+
+static void
+moreinfo_handle_normal(GKeyFile * key_file, gchar * group, gchar ** keys)
+{
+ GtkTreeIter parent;
+ GtkTreeStore *store = GTK_TREE_STORE(shell->moreinfo->model);
+
+ gtk_tree_store_append(store, &parent, NULL);
+ gtk_tree_store_set(store, &parent, INFO_TREE_COL_NAME, group, -1);
+
+ while (*keys) {
+ gchar *key = *keys;
+ GtkTreeIter child;
+ gchar *value;
+
+ value = g_key_file_get_value(key_file, group, key, NULL);
+
+ if (g_utf8_validate(key, -1, NULL) && g_utf8_validate(value, -1, NULL)) {
+ gchar *p = strchr(key, '#');
+ if (p)
+ *p = 0;
+
+ gtk_tree_store_append(store, &child, &parent);
+ gtk_tree_store_set(store, &child, INFO_TREE_COL_VALUE, value,
+ INFO_TREE_COL_NAME, key, -1);
+ }
+
+ g_free(value);
+
+ *keys++;
+ }
+}
+
+static gboolean
+g_true(gpointer key, gpointer value, gpointer data)
+{
+ return TRUE;
+}
+
+static void
+module_selected_show_info(ShellModuleEntry * entry, gboolean reload)
+{
+ GKeyFile *key_file = g_key_file_new();
+ gchar *key_data;
+ gchar **groups, **tmpgroups;
+ GtkTreeStore *store;
+
+ if (entry->func) {
+ key_data = entry->func(entry->number);
+ } else {
+ key_data = g_strdup("[Error]\n"
+ "Invalid module=");
+ }
+
+ /* reset the view type to normal */
+ shell_set_view_type(SHELL_VIEW_NORMAL);
+
+ /* recreate the iter hash table only if we're not reloading the module section */
+ if (!reload) {
+ if (update_tbl != NULL) {
+ g_hash_table_foreach_remove(update_tbl, g_true, NULL);
+ }
+ update_tbl = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ }
+
+ store = GTK_TREE_STORE(shell->info->model);
+ gtk_tree_store_clear(store);
+
+ g_key_file_load_from_data(key_file, key_data, strlen(key_data), 0, NULL);
+ groups = g_key_file_get_groups(key_file, NULL);
+
+ tmpgroups = groups;
+
+ while (*groups) {
+ gchar *group = *groups;
+ gchar **keys =
+ g_key_file_get_keys(key_file, group, NULL, NULL), **tmpkeys;
+
+ tmpkeys = keys;
+
+ if (*group == '$') {
+ group_handle_special(key_file, entry, group, keys);
+ } else {
+ group_handle_normal(key_file, entry, group, keys);
+ }
+
+ g_strfreev(tmpkeys);
+ *groups++;
+ }
+
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(shell->info->view));
+
+ g_strfreev(tmpgroups);
+ g_key_file_free(key_file);
+ g_free(key_data);
+}
+
+static void
+info_selected_show_extra(gchar * data)
+{
+ GtkTreeStore *store;
+
+ store = GTK_TREE_STORE(shell->moreinfo->model);
+ gtk_tree_store_clear(store);
+
+ if (!shell->selected->morefunc)
+ return;
+
+ if (data) {
+ GKeyFile *key_file = g_key_file_new();
+ gchar *key_data = shell->selected->morefunc(data);
+ gchar **groups, **tmpgroups;
+
+ g_key_file_load_from_data(key_file, key_data, strlen(key_data), 0,
+ NULL);
+ groups = g_key_file_get_groups(key_file, NULL);
+
+ tmpgroups = groups;
+
+ while (*groups) {
+ gchar *group = *groups;
+ gchar **keys =
+ g_key_file_get_keys(key_file, group, NULL, NULL),
+ **tmpkeys;
+
+ tmpkeys = keys;
+
+ moreinfo_handle_normal(key_file, group, keys);
+
+ g_strfreev(tmpkeys);
+ *groups++;
+ }
+
+ gtk_tree_view_expand_all(GTK_TREE_VIEW
+ (shell->moreinfo->view));
+
+ g_strfreev(tmpgroups);
+ g_key_file_free(key_file);
+ g_free(key_data);
+ }
+}
+
+static void
+module_selected(GtkTreeSelection * ts, gpointer data)
+{
+ ShellTree *shelltree = shell->tree;
+ GtkTreeModel *model = GTK_TREE_MODEL(shelltree->model);
+ GtkTreeIter parent;
+ ShellModuleEntry *entry;
+ static ShellModuleEntry *current = NULL;
+ static gboolean updating = FALSE;
+
+ if (updating)
+ return;
+
+ updating = TRUE;
+
+ /* Gets the currently selected item on the left-side TreeView; if there is no
+ selection, silently return */
+ if (!gtk_tree_selection_get_selected(ts, &model, &parent))
+ return;
+
+ /* Mark the currently selected module as "unselected"; this is used to kill the
+ update timeout. */
+ if (current)
+ current->selected = FALSE;
+
+ /* Get the current selection and shows its related info */
+ gtk_tree_model_get(model, &parent, TREE_COL_DATA, &entry, -1);
+ if (entry && entry->func && !entry->selected) {
+ shell_status_set_enabled(TRUE);
+ shell_status_update("Updating...");
+
+ entry->selected = TRUE;
+ shell->selected = entry;
+ module_selected_show_info(entry, FALSE);
+
+ info_selected_show_extra(NULL); /* clears the more info store */
+ gtk_tree_view_columns_autosize(GTK_TREE_VIEW(shell->info->view));
+ gtk_range_set_value(GTK_RANGE(GTK_SCROLLED_WINDOW(shell->info->scroll)->vscrollbar), 0.0);
+ gtk_range_set_value(GTK_RANGE(GTK_SCROLLED_WINDOW(shell->moreinfo->scroll)->vscrollbar), 0.0);
+
+ shell_status_update("Done.");
+ shell_status_set_enabled(FALSE);
+
+ gchar *tmp = g_strdup_printf("%s - System Information", entry->name);
+ gtk_window_set_title(GTK_WINDOW(shell->window), tmp);
+ g_free(tmp);
+
+ shell_action_set_enabled("RefreshAction", entry->reloadfunc ? TRUE : FALSE);
+ } else {
+ gtk_window_set_title(GTK_WINDOW(shell->window), "System Information");
+ shell_action_set_enabled("RefreshAction", FALSE);
+
+ gtk_tree_store_clear(GTK_TREE_STORE(shell->info->model));
+ shell_set_view_type(SHELL_VIEW_NORMAL);
+ }
+
+ current = entry;
+ updating = FALSE;
+}
+
+static void
+info_selected(GtkTreeSelection * ts, gpointer data)
+{
+ ShellInfoTree *info = (ShellInfoTree *) data;
+ GtkTreeModel *model = GTK_TREE_MODEL(info->model);
+ GtkTreeIter parent;
+ gchar *datacol;
+
+ if (!gtk_tree_selection_get_selected(ts, &model, &parent))
+ return;
+
+ gtk_tree_model_get(model, &parent, INFO_TREE_COL_DATA, &datacol, -1);
+ info_selected_show_extra(datacol);
+ gtk_tree_view_columns_autosize(GTK_TREE_VIEW
+ (shell->moreinfo->view));
+}
+
+static ShellInfoTree *
+shell_info_tree_new(gboolean extra)
+{
+ ShellInfoTree *info;
+ GtkWidget *treeview, *scroll;
+ GtkTreeModel *model;
+ GtkTreeStore *store;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *cr_text, *cr_pbuf;
+
+ info = g_new0(ShellInfoTree, 1);
+
+ scroll = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ store = gtk_tree_store_new(INFO_TREE_NCOL, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, GDK_TYPE_PIXBUF);
+ model = GTK_TREE_MODEL(store);
+ treeview = gtk_tree_view_new_with_model(model);
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+ cr_pbuf = gtk_cell_renderer_pixbuf_new();
+ gtk_tree_view_column_pack_start(column, cr_pbuf, FALSE);
+ gtk_tree_view_column_add_attribute(column, cr_pbuf, "pixbuf",
+ INFO_TREE_COL_PBUF);
+
+ cr_text = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(column, cr_text, TRUE);
+ gtk_tree_view_column_add_attribute(column, cr_text, "markup",
+ INFO_TREE_COL_NAME);
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+ cr_text = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(column, cr_text, TRUE);
+ gtk_tree_view_column_add_attribute(column, cr_text, "markup",
+ INFO_TREE_COL_VALUE);
+
+ if (!extra) {
+ GtkTreeSelection *sel;
+
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+ g_signal_connect(G_OBJECT(sel), "changed",
+ (GCallback) info_selected, info);
+ }
+
+ gtk_container_add(GTK_CONTAINER(scroll), treeview);
+
+ info->scroll = scroll;
+ info->view = treeview;
+ info->model = model;
+
+ gtk_widget_show_all(scroll);
+
+ return info;
+}
+
+static ShellTree *
+shell_tree_new()
+{
+ ShellTree *shelltree;
+ GtkWidget *treeview, *scroll;
+ GtkTreeModel *model;
+ GtkTreeStore *store;
+ GtkCellRenderer *cr_text, *cr_pbuf;
+ GtkTreeViewColumn *column;
+ GtkTreeSelection *sel;
+
+ shelltree = g_new0(ShellTree, 1);
+
+ scroll = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ store = gtk_tree_store_new(TREE_NCOL, GDK_TYPE_PIXBUF, G_TYPE_STRING,
+ G_TYPE_POINTER);
+ model = GTK_TREE_MODEL(store);
+ treeview = gtk_tree_view_new_with_model(model);
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+ cr_pbuf = gtk_cell_renderer_pixbuf_new();
+ cr_text = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(column, cr_pbuf, FALSE);
+ gtk_tree_view_column_pack_start(column, cr_text, TRUE);
+
+ gtk_tree_view_column_add_attribute(column, cr_pbuf, "pixbuf",
+ TREE_COL_PBUF);
+ gtk_tree_view_column_add_attribute(column, cr_text, "markup",
+ TREE_COL_NAME);
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+ g_signal_connect(G_OBJECT(sel), "changed", (GCallback) module_selected,
+ NULL);
+
+ gtk_container_add(GTK_CONTAINER(scroll), treeview);
+
+ shelltree->scroll = scroll;
+ shelltree->view = treeview;
+ shelltree->model = model;
+ shelltree->modules = NULL;
+
+ gtk_widget_show_all(scroll);
+
+ return shelltree;
+}
diff --git a/hardinfo2/shell.h b/hardinfo2/shell.h
new file mode 100644
index 00000000..6614b8e1
--- /dev/null
+++ b/hardinfo2/shell.h
@@ -0,0 +1,137 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 __SHELL_H__
+#define __SHELL_H__
+
+#include <gtk/gtk.h>
+#include <loadgraph.h>
+
+typedef struct _Shell Shell;
+typedef struct _ShellTree ShellTree;
+typedef struct _ShellInfoTree ShellInfoTree;
+
+typedef struct _ShellModule ShellModule;
+typedef struct _ShellModuleEntry ShellModuleEntry;
+
+typedef struct _ShellFieldUpdate ShellFieldUpdate;
+
+typedef enum {
+ SHELL_PACK_RESIZE = 1 << 0,
+ SHELL_PACK_SHRINK = 1 << 1
+} ShellPackOptions;
+
+typedef enum {
+ SHELL_VIEW_NORMAL,
+ SHELL_VIEW_DUAL,
+ SHELL_VIEW_LOAD_GRAPH,
+} ShellViewType;
+
+typedef enum {
+ TREE_COL_PBUF,
+ TREE_COL_NAME,
+ TREE_COL_DATA,
+ TREE_NCOL
+} ShellTreeColumns;
+
+typedef enum {
+ INFO_TREE_COL_NAME,
+ INFO_TREE_COL_VALUE,
+ INFO_TREE_COL_DATA,
+ INFO_TREE_COL_PBUF,
+ INFO_TREE_NCOL
+} ShellInfoTreeColumns;
+
+struct _Shell {
+ GtkWidget *window, *vbox;
+ GtkWidget *status, *progress;
+ GtkWidget *notebook;
+ GtkWidget *hpaned, *vpaned;
+
+ ShellTree *tree;
+ ShellInfoTree *info, *moreinfo;
+ ShellModuleEntry *selected;
+ LoadGraph *loadgraph;
+
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+
+ ShellViewType view_type;
+};
+
+struct _ShellTree {
+ GtkWidget *scroll;
+ GtkWidget *view;
+ GtkTreeModel *model;
+
+ GSList *modules;
+};
+
+struct _ShellInfoTree {
+ GtkWidget *scroll;
+ GtkWidget *view;
+ GtkTreeModel *model;
+};
+
+struct _ShellModule {
+ gchar *name;
+ GdkPixbuf *icon;
+ GModule *dll;
+
+ GSList *entries;
+};
+
+struct _ShellModuleEntry {
+ gchar *name;
+ gint number;
+ GdkPixbuf *icon;
+ gboolean selected;
+
+ gchar *(*func) (gint entry);
+ gchar *(*reloadfunc) (gint entry);
+ gchar *(*fieldfunc) (gchar * entry);
+ gchar *(*morefunc) (gchar * entry);
+};
+
+struct _ShellFieldUpdate {
+ ShellModuleEntry *entry;
+ gchar *field_name;
+ gboolean loadgraph;
+};
+
+void shell_init(void);
+void shell_do_reload(void);
+
+void shell_action_set_enabled(const gchar *action_name,
+ gboolean setting);
+gboolean shell_action_get_active(const gchar *action_name);
+void shell_action_set_active(const gchar *action_name,
+ gboolean setting);
+void shell_action_set_property(const gchar *action_name,
+ const gchar *property,
+ gboolean setting);
+
+void shell_set_left_pane_visible(gboolean setting);
+void shell_ui_manager_set_visible(const gchar *path,
+ gboolean setting);
+
+void shell_status_update(const gchar *message);
+void shell_status_pulse(void);
+void shell_status_set_percentage(gint percentage);
+void shell_view_set_enabled(gboolean setting);
+
+#endif /* __SHELL_H__ */
diff --git a/hardinfo2/stock.c b/hardinfo2/stock.c
new file mode 100644
index 00000000..614d1b8f
--- /dev/null
+++ b/hardinfo2/stock.c
@@ -0,0 +1,81 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 <gtk/gtk.h>
+#include <stock.h>
+#include <iconcache.h>
+
+static struct {
+ gchar *filename;
+ gchar *stock_id;
+} stock_icons[] = {
+ { "report.png", HI_STOCK_REPORT},
+ { "module.png", HI_STOCK_MODULE}
+};
+
+static GtkIconFactory *icon_factory;
+
+void stock_icon_register(gchar *filename, gchar *stock_id)
+{
+ GtkIconSet *icon_set;
+ GtkIconSource *icon_source;
+
+ icon_set = gtk_icon_set_new();
+ icon_source = gtk_icon_source_new();
+
+ gtk_icon_source_set_pixbuf(icon_source, icon_cache_get_pixbuf(filename));
+ gtk_icon_set_add_source(icon_set, icon_source);
+ gtk_icon_source_free(icon_source);
+
+ gtk_icon_factory_add(icon_factory, stock_id, icon_set);
+
+ gtk_icon_set_unref(icon_set);
+}
+
+void stock_icon_register_pixbuf(GdkPixbuf *pixbuf, gchar *stock_id)
+{
+ GtkIconSet *icon_set;
+ GtkIconSource *icon_source;
+
+ icon_set = gtk_icon_set_new();
+ icon_source = gtk_icon_source_new();
+
+ gtk_icon_source_set_pixbuf(icon_source, pixbuf);
+ gtk_icon_set_add_source(icon_set, icon_source);
+ gtk_icon_source_free(icon_source);
+
+ gtk_icon_factory_add(icon_factory, stock_id, icon_set);
+
+ gtk_icon_set_unref(icon_set);
+}
+
+void stock_icons_init(void)
+{
+ gint i;
+ guint n_stock_icons = G_N_ELEMENTS(stock_icons);
+
+ icon_factory = gtk_icon_factory_new();
+
+ for (i = 0; i < n_stock_icons; i++) {
+ stock_icon_register(stock_icons[i].filename, stock_icons[i].stock_id);
+ }
+
+ gtk_icon_factory_add_default(icon_factory);
+
+ g_object_unref(icon_factory);
+}
diff --git a/hardinfo2/stock.h b/hardinfo2/stock.h
new file mode 100644
index 00000000..e86ad94d
--- /dev/null
+++ b/hardinfo2/stock.h
@@ -0,0 +1,29 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 __STOCK_H__
+#define __STOCK_H__
+
+#define HI_STOCK_REPORT "hi-stock-report"
+#define HI_STOCK_MODULE "hi-stock-module"
+
+void stock_icons_init(void);
+void stock_icon_register(gchar *filename, gchar *stock_id);
+void stock_icon_register_pixbuf(GdkPixbuf *pixbuf, gchar *stock_id);
+
+#endif /* __STOCK_H__ */
diff --git a/hardinfo2/uidefs.xml b/hardinfo2/uidefs.xml
new file mode 100644
index 00000000..f70031c8
--- /dev/null
+++ b/hardinfo2/uidefs.xml
@@ -0,0 +1,29 @@
+<ui>
+ <menubar>
+ <menu name="FileMenu" action="FileMenuAction">
+ <menuitem name="Generate Report..." action="ReportAction" />
+ <separator/>
+ <menuitem name="Quit" action="QuitAction" />
+ <placeholder name="FileMenuAdditions" />
+ </menu>
+ <menu name="ViewMenu" action="ViewMenuAction">
+ <menuitem name="LeftPane" action="LeftPaneAction"/>
+ <menuitem name="Toolbar" action="ToolbarAction"/>
+ <separator/>
+ <menuitem name="Refresh" action="RefreshAction"/>
+ <separator/>
+ <separator name="LastSep"/>
+ </menu>
+ <menu name="HelpMenu" action="HelpMenuAction">
+ <menuitem name="About" action="AboutAction"/>
+ </menu>
+ </menubar>
+
+ <toolbar action="MainMenuBar" action="MainMenuBarAction">
+ <placeholder name="ToolItems">
+ <toolitem name="Refresh" action="RefreshAction"/>
+ <separator/>
+ <toolitem name="Report" action="ReportAction"/>
+ </placeholder>
+ </toolbar>
+</ui>
diff --git a/hardinfo2/util.c b/hardinfo2/util.c
new file mode 100644
index 00000000..9df6fc75
--- /dev/null
+++ b/hardinfo2/util.c
@@ -0,0 +1,50 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.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.
+ *
+ * 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 <string.h>
+#include <hardinfo.h>
+
+inline void
+remove_quotes(gchar *str)
+{
+ if (!str)
+ return;
+
+ while (*str == '"')
+ *(str++) = ' ';
+
+ gchar *p;
+ if ((p = strchr(str, '"')))
+ *p = 0;
+}
+
+inline void
+strend(gchar *str, gchar chr)
+{
+ if (!str)
+ return;
+
+ char *p;
+ if ((p = strchr(str, chr)))
+ *p = 0;
+}
+
+inline void
+remove_linefeed(gchar * str)
+{
+ strend(str, '\n');
+}