/* * MATE CPUFreq Applet * Copyright (C) 2008 Carlos Garcia Campos * * This library 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 library 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 library; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #ifdef HAVE_POLKIT #include #endif /* HAVE_POLKIT */ #include "cpufreq-selector.h" struct _CPUFreqSelector { GObject parent; #ifdef HAVE_POLKIT GDBusConnection *system_bus; GDBusProxy *proxy; #endif /* HAVE_POLKIT */ }; struct _CPUFreqSelectorClass { GObjectClass parent_class; }; G_DEFINE_TYPE (CPUFreqSelector, cpufreq_selector, G_TYPE_OBJECT) static void cpufreq_selector_finalize (GObject *object) { #ifdef HAVE_POLKIT CPUFreqSelector *selector = CPUFREQ_SELECTOR (object); g_clear_object (&selector->proxy); g_clear_object (&selector->system_bus); #endif /* HAVE_POLKIT */ G_OBJECT_CLASS (cpufreq_selector_parent_class)->finalize (object); } static void cpufreq_selector_class_init (CPUFreqSelectorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = cpufreq_selector_finalize; } static void cpufreq_selector_init (CPUFreqSelector *selector) { } CPUFreqSelector * cpufreq_selector_get_default (void) { static CPUFreqSelector *selector = NULL; if (!selector) selector = CPUFREQ_SELECTOR (g_object_new (CPUFREQ_TYPE_SELECTOR, NULL)); return selector; } #ifdef HAVE_POLKIT typedef enum { FREQUENCY, GOVERNOR } CPUFreqSelectorCall; typedef struct { CPUFreqSelector *selector; CPUFreqSelectorCall call; guint cpu; guint frequency; gchar *governor; guint32 parent_xid; } SelectorAsyncData; static void selector_async_data_free (SelectorAsyncData *data) { if (!data) return; g_free (data->governor); g_free (data); } static gboolean cpufreq_selector_connect_to_system_bus (CPUFreqSelector *selector, GError **error) { if (selector->system_bus) return TRUE; selector->system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); return (selector->system_bus != NULL); } static gboolean cpufreq_selector_create_proxy (CPUFreqSelector *selector, GError **error) { if (selector->proxy) return TRUE; selector->proxy = g_dbus_proxy_new_sync (selector->system_bus, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.mate.CPUFreqSelector", "/org/mate/cpufreq_selector/selector", "org.mate.CPUFreqSelector", NULL, error); return (selector->proxy != NULL); } static void selector_setter_cb (GObject *source, GAsyncResult *result, gpointer user_data) { GDBusProxy *proxy = G_DBUS_PROXY (source); SelectorAsyncData *data = (SelectorAsyncData *)user_data; GError *error = NULL; g_dbus_proxy_call_finish (proxy, result, &error); if (error != NULL) { g_warning ("%s", error->message); g_clear_error (&error); } selector_async_data_free (data); } static void selector_set_frequency_async (SelectorAsyncData *data) { GError *error = NULL; if (!cpufreq_selector_connect_to_system_bus (data->selector, &error)) { g_warning ("%s", error->message); g_error_free (error); selector_async_data_free (data); return; } if (!cpufreq_selector_create_proxy (data->selector, &error)) { g_warning ("%s", error->message); g_error_free (error); selector_async_data_free (data); return; } g_dbus_proxy_call (data->selector->proxy, "SetFrequency", g_variant_new ("(uu)", data->cpu, data->frequency), G_DBUS_CALL_FLAGS_NONE, -1, NULL, selector_setter_cb, data); } void cpufreq_selector_set_frequency_async (CPUFreqSelector *selector, guint cpu, guint frequency) { guint cores; cores = get_nprocs() ; for (cpu = 0; cpu < cores; cpu = cpu+1){ SelectorAsyncData *data; data = g_new0 (SelectorAsyncData, 1); data->selector = selector; data->call = FREQUENCY; data->cpu = cpu; data->frequency = frequency; selector_set_frequency_async (data); } } static void selector_set_governor_async (SelectorAsyncData *data) { GError *error = NULL; if (!cpufreq_selector_connect_to_system_bus (data->selector, &error)) { g_warning ("%s", error->message); g_error_free (error); selector_async_data_free (data); return; } if (!cpufreq_selector_create_proxy (data->selector, &error)) { g_warning ("%s", error->message); g_error_free (error); selector_async_data_free (data); return; } g_dbus_proxy_call (data->selector->proxy, "SetGovernor", g_variant_new ("(us)", data->cpu, data->governor), G_DBUS_CALL_FLAGS_NONE, -1, NULL, selector_setter_cb, data); } void cpufreq_selector_set_governor_async (CPUFreqSelector *selector, guint cpu, const gchar *governor) { guint cores; cores = get_nprocs() ; for (cpu = 0; cpu < cores; cpu = cpu+1){ SelectorAsyncData *data; data = g_new0 (SelectorAsyncData, 1); data->selector = selector; data->call = GOVERNOR; data->cpu = cpu; data->governor = g_strdup (governor); selector_set_governor_async (data); } } #else /* !HAVE_POLKIT */ static void cpufreq_selector_run_command (CPUFreqSelector *selector, const gchar *args) { gchar *command; gchar *path; GError *error = NULL; path = g_find_program_in_path ("cpufreq-selector"); if (!path) return; command = g_strdup_printf ("%s %s", path, args); g_free (path); g_spawn_command_line_async (command, &error); g_free (command); if (error) { g_warning ("%s", error->message); g_error_free (error); } } void cpufreq_selector_set_frequency_async (CPUFreqSelector *selector, guint cpu, guint frequency) { guint cores; cores = get_nprocs() ; for (cpu = 0; cpu < cores; cpu = cpu+1){ gchar *args; args = g_strdup_printf ("-c %u -f %u", cpu, frequency); cpufreq_selector_run_command (selector, args); g_free (args); } } void cpufreq_selector_set_governor_async (CPUFreqSelector *selector, guint cpu, const gchar *governor) { guint cores; cores = get_nprocs() ; for (cpu = 0; cpu < cores; cpu = cpu+1){ gchar *args; args = g_strdup_printf ("-c %u -g %s", cpu, governor); cpufreq_selector_run_command (selector, args); g_free (args); } } #endif /* HAVE_POLKIT */