diff options
author | zhuyaliang <[email protected]> | 2023-09-28 10:41:46 +0800 |
---|---|---|
committer | Luke from DC <[email protected]> | 2023-10-02 01:31:41 +0000 |
commit | 5d9cbe65cdf296d9a69c93712243617dd6ba6848 (patch) | |
tree | 7703719caaf3cb74c22e16f1fab7ae34e5ebe80d | |
parent | bc4db7647c5a1b2a1ec4fadea1e05ddfa9c98f18 (diff) | |
download | mate-control-center-5d9cbe65cdf296d9a69c93712243617dd6ba6848.tar.bz2 mate-control-center-5d9cbe65cdf296d9a69c93712243617dd6ba6848.tar.xz |
Add new capplets: system info
-rw-r--r-- | .build.yml | 6 | ||||
-rw-r--r-- | capplets/Makefile.am | 6 | ||||
-rw-r--r-- | capplets/system-info/Makefile.am | 45 | ||||
-rw-r--r-- | capplets/system-info/info-cleanup.c | 133 | ||||
-rw-r--r-- | capplets/system-info/info-cleanup.h | 23 | ||||
-rw-r--r-- | capplets/system-info/main.c | 35 | ||||
-rw-r--r-- | capplets/system-info/mate-system-info.c | 758 | ||||
-rw-r--r-- | capplets/system-info/mate-system-info.desktop.in | 13 | ||||
-rw-r--r-- | capplets/system-info/mate-system-info.h | 41 | ||||
-rw-r--r-- | capplets/system-info/mate-system-info.ui | 156 | ||||
-rw-r--r-- | capplets/system-info/system-info.gresource.xml | 6 | ||||
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | org.mate.control-center.gschema.xml.in | 2 | ||||
-rw-r--r-- | po/POTFILES.in | 4 |
14 files changed, 1234 insertions, 3 deletions
@@ -13,12 +13,14 @@ requires: - intltool - itstool - libxss + - libgtop - libmatekbd - make - marco - mate-common - mate-menus - polkit + - udisks2 - which - yelp-tools @@ -47,6 +49,7 @@ requires: - librsvg2-bin - librsvg2-dev - libstartup-notification0-dev + - libudisks2-dev - libx11-dev - libxcursor-dev - libxi-dev @@ -84,8 +87,10 @@ requires: - libXScrnSaver-devel - libcanberra-devel - libmatekbd-devel + - libgtop2-devel - librsvg2-devel - librsvg2-tools + - libudisks2-devel - make - marco-devel - mate-menus-devel @@ -118,6 +123,7 @@ requires: - librsvg2-bin - librsvg2-dev - libstartup-notification0-dev + - libudisks2-dev - libx11-dev - libxcursor-dev - libxi-dev diff --git a/capplets/Makefile.am b/capplets/Makefile.am index fba5739e..017bdea3 100644 --- a/capplets/Makefile.am +++ b/capplets/Makefile.am @@ -10,7 +10,8 @@ SUBDIRS = \ network \ time-admin \ windows \ - about-me + about-me \ + system-info DIST_SUBDIRS = \ common \ @@ -24,6 +25,7 @@ DIST_SUBDIRS = \ time-admin \ windows \ display \ - about-me + about-me \ + system-info -include $(top_srcdir)/git.mk diff --git a/capplets/system-info/Makefile.am b/capplets/system-info/Makefile.am new file mode 100644 index 00000000..2e87da31 --- /dev/null +++ b/capplets/system-info/Makefile.am @@ -0,0 +1,45 @@ +# This is used in MATECC_CAPPLETS_CFLAGS +cappletname = system-info + +ui_files = mate-system-info.ui + +bin_PROGRAMS = mate-system-info + +mate_system_info_LDADD = $(MATECC_CAPPLETS_LIBS) +BUILT_SOURCES = mate-system-info-resources.h mate-system-info-resources.c +nodist_mate_system_info_SOURCES = \ + $(BUILT_SOURCES) +mate_system_info_SOURCES = \ + mate-system-info.c \ + mate-system-info.h \ + info-cleanup.c \ + info-cleanup.h \ + main.c + +include $(top_srcdir)/gla11y.mk + +desktopdir = $(datadir)/applications +Desktop_in_files = mate-system-info.desktop.in +desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop) + +$(desktop_DATA): $(Desktop_in_files) +if USE_NLS + $(AM_V_GEN) $(MSGFMT) --desktop --keyword= --keyword=Name --keyword=Comment --keyword=Keywords --template $< -d $(top_srcdir)/po -o $@ +else + $(AM_V_GEN) sed '/^# Translators/d' < $< > $@ +endif + +mate-system-info-resources.h mate-system-info-resources.c: system-info.gresource.xml Makefile $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir $(srcdir) $(srcdir)/system-info.gresource.xml) + $(AM_V_GEN) XMLLINT=$(XMLLINT) $(GLIB_COMPILE_RESOURCES) --target $@ --sourcedir $(srcdir) --generate --c-name mate_system_info $< + +AM_CPPFLAGS = \ + $(WARN_CFLAGS) \ + $(MATECC_CAPPLETS_CFLAGS) \ + -DMATECC_DATA_DIR="\"$(pkgdatadir)\"" +CLEANFILES = $(MATECC_CAPPLETS_CLEANFILES) $(desktop_DATA) $(BUILT_SOURCES) +EXTRA_DIST = \ + $(ui_files) \ + $(Desktop_in_files) \ + system-info.gresource.xml + +-include $(top_srcdir)/git.mk diff --git a/capplets/system-info/info-cleanup.c b/capplets/system-info/info-cleanup.c new file mode 100644 index 00000000..588ed4f3 --- /dev/null +++ b/capplets/system-info/info-cleanup.c @@ -0,0 +1,133 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2010 Red Hat, Inc + * Copyright (C) 2008 William Jon McCann <[email protected]> + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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, see <http://www.gnu.org/licenses/>. + * + */ + +#include <glib.h> +#include "info-cleanup.h" + +typedef struct +{ + char *regex; + char *replacement; +} ReplaceStrings; + +static char * +prettify_info (const char *info) +{ + g_autofree char *escaped = NULL; + g_autofree gchar *pretty = NULL; + int i; + static const ReplaceStrings rs[] = { + { "Mesa DRI ", ""}, + { "Mesa Intel", "Intel"}, + { "[(]R[)]", "\302\256"}, + { "[(](tm|TM)[)]", "\342\204\242"}, + { "(ATI|EPYC|AMD FX|Radeon|Ryzen|Threadripper|GeForce RTX) ", "\\1\342\204\242 "}, + { "Gallium \\d+\\.\\d+ on (.*)", "\\1"}, + { " CPU| Processor| \\S+-Core| @ \\d+\\.\\d+GHz", ""}, + { " x86|/MMX|/SSE2|/PCIe", ""}, + { " [(][^)]*(DRM|MESA|LLVM)[^)]*[)]?", ""}, + { "Graphics Controller", "Graphics"}, + { ".*llvmpipe.*", "Software Rendering"}, + { "(AMD .*) [(].*", "\\1"}, + { "(AMD [A-Z])(.*)", "\\1\\L\\2\\E"}, + { "AMD", "AMD<sup>\302\256</sup>"}, + + }; + + if (*info == '\0') + return NULL; + + escaped = g_markup_escape_text (info, -1); + pretty = g_strdup (g_strstrip (escaped)); + + for (i = 0; i < G_N_ELEMENTS (rs); i++) + { + g_autoptr(GError) error = NULL; + g_autoptr(GRegex) re = NULL; + g_autofree gchar *new = NULL; + + re = g_regex_new (rs[i].regex, 0, 0, &error); + if (re == NULL) + { + g_warning ("Error building regex: %s", error->message); + continue; + } + + new = g_regex_replace (re, + pretty, + -1, + 0, + rs[i].replacement, + 0, + &error); + + if (error != NULL) + { + g_warning ("Error replacing %s: %s", rs[i].regex, error->message); + continue; + } + + g_free (pretty); + pretty = g_steal_pointer (&new); + } + + return g_steal_pointer (&pretty); +} + +static char * +remove_duplicate_whitespace (const char *old) +{ + g_autofree gchar *new = NULL; + g_autoptr(GRegex) re = NULL; + g_autoptr(GError) error = NULL; + + if (old == NULL) + return NULL; + + re = g_regex_new ("[ \t\n\r]+", G_REGEX_MULTILINE, 0, &error); + if (re == NULL) + { + g_warning ("Error building regex: %s", error->message); + return g_strdup (old); + } + new = g_regex_replace (re, + old, + -1, + 0, + " ", + 0, + &error); + if (new == NULL) + { + g_warning ("Error replacing string: %s", error->message); + return g_strdup (old); + } + + return g_steal_pointer (&new); +} + +char * +info_cleanup (const char *input) +{ + g_autofree char *pretty = NULL; + + pretty = prettify_info (input); + return remove_duplicate_whitespace (pretty); +} diff --git a/capplets/system-info/info-cleanup.h b/capplets/system-info/info-cleanup.h new file mode 100644 index 00000000..cbc8d541 --- /dev/null +++ b/capplets/system-info/info-cleanup.h @@ -0,0 +1,23 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2010 Red Hat, Inc + * Copyright (C) 2008 William Jon McCann <[email protected]> + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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, see <http://www.gnu.org/licenses/>. + * + */ + +#include <glib.h> + +char *info_cleanup (const char *input); diff --git a/capplets/system-info/main.c b/capplets/system-info/main.c new file mode 100644 index 00000000..41db34fe --- /dev/null +++ b/capplets/system-info/main.c @@ -0,0 +1,35 @@ +/************************************************************************* + File Name: main.c + Copyright (C) 2023 MATE Developers + 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, either version 3 of the License, or + (at your option) any later version. + + 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, see <https://www.gnu.org/licenses/>. + +************************************************************************/ +#include "mate-system-info.h" +#include "capplet-util.h" + +int main (int argc, char *argv[]) +{ + GtkWidget *dialog; + + capplet_init (NULL, &argc, &argv); + + dialog = mate_system_info_new (); + mate_system_info_setup (MATE_SYSTEM_INFO (dialog)); + g_signal_connect (dialog, "response", G_CALLBACK (gtk_main_quit), NULL); + gtk_widget_show (dialog); + + gtk_main (); + + return 0; +} diff --git a/capplets/system-info/mate-system-info.c b/capplets/system-info/mate-system-info.c new file mode 100644 index 00000000..36380678 --- /dev/null +++ b/capplets/system-info/mate-system-info.c @@ -0,0 +1,758 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2023 MATE Developers + * Copyright (C) 2019 Purism SPC + * Copyright (C) 2017 Mohammed Sadiq <[email protected]> + * Copyright (C) 2010 Red Hat, Inc + * Copyright (C) 2008 William Jon McCann <[email protected]> + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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, see <http://www.gnu.org/licenses/>. + * + */ +#include <gtk/gtk.h> +#include <glibtop/fsusage.h> +#include <glibtop/mountlist.h> +#include <glibtop/mem.h> +#include <glibtop/sysinfo.h> +#include <udisks/udisks.h> +#include <sys/utsname.h> + +#ifdef GDK_WINDOWING_WAYLAND +#include <gdk/gdkwayland.h> +#endif +#ifdef GDK_WINDOWING_X11 +#include <gdk/gdkx.h> +#endif + +#include "info-cleanup.h" +#include "mate-system-info.h" +#include "mate-system-info-resources.h" + +struct _MateSystemInfo +{ + GtkDialog parent_instance; + GtkWidget *logo_image; + GtkWidget *hostname_row; + GtkListBox *hardware_box; + GtkWidget *hardware_model_row; + GtkWidget *memory_row; + GtkWidget *processor_row; + GtkWidget *graphics_row; + GtkWidget *disk_row; + GtkListBox *os_box; + GtkWidget *kernel_row; + GtkWidget *virtualization_row; + GtkWidget *windowing_system_row; + GtkWidget *mate_version_row; + GtkWidget *os_name_row; + GtkWidget *os_type_row; +}; + +G_DEFINE_TYPE (MateSystemInfo, mate_system_info, GTK_TYPE_DIALOG) + +static void +set_lable_style (GtkWidget *lable, + const char *color, + int font_szie, + const char *text, + gboolean blod) +{ + g_autofree gchar *lable_text = NULL; + + if (color == NULL) + { + lable_text = g_strdup_printf ("<span weight=\'light\'font_desc=\'%d\'><b>%s</b></span>", font_szie, text); + } + else + { + if(blod) + { + lable_text = g_strdup_printf ("<span foreground=\'%s\'weight=\'light\'font_desc=\'%d\'><b>%s</b></span>", + color, + font_szie, + text); + } + else + { + lable_text = g_strdup_printf ("<span foreground=\'%s\'weight=\'light\'font_desc=\'%d\'>%s</span>", + color, + font_szie, + text); + } + } + + gtk_label_set_markup (GTK_LABEL(lable), lable_text); +} + +static void +mate_system_info_row_fill (GtkWidget *row, + const char *labelname, + gboolean is_separator) +{ + GtkWidget *vbox; + GtkWidget *box; + GtkWidget *label; + GtkWidget *separator; + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_set_spacing (GTK_BOX (box), 12); + g_object_set (box, "margin", 12, NULL); + gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 3); + + label = gtk_label_new (NULL); + set_lable_style (label, NULL, 12, labelname, TRUE); + gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END); + gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 6); + + label = gtk_label_new (NULL); + gtk_box_pack_end (GTK_BOX (box), label, FALSE, FALSE, 6); + g_object_set_data (G_OBJECT (row), "labelvalue", label); + + separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); + if (is_separator) + gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0); + + gtk_container_add (GTK_CONTAINER (row), vbox); +} + +static void +mate_system_info_set_row (MateSystemInfo *info) +{ + mate_system_info_row_fill (info->hostname_row, _("Device Name"), FALSE); + mate_system_info_row_fill (info->hardware_model_row, _("Hardware Model"), TRUE); + mate_system_info_row_fill (info->memory_row, _("Memory"), TRUE); + mate_system_info_row_fill (info->processor_row, _("Processor"), TRUE); + mate_system_info_row_fill (info->graphics_row, _("Graphics"), TRUE); + mate_system_info_row_fill (info->disk_row, _("Disk Capacity"), FALSE); + mate_system_info_row_fill (info->kernel_row, _("Kernel Version"), FALSE); + mate_system_info_row_fill (info->virtualization_row, _("Virtualization"), TRUE); + mate_system_info_row_fill (info->windowing_system_row, _("Windowing System"), TRUE); + mate_system_info_row_fill (info->mate_version_row, _("MATE Version"), TRUE); + mate_system_info_row_fill (info->os_name_row, _("OS Name"), TRUE); + mate_system_info_row_fill (info->os_type_row, _("OS Type"), TRUE); + + gtk_widget_show (info->logo_image); + gtk_widget_show_all (info->hostname_row); + gtk_widget_show_all (info->memory_row); + gtk_widget_show_all (info->processor_row); + gtk_widget_show_all (info->graphics_row); + gtk_widget_show_all (info->disk_row); + gtk_widget_show_all (info->kernel_row); + gtk_widget_show_all (info->windowing_system_row); + gtk_widget_show_all (info->mate_version_row); + gtk_widget_show_all (info->os_type_row); + gtk_widget_show_all (info->os_name_row); +} + +static char * +get_system_hostname (void) +{ + GDBusProxy *hostnamed_proxy; + g_autoptr(GVariant) variant = NULL; + g_autoptr(GError) error = NULL; + + hostnamed_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + NULL, + &error); + + if (!hostnamed_proxy) + return g_strdup (""); + + variant = g_dbus_proxy_get_cached_property (hostnamed_proxy, "Hostname"); + if (!variant) + { + g_autoptr(GError) error = NULL; + g_autoptr(GVariant) inner = NULL; + + /* Work around systemd-hostname not sending us back + * the property value when changing values */ + variant = g_dbus_proxy_call_sync (hostnamed_proxy, + "org.freedesktop.DBus.Properties.Get", + g_variant_new ("(ss)", "org.freedesktop.hostname1", "Hostname"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (variant == NULL) + { + g_warning ("Failed to get property '%s': %s", "Hostname", error->message); + g_object_unref (hostnamed_proxy); + return NULL; + } + + g_variant_get (variant, "(v)", &inner); + g_object_unref (hostnamed_proxy); + return g_variant_dup_string (inner, NULL); + } + else + { + g_object_unref (hostnamed_proxy); + return g_variant_dup_string (variant, NULL); + } +} + +static char * +get_hardware_model (void) +{ + g_autoptr(GDBusProxy) hostnamed_proxy = NULL; + g_autoptr(GVariant) vendor_variant = NULL; + g_autoptr(GVariant) model_variant = NULL; + const char *vendor_string, *model_string; + g_autoptr(GError) error = NULL; + + hostnamed_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + NULL, + &error); + if (hostnamed_proxy == NULL) + { + g_debug ("Couldn't get hostnamed to start, bailing: %s", error->message); + return NULL; + } + + vendor_variant = g_dbus_proxy_get_cached_property (hostnamed_proxy, "HardwareVendor"); + if (!vendor_variant) + { + g_debug ("Unable to retrieve org.freedesktop.hostname1.HardwareVendor property"); + return NULL; + } + + model_variant = g_dbus_proxy_get_cached_property (hostnamed_proxy, "HardwareModel"); + if (!model_variant) + { + g_debug ("Unable to retrieve org.freedesktop.hostname1.HardwareModel property"); + return NULL; + } + + vendor_string = g_variant_get_string (vendor_variant, NULL), + model_string = g_variant_get_string (model_variant, NULL); + + if (vendor_string && g_strcmp0 (vendor_string, "") != 0) + { + gchar *vendor_model = NULL; + + vendor_model = g_strdup_printf ("%s %s", vendor_string, model_string); + return vendor_model; + } + + return NULL; +} + +static char * +get_cpu_info (void) +{ + g_autoptr(GHashTable) counts = NULL; + const glibtop_sysinfo *info; + g_autoptr(GString) cpu = NULL; + GHashTableIter iter; + gpointer key, value; + int i; + int j; + + counts = g_hash_table_new (g_str_hash, g_str_equal); + info = glibtop_get_sysinfo (); + + /* count duplicates */ + for (i = 0; i != info->ncpu; ++i) + { + const char * const keys[] = { "model name", "cpu", "Processor" ,"Model Name"}; + char *model; + int *count; + model = NULL; + + for (j = 0; model == NULL && j != G_N_ELEMENTS (keys); ++j) + { + model = g_hash_table_lookup (info->cpuinfo[i].values, + keys[j]); + } + + if (model == NULL) + continue; + count = g_hash_table_lookup (counts, model); + if (count == NULL) + g_hash_table_insert (counts, model, GINT_TO_POINTER (1)); + else + g_hash_table_replace (counts, model, GINT_TO_POINTER (GPOINTER_TO_INT (count) + 1)); + } + + cpu = g_string_new (NULL); + g_hash_table_iter_init (&iter, counts); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + g_autofree char *cleanedup = NULL; + int count; + + count = GPOINTER_TO_INT (value); + cleanedup = info_cleanup ((const char *) key); + if (count > 1) + g_string_append_printf (cpu, "%s \303\227 %d ", cleanedup, count); + else + g_string_append_printf (cpu, "%s ", cleanedup); + } + + return g_strdup (cpu->str); +} + +static char * +get_renderer_from_session (void) +{ + g_autoptr(GDBusProxy) session_proxy = NULL; + g_autoptr(GVariant) renderer_variant = NULL; + char *renderer; + g_autoptr(GError) error = NULL; + + session_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + NULL, &error); + if (error != NULL) + { + g_warning ("Unable to connect to create a proxy for org.gnome.SessionManager: %s", + error->message); + return NULL; + } + + renderer_variant = g_dbus_proxy_get_cached_property (session_proxy, "Renderer"); + + if (!renderer_variant) + { + g_warning ("Unable to retrieve org.gnome.SessionManager.Renderer property"); + return NULL; + } + + renderer = info_cleanup (g_variant_get_string (renderer_variant, NULL)); + + return renderer; +} + +static gchar * +get_graphics_hardware_string (void) +{ + g_autofree char *discrete_renderer = NULL; + g_autofree char *renderer = NULL; + + renderer = get_renderer_from_session (); + if (!renderer) + return g_strdup ("Unknown"); + + return g_strdup (renderer); +} + +static char * +get_primary_disk_size (void) +{ + g_autoptr(UDisksClient) client = NULL; + GDBusObjectManager *manager; + g_autolist(GDBusObject) objects = NULL; + GList *l; + gchar *size; + guint64 total_size; + g_autoptr(GError) error = NULL; + + total_size = 0; + + client = udisks_client_new_sync (NULL, &error); + if (client == NULL) + { + g_warning ("Unable to get UDisks client: %s. Disk information will not be available.", + error->message); + return g_strdup ("Unknown"); + } + + manager = udisks_client_get_object_manager (client); + objects = g_dbus_object_manager_get_objects (manager); + + for (l = objects; l != NULL; l = l->next) + { + UDisksDrive *drive; + drive = udisks_object_peek_drive (UDISKS_OBJECT (l->data)); + + /* Skip removable devices */ + if (drive == NULL || + udisks_drive_get_removable (drive) || + udisks_drive_get_ejectable (drive)) + { + continue; + } + + total_size += udisks_drive_get_size (drive); + } + if (total_size > 0) + { + size = g_format_size (total_size); + } + else + { + size = g_strdup ("Unknown"); + } + + return size; +} + +static char * +get_os_name (void) +{ + g_autofree gchar *name = NULL; + g_autofree gchar *version_id = NULL; + g_autofree gchar *pretty_name = NULL; + g_autofree gchar *name_version = NULL; + gchar *result = NULL; + + name = g_get_os_info (G_OS_INFO_KEY_NAME); + version_id = g_get_os_info (G_OS_INFO_KEY_VERSION_ID); + pretty_name = g_get_os_info (G_OS_INFO_KEY_PRETTY_NAME); + + if (pretty_name) + name_version = g_strdup (pretty_name); + else if (name && version_id) + name_version = g_strdup_printf ("%s %s", name, version_id); + else + name_version = g_strdup (("Unknown")); + + result = g_strdup (name_version); + + return result; +} + +static char * +get_os_type (void) +{ + if (GLIB_SIZEOF_VOID_P == 8) + /* translators: This is the type of architecture for the OS */ + return g_strdup_printf ("64-bit"); + else + /* translators: This is the type of architecture for the OS */ + return g_strdup_printf ("32-bit"); +} + +static char * +get_windowing_system (void) +{ + GdkDisplay *display; + + display = gdk_display_get_default (); + +#if defined(GDK_WINDOWING_X11) + if (GDK_IS_X11_DISPLAY (display)) + return g_strdup ("X11"); +#endif /* GDK_WINDOWING_X11 */ +#if defined(GDK_WINDOWING_WAYLAND) + if (GDK_IS_WAYLAND_DISPLAY (display)) + return g_strdup ("Wayland"); +#endif /* GDK_WINDOWING_WAYLAND */ + return g_strdup (C_("Windowing system (Wayland, X11, or Unknown)", "Unknown")); +} + +static char * +get_kernel_vesrion (void) +{ + struct utsname un; + + if (uname (&un) < 0) + return NULL; + + return g_strdup_printf ("%s %s", un.sysname, un.release); +} + +static struct { + const char *id; + const char *display; +} const virt_tech[] = { + { "kvm", "KVM" }, + { "qemu", "QEmu" }, + { "vmware", "VMware" }, + { "microsoft", "Microsoft" }, + { "oracle", "Oracle" }, + { "xen", "Xen" }, + { "bochs", "Bochs" }, + { "chroot", "chroot" }, + { "openvz", "OpenVZ" }, + { "lxc", "LXC" }, + { "lxc-libvirt", "LXC (libvirt)" }, + { "systemd-nspawn", "systemd (nspawn)" } +}; + +static char * +get_virtualization_label (const char *virt) +{ + const char *display_name; + guint i; + + if (virt == NULL || *virt == '\0') + { + return NULL; + } + + display_name = NULL; + for (i = 0; i < G_N_ELEMENTS (virt_tech); i++) + { + if (g_str_equal (virt_tech[i].id, virt)) + { + display_name = virt_tech[i].display; + break; + } + } + + return display_name ? g_strdup (display_name) : g_strdup (virt); +} + +static char * +get_system_virt (void) +{ + g_autoptr(GError) error = NULL; + g_autoptr(GDBusProxy) systemd_proxy = NULL; + g_autoptr(GVariant) variant = NULL; + GVariant *inner; + + systemd_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1", + NULL, + &error); + + if (systemd_proxy == NULL) + { + g_debug ("systemd not available, bailing: %s", error->message); + return NULL; + } + + variant = g_dbus_proxy_call_sync (systemd_proxy, + "org.freedesktop.DBus.Properties.Get", + g_variant_new ("(ss)", "org.freedesktop.systemd1.Manager", "Virtualization"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (variant == NULL) + { + g_debug ("Failed to get property '%s': %s", "Virtualization", error->message); + return NULL; + } + + g_variant_get (variant, "(v)", &inner); + + return get_virtualization_label (g_variant_get_string (inner, NULL)); +} + +static char * +get_mate_desktop_version () +{ + int status; + int i = 0; + char *version = NULL; + char *argv[] = {"/usr/bin/mate-about", "-v", NULL}; + g_autoptr(GError) error = NULL; + + g_debug ("About to launch '%s'", argv[0]); + + if (!g_spawn_sync (NULL, (char **) argv, NULL, 0, NULL, NULL, &version, NULL, &status, &error)) + { + g_warning ("Failed to get GPU: %s", error->message); + return NULL; + } +#if GLIB_CHECK_VERSION(2, 70, 0) + if (!g_spawn_check_wait_status (status, NULL)) +#else + if (!g_spawn_check_exit_status (status, NULL)) +#endif + return NULL; + + while (version[i] != '\0') + { + if (version[i] == '\n') + { + version[i] = '\0'; + break; + } + i++; + } + + return version; +} + +static char * +get_logo_name (void) +{ + char *logo_name = NULL; + + logo_name = g_get_os_info ("LOGO"); + + if (logo_name == NULL) + logo_name = g_strdup ("mate-desktop"); + + return logo_name; +} + +void +mate_system_info_setup (MateSystemInfo *info) +{ + g_autofree char *logo_name = NULL; + g_autofree char *hostname_text = NULL; + g_autofree char *hw_model_text = NULL; + g_autofree char *memory_text = NULL; + g_autofree char *cpu_text = NULL; + g_autofree char *os_type_text = NULL; + g_autofree char *os_name_text = NULL; + g_autofree char *disk_text = NULL; + g_autofree char *kernel_text = NULL; + g_autofree char *windowing_system_text = NULL; + g_autofree char *virt_text = NULL; + g_autofree char *de_text = NULL; + g_autofree char *graphics_hardware_string = NULL; + + GtkWidget *label; + glibtop_mem mem; + + logo_name = get_logo_name (); + gtk_image_set_from_icon_name (GTK_IMAGE (info->logo_image), logo_name, GTK_ICON_SIZE_INVALID); + gtk_image_set_pixel_size (GTK_IMAGE (info->logo_image), 128); + + hostname_text = get_system_hostname (); + label = g_object_get_data (G_OBJECT (info->hostname_row), "labelvalue"); + set_lable_style (label, "gray", 12, hostname_text, FALSE); + + hw_model_text = get_hardware_model (); + if (hw_model_text != NULL) + { + gtk_widget_show_all (info->hardware_model_row); + label = g_object_get_data (G_OBJECT (info->hardware_model_row), "labelvalue"); + set_lable_style (label, "gray", 12, hw_model_text, FALSE); + } + + glibtop_get_mem (&mem); + memory_text = g_format_size_full (mem.total, G_FORMAT_SIZE_IEC_UNITS); + label = g_object_get_data (G_OBJECT (info->memory_row), "labelvalue"); + set_lable_style (label, "gray", 12, memory_text, FALSE); + + cpu_text = get_cpu_info (); + label = g_object_get_data (G_OBJECT (info->processor_row), "labelvalue"); + set_lable_style (label, "gray", 12, cpu_text, FALSE); + + graphics_hardware_string = get_graphics_hardware_string (); + label = g_object_get_data (G_OBJECT (info->graphics_row), "labelvalue"); + set_lable_style (label, "gray", 12, graphics_hardware_string, FALSE); + + disk_text = get_primary_disk_size (); + label = g_object_get_data (G_OBJECT (info->disk_row), "labelvalue"); + set_lable_style (label, "gray", 12, disk_text, FALSE); + + kernel_text = get_kernel_vesrion (); + label = g_object_get_data (G_OBJECT (info->kernel_row), "labelvalue"); + set_lable_style (label, "gray", 12, kernel_text, FALSE); + + virt_text = get_system_virt (); + if (virt_text != NULL) + { + gtk_widget_show_all (info->virtualization_row); + label = g_object_get_data (G_OBJECT (info->virtualization_row), "labelvalue"); + set_lable_style (label, "gray", 12, virt_text, FALSE); + } + windowing_system_text = get_windowing_system (); + label = g_object_get_data (G_OBJECT (info->windowing_system_row), "labelvalue"); + set_lable_style (label, "gray", 12, windowing_system_text, FALSE); + + de_text = get_mate_desktop_version (); + label = g_object_get_data (G_OBJECT (info->mate_version_row), "labelvalue"); + set_lable_style (label, "gray", 12, de_text, FALSE); + + os_type_text = get_os_type (); + label = g_object_get_data (G_OBJECT (info->os_type_row), "labelvalue"); + set_lable_style (label, "gray", 12, os_type_text, FALSE); + + os_name_text = get_os_name (); + label = g_object_get_data (G_OBJECT (info->os_name_row), "labelvalue"); + set_lable_style (label, "gray", 12, os_name_text, FALSE); +} + +static void +mate_system_info_destroy (GtkWidget *widget) +{ + GTK_WIDGET_CLASS (mate_system_info_parent_class)->destroy (widget); +} + +static void +mate_system_info_class_init (MateSystemInfoClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + widget_class->destroy = mate_system_info_destroy; + gtk_widget_class_set_template_from_resource (widget_class, "/org/mate/control-center/system-info/mate-system-info.ui"); + + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, hostname_row); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, hardware_box); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, disk_row); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, mate_version_row); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, graphics_row); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, hardware_model_row); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, memory_row); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, os_box); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, logo_image); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, os_name_row); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, os_type_row); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, processor_row); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, virtualization_row); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, kernel_row); + gtk_widget_class_bind_template_child (widget_class, MateSystemInfo, windowing_system_row); +} + +static void +mate_system_info_init (MateSystemInfo *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); + g_resources_register (mate_system_info_get_resource ()); + mate_system_info_set_row (MATE_SYSTEM_INFO (self)); +} + +GtkWidget * +mate_system_info_new (void) +{ + GtkWidget *dialog; + gboolean use_header; + GdkDisplay *display; + + g_object_get (gtk_settings_get_default (), + "gtk-dialogs-use-header", &use_header, + NULL); + + display = gdk_display_get_default (); +#if defined(GDK_WINDOWING_WAYLAND) + if (GDK_IS_WAYLAND_DISPLAY (display)) + use_header = FALSE; +#endif /* GDK_WINDOWING_WAYLAND */ + + dialog = g_object_new (MATE_TYPE_SYSTEM_INFO, + "use-header-bar", use_header, + NULL); + gtk_window_set_title (GTK_WINDOW (dialog), _("Mate System Info")); + gtk_widget_set_size_request (GTK_WIDGET (dialog), 600, 500); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + + return dialog; +} diff --git a/capplets/system-info/mate-system-info.desktop.in b/capplets/system-info/mate-system-info.desktop.in new file mode 100644 index 00000000..96408538 --- /dev/null +++ b/capplets/system-info/mate-system-info.desktop.in @@ -0,0 +1,13 @@ +[Desktop Entry] +Name=system-info +Comment=View mate desktop system info +Exec=mate-system-info +# Translators: Do NOT translate or transliterate this text (this is an icon file name)! +Icon=mate-desktop +Terminal=false +Type=Application +StartupNotify=true +Categories=GTK;Settings;HardwareSettings; +# Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +Keywords=mate-control-center;MATE;system;preferences; +OnlyShowIn=MATE; diff --git a/capplets/system-info/mate-system-info.h b/capplets/system-info/mate-system-info.h new file mode 100644 index 00000000..72d89ece --- /dev/null +++ b/capplets/system-info/mate-system-info.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 MATE Developers + * + * 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; either version 2, or (at your option) + * any later version. + * + * 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 <fcntl.h> +#include <sys/types.h> +#include <libintl.h> +#include <locale.h> +#include <glib/gi18n.h> + +#ifndef __MATE_SYSTEM_INFO_H__ +#define __MATE_SYSTEM_INFO_H__ 1 + +G_BEGIN_DECLS + +#define MATE_TYPE_SYSTEM_INFO (mate_system_info_get_type ()) +G_DECLARE_FINAL_TYPE (MateSystemInfo, mate_system_info, MATE, SYSTEM_INFO, GtkDialog) + +GtkWidget *mate_system_info_new (void); + +void mate_system_info_setup (MateSystemInfo *info); + +G_END_DECLS + +#endif diff --git a/capplets/system-info/mate-system-info.ui b/capplets/system-info/mate-system-info.ui new file mode 100644 index 00000000..d4cafa76 --- /dev/null +++ b/capplets/system-info/mate-system-info.ui @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <!-- interface-requires gtk+ 3.0 --> + <template class="MateSystemInfo" parent="GtkDialog"> + <property name="can-focus">False</property> + <property name="icon-name">mate-desktop</property> + <property name="type_hint">dialog</property> + + <child internal-child="vbox"> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">center</property> + <property name="spacing">30</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkImage" id="logo_image"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <object class="GtkListBox"> + <property name="visible">True</property> + <property name="selection-mode">none</property> + <style> + <class name="frame" /> + </style> + + <!-- Device name --> + <child> + <object class="GtkListBoxRow" id="hostname_row"> + <property name="visible">True</property> + </object> + </child> + + </object> + </child> + + <child> + <object class="GtkListBox" id="hardware_box"> + <property name="visible">True</property> + <property name="selection-mode">none</property> + <style> + <class name="frame" /> + </style> + + <!-- Hardware Model --> + <child> + <object class="GtkListBoxRow" id="hardware_model_row"> + <property name="visible">False</property> + <property name="activatable">False</property> + </object> + </child> + + <!-- Memory --> + <child> + <object class="GtkListBoxRow" id="memory_row"> + <property name="visible">True</property> + <property name="activatable">False</property> + </object> + </child> + + <!-- Processor --> + <child> + <object class="GtkListBoxRow" id="processor_row"> + <property name="visible">True</property> + <property name="activatable">False</property> + </object> + </child> + + <!-- Graphics --> + <child> + <object class="GtkListBoxRow" id="graphics_row"> + <property name="visible">True</property> + <property name="activatable">False</property> + </object> + </child> + + <!-- Disk Capacity --> + <child> + <object class="GtkListBoxRow" id="disk_row"> + <property name="visible">True</property> + <property name="activatable">False</property> + </object> + </child> + + </object> + </child> + + <child> + <object class="GtkListBox" id="os_box"> + <property name="visible">True</property> + <property name="selection-mode">none</property> + <style> + <class name="frame" /> + </style> + + <!-- OS Name --> + <child> + <object class="GtkListBoxRow" id="os_name_row"> + <property name="visible">True</property> + <property name="activatable">False</property> + </object> + </child> + + <!-- OS Type --> + <child> + <object class="GtkListBoxRow" id="os_type_row"> + <property name="visible">True</property> + <property name="activatable">False</property> + </object> + </child> + + <!-- MATE Version --> + <child> + <object class="GtkListBoxRow" id="mate_version_row"> + <property name="visible">True</property> + <property name="activatable">False</property> + </object> + </child> + + <!-- Windowing System --> + <child> + <object class="GtkListBoxRow" id="windowing_system_row"> + <property name="visible">True</property> + <property name="activatable">False</property> + </object> + </child> + + <!-- Virtualization --> + <child> + <object class="GtkListBoxRow" id="virtualization_row"> + <property name="visible">False</property> + <property name="activatable">False</property> + </object> + </child> + + <!-- Kernel --> + <child> + <object class="GtkListBoxRow" id="kernel_row"> + <property name="visible">True</property> + <property name="activatable">False</property> + </object> + </child> + </object> + </child> + </object> + </child> + </template> +</interface> diff --git a/capplets/system-info/system-info.gresource.xml b/capplets/system-info/system-info.gresource.xml new file mode 100644 index 00000000..f234e079 --- /dev/null +++ b/capplets/system-info/system-info.gresource.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<gresources> + <gresource prefix="/org/mate/control-center/system-info"> + <file preprocess="xml-stripblanks">mate-system-info.ui</file> + </gresource> +</gresources> diff --git a/configure.ac b/configure.ac index cc672254..4a1e19ed 100644 --- a/configure.ac +++ b/configure.ac @@ -67,6 +67,7 @@ AC_SUBST(TYPING_BREAK) AC_SUBST(SCREENSAVER_LIBS) GLIB_REQUIRED=2.64.0 +SYSTEMD_REQUIRED=248 GTK_REQUIRED=3.22.0 MARCO_REQUIRED=1.17.0 MATEKBD_REQUIRED=1.17.0 @@ -130,6 +131,8 @@ COMMON_MODULES="gtk+-3.0 >= $GTK_REQUIRED dnl gio-2.0 dnl gio-unix-2.0 dnl libxml-2.0 dnl + udisks2 dnl + libgtop-2.0 dnl mate-desktop-2.0 >= $MATE_DESKTOP_REQUIRED" PKG_CHECK_MODULES(CAPPLET, $COMMON_MODULES) PKG_CHECK_MODULES(MATECC, $COMMON_MODULES libmate-menu >= 1.21.0) @@ -141,10 +144,15 @@ PKG_CHECK_MODULES(DEFAULT_APPLICATIONS_CAPPLET, libxml-2.0) PKG_CHECK_MODULES(MARCO, libmarco-private >= $MARCO_REQUIRED) PKG_CHECK_MODULES(TYPING, $GMODULE_ADD glib-2.0 >= $GLIB_REQUIRED gio-2.0 gtk+-3.0 >= $GTK_REQUIRED) PKG_CHECK_MODULES(GIO, gio-2.0) +PKG_CHECK_MODULES(GLIBTOP, libgtop-2.0) +PKG_CHECK_MODULES(UDISKS, udisks2) +PKG_CHECK_MODULES(SYSTEMD, systemd >= $SYSTEMD_REQUIRED) PKG_CHECK_MODULES([DCONF], [dconf >= 0.13.4]) AC_SUBST(DCONF_CFLAGS) AC_SUBST(DCONF_LIBS) +AC_SUBST(GLIBTOP_CFLAGS) +AC_SUBST(GLIBTOP_LIBS) gtk_lib_dir=`$PKG_CONFIG --variable libdir gtk+-3.0` gtk_binary_version=`$PKG_CONFIG --variable gtk_binary_version gtk+-3.0` @@ -287,6 +295,7 @@ capplets/keybindings/Makefile capplets/keybindings/mate-keybindings.pc capplets/keyboard/Makefile capplets/mouse/Makefile +capplets/system-info/Makefile capplets/network/Makefile capplets/time-admin/Makefile capplets/time-admin/src/Makefile diff --git a/org.mate.control-center.gschema.xml.in b/org.mate.control-center.gschema.xml.in index e8546185..46b3d00d 100644 --- a/org.mate.control-center.gschema.xml.in +++ b/org.mate.control-center.gschema.xml.in @@ -2,7 +2,7 @@ <schema id="org.mate.control-center" path="/org/mate/control-center/"> <child name="appearance" schema="org.mate.control-center.appearance" /> <key name="cc-actions-list" type="as"> - <default l10n="messages">[ 'Change Theme;mate-appearance-properties.desktop', 'Set Preferred Applications;mate-default-applications-properties.desktop' ]</default> + <default l10n="messages">[ 'Change Theme;mate-appearance-properties.desktop', 'Set Preferred Applications;mate-default-applications-properties.desktop', 'Mate System Info;mate-system-info.desktop' ]</default> <summary>Task names and associated .desktop files</summary> <description>The task name to be displayed in the control-center followed by a ";" separator then the filename of an associated .desktop file to launch for that task.</description> </key> diff --git a/po/POTFILES.in b/po/POTFILES.in index 27c48f2c..8504b4fb 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -62,6 +62,10 @@ capplets/keyboard/mate-keyboard.desktop.in capplets/mouse/mate-mouse-properties.c capplets/mouse/mate-mouse-properties.ui capplets/mouse/mate-settings-mouse.desktop.in +capplets/system-info/main.c +capplets/system-info/mate-system-info.c +capplets/system-info/mate-system-info.ui +capplets/system-info/mate-system-info.desktop.in capplets/network/mate-network-properties.c capplets/network/mate-network-properties.desktop.in capplets/network/mate-network-properties.ui |