summaryrefslogtreecommitdiff
path: root/cpufreq/src/cpufreq-selector.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpufreq/src/cpufreq-selector.c')
-rw-r--r--cpufreq/src/cpufreq-selector.c289
1 files changed, 289 insertions, 0 deletions
diff --git a/cpufreq/src/cpufreq-selector.c b/cpufreq/src/cpufreq-selector.c
new file mode 100644
index 00000000..d5a37e15
--- /dev/null
+++ b/cpufreq/src/cpufreq-selector.c
@@ -0,0 +1,289 @@
+/*
+ * MATE CPUFreq Applet
+ * Copyright (C) 2008 Carlos Garcia Campos <[email protected]>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#ifdef HAVE_POLKIT
+#include <dbus/dbus-glib.h>
+#endif /* HAVE_POLKIT */
+
+#include "cpufreq-selector.h"
+
+struct _CPUFreqSelector {
+ GObject parent;
+
+#ifdef HAVE_POLKIT
+ DBusGConnection *system_bus;
+#endif /* HAVE_POLKIT */
+};
+
+struct _CPUFreqSelectorClass {
+ GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (CPUFreqSelector, cpufreq_selector, G_TYPE_OBJECT)
+
+static void
+cpufreq_selector_finalize (GObject *object)
+{
+ CPUFreqSelector *selector = CPUFREQ_SELECTOR (object);
+
+#ifdef HAVE_POLKIT
+ selector->system_bus = NULL;
+#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_set_frequency_async (SelectorAsyncData *data);
+static void selector_set_governor_async (SelectorAsyncData *data);
+
+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 = dbus_g_bus_get (DBUS_BUS_SYSTEM, error);
+
+ return (selector->system_bus != NULL);
+}
+
+static void
+dbus_set_call_notify_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ gpointer user_data)
+{
+ SelectorAsyncData *data;
+ GError *error = NULL;
+
+ data = (SelectorAsyncData *)user_data;
+
+ if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
+ selector_async_data_free (data);
+ return;
+ }
+
+ selector_async_data_free (data);
+ g_warning ("%s", error->message);
+ g_error_free (error);
+}
+
+static void
+selector_set_frequency_async (SelectorAsyncData *data)
+{
+ DBusGProxy *proxy;
+ 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;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (data->selector->system_bus,
+ "org.mate.CPUFreqSelector",
+ "/org/mate/cpufreq_selector/selector",
+ "org.mate.CPUFreqSelector");
+
+ dbus_g_proxy_begin_call_with_timeout (proxy, "SetFrequency",
+ dbus_set_call_notify_cb,
+ data, NULL,
+ INT_MAX,
+ G_TYPE_UINT, data->cpu,
+ G_TYPE_UINT, data->frequency,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+}
+
+void
+cpufreq_selector_set_frequency_async (CPUFreqSelector *selector,
+ guint cpu,
+ guint frequency,
+ guint32 parent)
+{
+ SelectorAsyncData *data;
+
+ data = g_new0 (SelectorAsyncData, 1);
+
+ data->selector = selector;
+ data->call = FREQUENCY;
+ data->cpu = cpu;
+ data->frequency = frequency;
+ data->parent_xid = parent;
+
+ selector_set_frequency_async (data);
+}
+
+static void
+selector_set_governor_async (SelectorAsyncData *data)
+{
+ DBusGProxy *proxy;
+ 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;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (data->selector->system_bus,
+ "org.mate.CPUFreqSelector",
+ "/org/mate/cpufreq_selector/selector",
+ "org.mate.CPUFreqSelector");
+
+ dbus_g_proxy_begin_call_with_timeout (proxy, "SetGovernor",
+ dbus_set_call_notify_cb,
+ data, NULL,
+ INT_MAX,
+ G_TYPE_UINT, data->cpu,
+ G_TYPE_STRING, data->governor,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+}
+
+void
+cpufreq_selector_set_governor_async (CPUFreqSelector *selector,
+ guint cpu,
+ const gchar *governor,
+ guint32 parent)
+{
+ SelectorAsyncData *data;
+
+ data = g_new0 (SelectorAsyncData, 1);
+
+ data->selector = selector;
+ data->call = GOVERNOR;
+ data->cpu = cpu;
+ data->governor = g_strdup (governor);
+ data->parent_xid = parent;
+
+ 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,
+ guint32 parent)
+{
+ 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,
+ guint32 parent)
+{
+ gchar *args;
+
+ args = g_strdup_printf ("-c %u -g %s", cpu, governor);
+ cpufreq_selector_run_command (selector, args);
+ g_free (args);
+}
+#endif /* HAVE_POLKIT */