gnome-applets r10849 - in trunk: . cpufreq cpufreq/src cpufreq/src/cpufreq-selector po
- From: carlosgc svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-applets r10849 - in trunk: . cpufreq cpufreq/src cpufreq/src/cpufreq-selector po
- Date: Sun, 25 May 2008 15:32:01 +0000 (UTC)
Author: carlosgc
Date: Sun May 25 15:32:01 2008
New Revision: 10849
URL: http://svn.gnome.org/viewvc/gnome-applets?rev=10849&view=rev
Log:
2008-05-25 Carlos Garcia Campos <carlosgc gnome org>
* src/Makefile.am:
* src/cpufreq-applet.c:
* src/cpufreq-popup.[ch]:
* src/cpufreq-selector.[ch]:
* src/cpufreq-utils.c:
* src/cpufreq-selector/Makefile.am:
* src/cpufreq-selector/main.c:
* src/cpufreq-selector/cpufreq-selector-factory.[ch]:
* src/cpufreq-selector/cpufreq-selector-service.[ch]:
* src/cpufreq-selector/cpufreq-selector-service.xml:
* src/cpufreq-selector/org.gnome.CPUFreqSelector.conf:
* src/cpufreq-selector/org.gnome.CPUFreqSelector.service.in:
* src/cpufreq-selector/org.gnome.cpufreqselector.policy.in:
Use PolicyKit when available in the cpufreq-selector instead of
installing it with suid bit enabled. Fixes bug #528536.
Added:
trunk/cpufreq/src/cpufreq-selector.c
trunk/cpufreq/src/cpufreq-selector.h
trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-factory.c
trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-factory.h
trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-service.c
trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-service.h
trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-service.xml
trunk/cpufreq/src/cpufreq-selector/org.gnome.CPUFreqSelector.conf
trunk/cpufreq/src/cpufreq-selector/org.gnome.CPUFreqSelector.service.in
trunk/cpufreq/src/cpufreq-selector/org.gnome.cpufreqselector.policy.in
Modified:
trunk/ChangeLog
trunk/configure.in
trunk/cpufreq/ChangeLog
trunk/cpufreq/src/Makefile.am
trunk/cpufreq/src/cpufreq-applet.c
trunk/cpufreq/src/cpufreq-popup.c
trunk/cpufreq/src/cpufreq-popup.h
trunk/cpufreq/src/cpufreq-selector/Makefile.am
trunk/cpufreq/src/cpufreq-selector/main.c
trunk/cpufreq/src/cpufreq-utils.c
trunk/po/POTFILES.in
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Sun May 25 15:32:01 2008
@@ -28,8 +28,8 @@
LIBGNOME_DESKTOP_REQUIRED=2.11.1
LIBNOTIFY_REQUIRED=0.3.2
HAL_REQUIRED=0.5.3
-DBUS_REQUIRED=0.92
-DBUS_GLIB_REQUIRED=0.34
+DBUS_REQUIRED=1.1.2
+DBUS_GLIB_REQUIRED=0.74
PYGTK_REQUIRED=2.6
PYGOBJECT_REQUIRED=2.6
GNOME_PYTHON_REQUIRED=2.10
@@ -38,6 +38,7 @@
GWEATHER_REQUIRED=2.22.1
GUCHARMAP2_REQUIRED=2.21.5
GUCHARMAP_REQUIRED=1.4.0
+POLKIT_REQUIRED=0.7
dnl ***************************************************************************
AM_MAINTAINER_MODE
@@ -210,10 +211,10 @@
AC_SUBST(CPUFREQ_SELECTOR_CFLAGS)
AC_SUBST(CPUFREQ_SELECTOR_LIBS)
-if test "x$BUILD_KEYBOARD_APPLET" = "xyes"; then
- dnl -- check for dbus
- PKG_CHECK_MODULES(DBUS, dbus-1 >= $DBUS_REQUIRED dbus-glib-1 >= $DBUS_GLIB_REQUIRED, HAVE_DBUS=yes, HAVE_DBUS=no)
+dnl -- check for dbus (required for gnome-keyboard-applet and cpufreq-selector)
+PKG_CHECK_MODULES(DBUS, dbus-1 >= $DBUS_REQUIRED dbus-glib-1 >= $DBUS_GLIB_REQUIRED, HAVE_DBUS=yes, HAVE_DBUS=no)
+if test "x$BUILD_KEYBOARD_APPLET" = "xyes"; then
if test "x$HAVE_DBUS" = "xno"; then
AC_MSG_ERROR(
[dbus was not found and is required to build gnome-keyboard-applet.])
@@ -223,6 +224,28 @@
AC_SUBST(DBUS_CFLAGS)
AC_SUBST(DBUS_LIBS)
+dnl -- check for PolicyKit and PolicyKit-gnome (optional) -----------------------------------------
+POLKIT_CFLAGS=
+POLKIT_LIBS=
+PKG_CHECK_MODULES(POLKIT, polkit >= $POLKIT_REQUIRED polkit-dbus >= $POLKIT_REQUIRED dbus-glib-1 >= $DBUS_GLIB_REQUIRED, HAVE_POLKIT=yes, HAVE_POLKIT=no)
+if test "x$HAVE_POLKIT" = "xyes"; then
+ AC_DEFINE(HAVE_POLKIT, [1], [PolicyKit available])
+fi
+AM_CONDITIONAL(HAVE_POLKIT, test "x$HAVE_POLKIT" = "xyes")
+AC_SUBST(POLKIT_CFLAGS)
+AC_SUBST(POLKIT_LIBS)
+
+POLKIT_GNOME_CFLAGS=
+POLKIT_GNOME_LIBS=
+PKG_CHECK_MODULES(POLKIT_GNOME, polkit-gnome >= $POLKIT_REQUIRED, polkit_gnome=yes, polkit_gnome=no)
+if test "x$polkit_gnome" = "xyes"; then
+ AC_DEFINE(HAVE_POLKIT_GNOME, [1], [PolicyKit-gnome available])
+fi
+AM_CONDITIONAL(HAVE_POLKIT_GNOME, test "x$polkit_gnome" = "xyes")
+AC_SUBST(POLKIT_GNOME_CFLAGS)
+AC_SUBST(POLKIT_GNOME_LIBS)
+
+
dnl -- check for libhal (optional) --------------------------------------------
HAL_CFLAGS=
HAL_LIBS=
@@ -562,9 +585,13 @@
dnl --enable-suid=(yes/no)
AC_ARG_ENABLE(suid,
- [ --enable-suid[[=yes/no]] suid root the frequency selector executable
- [[default: yes]]], ,
- suid=yes)
+ [ --enable-suid[[=yes/no]] suid root the frequency selector executable
+ [[default: yes]]], ,
+ suid=yes)
+
+if test "x$HAVE_POLKIT" = "xyes"; then
+ suid=no
+fi
AC_CHECK_HEADER(cpufreq.h, have_libcpufreq=yes, have_libcpufreq=no)
LIBCPUFREQ_LIBS=
@@ -785,6 +812,8 @@
- gucharmap support $HAVE_GUCHARMAP
- cpufreq $build_cpufreq_applet
- building selector $enable_selector
+ - using PolicyKit $HAVE_POLKIT
+ - using PolicyKit-gnome $polkit_gnome
- enabling suid bit $suid
- drivemount $build_gnome_vfs_applets
- geyes always
Modified: trunk/cpufreq/src/Makefile.am
==============================================================================
--- trunk/cpufreq/src/Makefile.am (original)
+++ trunk/cpufreq/src/Makefile.am Sun May 25 15:32:01 2008
@@ -8,6 +8,10 @@
$(GNOME_APPLETS_CFLAGS) \
$(LIBGLADE_CFLAGS)
+if HAVE_POLKIT_GNOME
+INCLUDES += $(POLKIT_GNOME_CFLAGS)
+endif
+
libexec_PROGRAMS = cpufreq-applet
if HAVE_LIBCPUFREQ
@@ -18,6 +22,7 @@
cpufreq-applet.c cpufreq-applet.h \
cpufreq-utils.c cpufreq-utils.h \
cpufreq-prefs.c cpufreq-prefs.h \
+ cpufreq-selector.c cpufreq-selector.h \
cpufreq-popup.c cpufreq-popup.h \
cpufreq-monitor.c cpufreq-monitor.h \
cpufreq-monitor-factory.c cpufreq-monitor-factory.h \
@@ -31,5 +36,8 @@
$(LIBGLADE_LIBS) \
$(LIBCPUFREQ_LIBS)
+if HAVE_POLKIT_GNOME
+cpufreq_applet_LDADD += $(POLKIT_GNOME_LIBS)
+endif
Modified: trunk/cpufreq/src/cpufreq-applet.c
==============================================================================
--- trunk/cpufreq/src/cpufreq-applet.c (original)
+++ trunk/cpufreq/src/cpufreq-applet.c Sun May 25 15:32:01 2008
@@ -471,6 +471,7 @@
if (!applet->popup) {
applet->popup = cpufreq_popup_new ();
cpufreq_popup_set_monitor (applet->popup, applet->monitor);
+ cpufreq_popup_set_parent (applet->popup, GTK_WIDGET (applet));
}
menu = cpufreq_popup_get_menu (applet->popup);
Modified: trunk/cpufreq/src/cpufreq-popup.c
==============================================================================
--- trunk/cpufreq/src/cpufreq-popup.c (original)
+++ trunk/cpufreq/src/cpufreq-popup.c Sun May 25 15:32:01 2008
@@ -25,10 +25,12 @@
#include <gtk/gtktoggleaction.h>
#include <gtk/gtkradioaction.h>
#include <gtk/gtkuimanager.h>
+#include <gdk/gdkx.h>
#include <stdlib.h>
#include <string.h>
#include "cpufreq-popup.h"
+#include "cpufreq-selector.h"
#include "cpufreq-utils.h"
struct _CPUFreqPopupPrivate {
@@ -46,6 +48,7 @@
gboolean show_freqs;
CPUFreqMonitor *monitor;
+ GtkWidget *parent;
};
#define CPUFREQ_POPUP_GET_PRIVATE(object) \
@@ -74,8 +77,6 @@
static void
cpufreq_popup_init (CPUFreqPopup *popup)
{
- GtkActionGroup *action_group;
-
popup->priv = CPUFREQ_POPUP_GET_PRIVATE (popup);
popup->priv->ui_manager = gtk_ui_manager_new ();
@@ -172,70 +173,61 @@
popup->priv->monitor = g_object_ref (monitor);
}
-static void
-cpufreq_popup_run_selector (CPUFreqPopup *popup,
- const gchar *params)
+void
+cpufreq_popup_set_parent (CPUFreqPopup *popup,
+ GtkWidget *parent)
{
- gchar *path;
- guint cpu;
- gchar *command;
- GError *error = NULL;
-
- path = g_find_program_in_path ("cpufreq-selector");
-
- if (!path)
- return;
-
- cpu = cpufreq_monitor_get_cpu (popup->priv->monitor);
-
- command = g_strdup_printf ("%s -c %d %s", path, cpu, params);
- g_free (path);
+ g_return_if_fail (CPUFREQ_IS_POPUP (popup));
+ g_return_if_fail (GTK_IS_WIDGET (parent));
- g_spawn_command_line_async (command, &error);
- g_free (command);
-
- if (error) {
- g_warning (error->message);
- g_error_free (error);
- }
+ popup->priv->parent = parent;
}
static void
cpufreq_popup_frequencies_menu_activate (GtkAction *action,
CPUFreqPopup *popup)
{
- const gchar *name;
- const gchar *freq;
- gchar *params;
+ CPUFreqSelector *selector;
+ const gchar *name;
+ guint cpu;
+ guint freq;
+ guint32 parent;
if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
return;
-
+
+ selector = cpufreq_selector_get_default ();
+
+ cpu = cpufreq_monitor_get_cpu (popup->priv->monitor);
name = gtk_action_get_name (action);
- freq = name + strlen ("Frequency");
+ freq = (guint) atoi (name + strlen ("Frequency"));
+ parent = GDK_WINDOW_XID (popup->priv->parent->window);
+
- params = g_strdup_printf ("-f %s", freq);
- cpufreq_popup_run_selector (popup, params);
- g_free (params);
+ cpufreq_selector_set_frequency_async (selector, cpu, freq, parent);
}
static void
cpufreq_popup_governors_menu_activate (GtkAction *action,
CPUFreqPopup *popup)
{
- const gchar *name;
- const gchar *governor;
- gchar *params;
+ CPUFreqSelector *selector;
+ const gchar *name;
+ guint cpu;
+ const gchar *governor;
+ guint32 parent;
if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
return;
+
+ selector = cpufreq_selector_get_default ();
+ cpu = cpufreq_monitor_get_cpu (popup->priv->monitor);
name = gtk_action_get_name (action);
governor = name + strlen ("Governor");
+ parent = GDK_WINDOW_XID (popup->priv->parent->window);
- params = g_strdup_printf ("-g %s", governor);
- cpufreq_popup_run_selector (popup, params);
- g_free (params);
+ cpufreq_selector_set_governor_async (selector, cpu, governor, parent);
}
static void
Modified: trunk/cpufreq/src/cpufreq-popup.h
==============================================================================
--- trunk/cpufreq/src/cpufreq-popup.h (original)
+++ trunk/cpufreq/src/cpufreq-popup.h Sun May 25 15:32:01 2008
@@ -57,6 +57,8 @@
CPUFreqPrefs *prefs);
void cpufreq_popup_set_monitor (CPUFreqPopup *popup,
CPUFreqMonitor *monitor);
+void cpufreq_popup_set_parent (CPUFreqPopup *popup,
+ GtkWidget *parent);
GtkWidget *cpufreq_popup_get_menu (CPUFreqPopup *popup);
G_END_DECLS
Added: trunk/cpufreq/src/cpufreq-selector.c
==============================================================================
--- (empty file)
+++ trunk/cpufreq/src/cpufreq-selector.c Sun May 25 15:32:01 2008
@@ -0,0 +1,375 @@
+/*
+ * GNOME CPUFreq Applet
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * 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_GNOME
+#include <dbus/dbus-glib.h>
+#endif /* HAVE_POLKIT_GNOME */
+
+#include "cpufreq-selector.h"
+
+struct _CPUFreqSelector {
+ GObject parent;
+
+#ifdef HAVE_POLKIT_GNOME
+ DBusGConnection *system_bus;
+ DBusGConnection *session_bus;
+#endif /* HAVE_POLKIT_GNOME */
+};
+
+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_GNOME
+ selector->system_bus = NULL;
+ selector->session_bus = NULL;
+#endif /* HAVE_POLKIT_GNOME */
+
+ 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_GNOME
+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 gboolean
+cpufreq_selector_connect_to_session_bus (CPUFreqSelector *selector,
+ GError **error)
+{
+ if (selector->session_bus)
+ return TRUE;
+
+ selector->session_bus = dbus_g_bus_get (DBUS_BUS_SESSION, error);
+
+ return (selector->session_bus != NULL);
+}
+
+static void
+dbus_auth_call_notify_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ gpointer user_data)
+{
+ SelectorAsyncData *data;
+ gboolean gained_privilege;
+ GError *error = NULL;
+
+ data = (SelectorAsyncData *)user_data;
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_BOOLEAN, &gained_privilege, G_TYPE_INVALID)) {
+ g_warning (error->message);
+ g_error_free (error);
+
+ selector_async_data_free (data);
+
+ return;
+ }
+
+ if (gained_privilege) {
+ switch (data->call) {
+ case FREQUENCY:
+ selector_set_frequency_async (data);
+ break;
+ case GOVERNOR:
+ selector_set_governor_async (data);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ } else {
+ selector_async_data_free (data);
+ }
+}
+
+static void
+do_auth_async (SelectorAsyncData *data)
+{
+ DBusGProxy *proxy;
+ GError *error = NULL;
+
+ if (!cpufreq_selector_connect_to_session_bus (data->selector, &error)) {
+ g_warning (error->message);
+ g_error_free (error);
+
+ selector_async_data_free (data);
+
+ return;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (data->selector->session_bus,
+ "org.gnome.PolicyKit",
+ "/org/gnome/PolicyKit/Manager",
+ "org.gnome.PolicyKit.Manager");
+
+ dbus_g_proxy_begin_call_with_timeout (proxy,
+ "ShowDialog",
+ dbus_auth_call_notify_cb,
+ data, NULL,
+ INT_MAX,
+ G_TYPE_STRING, "org.gnome.cpufreqselector",
+ G_TYPE_UINT, data->parent_xid,
+ G_TYPE_INVALID);
+}
+
+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;
+ }
+
+ if (error->domain == DBUS_GERROR && DBUS_GERROR_REMOTE_EXCEPTION &&
+ dbus_g_error_has_name (error, "org.gnome.CPUFreqSelector.NotAuthorized")) {
+ do_auth_async (data);
+ return;
+ }
+
+ selector_async_data_free (data);
+ g_warning (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 (error->message);
+ g_error_free (error);
+
+ selector_async_data_free (data);
+
+ return;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (data->selector->system_bus,
+ "org.gnome.CPUFreqSelector",
+ "/org/gnome/cpufreq_selector/selector",
+ "org.gnome.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 (error->message);
+ g_error_free (error);
+
+ selector_async_data_free (data);
+
+ return;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (data->selector->system_bus,
+ "org.gnome.CPUFreqSelector",
+ "/org/gnome/cpufreq_selector/selector",
+ "org.gnome.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_GNOME */
+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 (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_GNOME */
Added: trunk/cpufreq/src/cpufreq-selector.h
==============================================================================
--- (empty file)
+++ trunk/cpufreq/src/cpufreq-selector.h Sun May 25 15:32:01 2008
@@ -0,0 +1,51 @@
+/*
+ * GNOME CPUFreq Applet
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * 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.
+ */
+
+#ifndef __CPUFREQ_SELECTOR_H__
+#define __CPUFREQ_SELECTOR_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define CPUFREQ_TYPE_SELECTOR (cpufreq_selector_get_type ())
+#define CPUFREQ_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CPUFREQ_TYPE_SELECTOR, CPUFreqSelector))
+#define CPUFREQ_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CPUFREQ_TYPE_SELECTOR, CPUFreqSelectorClass))
+#define CPUFREQ_IS_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CPUFREQ_TYPE_SELECTOR))
+#define CPUFREQ_IS_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CPUFREQ_TYPE_SELECTOR))
+#define CPUFREQ_SELECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CPUFREQ_TYPE_SELECTOR, CPUFreqSelectorClass))
+
+typedef struct _CPUFreqSelector CPUFreqSelector;
+typedef struct _CPUFreqSelectorClass CPUFreqSelectorClass;
+
+GType cpufreq_selector_get_type (void) G_GNUC_CONST;
+
+CPUFreqSelector *cpufreq_selector_get_default (void);
+void cpufreq_selector_set_frequency_async (CPUFreqSelector *selector,
+ guint cpu,
+ guint frequency,
+ guint32 parent);
+void cpufreq_selector_set_governor_async (CPUFreqSelector *selector,
+ guint cpu,
+ const gchar *governor,
+ guint32 parent);
+
+G_END_DECLS
+
+#endif /* __CPUFREQ_SELECTOR_H__ */
Modified: trunk/cpufreq/src/cpufreq-selector/Makefile.am
==============================================================================
--- trunk/cpufreq/src/cpufreq-selector/Makefile.am (original)
+++ trunk/cpufreq/src/cpufreq-selector/Makefile.am Sun May 25 15:32:01 2008
@@ -2,7 +2,11 @@
INCLUDES = $(CPUFREQ_SELECTOR_CFLAGS)
-LDADD = $(CPUFREQ_SELECTOR_LIBS)
+if HAVE_POLKIT
+INCLUDES += \
+ $(DBUS_CFLAGS) \
+ $(POLKIT_CFLAGS)
+endif
bin_PROGRAMS = cpufreq-selector
@@ -11,19 +15,73 @@
chmod 4755 $(DESTDIR)$(bindir)/cpufreq-selector
endif
+
if HAVE_LIBCPUFREQ
cpufreq_files=cpufreq-selector-libcpufreq.c cpufreq-selector-libcpufreq.h
endif
+if HAVE_POLKIT
+service_files=cpufreq-selector-service.c cpufreq-selector-service.h
+endif
+
cpufreq_selector_SOURCES = \
- cpufreq-selector.c cpufreq-selector.h \
- cpufreq-selector-sysfs.c cpufreq-selector-sysfs.h \
- cpufreq-selector-procfs.c cpufreq-selector-procfs.h \
- $(cpufreq_files) \
+ cpufreq-selector.c cpufreq-selector.h \
+ cpufreq-selector-sysfs.c cpufreq-selector-sysfs.h \
+ cpufreq-selector-procfs.c cpufreq-selector-procfs.h \
+ $(cpufreq_files) \
+ $(service_files) \
+ cpufreq-selector-factory.c cpufreq-selector-factory.h \
+ $(BUILT_SOURCES) \
main.c
cpufreq_selector_LDADD = \
- $(CPUFREQ_SELECTOR_LIBS) \
+ $(CPUFREQ_SELECTOR_LIBS) \
$(LIBCPUFREQ_LIBS)
+if HAVE_POLKIT
+cpufreq_selector_LDADD += \
+ $(DBUS_LIBS) \
+ $(POLKIT_LIBS)
+endif
+
cpufreq_selector_LDFLAGS = $(LDFLAGS) -Wl,-z,now
+
+dbus_services_in_files = org.gnome.CPUFreqSelector.service.in
+polkit_in_files = org.gnome.cpufreqselector.policy.in
+
+dbus_servicesdir = $(datadir)/dbus-1/system-services
+dbus_confdir = $(sysconfdir)/dbus-1/system.d
+polkitdir = $(datadir)/PolicyKit/policy
+
+if HAVE_POLKIT
+BUILT_SOURCES = cpufreq-selector-service-glue.h
+
+cpufreq-selector-service-glue.h: $(srcdir)/cpufreq-selector-service.xml
+ dbus-binding-tool --prefix=cpufreq_selector_service --mode=glib-server \
+ --output=cpufreq-selector-service-glue.h \
+ $(srcdir)/cpufreq-selector-service.xml
+
+dbus_services_DATA = $(dbus_services_in_files:.service.in=.service)
+$(dbus_services_DATA): $(dbus_services_in_files)
+ sed -e "s|\ BINDIR\@|$(DESTDIR)$(bindir)|" $< > $@
+dbus_conf_DATA = org.gnome.CPUFreqSelector.conf
+
+ INTLTOOL_POLICY_RULE@
+polkit_DATA = $(polkit_in_files:.policy.in=.policy)
+
+else
+dbus_services_DATA=
+dbus_conf_DATA=
+polkit_DATA=
+endif
+
+EXTRA_DIST = \
+ cpufreq-selector-service.xml \
+ $(dbus_services_in_files) \
+ org.gnome.CPUFreqSelector.conf \
+ $(polkit_in_files)
+
+CLEANFILES = \
+ $(BUILT_SOURCES) \
+ $(dbus_services_DATA) \
+ $(polkit_DATA)
Added: trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-factory.c
==============================================================================
--- (empty file)
+++ trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-factory.c Sun May 25 15:32:01 2008
@@ -0,0 +1,47 @@
+/*
+ * GNOME CPUFreq Applet
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cpufreq-selector-factory.h"
+#include "cpufreq-selector-sysfs.h"
+#include "cpufreq-selector-procfs.h"
+#ifdef HAVE_LIBCPUFREQ
+#include "cpufreq-selector-libcpufreq.h"
+#endif
+
+CPUFreqSelector *
+cpufreq_selector_factory_create_selector (guint cpu)
+{
+ CPUFreqSelector *selector = NULL;
+
+#ifdef HAVE_LIBCPUFREQ
+ selector = cpufreq_selector_libcpufreq_new (cpu);
+#else
+ if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.6 kernel */
+ selector = cpufreq_selector_sysfs_new (cpu);
+ } else if (g_file_test ("/proc/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.4 kernel */
+ selector = cpufreq_selector_procfs_new (cpu);
+ }
+#endif /* HAVE_LIBCPUFREQ */
+
+ return selector;
+}
Added: trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-factory.h
==============================================================================
--- (empty file)
+++ trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-factory.h Sun May 25 15:32:01 2008
@@ -0,0 +1,31 @@
+/*
+ * GNOME CPUFreq Applet
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * 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.
+ */
+
+#ifndef CPUFREQ_SELECTOR_FACTORY
+#define CPUFREQ_SELECTOR_FACTORY
+
+#include "cpufreq-selector.h"
+
+G_BEGIN_DECLS
+
+CPUFreqSelector *cpufreq_selector_factory_create_selector (guint cpu);
+
+G_END_DECLS
+
+#endif /* CPUFREQ_SELECTOR_FACTORY */
Added: trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-service.c
==============================================================================
--- (empty file)
+++ trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-service.c Sun May 25 15:32:01 2008
@@ -0,0 +1,520 @@
+/*
+ * GNOME CPUFreq Applet
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * 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 <polkit-dbus/polkit-dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "cpufreq-selector.h"
+#include "cpufreq-selector-factory.h"
+#include "cpufreq-selector-service.h"
+
+#include "cpufreq-selector-service-glue.h"
+
+#define MAX_CPUS 255
+
+struct _CPUFreqSelectorService {
+ GObject parent;
+
+ CPUFreqSelector *selectors[MAX_CPUS];
+ gint selectors_max;
+
+ DBusGConnection *system_bus;
+
+ /* PolicyKit */
+ PolKitContext *pk_context;
+};
+
+struct _CPUFreqSelectorServiceClass {
+ GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (CPUFreqSelectorService, cpufreq_selector_service, G_TYPE_OBJECT)
+
+#define BUS_NAME "org.gnome.CPUFreqSelector"
+
+GType
+cpufreq_selector_service_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (G_UNLIKELY (etype == 0)) {
+ const GEnumValue values[] = {
+ { SERVICE_ERROR_GENERAL, "SERVICE_ERROR_GENERAL", "GeneralError" },
+ { SERVICE_ERROR_DBUS, "SERVICE_ERROR_DBUS", "DBUSError" },
+ { SERVICE_ERROR_ALREADY_REGISTERED, "SERVICE_ERROR_ALREADY_REGISTERED", "AlreadyRegistered" },
+ { SERVICE_ERROR_NOT_AUTHORIZED, "SERVICE_ERROR_NOT_AUTHORIZED", "NotAuthorized"},
+ { 0, NULL, NULL}
+ };
+
+ etype = g_enum_register_static ("CPUFreqSelectorServiceError", values);
+ }
+
+ return etype;
+}
+
+GQuark
+cpufreq_selector_service_error_quark (void)
+{
+ static GQuark error_quark = 0;
+
+ if (G_UNLIKELY (error_quark == 0))
+ error_quark =
+ g_quark_from_static_string ("cpufreq-selector-service-error-quark");
+
+ return error_quark;
+}
+
+static void
+cpufreq_selector_service_finalize (GObject *object)
+{
+ CPUFreqSelectorService *service = CPUFREQ_SELECTOR_SERVICE (object);
+ gint i;
+
+ service->system_bus = NULL;
+
+ if (service->selectors_max >= 0) {
+ for (i = 0; i < service->selectors_max; i++) {
+ if (service->selectors[i]) {
+ g_object_unref (service->selectors[i]);
+ service->selectors[i] = NULL;
+ }
+ }
+
+ service->selectors_max = -1;
+ }
+
+ if (service->pk_context) {
+ polkit_context_unref (service->pk_context);
+ service->pk_context = NULL;
+ }
+
+ G_OBJECT_CLASS (cpufreq_selector_service_parent_class)->finalize (object);
+}
+
+static void
+cpufreq_selector_service_class_init (CPUFreqSelectorServiceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = cpufreq_selector_service_finalize;
+}
+
+static void
+cpufreq_selector_service_init (CPUFreqSelectorService *service)
+{
+ service->selectors_max = -1;
+}
+
+CPUFreqSelectorService *
+cpufreq_selector_service_get_instance (void)
+{
+ static CPUFreqSelectorService *service = NULL;
+
+ if (!service)
+ service = CPUFREQ_SELECTOR_SERVICE (g_object_new (CPUFREQ_TYPE_SELECTOR_SERVICE, NULL));
+
+ return service;
+}
+
+static gboolean
+service_shutdown (gpointer user_data)
+{
+ g_object_unref (SELECTOR_SERVICE);
+
+ return FALSE;
+}
+
+static void
+reset_killtimer (void)
+{
+ static guint timer_id = 0;
+
+ if (timer_id > 0)
+ g_source_remove (timer_id);
+
+ timer_id = g_timeout_add_seconds (30,
+ (GSourceFunc) service_shutdown,
+ NULL);
+}
+
+static gboolean
+pk_io_watch_have_data (GIOChannel *channel,
+ GIOCondition condition,
+ PolKitContext *pk_context)
+{
+ polkit_context_io_func (pk_context,
+ g_io_channel_unix_get_fd (channel));
+ return TRUE;
+}
+
+static int
+pk_add_io_watch (PolKitContext *pk_context,
+ int watch_id)
+{
+ GIOChannel *channel;
+ guint id = 0;
+
+ channel = g_io_channel_unix_new (watch_id);
+ if (!channel)
+ return 0;
+
+ id = g_io_add_watch (channel, G_IO_IN,
+ (GIOFunc)pk_io_watch_have_data,
+ pk_context);
+ g_io_channel_unref (channel);
+
+ return id;
+}
+
+static void
+pk_remove_io_watch (PolKitContext *pk_context,
+ int watch_id)
+{
+ g_source_remove (watch_id);
+}
+
+gboolean
+cpufreq_selector_service_register (CPUFreqSelectorService *service,
+ GError **error)
+{
+ DBusGConnection *connection;
+ DBusGProxy *bus_proxy;
+ gboolean res;
+ guint result;
+ GError *err = NULL;
+ PolKitError *pk_err = NULL;
+
+ if (service->system_bus) {
+ g_set_error (error,
+ CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_ALREADY_REGISTERED,
+ "Service %s already registered", BUS_NAME);
+ return FALSE;
+ }
+
+ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+ if (!connection) {
+ g_set_error (error,
+ CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_DBUS,
+ "Couldn't connect to system bus: %s",
+ err->message);
+ g_error_free (err);
+
+ return FALSE;
+ }
+
+ bus_proxy = dbus_g_proxy_new_for_name (connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ if (!bus_proxy) {
+ g_set_error (error,
+ CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_DBUS,
+ "Could not construct bus_proxy object");
+ return FALSE;
+ }
+
+ res = dbus_g_proxy_call (bus_proxy,
+ "RequestName",
+ &err,
+ G_TYPE_STRING, BUS_NAME,
+ G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &result,
+ G_TYPE_INVALID);
+ g_object_unref (bus_proxy);
+
+ if (!res) {
+ if (err) {
+ g_set_error (error,
+ CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_DBUS,
+ "Failed to acquire %s: %s",
+ BUS_NAME, err->message);
+ g_error_free (err);
+ } else {
+ g_set_error (error,
+ CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_DBUS,
+ "Failed to acquire %s", BUS_NAME);
+ }
+
+ return FALSE;
+ }
+
+ if (result == DBUS_REQUEST_NAME_REPLY_EXISTS) {
+ g_set_error (error,
+ CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_ALREADY_REGISTERED,
+ "Service %s already registered", BUS_NAME);
+ return FALSE;
+ }
+
+ service->pk_context = polkit_context_new ();
+ polkit_context_set_io_watch_functions (service->pk_context,
+ pk_add_io_watch,
+ pk_remove_io_watch);
+ if (!polkit_context_init (service->pk_context, &pk_err)) {
+ polkit_context_unref (service->pk_context);
+ service->pk_context = NULL;
+
+ if (polkit_error_is_set (pk_err)) {
+ g_set_error (error,
+ CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_GENERAL,
+ "Cannot initialize libpolkit: %s",
+ polkit_error_get_error_message (pk_err));
+ polkit_error_free (pk_err);
+ } else {
+ g_set_error (error,
+ CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_GENERAL,
+ "Cannot initialize libpolkit");
+ }
+
+ return FALSE;
+ }
+
+ service->system_bus = connection;
+
+ dbus_g_object_type_install_info (CPUFREQ_TYPE_SELECTOR_SERVICE,
+ &dbus_glib_cpufreq_selector_service_object_info);
+ dbus_g_connection_register_g_object (connection,
+ "/org/gnome/cpufreq_selector/selector",
+ G_OBJECT (service));
+ dbus_g_error_domain_register (CPUFREQ_SELECTOR_SERVICE_ERROR, NULL,
+ CPUFREQ_TYPE_SELECTOR_SERVICE_ERROR);
+
+ reset_killtimer ();
+
+ return TRUE;
+}
+
+static CPUFreqSelector *
+get_selector_for_cpu (CPUFreqSelectorService *service,
+ guint cpu)
+{
+ if (!service->selectors[cpu]) {
+ service->selectors[cpu] = cpufreq_selector_factory_create_selector (cpu);
+ if (!service->selectors[cpu])
+ return NULL;
+
+ if (service->selectors_max < cpu)
+ service->selectors_max = cpu;
+ }
+
+ return service->selectors[cpu];
+}
+
+/* PolicyKit */
+static gboolean
+cpufreq_selector_service_check_policy (CPUFreqSelectorService *service,
+ DBusGMethodInvocation *context,
+ GError **error)
+{
+ PolKitAction *pk_action;
+ PolKitCaller *pk_caller;
+ PolKitResult pk_result;
+ gchar *sender;
+ DBusConnection *connection;
+ DBusError dbus_error;
+ PolKitError *pk_error = NULL;
+
+ sender = dbus_g_method_get_sender (context);
+ connection = dbus_g_connection_get_connection (service->system_bus);
+
+ dbus_error_init (&dbus_error);
+ pk_caller = polkit_caller_new_from_dbus_name (connection, sender, &dbus_error);
+ if (!pk_caller) {
+ g_set_error (error,
+ CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_DBUS,
+ "Error getting information about caller: %s: %s",
+ dbus_error.name, dbus_error.message);
+ dbus_error_free (&dbus_error);
+ g_free (sender);
+
+ return FALSE;
+ }
+ g_free (sender);
+
+ pk_action = polkit_action_new ();
+ polkit_action_set_action_id (pk_action, "org.gnome.cpufreqselector");
+ pk_result = polkit_context_is_caller_authorized (service->pk_context,
+ pk_action, pk_caller,
+ TRUE, &pk_error);
+ polkit_caller_unref (pk_caller);
+ polkit_action_unref (pk_action);
+
+ if (polkit_error_is_set (pk_error)) {
+ g_set_error (error,
+ CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_GENERAL,
+ "Could not determine if caller is authorized: %s",
+ polkit_error_get_error_message (pk_error));
+ polkit_error_free (pk_error);
+
+ return FALSE;
+ }
+
+ if (pk_result != POLKIT_RESULT_YES) {
+ g_set_error (error,
+ CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_NOT_AUTHORIZED,
+ "Caller is not authorized: %s",
+ polkit_result_to_string_representation (pk_result));
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* D-BUS interface */
+gboolean
+cpufreq_selector_service_set_frequency (CPUFreqSelectorService *service,
+ guint cpu,
+ guint frequency,
+ DBusGMethodInvocation *context)
+{
+ CPUFreqSelector *selector;
+ GError *error = NULL;
+
+ reset_killtimer ();
+
+ if (!cpufreq_selector_service_check_policy (service, context, &error)) {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+
+ return FALSE;
+ }
+
+ if (cpu > MAX_CPUS) {
+ GError *err;
+
+ err = g_error_new (CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_DBUS,
+ "Error setting frequency on cpu %d: Invalid cpu",
+ cpu);
+ dbus_g_method_return_error (context, err);
+ g_error_free (err);
+
+ return FALSE;
+ }
+
+ selector = get_selector_for_cpu (service, cpu);
+ if (!selector) {
+ GError *err;
+
+ err = g_error_new (CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_DBUS,
+ "Error setting frequency on cpu %d: No cpufreq support",
+ cpu);
+ dbus_g_method_return_error (context, err);
+ g_error_free (err);
+
+ return FALSE;
+ }
+
+ cpufreq_selector_set_frequency (selector, frequency, &error);
+ if (error) {
+ GError *err;
+
+ err = g_error_new (CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_DBUS,
+ "Error setting frequency %d on cpu %d: %s",
+ frequency, cpu, error->message);
+ dbus_g_method_return_error (context, err);
+ g_error_free (err);
+ g_error_free (error);
+
+ return FALSE;
+ }
+
+ dbus_g_method_return (context);
+
+ return TRUE;
+}
+
+gboolean
+cpufreq_selector_service_set_governor (CPUFreqSelectorService *service,
+ guint cpu,
+ const gchar *governor,
+ DBusGMethodInvocation *context)
+{
+ CPUFreqSelector *selector;
+ GError *error = NULL;
+
+ reset_killtimer ();
+
+ if (!cpufreq_selector_service_check_policy (service, context, &error)) {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+
+ return FALSE;
+ }
+
+ if (cpu > MAX_CPUS) {
+ GError *err;
+
+ err = g_error_new (CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_DBUS,
+ "Error setting governor on cpu %d: Invalid cpu",
+ cpu);
+ dbus_g_method_return_error (context, err);
+ g_error_free (err);
+
+ return FALSE;
+ }
+
+ selector = get_selector_for_cpu (service, cpu);
+ if (!selector) {
+ GError *err;
+
+ err = g_error_new (CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_DBUS,
+ "Error setting governor on cpu %d: No cpufreq support",
+ cpu);
+ dbus_g_method_return_error (context, err);
+ g_error_free (err);
+
+ return FALSE;
+ }
+
+ cpufreq_selector_set_governor (selector, governor, &error);
+ if (error) {
+ GError *err;
+
+ err = g_error_new (CPUFREQ_SELECTOR_SERVICE_ERROR,
+ SERVICE_ERROR_DBUS,
+ "Error setting governor %s on cpu %d: %s",
+ governor, cpu, error->message);
+ dbus_g_method_return_error (context, err);
+ g_error_free (err);
+ g_error_free (error);
+
+ return FALSE;
+ }
+
+ dbus_g_method_return (context);
+
+ return TRUE;
+}
Added: trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-service.h
==============================================================================
--- (empty file)
+++ trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-service.h Sun May 25 15:32:01 2008
@@ -0,0 +1,69 @@
+/*
+ * GNOME CPUFreq Applet
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * 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.
+ */
+
+#ifndef __CPUFREQ_SELECTOR_SERVICE_H__
+#define __CPUFREQ_SELECTOR_SERVICE_H__
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+G_BEGIN_DECLS
+
+#define CPUFREQ_TYPE_SELECTOR_SERVICE (cpufreq_selector_service_get_type ())
+#define CPUFREQ_SELECTOR_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CPUFREQ_TYPE_SELECTOR_SERVICE, CPUFreqSelectorService))
+#define CPUFREQ_SELECTOR_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CPUFREQ_TYPE_SELECTOR_SERVICE, CPUFreqSelectorServiceClass))
+#define CPUFREQ_IS_SELECTOR_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CPUFREQ_TYPE_SELECTOR_SERVICE))
+#define CPUFREQ_IS_SELECTOR_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CPUFREQ_TYPE_SELECTOR_SERVICE))
+#define CPUFREQ_SELECTOR_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CPUFREQ_TYPE_SELECTOR_SERVICE, CPUFreqSelectorServiceClass))
+
+#define SELECTOR_SERVICE (cpufreq_selector_service_get_instance ())
+
+#define CPUFREQ_SELECTOR_SERVICE_ERROR (cpufreq_selector_service_error_quark ())
+#define CPUFREQ_TYPE_SELECTOR_SERVICE_ERROR (cpufreq_selector_service_error_get_type ())
+
+enum {
+ SERVICE_ERROR_GENERAL,
+ SERVICE_ERROR_DBUS,
+ SERVICE_ERROR_ALREADY_REGISTERED,
+ SERVICE_ERROR_NOT_AUTHORIZED
+};
+
+typedef struct _CPUFreqSelectorService CPUFreqSelectorService;
+typedef struct _CPUFreqSelectorServiceClass CPUFreqSelectorServiceClass;
+
+GType cpufreq_selector_service_get_type (void) G_GNUC_CONST;
+GType cpufreq_selector_service_error_get_type (void) G_GNUC_CONST;
+GQuark cpufreq_selector_service_error_quark (void) G_GNUC_CONST;
+CPUFreqSelectorService *cpufreq_selector_service_get_instance (void);
+gboolean cpufreq_selector_service_register (CPUFreqSelectorService *service,
+ GError **error);
+
+gboolean cpufreq_selector_service_set_frequency (CPUFreqSelectorService *service,
+ guint cpu,
+ guint frequency,
+ DBusGMethodInvocation *context);
+gboolean cpufreq_selector_service_set_governor (CPUFreqSelectorService *service,
+ guint cpu,
+ const gchar *governor,
+ DBusGMethodInvocation *context);
+
+G_END_DECLS
+
+#endif /* __CPUFREQ_SELECTOR_SERVICE_H__ */
+
Added: trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-service.xml
==============================================================================
--- (empty file)
+++ trunk/cpufreq/src/cpufreq-selector/cpufreq-selector-service.xml Sun May 25 15:32:01 2008
@@ -0,0 +1,18 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+
+<node name="/org/gnome/CPUFreqSelector">
+ <interface name="org.gnome.CPUFreqSelector">
+ <method name="SetFrequency">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg name="cpu" direction="in" type="u"/>
+ <arg name="frequency" direction="in" type="u"/>
+ </method>
+
+ <method name="SetGovernor">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg name="cpu" direction="in" type="u"/>
+ <arg name="governor" direction="in" type="s"/>
+ </method>
+
+ </interface>
+</node>
Modified: trunk/cpufreq/src/cpufreq-selector/main.c
==============================================================================
--- trunk/cpufreq/src/cpufreq-selector/main.c (original)
+++ trunk/cpufreq/src/cpufreq-selector/main.c Sun May 25 15:32:01 2008
@@ -23,16 +23,14 @@
#include "config.h"
#endif
+#include <glib.h>
#include <glib-object.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include "cpufreq-selector.h"
-#include "cpufreq-selector-sysfs.h"
-#include "cpufreq-selector-procfs.h"
-#ifdef HAVE_LIBCPUFREQ
-#include "cpufreq-selector-libcpufreq.h"
+#ifdef HAVE_POLKIT
+#include "cpufreq-selector-service.h"
#endif
+#include "cpufreq-selector-factory.h"
+
static gint cpu = 0;
static gchar *governor = NULL;
@@ -45,56 +43,111 @@
{ NULL }
};
-gint
-main (gint argc, gchar **argv)
+#ifdef HAVE_POLKIT
+static void
+do_exit (GMainLoop *loop,
+ GObject *object)
+{
+ if (g_main_loop_is_running (loop))
+ g_main_loop_quit (loop);
+}
+
+static void
+cpufreq_selector_set_values_dbus (void)
+{
+ DBusGConnection *connection;
+ DBusGProxy *proxy;
+ gboolean res;
+ GError *error = NULL;
+
+ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (!connection) {
+ g_printerr ("Couldn't connect to system bus: %s\n",
+ error->message);
+ g_error_free (error);
+
+ return;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (connection,
+ "org.gnome.CPUFreqSelector",
+ "/org/gnome/cpufreq_selector/selector",
+ "org.gnome.CPUFreqSelector");
+ if (!proxy) {
+ g_printerr ("Could not construct proxy object\n");
+
+ return;
+ }
+
+ if (governor) {
+ res = dbus_g_proxy_call (proxy, "SetGovernor", &error,
+ G_TYPE_UINT, cpu,
+ G_TYPE_STRING, governor,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ if (!res) {
+ if (error) {
+ g_printerr ("Error calling SetGovernor: %s\n", error->message);
+ g_error_free (error);
+ } else {
+ g_printerr ("Error calling SetGovernor\n");
+ }
+
+ g_object_unref (proxy);
+
+ return;
+ }
+ }
+
+ if (frequency != 0) {
+ res = dbus_g_proxy_call (proxy, "SetFrequency", &error,
+ G_TYPE_UINT, cpu,
+ G_TYPE_UINT, frequency,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ if (!res) {
+ if (error) {
+ g_printerr ("Error calling SetFrequency: %s\n", error->message);
+ g_error_free (error);
+ } else {
+ g_printerr ("Error calling SetFrequency\n");
+ }
+
+ g_object_unref (proxy);
+
+ return;
+ }
+ }
+
+ g_object_unref (proxy);
+}
+#endif /* HAVE_POLKIT */
+
+static void
+cpufreq_selector_set_values (void)
{
CPUFreqSelector *selector;
- GOptionContext *context;
GError *error = NULL;
- if (geteuid () != 0) {
- g_printerr ("You must be root\n");
-
- return 1;
- }
-
- if (argc < 2) {
- g_printerr ("Missing operand after `cpufreq-selector'\n");
- g_printerr ("Try `cpufreq-selector --help' for more information.\n");
+ selector = cpufreq_selector_factory_create_selector (cpu);
+ if (!selector) {
+ g_printerr ("No cpufreq support\n");
- return 1;
+ return;
}
- g_type_init ();
+ if (governor) {
+ cpufreq_selector_set_governor (selector, governor, &error);
- context = g_option_context_new ("- CPUFreq Selector");
- g_option_context_add_main_entries (context, options, NULL);
-
- if (! g_option_context_parse (context, &argc, &argv, &error)) {
if (error) {
g_printerr ("%s\n", error->message);
g_error_free (error);
error = NULL;
}
}
-
- g_option_context_free (context);
-#ifdef HAVE_LIBCPUFREQ
- selector = cpufreq_selector_libcpufreq_new (cpu);
-#else
- if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.6 kernel */
- selector = cpufreq_selector_sysfs_new (cpu);
- } else if (g_file_test ("/proc/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.4 kernel */
- selector = cpufreq_selector_procfs_new (cpu);
- } else {
- g_printerr ("No cpufreq support\n");
- return 1;
- }
-#endif /* HAVE_LIBCPUFREQ */
-
- if (governor) {
- cpufreq_selector_set_governor (selector, governor, &error);
+ if (frequency != 0) {
+ cpufreq_selector_set_frequency (selector, frequency, &error);
if (error) {
g_printerr ("%s\n", error->message);
@@ -103,17 +156,78 @@
}
}
- if (frequency != 0) {
- cpufreq_selector_set_frequency (selector, frequency, &error);
+ g_object_unref (selector);
+}
+
+gint
+main (gint argc, gchar **argv)
+{
+#ifdef HAVE_POLKIT
+ GMainLoop *loop;
+#endif
+ GOptionContext *context;
+ GError *error = NULL;
+
+#ifndef HAVE_POLKIT
+ if (geteuid () != 0) {
+ g_printerr ("You must be root\n");
+ return 1;
+ }
+
+ if (argc < 2) {
+ g_printerr ("Missing operand after `cpufreq-selector'\n");
+ g_printerr ("Try `cpufreq-selector --help' for more information.\n");
+
+ return 1;
+ }
+#endif
+
+ g_type_init ();
+
+ context = g_option_context_new ("- CPUFreq Selector");
+ g_option_context_add_main_entries (context, options, NULL);
+
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
if (error) {
g_printerr ("%s\n", error->message);
g_error_free (error);
- error = NULL;
- }
+ }
+
+ g_option_context_free (context);
+
+ return 1;
}
- g_object_unref (selector);
+ g_option_context_free (context);
+
+#ifdef HAVE_POLKIT
+ if (!cpufreq_selector_service_register (SELECTOR_SERVICE, &error)) {
+ if (governor || frequency != 0) {
+ cpufreq_selector_set_values_dbus ();
+
+ return 0;
+ }
+
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+
+ return 1;
+ }
+
+ cpufreq_selector_set_values ();
+
+ loop = g_main_loop_new (NULL, FALSE);
+ g_object_weak_ref (G_OBJECT (SELECTOR_SERVICE),
+ (GWeakNotify) do_exit,
+ loop);
+
+ g_main_loop_run (loop);
+
+ g_main_loop_unref (loop);
+#else /* !HAVE_POLKIT */
+ cpufreq_selector_set_values ();
+#endif /* HAVE_POLKIT */
return 0;
}
Added: trunk/cpufreq/src/cpufreq-selector/org.gnome.CPUFreqSelector.conf
==============================================================================
--- (empty file)
+++ trunk/cpufreq/src/cpufreq-selector/org.gnome.CPUFreqSelector.conf Sun May 25 15:32:01 2008
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<busconfig>
+
+ <!-- Only root can own the service -->
+ <policy user="root">
+ <allow own="org.gnome.CPUFreqSelector"/>
+ <allow send_interface="org.gnome.CPUFreqSelector"/>
+ </policy>
+
+ <policy context="default">
+ <allow send_interface="org.gnome.CPUFreqSelector"/>
+ </policy>
+
+</busconfig>
+
Added: trunk/cpufreq/src/cpufreq-selector/org.gnome.CPUFreqSelector.service.in
==============================================================================
--- (empty file)
+++ trunk/cpufreq/src/cpufreq-selector/org.gnome.CPUFreqSelector.service.in Sun May 25 15:32:01 2008
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.gnome.CPUFreqSelector
+Exec= BINDIR@/cpufreq-selector
+User=root
Added: trunk/cpufreq/src/cpufreq-selector/org.gnome.cpufreqselector.policy.in
==============================================================================
--- (empty file)
+++ trunk/cpufreq/src/cpufreq-selector/org.gnome.cpufreqselector.policy.in Sun May 25 15:32:01 2008
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+
+<policyconfig>
+
+ <vendor>The GNOME Project</vendor>
+ <vendor_url>http://www.gnome.org/</vendor_url>
+ <icon_name>gnome-cpu-frequency-applet</icon_name>
+
+ <action id="org.gnome.cpufreqselector">
+ <_description>Change CPU Frequency scaling</_description>
+ <_message>Privileges are required to change the CPU Frequency scaling.</_message>
+ <defaults>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin_keep_always</allow_active>
+ </defaults>
+ </action>
+
+</policyconfig>
Modified: trunk/cpufreq/src/cpufreq-utils.c
==============================================================================
--- trunk/cpufreq/src/cpufreq-utils.c (original)
+++ trunk/cpufreq/src/cpufreq-utils.c Sun May 25 15:32:01 2008
@@ -19,6 +19,15 @@
* Authors : Carlos GarcíCampos <carlosgc gnome org>
*/
+#include <config.h>
+
+#ifdef HAVE_POLKIT_GNOME
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <polkit/polkit.h>
+#include <polkit-dbus/polkit-dbus.h>
+#endif
+
#include <glib.h>
#include <gtk/gtkmessagedialog.h>
#include <sys/types.h>
@@ -99,6 +108,133 @@
gtk_widget_show (dialog);
}
+#ifdef HAVE_POLKIT_GNOME
+#define CACHE_VALIDITY_SEC 2
+
+static gboolean
+pk_io_watch_have_data (GIOChannel *channel,
+ GIOCondition condition,
+ PolKitContext *pk_context)
+{
+ polkit_context_io_func (pk_context,
+ g_io_channel_unix_get_fd (channel));
+ return TRUE;
+}
+
+static int
+pk_add_io_watch (PolKitContext *pk_context,
+ int watch_id)
+{
+ GIOChannel *channel;
+ guint id = 0;
+
+ channel = g_io_channel_unix_new (watch_id);
+ if (!channel)
+ return 0;
+
+ id = g_io_add_watch (channel, G_IO_IN,
+ (GIOFunc)pk_io_watch_have_data,
+ pk_context);
+ g_io_channel_unref (channel);
+
+ return id;
+}
+
+static void
+pk_remove_io_watch (PolKitContext *pk_context,
+ int watch_id)
+{
+ g_source_remove (watch_id);
+}
+
+static gboolean
+selector_is_available (const gchar *action)
+{
+ static DBusGConnection *system_bus = NULL;
+ static PolKitContext *pk_context = NULL;
+ PolKitCaller *pk_caller;
+ PolKitAction *pk_action;
+ PolKitResult pk_result;
+ PolKitError *pk_error = NULL;
+ GError *error = NULL;
+ DBusError dbus_error;
+
+ if (!system_bus) {
+ system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (!system_bus) {
+ g_warning (error->message);
+ g_error_free (error);
+
+ return FALSE;
+ }
+ }
+
+ if (!pk_context) {
+ PolKitError *pk_error = NULL;
+
+ pk_context = polkit_context_new ();
+ polkit_context_set_io_watch_functions (pk_context,
+ pk_add_io_watch,
+ pk_remove_io_watch);
+ if (!polkit_context_init (pk_context, &pk_error)) {
+ polkit_context_unref (pk_context);
+ pk_context = NULL;
+
+ if (polkit_error_is_set (pk_error)) {
+ g_warning (polkit_error_get_error_message (pk_error));
+ polkit_error_free (pk_error);
+ } else {
+ g_warning ("Cannot initialize libpolkit");
+ }
+
+ return FALSE;
+ }
+ }
+
+ dbus_error_init (&dbus_error);
+ pk_caller = polkit_caller_new_from_pid (dbus_g_connection_get_connection (system_bus),
+ getpid (), &dbus_error);
+ if (!pk_caller) {
+ g_warning ("Cannot get caller from dbus name");
+
+ return FALSE;
+ }
+
+ pk_action = polkit_action_new ();
+ polkit_action_set_action_id (pk_action, action);
+ pk_result = polkit_context_is_caller_authorized (pk_context,
+ pk_action, pk_caller,
+ FALSE, &pk_error);
+
+ polkit_caller_unref (pk_caller);
+ polkit_action_unref (pk_action);
+
+ if (polkit_error_is_set (pk_error)) {
+ g_warning (polkit_error_get_error_message (pk_error));
+ polkit_error_free (pk_error);
+
+ return FALSE;
+ }
+
+ return !(pk_result == POLKIT_RESULT_UNKNOWN || pk_result == POLKIT_RESULT_NO);
+}
+
+gboolean
+cpufreq_utils_selector_is_available (void)
+{
+ static gboolean cache = FALSE;
+ static time_t last_refreshed = 0;
+ time_t now;
+
+ time (&now);
+ if (ABS (now - last_refreshed) > CACHE_VALIDITY_SEC) {
+ cache = selector_is_available ("org.gnome.cpufreqselector");
+ last_refreshed = now;
+ }
+
+ return cache;
+}
+#else /* !HAVE_POLKIT_GNOME */
gboolean
cpufreq_utils_selector_is_available (void)
{
@@ -130,6 +266,7 @@
return FALSE;
}
+#endif /* HAVE_POLKIT_GNOME */
gchar *
cpufreq_utils_get_frequency_label (guint freq)
Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in (original)
+++ trunk/po/POTFILES.in Sun May 25 15:32:01 2008
@@ -28,6 +28,7 @@
cpufreq/src/cpufreq-monitor-factory.c
cpufreq/src/cpufreq-monitor-procfs.c
cpufreq/src/cpufreq-popup.c
+cpufreq/src/cpufreq-selector/org.gnome.cpufreqselector.policy.in
drivemount/GNOME_DriveMountApplet.server.in.in
drivemount/GNOME_DriveMountApplet.xml
drivemount/drive-button.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]